diff options
Diffstat (limited to 'drivers/char/drm/drm_drv.c')
-rw-r--r-- | drivers/char/drm/drm_drv.c | 79 |
1 files changed, 26 insertions, 53 deletions
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 3333c250c4d9..6ba48f346fcf 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -70,8 +70,8 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
70 | [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 }, | 70 | [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 }, |
71 | [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, | 71 | [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, |
72 | 72 | ||
73 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, | 73 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl,1, 1 }, |
74 | [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap, 1, 0 }, | 74 | [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, 1, 0 }, |
75 | 75 | ||
76 | [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 }, | 76 | [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 }, |
77 | [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 }, | 77 | [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 }, |
@@ -102,10 +102,10 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
102 | [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 }, | 102 | [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 }, |
103 | 103 | ||
104 | #if __OS_HAS_AGP | 104 | #if __OS_HAS_AGP |
105 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, | 105 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, 1, 1 }, |
106 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, | 106 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, 1, 1 }, |
107 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, | 107 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, 1, 1 }, |
108 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, | 108 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, 1, 0 }, |
109 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, | 109 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, |
110 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, | 110 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, |
111 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, | 111 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, |
@@ -127,14 +127,12 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
127 | * | 127 | * |
128 | * Frees every resource in \p dev. | 128 | * Frees every resource in \p dev. |
129 | * | 129 | * |
130 | * \sa drm_device and setup(). | 130 | * \sa drm_device |
131 | */ | 131 | */ |
132 | int drm_takedown( drm_device_t *dev ) | 132 | int drm_takedown( drm_device_t *dev ) |
133 | { | 133 | { |
134 | drm_magic_entry_t *pt, *next; | 134 | drm_magic_entry_t *pt, *next; |
135 | drm_map_t *map; | ||
136 | drm_map_list_t *r_list; | 135 | drm_map_list_t *r_list; |
137 | struct list_head *list, *list_next; | ||
138 | drm_vma_entry_t *vma, *vma_next; | 136 | drm_vma_entry_t *vma, *vma_next; |
139 | int i; | 137 | int i; |
140 | 138 | ||
@@ -142,6 +140,7 @@ int drm_takedown( drm_device_t *dev ) | |||
142 | 140 | ||
143 | if (dev->driver->pretakedown) | 141 | if (dev->driver->pretakedown) |
144 | dev->driver->pretakedown(dev); | 142 | dev->driver->pretakedown(dev); |
143 | DRM_DEBUG("driver pretakedown completed\n"); | ||
145 | 144 | ||
146 | if (dev->unique) { | 145 | if (dev->unique) { |
147 | drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); | 146 | drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); |
@@ -178,11 +177,16 @@ int drm_takedown( drm_device_t *dev ) | |||
178 | } | 177 | } |
179 | dev->agp->memory = NULL; | 178 | dev->agp->memory = NULL; |
180 | 179 | ||
181 | if ( dev->agp->acquired ) drm_agp_do_release(dev); | 180 | if (dev->agp->acquired) |
181 | drm_agp_release(dev); | ||
182 | 182 | ||
183 | dev->agp->acquired = 0; | 183 | dev->agp->acquired = 0; |
184 | dev->agp->enabled = 0; | 184 | dev->agp->enabled = 0; |
185 | } | 185 | } |
186 | if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { | ||
187 | drm_sg_cleanup(dev->sg); | ||
188 | dev->sg = NULL; | ||
189 | } | ||
186 | 190 | ||
187 | /* Clear vma list (only built for debugging) */ | 191 | /* Clear vma list (only built for debugging) */ |
188 | if ( dev->vmalist ) { | 192 | if ( dev->vmalist ) { |
@@ -194,48 +198,11 @@ int drm_takedown( drm_device_t *dev ) | |||
194 | } | 198 | } |
195 | 199 | ||
196 | if( dev->maplist ) { | 200 | if( dev->maplist ) { |
197 | list_for_each_safe( list, list_next, &dev->maplist->head ) { | 201 | while (!list_empty(&dev->maplist->head)) { |
198 | r_list = (drm_map_list_t *)list; | 202 | struct list_head *list = dev->maplist->head.next; |
199 | 203 | r_list = list_entry(list, drm_map_list_t, head); | |
200 | if ( ( map = r_list->map ) ) { | 204 | drm_rmmap_locked(dev, r_list->map); |
201 | switch ( map->type ) { | 205 | } |
202 | case _DRM_REGISTERS: | ||
203 | case _DRM_FRAME_BUFFER: | ||
204 | if (drm_core_has_MTRR(dev)) { | ||
205 | if ( map->mtrr >= 0 ) { | ||
206 | int retcode; | ||
207 | retcode = mtrr_del( map->mtrr, | ||
208 | map->offset, | ||
209 | map->size ); | ||
210 | DRM_DEBUG( "mtrr_del=%d\n", retcode ); | ||
211 | } | ||
212 | } | ||
213 | drm_ioremapfree( map->handle, map->size, dev ); | ||
214 | break; | ||
215 | case _DRM_SHM: | ||
216 | vfree(map->handle); | ||
217 | break; | ||
218 | |||
219 | case _DRM_AGP: | ||
220 | /* Do nothing here, because this is all | ||
221 | * handled in the AGP/GART driver. | ||
222 | */ | ||
223 | break; | ||
224 | case _DRM_SCATTER_GATHER: | ||
225 | /* Handle it */ | ||
226 | if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { | ||
227 | drm_sg_cleanup(dev->sg); | ||
228 | dev->sg = NULL; | ||
229 | } | ||
230 | break; | ||
231 | } | ||
232 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
233 | } | ||
234 | list_del( list ); | ||
235 | drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS); | ||
236 | } | ||
237 | drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); | ||
238 | dev->maplist = NULL; | ||
239 | } | 206 | } |
240 | 207 | ||
241 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) { | 208 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) { |
@@ -264,6 +231,7 @@ int drm_takedown( drm_device_t *dev ) | |||
264 | } | 231 | } |
265 | up( &dev->struct_sem ); | 232 | up( &dev->struct_sem ); |
266 | 233 | ||
234 | DRM_DEBUG("takedown completed\n"); | ||
267 | return 0; | 235 | return 0; |
268 | } | 236 | } |
269 | 237 | ||
@@ -312,7 +280,7 @@ EXPORT_SYMBOL(drm_init); | |||
312 | * | 280 | * |
313 | * Cleans up all DRM device, calling takedown(). | 281 | * Cleans up all DRM device, calling takedown(). |
314 | * | 282 | * |
315 | * \sa drm_init(). | 283 | * \sa drm_init |
316 | */ | 284 | */ |
317 | static void drm_cleanup( drm_device_t *dev ) | 285 | static void drm_cleanup( drm_device_t *dev ) |
318 | { | 286 | { |
@@ -325,6 +293,11 @@ static void drm_cleanup( drm_device_t *dev ) | |||
325 | 293 | ||
326 | drm_takedown( dev ); | 294 | drm_takedown( dev ); |
327 | 295 | ||
296 | if (dev->maplist) { | ||
297 | drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); | ||
298 | dev->maplist = NULL; | ||
299 | } | ||
300 | |||
328 | drm_ctxbitmap_cleanup( dev ); | 301 | drm_ctxbitmap_cleanup( dev ); |
329 | 302 | ||
330 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && | 303 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && |