diff options
| author | Dave Airlie <airlied@starflyer.(none)> | 2005-07-10 05:27:04 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@linux.ie> | 2005-07-10 05:27:04 -0400 |
| commit | 836cf0465c422ee6d654060edd7c620d9cf0c09c (patch) | |
| tree | 622ed9a2ca774818084ffdcfbf1622ef1735bb74 | |
| parent | d01cff408057fa925b2f766fa1fd5a305fd1acbf (diff) | |
drm: cleanup buffer/map code
This is a patch from DRM CVS that cleans up some code that was in CVS
that I never moved to the kernel, this patch produces the result of the
cleanups and puts it into the kernel drm.
From: Eric Anholt <anholt@freebsd.org>, Jon Smirl, Dave Airlie
Signed-off-by: Dave Airlie <airlied@linux.ie>
| -rw-r--r-- | drivers/char/drm/drmP.h | 9 | ||||
| -rw-r--r-- | drivers/char/drm/drm_bufs.c | 229 | ||||
| -rw-r--r-- | drivers/char/drm/drm_drv.c | 68 | ||||
| -rw-r--r-- | drivers/char/drm/drm_fops.c | 6 | ||||
| -rw-r--r-- | drivers/char/drm/drm_stub.c | 5 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_cp.c | 21 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drv.c | 1 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drv.h | 1 |
8 files changed, 210 insertions, 130 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index a7fdcece6129..fb2af9279148 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
| @@ -908,10 +908,11 @@ extern int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request); | |||
| 908 | extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request); | 908 | extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request); |
| 909 | extern int drm_addmap(drm_device_t *dev, unsigned int offset, | 909 | extern int drm_addmap(drm_device_t *dev, unsigned int offset, |
| 910 | unsigned int size, drm_map_type_t type, | 910 | unsigned int size, drm_map_type_t type, |
| 911 | drm_map_flags_t flags, drm_map_t **map_ptr); | 911 | drm_map_flags_t flags, drm_local_map_t **map_ptr); |
| 912 | extern int drm_addmap_ioctl(struct inode *inode, struct file *filp, | 912 | extern int drm_addmap_ioctl(struct inode *inode, struct file *filp, |
| 913 | unsigned int cmd, unsigned long arg); | 913 | unsigned int cmd, unsigned long arg); |
| 914 | extern int drm_rmmap(drm_device_t *dev, void *handle); | 914 | extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map); |
| 915 | extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map); | ||
| 915 | extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | 916 | extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp, |
| 916 | unsigned int cmd, unsigned long arg); | 917 | unsigned int cmd, unsigned long arg); |
| 917 | 918 | ||
| @@ -926,6 +927,10 @@ extern int drm_freebufs( struct inode *inode, struct file *filp, | |||
| 926 | unsigned int cmd, unsigned long arg ); | 927 | unsigned int cmd, unsigned long arg ); |
| 927 | extern int drm_mapbufs( struct inode *inode, struct file *filp, | 928 | extern int drm_mapbufs( struct inode *inode, struct file *filp, |
| 928 | unsigned int cmd, unsigned long arg ); | 929 | unsigned int cmd, unsigned long arg ); |
| 930 | extern unsigned long drm_get_resource_start(drm_device_t *dev, | ||
| 931 | unsigned int resource); | ||
| 932 | extern unsigned long drm_get_resource_len(drm_device_t *dev, | ||
| 933 | unsigned int resource); | ||
| 929 | 934 | ||
| 930 | /* DMA support (drm_dma.h) */ | 935 | /* DMA support (drm_dma.h) */ |
| 931 | extern int drm_dma_setup(drm_device_t *dev); | 936 | extern int drm_dma_setup(drm_device_t *dev); |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 06b01215fdf3..fcc8d244f46f 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
| @@ -36,29 +36,33 @@ | |||
| 36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
| 37 | #include "drmP.h" | 37 | #include "drmP.h" |
| 38 | 38 | ||
| 39 | /** | 39 | unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) |
| 40 | * Compute size order. Returns the exponent of the smaller power of two which | ||
| 41 | * is greater or equal to given number. | ||
| 42 | * | ||
| 43 | * \param size size. | ||
| 44 | * \return order. | ||
| 45 | * | ||
| 46 | * \todo Can be made faster. | ||
| 47 | */ | ||
| 48 | int drm_order( unsigned long size ) | ||
| 49 | { | 40 | { |
| 50 | int order; | 41 | return pci_resource_start(dev->pdev, resource); |
| 51 | unsigned long tmp; | 42 | } |
| 43 | EXPORT_SYMBOL(drm_get_resource_start); | ||
| 52 | 44 | ||
| 53 | for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) | 45 | unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) |
| 54 | ; | 46 | { |
| 47 | return pci_resource_len(dev->pdev, resource); | ||
| 48 | } | ||
| 49 | EXPORT_SYMBOL(drm_get_resource_len); | ||
| 55 | 50 | ||
| 56 | if (size & (size - 1)) | 51 | static drm_local_map_t *drm_find_matching_map(drm_device_t *dev, |
| 57 | ++order; | 52 | drm_local_map_t *map) |
| 53 | { | ||
| 54 | struct list_head *list; | ||
| 58 | 55 | ||
| 59 | return order; | 56 | list_for_each(list, &dev->maplist->head) { |
| 57 | drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); | ||
| 58 | if (entry->map && map->type == entry->map->type && | ||
| 59 | entry->map->offset == map->offset) { | ||
| 60 | return entry->map; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | return NULL; | ||
| 60 | } | 65 | } |
| 61 | EXPORT_SYMBOL(drm_order); | ||
| 62 | 66 | ||
| 63 | #ifdef CONFIG_COMPAT | 67 | #ifdef CONFIG_COMPAT |
| 64 | /* | 68 | /* |
| @@ -89,6 +93,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset, | |||
| 89 | drm_map_t *map; | 93 | drm_map_t *map; |
| 90 | drm_map_list_t *list; | 94 | drm_map_list_t *list; |
| 91 | drm_dma_handle_t *dmah; | 95 | drm_dma_handle_t *dmah; |
| 96 | drm_local_map_t *found_map; | ||
| 92 | 97 | ||
| 93 | map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); | 98 | map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); |
| 94 | if ( !map ) | 99 | if ( !map ) |
| @@ -129,6 +134,24 @@ int drm_addmap(drm_device_t * dev, unsigned int offset, | |||
| 129 | #ifdef __alpha__ | 134 | #ifdef __alpha__ |
| 130 | map->offset += dev->hose->mem_space->start; | 135 | map->offset += dev->hose->mem_space->start; |
| 131 | #endif | 136 | #endif |
| 137 | /* Some drivers preinitialize some maps, without the X Server | ||
| 138 | * needing to be aware of it. Therefore, we just return success | ||
| 139 | * when the server tries to create a duplicate map. | ||
| 140 | */ | ||
| 141 | found_map = drm_find_matching_map(dev, map); | ||
| 142 | if (found_map != NULL) { | ||
| 143 | if (found_map->size != map->size) { | ||
| 144 | DRM_DEBUG("Matching maps of type %d with " | ||
| 145 | "mismatched sizes, (%ld vs %ld)\n", | ||
| 146 | map->type, map->size, found_map->size); | ||
| 147 | found_map->size = map->size; | ||
| 148 | } | ||
| 149 | |||
| 150 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
| 151 | *map_ptr = found_map; | ||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 132 | if (drm_core_has_MTRR(dev)) { | 155 | if (drm_core_has_MTRR(dev)) { |
| 133 | if ( map->type == _DRM_FRAME_BUFFER || | 156 | if ( map->type == _DRM_FRAME_BUFFER || |
| 134 | (map->flags & _DRM_WRITE_COMBINING) ) { | 157 | (map->flags & _DRM_WRITE_COMBINING) ) { |
| @@ -270,93 +293,136 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, | |||
| 270 | * | 293 | * |
| 271 | * \sa drm_addmap | 294 | * \sa drm_addmap |
| 272 | */ | 295 | */ |
| 273 | int drm_rmmap(drm_device_t *dev, void *handle) | 296 | int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) |
| 274 | { | 297 | { |
| 275 | struct list_head *list; | 298 | struct list_head *list; |
| 276 | drm_map_list_t *r_list = NULL; | 299 | drm_map_list_t *r_list = NULL; |
| 277 | drm_vma_entry_t *pt, *prev; | 300 | drm_dma_handle_t dmah; |
| 278 | drm_map_t *map; | ||
| 279 | int found_maps = 0; | ||
| 280 | 301 | ||
| 281 | down(&dev->struct_sem); | 302 | /* Find the list entry for the map and remove it */ |
| 282 | list = &dev->maplist->head; | ||
| 283 | list_for_each(list, &dev->maplist->head) { | 303 | list_for_each(list, &dev->maplist->head) { |
| 284 | r_list = list_entry(list, drm_map_list_t, head); | 304 | r_list = list_entry(list, drm_map_list_t, head); |
| 285 | 305 | ||
| 286 | if(r_list->map && | 306 | if (r_list->map == map) { |
| 287 | r_list->map->handle == handle && | 307 | list_del(list); |
| 288 | r_list->map->flags & _DRM_REMOVABLE) break; | 308 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); |
| 309 | break; | ||
| 310 | } | ||
| 289 | } | 311 | } |
| 290 | 312 | ||
| 291 | /* List has wrapped around to the head pointer, or its empty we didn't | 313 | /* List has wrapped around to the head pointer, or it's empty and we |
| 292 | * find anything. | 314 | * didn't find anything. |
| 293 | */ | 315 | */ |
| 294 | if(list == (&dev->maplist->head)) { | 316 | if (list == (&dev->maplist->head)) { |
| 295 | up(&dev->struct_sem); | ||
| 296 | return -EINVAL; | 317 | return -EINVAL; |
| 297 | } | 318 | } |
| 298 | map = r_list->map; | ||
| 299 | list_del(list); | ||
| 300 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | ||
| 301 | |||
| 302 | for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { | ||
| 303 | if (pt->vma->vm_private_data == map) found_maps++; | ||
| 304 | } | ||
| 305 | 319 | ||
| 306 | if(!found_maps) { | 320 | switch (map->type) { |
| 307 | drm_dma_handle_t dmah; | 321 | case _DRM_REGISTERS: |
| 308 | 322 | drm_ioremapfree(map->handle, map->size, dev); | |
| 309 | switch (map->type) { | 323 | /* FALLTHROUGH */ |
| 310 | case _DRM_REGISTERS: | 324 | case _DRM_FRAME_BUFFER: |
| 311 | case _DRM_FRAME_BUFFER: | 325 | if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { |
| 312 | if (drm_core_has_MTRR(dev)) { | 326 | int retcode; |
| 313 | if (map->mtrr >= 0) { | 327 | retcode = mtrr_del(map->mtrr, map->offset, |
| 314 | int retcode; | 328 | map->size); |
| 315 | retcode = mtrr_del(map->mtrr, | 329 | DRM_DEBUG ("mtrr_del=%d\n", retcode); |
| 316 | map->offset, | ||
| 317 | map->size); | ||
| 318 | DRM_DEBUG("mtrr_del = %d\n", retcode); | ||
| 319 | } | ||
| 320 | } | ||
| 321 | drm_ioremapfree(map->handle, map->size, dev); | ||
| 322 | break; | ||
| 323 | case _DRM_SHM: | ||
| 324 | vfree(map->handle); | ||
| 325 | break; | ||
| 326 | case _DRM_AGP: | ||
| 327 | case _DRM_SCATTER_GATHER: | ||
| 328 | break; | ||
| 329 | case _DRM_CONSISTENT: | ||
| 330 | dmah.vaddr = map->handle; | ||
| 331 | dmah.busaddr = map->offset; | ||
| 332 | dmah.size = map->size; | ||
| 333 | __drm_pci_free(dev, &dmah); | ||
| 334 | break; | ||
| 335 | } | 330 | } |
| 336 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 331 | break; |
| 332 | case _DRM_SHM: | ||
| 333 | vfree(map->handle); | ||
| 334 | break; | ||
| 335 | case _DRM_AGP: | ||
| 336 | case _DRM_SCATTER_GATHER: | ||
| 337 | break; | ||
| 338 | case _DRM_CONSISTENT: | ||
| 339 | dmah.vaddr = map->handle; | ||
| 340 | dmah.busaddr = map->offset; | ||
| 341 | dmah.size = map->size; | ||
| 342 | __drm_pci_free(dev, &dmah); | ||
| 343 | break; | ||
| 337 | } | 344 | } |
| 338 | up(&dev->struct_sem); | 345 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
| 346 | |||
| 339 | return 0; | 347 | return 0; |
| 340 | } | 348 | } |
| 349 | EXPORT_SYMBOL(drm_rmmap_locked); | ||
| 350 | |||
| 351 | int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) | ||
| 352 | { | ||
| 353 | int ret; | ||
| 354 | |||
| 355 | down(&dev->struct_sem); | ||
| 356 | ret = drm_rmmap_locked(dev, map); | ||
| 357 | up(&dev->struct_sem); | ||
| 358 | |||
| 359 | return ret; | ||
| 360 | } | ||
| 341 | EXPORT_SYMBOL(drm_rmmap); | 361 | EXPORT_SYMBOL(drm_rmmap); |
| 342 | 362 | ||
| 363 | /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on | ||
| 364 | * the last close of the device, and this is necessary for cleanup when things | ||
| 365 | * exit uncleanly. Therefore, having userland manually remove mappings seems | ||
| 366 | * like a pointless exercise since they're going away anyway. | ||
| 367 | * | ||
| 368 | * One use case might be after addmap is allowed for normal users for SHM and | ||
| 369 | * gets used by drivers that the server doesn't need to care about. This seems | ||
| 370 | * unlikely. | ||
| 371 | */ | ||
| 343 | int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | 372 | int drm_rmmap_ioctl(struct inode *inode, struct file *filp, |
| 344 | unsigned int cmd, unsigned long arg) | 373 | unsigned int cmd, unsigned long arg) |
| 345 | { | 374 | { |
| 346 | drm_file_t *priv = filp->private_data; | 375 | drm_file_t *priv = filp->private_data; |
| 347 | drm_device_t *dev = priv->head->dev; | 376 | drm_device_t *dev = priv->head->dev; |
| 348 | drm_map_t request; | 377 | drm_map_t request; |
| 378 | drm_local_map_t *map = NULL; | ||
| 379 | struct list_head *list; | ||
| 380 | int ret; | ||
| 349 | 381 | ||
| 350 | if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) { | 382 | if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) { |
| 351 | return -EFAULT; | 383 | return -EFAULT; |
| 352 | } | 384 | } |
| 353 | 385 | ||
| 354 | return drm_rmmap(dev, request.handle); | 386 | down(&dev->struct_sem); |
| 387 | list_for_each(list, &dev->maplist->head) { | ||
| 388 | drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); | ||
| 389 | |||
| 390 | if (r_list->map && | ||
| 391 | r_list->map->handle == request.handle && | ||
| 392 | r_list->map->flags & _DRM_REMOVABLE) { | ||
| 393 | map = r_list->map; | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | /* List has wrapped around to the head pointer, or its empty we didn't | ||
| 399 | * find anything. | ||
| 400 | */ | ||
| 401 | if (list == (&dev->maplist->head)) { | ||
| 402 | up(&dev->struct_sem); | ||
| 403 | return -EINVAL; | ||
| 404 | } | ||
| 405 | |||
| 406 | if (!map) | ||
| 407 | return -EINVAL; | ||
| 408 | |||
| 409 | /* Register and framebuffer maps are permanent */ | ||
| 410 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { | ||
| 411 | up(&dev->struct_sem); | ||
| 412 | return 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | ret = drm_rmmap_locked(dev, map); | ||
| 416 | |||
| 417 | up(&dev->struct_sem); | ||
| 418 | |||
| 419 | return ret; | ||
| 355 | } | 420 | } |
| 356 | 421 | ||
| 357 | /** | 422 | /** |
| 358 | * Cleanup after an error on one of the addbufs() functions. | 423 | * Cleanup after an error on one of the addbufs() functions. |
| 359 | * | 424 | * |
| 425 | * \param dev DRM device. | ||
| 360 | * \param entry buffer entry where the error occurred. | 426 | * \param entry buffer entry where the error occurred. |
| 361 | * | 427 | * |
| 362 | * Frees any pages and buffers associated with the given entry. | 428 | * Frees any pages and buffers associated with the given entry. |
| @@ -1470,3 +1536,26 @@ int drm_mapbufs( struct inode *inode, struct file *filp, | |||
| 1470 | return retcode; | 1536 | return retcode; |
| 1471 | } | 1537 | } |
| 1472 | 1538 | ||
| 1539 | /** | ||
| 1540 | * Compute size order. Returns the exponent of the smaller power of two which | ||
| 1541 | * is greater or equal to given number. | ||
| 1542 | * | ||
| 1543 | * \param size size. | ||
| 1544 | * \return order. | ||
| 1545 | * | ||
| 1546 | * \todo Can be made faster. | ||
| 1547 | */ | ||
| 1548 | int drm_order( unsigned long size ) | ||
| 1549 | { | ||
| 1550 | int order; | ||
| 1551 | unsigned long tmp; | ||
| 1552 | |||
| 1553 | for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) | ||
| 1554 | ; | ||
| 1555 | |||
| 1556 | if (size & (size - 1)) | ||
| 1557 | ++order; | ||
| 1558 | |||
| 1559 | return order; | ||
| 1560 | } | ||
| 1561 | EXPORT_SYMBOL(drm_order); | ||
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index 733af58fb3ac..6ba48f346fcf 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
| @@ -132,9 +132,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
| 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); |
| @@ -184,6 +183,10 @@ int drm_takedown( drm_device_t *dev ) | |||
| 184 | dev->agp->acquired = 0; | 183 | dev->agp->acquired = 0; |
| 185 | dev->agp->enabled = 0; | 184 | dev->agp->enabled = 0; |
| 186 | } | 185 | } |
| 186 | if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { | ||
| 187 | drm_sg_cleanup(dev->sg); | ||
| 188 | dev->sg = NULL; | ||
| 189 | } | ||
| 187 | 190 | ||
| 188 | /* Clear vma list (only built for debugging) */ | 191 | /* Clear vma list (only built for debugging) */ |
| 189 | if ( dev->vmalist ) { | 192 | if ( dev->vmalist ) { |
| @@ -195,56 +198,11 @@ int drm_takedown( drm_device_t *dev ) | |||
| 195 | } | 198 | } |
| 196 | 199 | ||
| 197 | if( dev->maplist ) { | 200 | if( dev->maplist ) { |
| 198 | list_for_each_safe( list, list_next, &dev->maplist->head ) { | 201 | while (!list_empty(&dev->maplist->head)) { |
| 199 | r_list = (drm_map_list_t *)list; | 202 | struct list_head *list = dev->maplist->head.next; |
| 200 | 203 | r_list = list_entry(list, drm_map_list_t, head); | |
| 201 | if ( ( map = r_list->map ) ) { | 204 | drm_rmmap_locked(dev, r_list->map); |
| 202 | drm_dma_handle_t dmah; | 205 | } |
| 203 | |||
| 204 | switch ( map->type ) { | ||
| 205 | case _DRM_REGISTERS: | ||
| 206 | case _DRM_FRAME_BUFFER: | ||
| 207 | if (drm_core_has_MTRR(dev)) { | ||
| 208 | if ( map->mtrr >= 0 ) { | ||
| 209 | int retcode; | ||
| 210 | retcode = mtrr_del( map->mtrr, | ||
| 211 | map->offset, | ||
| 212 | map->size ); | ||
| 213 | DRM_DEBUG( "mtrr_del=%d\n", retcode ); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | drm_ioremapfree( map->handle, map->size, dev ); | ||
| 217 | break; | ||
| 218 | case _DRM_SHM: | ||
| 219 | vfree(map->handle); | ||
| 220 | break; | ||
| 221 | |||
| 222 | case _DRM_AGP: | ||
| 223 | /* Do nothing here, because this is all | ||
| 224 | * handled in the AGP/GART driver. | ||
| 225 | */ | ||
| 226 | break; | ||
| 227 | case _DRM_SCATTER_GATHER: | ||
| 228 | /* Handle it */ | ||
| 229 | if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { | ||
| 230 | drm_sg_cleanup(dev->sg); | ||
| 231 | dev->sg = NULL; | ||
| 232 | } | ||
| 233 | break; | ||
| 234 | case _DRM_CONSISTENT: | ||
| 235 | dmah.vaddr = map->handle; | ||
| 236 | dmah.busaddr = map->offset; | ||
| 237 | dmah.size = map->size; | ||
| 238 | __drm_pci_free(dev, &dmah); | ||
| 239 | break; | ||
| 240 | } | ||
| 241 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
| 242 | } | ||
| 243 | list_del( list ); | ||
| 244 | drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS); | ||
| 245 | } | ||
| 246 | drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); | ||
| 247 | dev->maplist = NULL; | ||
| 248 | } | 206 | } |
| 249 | 207 | ||
| 250 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) { | 208 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) { |
| @@ -273,6 +231,7 @@ int drm_takedown( drm_device_t *dev ) | |||
| 273 | } | 231 | } |
| 274 | up( &dev->struct_sem ); | 232 | up( &dev->struct_sem ); |
| 275 | 233 | ||
| 234 | DRM_DEBUG("takedown completed\n"); | ||
| 276 | return 0; | 235 | return 0; |
| 277 | } | 236 | } |
| 278 | 237 | ||
| @@ -334,6 +293,11 @@ static void drm_cleanup( drm_device_t *dev ) | |||
| 334 | 293 | ||
| 335 | drm_takedown( dev ); | 294 | drm_takedown( dev ); |
| 336 | 295 | ||
| 296 | if (dev->maplist) { | ||
| 297 | drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); | ||
| 298 | dev->maplist = NULL; | ||
| 299 | } | ||
| 300 | |||
| 337 | drm_ctxbitmap_cleanup( dev ); | 301 | drm_ctxbitmap_cleanup( dev ); |
| 338 | 302 | ||
| 339 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && | 303 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 10e64fde8d78..a1f4e9cd64ed 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
| @@ -71,12 +71,6 @@ static int drm_setup( drm_device_t *dev ) | |||
| 71 | dev->magiclist[i].tail = NULL; | 71 | dev->magiclist[i].tail = NULL; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | dev->maplist = drm_alloc(sizeof(*dev->maplist), | ||
| 75 | DRM_MEM_MAPS); | ||
| 76 | if(dev->maplist == NULL) return -ENOMEM; | ||
| 77 | memset(dev->maplist, 0, sizeof(*dev->maplist)); | ||
| 78 | INIT_LIST_HEAD(&dev->maplist->head); | ||
| 79 | |||
| 80 | dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), | 74 | dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), |
| 81 | DRM_MEM_CTXLIST); | 75 | DRM_MEM_CTXLIST); |
| 82 | if(dev->ctxlist == NULL) return -ENOMEM; | 76 | if(dev->ctxlist == NULL) return -ENOMEM; |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 068ca9a8b0b4..95a976c96eb8 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
| @@ -75,6 +75,11 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct | |||
| 75 | dev->pci_func = PCI_FUNC(pdev->devfn); | 75 | dev->pci_func = PCI_FUNC(pdev->devfn); |
| 76 | dev->irq = pdev->irq; | 76 | dev->irq = pdev->irq; |
| 77 | 77 | ||
| 78 | dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); | ||
| 79 | if (dev->maplist == NULL) | ||
| 80 | return -ENOMEM; | ||
| 81 | INIT_LIST_HEAD(&dev->maplist->head); | ||
| 82 | |||
| 78 | /* the DRM has 6 basic counters */ | 83 | /* the DRM has 6 basic counters */ |
| 79 | dev->counters = 6; | 84 | dev->counters = 6; |
| 80 | dev->types[0] = _DRM_STAT_LOCK; | 85 | dev->types[0] = _DRM_STAT_LOCK; |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 20bcf872b348..8255cc6fdc28 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
| @@ -2048,6 +2048,27 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) | |||
| 2048 | return ret; | 2048 | return ret; |
| 2049 | } | 2049 | } |
| 2050 | 2050 | ||
| 2051 | int radeon_presetup(struct drm_device *dev) | ||
| 2052 | { | ||
| 2053 | int ret; | ||
| 2054 | drm_local_map_t *map; | ||
| 2055 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
| 2056 | |||
| 2057 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | ||
| 2058 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | ||
| 2059 | _DRM_READ_ONLY, &dev_priv->mmio); | ||
| 2060 | if (ret != 0) | ||
| 2061 | return ret; | ||
| 2062 | |||
| 2063 | ret = drm_addmap(dev, drm_get_resource_start(dev, 0), | ||
| 2064 | drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, | ||
| 2065 | _DRM_WRITE_COMBINING, &map); | ||
| 2066 | if (ret != 0) | ||
| 2067 | return ret; | ||
| 2068 | |||
| 2069 | return 0; | ||
| 2070 | } | ||
| 2071 | |||
| 2051 | int radeon_driver_postcleanup(struct drm_device *dev) | 2072 | int radeon_driver_postcleanup(struct drm_device *dev) |
| 2052 | { | 2073 | { |
| 2053 | drm_radeon_private_t *dev_priv = dev->dev_private; | 2074 | drm_radeon_private_t *dev_priv = dev->dev_private; |
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index 18e4e5b0952f..e0682f64b400 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c | |||
| @@ -76,6 +76,7 @@ static struct drm_driver driver = { | |||
| 76 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, | 76 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, |
| 77 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), | 77 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), |
| 78 | .preinit = radeon_driver_preinit, | 78 | .preinit = radeon_driver_preinit, |
| 79 | .presetup = radeon_presetup, | ||
| 79 | .postcleanup = radeon_driver_postcleanup, | 80 | .postcleanup = radeon_driver_postcleanup, |
| 80 | .prerelease = radeon_driver_prerelease, | 81 | .prerelease = radeon_driver_prerelease, |
| 81 | .pretakedown = radeon_driver_pretakedown, | 82 | .pretakedown = radeon_driver_pretakedown, |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 771aa80a5e8c..e701dffe978d 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
| @@ -290,6 +290,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); | |||
| 290 | extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); | 290 | extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); |
| 291 | 291 | ||
| 292 | extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); | 292 | extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); |
| 293 | extern int radeon_presetup(struct drm_device *dev); | ||
| 293 | extern int radeon_driver_postcleanup(struct drm_device *dev); | 294 | extern int radeon_driver_postcleanup(struct drm_device *dev); |
| 294 | 295 | ||
| 295 | extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); | 296 | extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); |
