LCOV - code coverage report
Current view: top level - drivers/char/agp - frontend.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 416 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 22 0.0 %
Branches: 0 217 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * AGPGART driver frontend
       3                 :            :  * Copyright (C) 2004 Silicon Graphics, Inc.
       4                 :            :  * Copyright (C) 2002-2003 Dave Jones
       5                 :            :  * Copyright (C) 1999 Jeff Hartmann
       6                 :            :  * Copyright (C) 1999 Precision Insight, Inc.
       7                 :            :  * Copyright (C) 1999 Xi Graphics, Inc.
       8                 :            :  *
       9                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
      10                 :            :  * copy of this software and associated documentation files (the "Software"),
      11                 :            :  * to deal in the Software without restriction, including without limitation
      12                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
      14                 :            :  * Software is furnished to do so, subject to the following conditions:
      15                 :            :  *
      16                 :            :  * The above copyright notice and this permission notice shall be included
      17                 :            :  * in all copies or substantial portions of the Software.
      18                 :            :  *
      19                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20                 :            :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      22                 :            :  * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
      23                 :            :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
      24                 :            :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
      25                 :            :  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      26                 :            :  *
      27                 :            :  */
      28                 :            : 
      29                 :            : #include <linux/types.h>
      30                 :            : #include <linux/kernel.h>
      31                 :            : #include <linux/module.h>
      32                 :            : #include <linux/mman.h>
      33                 :            : #include <linux/pci.h>
      34                 :            : #include <linux/miscdevice.h>
      35                 :            : #include <linux/agp_backend.h>
      36                 :            : #include <linux/agpgart.h>
      37                 :            : #include <linux/slab.h>
      38                 :            : #include <linux/mm.h>
      39                 :            : #include <linux/fs.h>
      40                 :            : #include <linux/sched.h>
      41                 :            : #include <linux/uaccess.h>
      42                 :            : #include <asm/pgtable.h>
      43                 :            : #include "agp.h"
      44                 :            : 
      45                 :            : struct agp_front_data agp_fe;
      46                 :            : 
      47                 :          0 : struct agp_memory *agp_find_mem_by_key(int key)
      48                 :            : {
      49                 :          0 :         struct agp_memory *curr;
      50                 :            : 
      51         [ #  # ]:          0 :         if (agp_fe.current_controller == NULL)
      52                 :            :                 return NULL;
      53                 :            : 
      54                 :          0 :         curr = agp_fe.current_controller->pool;
      55                 :            : 
      56   [ #  #  #  #  :          0 :         while (curr != NULL) {
                   #  # ]
      57   [ #  #  #  #  :          0 :                 if (curr->key == key)
                   #  # ]
      58                 :            :                         break;
      59                 :          0 :                 curr = curr->next;
      60                 :            :         }
      61                 :            : 
      62                 :            :         DBG("key=%d -> mem=%p", key, curr);
      63                 :            :         return curr;
      64                 :            : }
      65                 :            : 
      66                 :          0 : static void agp_remove_from_pool(struct agp_memory *temp)
      67                 :            : {
      68                 :          0 :         struct agp_memory *prev;
      69                 :          0 :         struct agp_memory *next;
      70                 :            : 
      71                 :            :         /* Check to see if this is even in the memory pool */
      72                 :            : 
      73                 :          0 :         DBG("mem=%p", temp);
      74   [ #  #  #  # ]:          0 :         if (agp_find_mem_by_key(temp->key) != NULL) {
      75                 :          0 :                 next = temp->next;
      76                 :          0 :                 prev = temp->prev;
      77                 :            : 
      78         [ #  # ]:          0 :                 if (prev != NULL) {
      79                 :          0 :                         prev->next = next;
      80         [ #  # ]:          0 :                         if (next != NULL)
      81                 :          0 :                                 next->prev = prev;
      82                 :            : 
      83                 :            :                 } else {
      84                 :            :                         /* This is the first item on the list */
      85         [ #  # ]:          0 :                         if (next != NULL)
      86                 :          0 :                                 next->prev = NULL;
      87                 :            : 
      88                 :          0 :                         agp_fe.current_controller->pool = next;
      89                 :            :                 }
      90                 :            :         }
      91                 :          0 : }
      92                 :            : 
      93                 :            : /*
      94                 :            :  * Routines for managing each client's segment list -
      95                 :            :  * These routines handle adding and removing segments
      96                 :            :  * to each auth'ed client.
      97                 :            :  */
      98                 :            : 
      99                 :            : static struct
     100                 :          0 : agp_segment_priv *agp_find_seg_in_client(const struct agp_client *client,
     101                 :            :                                                 unsigned long offset,
     102                 :            :                                             int size, pgprot_t page_prot)
     103                 :            : {
     104                 :          0 :         struct agp_segment_priv *seg;
     105                 :          0 :         int i;
     106                 :          0 :         off_t pg_start;
     107                 :          0 :         size_t pg_count;
     108                 :            : 
     109                 :          0 :         pg_start = offset / 4096;
     110                 :          0 :         pg_count = size / 4096;
     111                 :          0 :         seg = *(client->segments);
     112                 :            : 
     113         [ #  # ]:          0 :         for (i = 0; i < client->num_segments; i++) {
     114         [ #  # ]:          0 :                 if ((seg[i].pg_start == pg_start) &&
     115         [ #  # ]:          0 :                     (seg[i].pg_count == pg_count) &&
     116         [ #  # ]:          0 :                     (pgprot_val(seg[i].prot) == pgprot_val(page_prot))) {
     117                 :            :                         return seg + i;
     118                 :            :                 }
     119                 :            :         }
     120                 :            : 
     121                 :            :         return NULL;
     122                 :            : }
     123                 :            : 
     124                 :            : static void agp_remove_seg_from_client(struct agp_client *client)
     125                 :            : {
     126                 :            :         DBG("client=%p", client);
     127                 :            : 
     128                 :            :         if (client->segments != NULL) {
     129                 :            :                 if (*(client->segments) != NULL) {
     130                 :            :                         DBG("Freeing %p from client %p", *(client->segments), client);
     131                 :            :                         kfree(*(client->segments));
     132                 :            :                 }
     133                 :            :                 DBG("Freeing %p from client %p", client->segments, client);
     134                 :            :                 kfree(client->segments);
     135                 :            :                 client->segments = NULL;
     136                 :            :         }
     137                 :            : }
     138                 :            : 
     139                 :          0 : static void agp_add_seg_to_client(struct agp_client *client,
     140                 :            :                                struct agp_segment_priv ** seg, int num_segments)
     141                 :            : {
     142                 :          0 :         struct agp_segment_priv **prev_seg;
     143                 :            : 
     144                 :          0 :         prev_seg = client->segments;
     145                 :            : 
     146                 :          0 :         if (prev_seg != NULL)
     147                 :          0 :                 agp_remove_seg_from_client(client);
     148                 :            : 
     149                 :          0 :         DBG("Adding seg %p (%d segments) to client %p", seg, num_segments, client);
     150                 :          0 :         client->num_segments = num_segments;
     151                 :          0 :         client->segments = seg;
     152                 :            : }
     153                 :            : 
     154                 :          0 : static pgprot_t agp_convert_mmap_flags(int prot)
     155                 :            : {
     156                 :          0 :         unsigned long prot_bits;
     157                 :            : 
     158                 :          0 :         prot_bits = calc_vm_prot_bits(prot, 0) | VM_SHARED;
     159                 :          0 :         return vm_get_page_prot(prot_bits);
     160                 :            : }
     161                 :            : 
     162                 :          0 : int agp_create_segment(struct agp_client *client, struct agp_region *region)
     163                 :            : {
     164                 :          0 :         struct agp_segment_priv **ret_seg;
     165                 :          0 :         struct agp_segment_priv *seg;
     166                 :          0 :         struct agp_segment *user_seg;
     167                 :          0 :         size_t i;
     168                 :            : 
     169                 :          0 :         seg = kzalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL);
     170         [ #  # ]:          0 :         if (seg == NULL) {
     171                 :          0 :                 kfree(region->seg_list);
     172                 :          0 :                 region->seg_list = NULL;
     173                 :          0 :                 return -ENOMEM;
     174                 :            :         }
     175                 :          0 :         user_seg = region->seg_list;
     176                 :            : 
     177         [ #  # ]:          0 :         for (i = 0; i < region->seg_count; i++) {
     178                 :          0 :                 seg[i].pg_start = user_seg[i].pg_start;
     179                 :          0 :                 seg[i].pg_count = user_seg[i].pg_count;
     180                 :          0 :                 seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot);
     181                 :            :         }
     182                 :          0 :         kfree(region->seg_list);
     183                 :          0 :         region->seg_list = NULL;
     184                 :            : 
     185                 :          0 :         ret_seg = kmalloc(sizeof(void *), GFP_KERNEL);
     186         [ #  # ]:          0 :         if (ret_seg == NULL) {
     187                 :          0 :                 kfree(seg);
     188                 :          0 :                 return -ENOMEM;
     189                 :            :         }
     190                 :          0 :         *ret_seg = seg;
     191         [ #  # ]:          0 :         agp_add_seg_to_client(client, ret_seg, region->seg_count);
     192                 :          0 :         return 0;
     193                 :            : }
     194                 :            : 
     195                 :            : /* End - Routines for managing each client's segment list */
     196                 :            : 
     197                 :            : /* This function must only be called when current_controller != NULL */
     198                 :          0 : static void agp_insert_into_pool(struct agp_memory * temp)
     199                 :            : {
     200                 :          0 :         struct agp_memory *prev;
     201                 :            : 
     202                 :          0 :         prev = agp_fe.current_controller->pool;
     203                 :            : 
     204                 :          0 :         if (prev != NULL) {
     205                 :          0 :                 prev->prev = temp;
     206                 :          0 :                 temp->next = prev;
     207                 :            :         }
     208                 :          0 :         agp_fe.current_controller->pool = temp;
     209                 :            : }
     210                 :            : 
     211                 :            : 
     212                 :            : /* File private list routines */
     213                 :            : 
     214                 :          0 : struct agp_file_private *agp_find_private(pid_t pid)
     215                 :            : {
     216                 :          0 :         struct agp_file_private *curr;
     217                 :            : 
     218                 :          0 :         curr = agp_fe.file_priv_list;
     219                 :            : 
     220   [ #  #  #  # ]:          0 :         while (curr != NULL) {
     221   [ #  #  #  # ]:          0 :                 if (curr->my_pid == pid)
     222                 :          0 :                         return curr;
     223                 :          0 :                 curr = curr->next;
     224                 :            :         }
     225                 :            : 
     226                 :            :         return NULL;
     227                 :            : }
     228                 :            : 
     229                 :          0 : static void agp_insert_file_private(struct agp_file_private * priv)
     230                 :            : {
     231                 :          0 :         struct agp_file_private *prev;
     232                 :            : 
     233                 :          0 :         prev = agp_fe.file_priv_list;
     234                 :            : 
     235                 :          0 :         if (prev != NULL)
     236                 :          0 :                 prev->prev = priv;
     237                 :          0 :         priv->next = prev;
     238                 :          0 :         agp_fe.file_priv_list = priv;
     239                 :            : }
     240                 :            : 
     241                 :          0 : static void agp_remove_file_private(struct agp_file_private * priv)
     242                 :            : {
     243                 :          0 :         struct agp_file_private *next;
     244                 :          0 :         struct agp_file_private *prev;
     245                 :            : 
     246                 :          0 :         next = priv->next;
     247                 :          0 :         prev = priv->prev;
     248                 :            : 
     249                 :          0 :         if (prev != NULL) {
     250                 :          0 :                 prev->next = next;
     251                 :            : 
     252         [ #  # ]:          0 :                 if (next != NULL)
     253                 :          0 :                         next->prev = prev;
     254                 :            : 
     255                 :            :         } else {
     256         [ #  # ]:          0 :                 if (next != NULL)
     257                 :          0 :                         next->prev = NULL;
     258                 :            : 
     259                 :          0 :                 agp_fe.file_priv_list = next;
     260                 :            :         }
     261                 :            : }
     262                 :            : 
     263                 :            : /* End - File flag list routines */
     264                 :            : 
     265                 :            : /*
     266                 :            :  * Wrappers for agp_free_memory & agp_allocate_memory
     267                 :            :  * These make sure that internal lists are kept updated.
     268                 :            :  */
     269                 :          0 : void agp_free_memory_wrap(struct agp_memory *memory)
     270                 :            : {
     271                 :          0 :         agp_remove_from_pool(memory);
     272                 :          0 :         agp_free_memory(memory);
     273                 :          0 : }
     274                 :            : 
     275                 :          0 : struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
     276                 :            : {
     277                 :          0 :         struct agp_memory *memory;
     278                 :            : 
     279                 :          0 :         memory = agp_allocate_memory(agp_bridge, pg_count, type);
     280         [ #  # ]:          0 :         if (memory == NULL)
     281                 :            :                 return NULL;
     282                 :            : 
     283         [ #  # ]:          0 :         agp_insert_into_pool(memory);
     284                 :          0 :         return memory;
     285                 :            : }
     286                 :            : 
     287                 :            : /* Routines for managing the list of controllers -
     288                 :            :  * These routines manage the current controller, and the list of
     289                 :            :  * controllers
     290                 :            :  */
     291                 :            : 
     292                 :          0 : static struct agp_controller *agp_find_controller_by_pid(pid_t id)
     293                 :            : {
     294                 :          0 :         struct agp_controller *controller;
     295                 :            : 
     296                 :          0 :         controller = agp_fe.controllers;
     297                 :            : 
     298   [ #  #  #  # ]:          0 :         while (controller != NULL) {
     299   [ #  #  #  # ]:          0 :                 if (controller->pid == id)
     300                 :            :                         return controller;
     301                 :          0 :                 controller = controller->next;
     302                 :            :         }
     303                 :            : 
     304                 :            :         return NULL;
     305                 :            : }
     306                 :            : 
     307                 :          0 : static struct agp_controller *agp_create_controller(pid_t id)
     308                 :            : {
     309                 :          0 :         struct agp_controller *controller;
     310                 :            : 
     311                 :          0 :         controller = kzalloc(sizeof(struct agp_controller), GFP_KERNEL);
     312         [ #  # ]:          0 :         if (controller == NULL)
     313                 :            :                 return NULL;
     314                 :            : 
     315                 :          0 :         controller->pid = id;
     316                 :          0 :         return controller;
     317                 :            : }
     318                 :            : 
     319                 :          0 : static int agp_insert_controller(struct agp_controller *controller)
     320                 :            : {
     321                 :          0 :         struct agp_controller *prev_controller;
     322                 :            : 
     323                 :          0 :         prev_controller = agp_fe.controllers;
     324                 :          0 :         controller->next = prev_controller;
     325                 :            : 
     326                 :          0 :         if (prev_controller != NULL)
     327                 :          0 :                 prev_controller->prev = controller;
     328                 :            : 
     329                 :          0 :         agp_fe.controllers = controller;
     330                 :            : 
     331                 :          0 :         return 0;
     332                 :            : }
     333                 :            : 
     334                 :            : static void agp_remove_all_clients(struct agp_controller *controller)
     335                 :            : {
     336                 :            :         struct agp_client *client;
     337                 :            :         struct agp_client *temp;
     338                 :            : 
     339                 :            :         client = controller->clients;
     340                 :            : 
     341                 :            :         while (client) {
     342                 :            :                 struct agp_file_private *priv;
     343                 :            : 
     344                 :            :                 temp = client;
     345                 :            :                 agp_remove_seg_from_client(temp);
     346                 :            :                 priv = agp_find_private(temp->pid);
     347                 :            : 
     348                 :            :                 if (priv != NULL) {
     349                 :            :                         clear_bit(AGP_FF_IS_VALID, &priv->access_flags);
     350                 :            :                         clear_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
     351                 :            :                 }
     352                 :            :                 client = client->next;
     353                 :            :                 kfree(temp);
     354                 :            :         }
     355                 :            : }
     356                 :            : 
     357                 :            : static void agp_remove_all_memory(struct agp_controller *controller)
     358                 :            : {
     359                 :            :         struct agp_memory *memory;
     360                 :            :         struct agp_memory *temp;
     361                 :            : 
     362                 :            :         memory = controller->pool;
     363                 :            : 
     364                 :            :         while (memory) {
     365                 :            :                 temp = memory;
     366                 :            :                 memory = memory->next;
     367                 :            :                 agp_free_memory_wrap(temp);
     368                 :            :         }
     369                 :            : }
     370                 :            : 
     371                 :          0 : static int agp_remove_controller(struct agp_controller *controller)
     372                 :            : {
     373                 :          0 :         struct agp_controller *prev_controller;
     374                 :          0 :         struct agp_controller *next_controller;
     375                 :            : 
     376                 :          0 :         prev_controller = controller->prev;
     377                 :          0 :         next_controller = controller->next;
     378                 :            : 
     379         [ #  # ]:          0 :         if (prev_controller != NULL) {
     380                 :          0 :                 prev_controller->next = next_controller;
     381         [ #  # ]:          0 :                 if (next_controller != NULL)
     382                 :          0 :                         next_controller->prev = prev_controller;
     383                 :            : 
     384                 :            :         } else {
     385         [ #  # ]:          0 :                 if (next_controller != NULL)
     386                 :          0 :                         next_controller->prev = NULL;
     387                 :            : 
     388                 :          0 :                 agp_fe.controllers = next_controller;
     389                 :            :         }
     390                 :            : 
     391                 :          0 :         agp_remove_all_memory(controller);
     392                 :          0 :         agp_remove_all_clients(controller);
     393                 :            : 
     394         [ #  # ]:          0 :         if (agp_fe.current_controller == controller) {
     395                 :          0 :                 agp_fe.current_controller = NULL;
     396                 :          0 :                 agp_fe.backend_acquired = false;
     397                 :          0 :                 agp_backend_release(agp_bridge);
     398                 :            :         }
     399                 :          0 :         kfree(controller);
     400                 :          0 :         return 0;
     401                 :            : }
     402                 :            : 
     403                 :          0 : static void agp_controller_make_current(struct agp_controller *controller)
     404                 :            : {
     405                 :          0 :         struct agp_client *clients;
     406                 :            : 
     407                 :          0 :         clients = controller->clients;
     408                 :            : 
     409         [ #  # ]:          0 :         while (clients != NULL) {
     410                 :          0 :                 struct agp_file_private *priv;
     411                 :            : 
     412                 :          0 :                 priv = agp_find_private(clients->pid);
     413                 :            : 
     414         [ #  # ]:          0 :                 if (priv != NULL) {
     415                 :          0 :                         set_bit(AGP_FF_IS_VALID, &priv->access_flags);
     416                 :          0 :                         set_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
     417                 :            :                 }
     418                 :          0 :                 clients = clients->next;
     419                 :            :         }
     420                 :            : 
     421                 :          0 :         agp_fe.current_controller = controller;
     422                 :          0 : }
     423                 :            : 
     424                 :            : static void agp_controller_release_current(struct agp_controller *controller,
     425                 :            :                                       struct agp_file_private *controller_priv)
     426                 :            : {
     427                 :            :         struct agp_client *clients;
     428                 :            : 
     429                 :            :         clear_bit(AGP_FF_IS_VALID, &controller_priv->access_flags);
     430                 :            :         clients = controller->clients;
     431                 :            : 
     432                 :            :         while (clients != NULL) {
     433                 :            :                 struct agp_file_private *priv;
     434                 :            : 
     435                 :            :                 priv = agp_find_private(clients->pid);
     436                 :            : 
     437                 :            :                 if (priv != NULL)
     438                 :            :                         clear_bit(AGP_FF_IS_VALID, &priv->access_flags);
     439                 :            : 
     440                 :            :                 clients = clients->next;
     441                 :            :         }
     442                 :            : 
     443                 :            :         agp_fe.current_controller = NULL;
     444                 :            :         agp_fe.used_by_controller = false;
     445                 :            :         agp_backend_release(agp_bridge);
     446                 :            : }
     447                 :            : 
     448                 :            : /*
     449                 :            :  * Routines for managing client lists -
     450                 :            :  * These routines are for managing the list of auth'ed clients.
     451                 :            :  */
     452                 :            : 
     453                 :            : static struct agp_client
     454                 :          0 : *agp_find_client_in_controller(struct agp_controller *controller, pid_t id)
     455                 :            : {
     456                 :          0 :         struct agp_client *client;
     457                 :            : 
     458                 :          0 :         if (controller == NULL)
     459                 :            :                 return NULL;
     460                 :            : 
     461                 :          0 :         client = controller->clients;
     462                 :            : 
     463   [ #  #  #  #  :          0 :         while (client != NULL) {
          #  #  #  #  #  
                      # ]
     464   [ #  #  #  #  :          0 :                 if (client->pid == id)
          #  #  #  #  #  
                      # ]
     465                 :            :                         return client;
     466                 :          0 :                 client = client->next;
     467                 :            :         }
     468                 :            : 
     469                 :            :         return NULL;
     470                 :            : }
     471                 :            : 
     472                 :          0 : static struct agp_controller *agp_find_controller_for_client(pid_t id)
     473                 :            : {
     474                 :          0 :         struct agp_controller *controller;
     475                 :            : 
     476                 :          0 :         controller = agp_fe.controllers;
     477                 :            : 
     478         [ #  # ]:          0 :         while (controller != NULL) {
     479         [ #  # ]:          0 :                 if ((agp_find_client_in_controller(controller, id)) != NULL)
     480                 :            :                         return controller;
     481                 :          0 :                 controller = controller->next;
     482                 :            :         }
     483                 :            : 
     484                 :            :         return NULL;
     485                 :            : }
     486                 :            : 
     487                 :          0 : struct agp_client *agp_find_client_by_pid(pid_t id)
     488                 :            : {
     489                 :          0 :         struct agp_client *temp;
     490                 :            : 
     491   [ #  #  #  #  :          0 :         if (agp_fe.current_controller == NULL)
                   #  # ]
     492                 :            :                 return NULL;
     493                 :            : 
     494                 :          0 :         temp = agp_find_client_in_controller(agp_fe.current_controller, id);
     495                 :            :         return temp;
     496                 :            : }
     497                 :            : 
     498                 :          0 : static void agp_insert_client(struct agp_client *client)
     499                 :            : {
     500                 :          0 :         struct agp_client *prev_client;
     501                 :            : 
     502                 :          0 :         prev_client = agp_fe.current_controller->clients;
     503                 :          0 :         client->next = prev_client;
     504                 :            : 
     505                 :          0 :         if (prev_client != NULL)
     506                 :          0 :                 prev_client->prev = client;
     507                 :            : 
     508                 :          0 :         agp_fe.current_controller->clients = client;
     509                 :          0 :         agp_fe.current_controller->num_clients++;
     510                 :            : }
     511                 :            : 
     512                 :          0 : struct agp_client *agp_create_client(pid_t id)
     513                 :            : {
     514                 :          0 :         struct agp_client *new_client;
     515                 :            : 
     516                 :          0 :         new_client = kzalloc(sizeof(struct agp_client), GFP_KERNEL);
     517         [ #  # ]:          0 :         if (new_client == NULL)
     518                 :            :                 return NULL;
     519                 :            : 
     520                 :          0 :         new_client->pid = id;
     521         [ #  # ]:          0 :         agp_insert_client(new_client);
     522                 :          0 :         return new_client;
     523                 :            : }
     524                 :            : 
     525                 :          0 : int agp_remove_client(pid_t id)
     526                 :            : {
     527                 :          0 :         struct agp_client *client;
     528                 :          0 :         struct agp_client *prev_client;
     529                 :          0 :         struct agp_client *next_client;
     530                 :          0 :         struct agp_controller *controller;
     531                 :            : 
     532                 :          0 :         controller = agp_find_controller_for_client(id);
     533         [ #  # ]:          0 :         if (controller == NULL)
     534                 :            :                 return -EINVAL;
     535                 :            : 
     536                 :          0 :         client = agp_find_client_in_controller(controller, id);
     537         [ #  # ]:          0 :         if (client == NULL)
     538                 :            :                 return -EINVAL;
     539                 :            : 
     540                 :          0 :         prev_client = client->prev;
     541                 :          0 :         next_client = client->next;
     542                 :            : 
     543         [ #  # ]:          0 :         if (prev_client != NULL) {
     544                 :          0 :                 prev_client->next = next_client;
     545         [ #  # ]:          0 :                 if (next_client != NULL)
     546                 :          0 :                         next_client->prev = prev_client;
     547                 :            : 
     548                 :            :         } else {
     549         [ #  # ]:          0 :                 if (next_client != NULL)
     550                 :          0 :                         next_client->prev = NULL;
     551                 :          0 :                 controller->clients = next_client;
     552                 :            :         }
     553                 :            : 
     554                 :          0 :         controller->num_clients--;
     555                 :          0 :         agp_remove_seg_from_client(client);
     556                 :          0 :         kfree(client);
     557                 :          0 :         return 0;
     558                 :            : }
     559                 :            : 
     560                 :            : /* End - Routines for managing client lists */
     561                 :            : 
     562                 :            : /* File Operations */
     563                 :            : 
     564                 :          0 : static int agp_mmap(struct file *file, struct vm_area_struct *vma)
     565                 :            : {
     566                 :          0 :         unsigned int size, current_size;
     567                 :          0 :         unsigned long offset;
     568                 :          0 :         struct agp_client *client;
     569                 :          0 :         struct agp_file_private *priv = file->private_data;
     570                 :          0 :         struct agp_kern_info kerninfo;
     571                 :            : 
     572                 :          0 :         mutex_lock(&(agp_fe.agp_mutex));
     573                 :            : 
     574         [ #  # ]:          0 :         if (agp_fe.backend_acquired != true)
     575                 :          0 :                 goto out_eperm;
     576                 :            : 
     577         [ #  # ]:          0 :         if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags)))
     578                 :          0 :                 goto out_eperm;
     579                 :            : 
     580                 :          0 :         agp_copy_info(agp_bridge, &kerninfo);
     581                 :          0 :         size = vma->vm_end - vma->vm_start;
     582                 :          0 :         current_size = kerninfo.aper_size;
     583                 :          0 :         current_size = current_size * 0x100000;
     584                 :          0 :         offset = vma->vm_pgoff << PAGE_SHIFT;
     585                 :          0 :         DBG("%lx:%lx", offset, offset+size);
     586                 :            : 
     587         [ #  # ]:          0 :         if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {
     588         [ #  # ]:          0 :                 if ((size + offset) > current_size)
     589                 :          0 :                         goto out_inval;
     590                 :            : 
     591         [ #  # ]:          0 :                 client = agp_find_client_by_pid(current->pid);
     592                 :            : 
     593         [ #  # ]:          0 :                 if (client == NULL)
     594                 :          0 :                         goto out_eperm;
     595                 :            : 
     596         [ #  # ]:          0 :                 if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot))
     597                 :          0 :                         goto out_inval;
     598                 :            : 
     599                 :          0 :                 DBG("client vm_ops=%p", kerninfo.vm_ops);
     600         [ #  # ]:          0 :                 if (kerninfo.vm_ops) {
     601                 :          0 :                         vma->vm_ops = kerninfo.vm_ops;
     602         [ #  # ]:          0 :                 } else if (io_remap_pfn_range(vma, vma->vm_start,
     603                 :          0 :                                 (kerninfo.aper_base + offset) >> PAGE_SHIFT,
     604                 :            :                                 size,
     605                 :            :                                 pgprot_writecombine(vma->vm_page_prot))) {
     606                 :          0 :                         goto out_again;
     607                 :            :                 }
     608                 :          0 :                 mutex_unlock(&(agp_fe.agp_mutex));
     609                 :          0 :                 return 0;
     610                 :            :         }
     611                 :            : 
     612         [ #  # ]:          0 :         if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
     613         [ #  # ]:          0 :                 if (size != current_size)
     614                 :          0 :                         goto out_inval;
     615                 :            : 
     616                 :          0 :                 DBG("controller vm_ops=%p", kerninfo.vm_ops);
     617         [ #  # ]:          0 :                 if (kerninfo.vm_ops) {
     618                 :          0 :                         vma->vm_ops = kerninfo.vm_ops;
     619         [ #  # ]:          0 :                 } else if (io_remap_pfn_range(vma, vma->vm_start,
     620                 :          0 :                                 kerninfo.aper_base >> PAGE_SHIFT,
     621                 :            :                                 size,
     622                 :            :                                 pgprot_writecombine(vma->vm_page_prot))) {
     623                 :          0 :                         goto out_again;
     624                 :            :                 }
     625                 :          0 :                 mutex_unlock(&(agp_fe.agp_mutex));
     626                 :          0 :                 return 0;
     627                 :            :         }
     628                 :            : 
     629                 :          0 : out_eperm:
     630                 :          0 :         mutex_unlock(&(agp_fe.agp_mutex));
     631                 :          0 :         return -EPERM;
     632                 :            : 
     633                 :          0 : out_inval:
     634                 :          0 :         mutex_unlock(&(agp_fe.agp_mutex));
     635                 :          0 :         return -EINVAL;
     636                 :            : 
     637                 :          0 : out_again:
     638                 :          0 :         mutex_unlock(&(agp_fe.agp_mutex));
     639                 :          0 :         return -EAGAIN;
     640                 :            : }
     641                 :            : 
     642                 :          0 : static int agp_release(struct inode *inode, struct file *file)
     643                 :            : {
     644                 :          0 :         struct agp_file_private *priv = file->private_data;
     645                 :            : 
     646                 :          0 :         mutex_lock(&(agp_fe.agp_mutex));
     647                 :            : 
     648                 :          0 :         DBG("priv=%p", priv);
     649                 :            : 
     650         [ #  # ]:          0 :         if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
     651                 :          0 :                 struct agp_controller *controller;
     652                 :            : 
     653                 :          0 :                 controller = agp_find_controller_by_pid(priv->my_pid);
     654                 :            : 
     655         [ #  # ]:          0 :                 if (controller != NULL) {
     656         [ #  # ]:          0 :                         if (controller == agp_fe.current_controller)
     657                 :          0 :                                 agp_controller_release_current(controller, priv);
     658                 :          0 :                         agp_remove_controller(controller);
     659                 :          0 :                         controller = NULL;
     660                 :            :                 }
     661                 :            :         }
     662                 :            : 
     663         [ #  # ]:          0 :         if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags))
     664                 :          0 :                 agp_remove_client(priv->my_pid);
     665                 :            : 
     666         [ #  # ]:          0 :         agp_remove_file_private(priv);
     667                 :          0 :         kfree(priv);
     668                 :          0 :         file->private_data = NULL;
     669                 :          0 :         mutex_unlock(&(agp_fe.agp_mutex));
     670                 :          0 :         return 0;
     671                 :            : }
     672                 :            : 
     673                 :          0 : static int agp_open(struct inode *inode, struct file *file)
     674                 :            : {
     675         [ #  # ]:          0 :         int minor = iminor(inode);
     676                 :          0 :         struct agp_file_private *priv;
     677                 :          0 :         struct agp_client *client;
     678                 :            : 
     679         [ #  # ]:          0 :         if (minor != AGPGART_MINOR)
     680                 :            :                 return -ENXIO;
     681                 :            : 
     682                 :          0 :         mutex_lock(&(agp_fe.agp_mutex));
     683                 :            : 
     684                 :          0 :         priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
     685         [ #  # ]:          0 :         if (priv == NULL) {
     686                 :          0 :                 mutex_unlock(&(agp_fe.agp_mutex));
     687                 :          0 :                 return -ENOMEM;
     688                 :            :         }
     689                 :            : 
     690                 :          0 :         set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
     691                 :          0 :         priv->my_pid = current->pid;
     692                 :            : 
     693         [ #  # ]:          0 :         if (capable(CAP_SYS_RAWIO))
     694                 :            :                 /* Root priv, can be controller */
     695                 :          0 :                 set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags);
     696                 :            : 
     697         [ #  # ]:          0 :         client = agp_find_client_by_pid(current->pid);
     698                 :            : 
     699         [ #  # ]:          0 :         if (client != NULL) {
     700                 :          0 :                 set_bit(AGP_FF_IS_CLIENT, &priv->access_flags);
     701                 :          0 :                 set_bit(AGP_FF_IS_VALID, &priv->access_flags);
     702                 :            :         }
     703                 :          0 :         file->private_data = (void *) priv;
     704         [ #  # ]:          0 :         agp_insert_file_private(priv);
     705                 :          0 :         DBG("private=%p, client=%p", priv, client);
     706                 :            : 
     707                 :          0 :         mutex_unlock(&(agp_fe.agp_mutex));
     708                 :            : 
     709                 :          0 :         return 0;
     710                 :            : }
     711                 :            : 
     712                 :            : static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
     713                 :            : {
     714                 :            :         struct agp_info userinfo;
     715                 :            :         struct agp_kern_info kerninfo;
     716                 :            : 
     717                 :            :         agp_copy_info(agp_bridge, &kerninfo);
     718                 :            : 
     719                 :            :         memset(&userinfo, 0, sizeof(userinfo));
     720                 :            :         userinfo.version.major = kerninfo.version.major;
     721                 :            :         userinfo.version.minor = kerninfo.version.minor;
     722                 :            :         userinfo.bridge_id = kerninfo.device->vendor |
     723                 :            :             (kerninfo.device->device << 16);
     724                 :            :         userinfo.agp_mode = kerninfo.mode;
     725                 :            :         userinfo.aper_base = kerninfo.aper_base;
     726                 :            :         userinfo.aper_size = kerninfo.aper_size;
     727                 :            :         userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
     728                 :            :         userinfo.pg_used = kerninfo.current_memory;
     729                 :            : 
     730                 :            :         if (copy_to_user(arg, &userinfo, sizeof(struct agp_info)))
     731                 :            :                 return -EFAULT;
     732                 :            : 
     733                 :            :         return 0;
     734                 :            : }
     735                 :            : 
     736                 :          0 : int agpioc_acquire_wrap(struct agp_file_private *priv)
     737                 :            : {
     738                 :          0 :         struct agp_controller *controller;
     739                 :            : 
     740                 :          0 :         DBG("");
     741                 :            : 
     742         [ #  # ]:          0 :         if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags)))
     743                 :            :                 return -EPERM;
     744                 :            : 
     745         [ #  # ]:          0 :         if (agp_fe.current_controller != NULL)
     746                 :            :                 return -EBUSY;
     747                 :            : 
     748         [ #  # ]:          0 :         if (!agp_bridge)
     749                 :            :                 return -ENODEV;
     750                 :            : 
     751         [ #  # ]:          0 :         if (atomic_read(&agp_bridge->agp_in_use))
     752                 :            :                 return -EBUSY;
     753                 :            : 
     754                 :          0 :         atomic_inc(&agp_bridge->agp_in_use);
     755                 :            : 
     756                 :          0 :         agp_fe.backend_acquired = true;
     757                 :            : 
     758                 :          0 :         controller = agp_find_controller_by_pid(priv->my_pid);
     759                 :            : 
     760         [ #  # ]:          0 :         if (controller != NULL) {
     761                 :          0 :                 agp_controller_make_current(controller);
     762                 :            :         } else {
     763                 :          0 :                 controller = agp_create_controller(priv->my_pid);
     764                 :            : 
     765                 :          0 :                 if (controller == NULL) {
     766                 :          0 :                         agp_fe.backend_acquired = false;
     767                 :          0 :                         agp_backend_release(agp_bridge);
     768                 :          0 :                         return -ENOMEM;
     769                 :            :                 }
     770         [ #  # ]:          0 :                 agp_insert_controller(controller);
     771                 :          0 :                 agp_controller_make_current(controller);
     772                 :            :         }
     773                 :            : 
     774                 :          0 :         set_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags);
     775                 :          0 :         set_bit(AGP_FF_IS_VALID, &priv->access_flags);
     776                 :          0 :         return 0;
     777                 :            : }
     778                 :            : 
     779                 :          0 : int agpioc_release_wrap(struct agp_file_private *priv)
     780                 :            : {
     781                 :          0 :         DBG("");
     782                 :          0 :         agp_controller_release_current(agp_fe.current_controller, priv);
     783                 :          0 :         return 0;
     784                 :            : }
     785                 :            : 
     786                 :          0 : int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg)
     787                 :            : {
     788                 :          0 :         struct agp_setup mode;
     789                 :            : 
     790                 :          0 :         DBG("");
     791         [ #  # ]:          0 :         if (copy_from_user(&mode, arg, sizeof(struct agp_setup)))
     792                 :            :                 return -EFAULT;
     793                 :            : 
     794                 :          0 :         agp_enable(agp_bridge, mode.agp_mode);
     795                 :          0 :         return 0;
     796                 :            : }
     797                 :            : 
     798                 :            : static int agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
     799                 :            : {
     800                 :            :         struct agp_region reserve;
     801                 :            :         struct agp_client *client;
     802                 :            :         struct agp_file_private *client_priv;
     803                 :            : 
     804                 :            :         DBG("");
     805                 :            :         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
     806                 :            :                 return -EFAULT;
     807                 :            : 
     808                 :            :         if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
     809                 :            :                 return -EFAULT;
     810                 :            : 
     811                 :            :         client = agp_find_client_by_pid(reserve.pid);
     812                 :            : 
     813                 :            :         if (reserve.seg_count == 0) {
     814                 :            :                 /* remove a client */
     815                 :            :                 client_priv = agp_find_private(reserve.pid);
     816                 :            : 
     817                 :            :                 if (client_priv != NULL) {
     818                 :            :                         set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
     819                 :            :                         set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
     820                 :            :                 }
     821                 :            :                 if (client == NULL) {
     822                 :            :                         /* client is already removed */
     823                 :            :                         return 0;
     824                 :            :                 }
     825                 :            :                 return agp_remove_client(reserve.pid);
     826                 :            :         } else {
     827                 :            :                 struct agp_segment *segment;
     828                 :            : 
     829                 :            :                 if (reserve.seg_count >= 16384)
     830                 :            :                         return -EINVAL;
     831                 :            : 
     832                 :            :                 segment = kmalloc((sizeof(struct agp_segment) * reserve.seg_count),
     833                 :            :                                   GFP_KERNEL);
     834                 :            : 
     835                 :            :                 if (segment == NULL)
     836                 :            :                         return -ENOMEM;
     837                 :            : 
     838                 :            :                 if (copy_from_user(segment, (void __user *) reserve.seg_list,
     839                 :            :                                    sizeof(struct agp_segment) * reserve.seg_count)) {
     840                 :            :                         kfree(segment);
     841                 :            :                         return -EFAULT;
     842                 :            :                 }
     843                 :            :                 reserve.seg_list = segment;
     844                 :            : 
     845                 :            :                 if (client == NULL) {
     846                 :            :                         /* Create the client and add the segment */
     847                 :            :                         client = agp_create_client(reserve.pid);
     848                 :            : 
     849                 :            :                         if (client == NULL) {
     850                 :            :                                 kfree(segment);
     851                 :            :                                 return -ENOMEM;
     852                 :            :                         }
     853                 :            :                         client_priv = agp_find_private(reserve.pid);
     854                 :            : 
     855                 :            :                         if (client_priv != NULL) {
     856                 :            :                                 set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
     857                 :            :                                 set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
     858                 :            :                         }
     859                 :            :                 }
     860                 :            :                 return agp_create_segment(client, &reserve);
     861                 :            :         }
     862                 :            :         /* Will never really happen */
     863                 :            :         return -EINVAL;
     864                 :            : }
     865                 :            : 
     866                 :          0 : int agpioc_protect_wrap(struct agp_file_private *priv)
     867                 :            : {
     868                 :          0 :         DBG("");
     869                 :            :         /* This function is not currently implemented */
     870                 :          0 :         return -EINVAL;
     871                 :            : }
     872                 :            : 
     873                 :            : static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
     874                 :            : {
     875                 :            :         struct agp_memory *memory;
     876                 :            :         struct agp_allocate alloc;
     877                 :            : 
     878                 :            :         DBG("");
     879                 :            :         if (copy_from_user(&alloc, arg, sizeof(struct agp_allocate)))
     880                 :            :                 return -EFAULT;
     881                 :            : 
     882                 :            :         if (alloc.type >= AGP_USER_TYPES)
     883                 :            :                 return -EINVAL;
     884                 :            : 
     885                 :            :         memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
     886                 :            : 
     887                 :            :         if (memory == NULL)
     888                 :            :                 return -ENOMEM;
     889                 :            : 
     890                 :            :         alloc.key = memory->key;
     891                 :            :         alloc.physical = memory->physical;
     892                 :            : 
     893                 :            :         if (copy_to_user(arg, &alloc, sizeof(struct agp_allocate))) {
     894                 :            :                 agp_free_memory_wrap(memory);
     895                 :            :                 return -EFAULT;
     896                 :            :         }
     897                 :            :         return 0;
     898                 :            : }
     899                 :            : 
     900                 :          0 : int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg)
     901                 :            : {
     902                 :          0 :         struct agp_memory *memory;
     903                 :            : 
     904                 :          0 :         DBG("");
     905         [ #  # ]:          0 :         memory = agp_find_mem_by_key(arg);
     906                 :            : 
     907         [ #  # ]:          0 :         if (memory == NULL)
     908                 :            :                 return -EINVAL;
     909                 :            : 
     910                 :          0 :         agp_free_memory_wrap(memory);
     911                 :          0 :         return 0;
     912                 :            : }
     913                 :            : 
     914                 :            : static int agpioc_bind_wrap(struct agp_file_private *priv, void __user *arg)
     915                 :            : {
     916                 :            :         struct agp_bind bind_info;
     917                 :            :         struct agp_memory *memory;
     918                 :            : 
     919                 :            :         DBG("");
     920                 :            :         if (copy_from_user(&bind_info, arg, sizeof(struct agp_bind)))
     921                 :            :                 return -EFAULT;
     922                 :            : 
     923                 :            :         memory = agp_find_mem_by_key(bind_info.key);
     924                 :            : 
     925                 :            :         if (memory == NULL)
     926                 :            :                 return -EINVAL;
     927                 :            : 
     928                 :            :         return agp_bind_memory(memory, bind_info.pg_start);
     929                 :            : }
     930                 :            : 
     931                 :            : static int agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg)
     932                 :            : {
     933                 :            :         struct agp_memory *memory;
     934                 :            :         struct agp_unbind unbind;
     935                 :            : 
     936                 :            :         DBG("");
     937                 :            :         if (copy_from_user(&unbind, arg, sizeof(struct agp_unbind)))
     938                 :            :                 return -EFAULT;
     939                 :            : 
     940                 :            :         memory = agp_find_mem_by_key(unbind.key);
     941                 :            : 
     942                 :            :         if (memory == NULL)
     943                 :            :                 return -EINVAL;
     944                 :            : 
     945                 :            :         return agp_unbind_memory(memory);
     946                 :            : }
     947                 :            : 
     948                 :          0 : static long agp_ioctl(struct file *file,
     949                 :            :                      unsigned int cmd, unsigned long arg)
     950                 :            : {
     951                 :          0 :         struct agp_file_private *curr_priv = file->private_data;
     952                 :          0 :         int ret_val = -ENOTTY;
     953                 :            : 
     954                 :          0 :         DBG("priv=%p, cmd=%x", curr_priv, cmd);
     955                 :          0 :         mutex_lock(&(agp_fe.agp_mutex));
     956                 :            : 
     957   [ #  #  #  # ]:          0 :         if ((agp_fe.current_controller == NULL) &&
     958                 :            :             (cmd != AGPIOC_ACQUIRE)) {
     959                 :          0 :                 ret_val = -EINVAL;
     960                 :          0 :                 goto ioctl_out;
     961                 :            :         }
     962   [ #  #  #  # ]:          0 :         if ((agp_fe.backend_acquired != true) &&
     963                 :            :             (cmd != AGPIOC_ACQUIRE)) {
     964                 :          0 :                 ret_val = -EBUSY;
     965                 :          0 :                 goto ioctl_out;
     966                 :            :         }
     967         [ #  # ]:          0 :         if (cmd != AGPIOC_ACQUIRE) {
     968         [ #  # ]:          0 :                 if (!(test_bit(AGP_FF_IS_CONTROLLER, &curr_priv->access_flags))) {
     969                 :          0 :                         ret_val = -EPERM;
     970                 :          0 :                         goto ioctl_out;
     971                 :            :                 }
     972                 :            :                 /* Use the original pid of the controller,
     973                 :            :                  * in case it's threaded */
     974                 :            : 
     975         [ #  # ]:          0 :                 if (agp_fe.current_controller->pid != curr_priv->my_pid) {
     976                 :          0 :                         ret_val = -EBUSY;
     977                 :          0 :                         goto ioctl_out;
     978                 :            :                 }
     979                 :            :         }
     980                 :            : 
     981   [ #  #  #  #  :          0 :         switch (cmd) {
          #  #  #  #  #  
                   #  # ]
     982                 :          0 :         case AGPIOC_INFO:
     983                 :          0 :                 ret_val = agpioc_info_wrap(curr_priv, (void __user *) arg);
     984                 :          0 :                 break;
     985                 :            : 
     986                 :          0 :         case AGPIOC_ACQUIRE:
     987                 :          0 :                 ret_val = agpioc_acquire_wrap(curr_priv);
     988                 :          0 :                 break;
     989                 :            : 
     990                 :            :         case AGPIOC_RELEASE:
     991                 :          0 :                 ret_val = agpioc_release_wrap(curr_priv);
     992                 :          0 :                 break;
     993                 :            : 
     994                 :          0 :         case AGPIOC_SETUP:
     995                 :          0 :                 ret_val = agpioc_setup_wrap(curr_priv, (void __user *) arg);
     996                 :          0 :                 break;
     997                 :            : 
     998                 :          0 :         case AGPIOC_RESERVE:
     999                 :          0 :                 ret_val = agpioc_reserve_wrap(curr_priv, (void __user *) arg);
    1000                 :          0 :                 break;
    1001                 :            : 
    1002                 :            :         case AGPIOC_PROTECT:
    1003                 :          0 :                 ret_val = agpioc_protect_wrap(curr_priv);
    1004                 :          0 :                 break;
    1005                 :            : 
    1006                 :          0 :         case AGPIOC_ALLOCATE:
    1007                 :          0 :                 ret_val = agpioc_allocate_wrap(curr_priv, (void __user *) arg);
    1008                 :          0 :                 break;
    1009                 :            : 
    1010                 :          0 :         case AGPIOC_DEALLOCATE:
    1011                 :          0 :                 ret_val = agpioc_deallocate_wrap(curr_priv, (int) arg);
    1012                 :          0 :                 break;
    1013                 :            : 
    1014                 :          0 :         case AGPIOC_BIND:
    1015                 :          0 :                 ret_val = agpioc_bind_wrap(curr_priv, (void __user *) arg);
    1016                 :          0 :                 break;
    1017                 :            : 
    1018                 :          0 :         case AGPIOC_UNBIND:
    1019                 :          0 :                 ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg);
    1020                 :          0 :                 break;
    1021                 :            :                
    1022                 :            :         case AGPIOC_CHIPSET_FLUSH:
    1023                 :            :                 break;
    1024                 :            :         }
    1025                 :            : 
    1026                 :          0 : ioctl_out:
    1027                 :          0 :         DBG("ioctl returns %d\n", ret_val);
    1028                 :          0 :         mutex_unlock(&(agp_fe.agp_mutex));
    1029                 :          0 :         return ret_val;
    1030                 :            : }
    1031                 :            : 
    1032                 :            : static const struct file_operations agp_fops =
    1033                 :            : {
    1034                 :            :         .owner          = THIS_MODULE,
    1035                 :            :         .llseek         = no_llseek,
    1036                 :            :         .unlocked_ioctl = agp_ioctl,
    1037                 :            : #ifdef CONFIG_COMPAT
    1038                 :            :         .compat_ioctl   = compat_agp_ioctl,
    1039                 :            : #endif
    1040                 :            :         .mmap           = agp_mmap,
    1041                 :            :         .open           = agp_open,
    1042                 :            :         .release        = agp_release,
    1043                 :            : };
    1044                 :            : 
    1045                 :            : static struct miscdevice agp_miscdev =
    1046                 :            : {
    1047                 :            :         .minor  = AGPGART_MINOR,
    1048                 :            :         .name   = "agpgart",
    1049                 :            :         .fops   = &agp_fops
    1050                 :            : };
    1051                 :            : 
    1052                 :          0 : int agp_frontend_initialize(void)
    1053                 :            : {
    1054                 :          0 :         memset(&agp_fe, 0, sizeof(struct agp_front_data));
    1055                 :          0 :         mutex_init(&(agp_fe.agp_mutex));
    1056                 :            : 
    1057         [ #  # ]:          0 :         if (misc_register(&agp_miscdev)) {
    1058                 :          0 :                 printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR);
    1059                 :          0 :                 return -EIO;
    1060                 :            :         }
    1061                 :            :         return 0;
    1062                 :            : }
    1063                 :            : 
    1064                 :          0 : void agp_frontend_cleanup(void)
    1065                 :            : {
    1066                 :          0 :         misc_deregister(&agp_miscdev);
    1067                 :          0 : }

Generated by: LCOV version 1.14