diff options
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/drm/drmP.h | 25 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_agpsupport.c | 127 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 34 |
3 files changed, 71 insertions, 115 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index 7ab0d21ce41..413d491ace1 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -171,12 +171,6 @@ extern int ticks; /* really should be in a header */ #define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) -#ifdef DRM_NO_AGP -#define DRM_AGP_FIND_DEVICE() 0 -#else -#define DRM_AGP_FIND_DEVICE() agp_find_device(0) -#endif - extern struct cfdriver drm_cd; typedef unsigned long dma_addr_t; @@ -382,7 +376,7 @@ struct drm_agp_mem { TAILQ_ENTRY(drm_agp_mem) link; }; -typedef struct drm_agp_head { +struct drm_agp_head { struct device *agpdev; const char *chipset; TAILQ_HEAD(agp_memlist, drm_agp_mem) memory; @@ -394,7 +388,7 @@ typedef struct drm_agp_head { int cant_use_aperture; int enabled; int mtrr; -} drm_agp_head_t; +}; struct drm_sg_dmamem { bus_dma_tag_t sg_tag; @@ -593,12 +587,12 @@ struct drm_device { pid_t buf_pgid; - drm_agp_head_t *agp; - drm_sg_mem_t *sg; /* Scatter gather memory */ - atomic_t *ctx_bitmap; - void *dev_private; - unsigned int agp_buffer_token; - drm_local_map_t *agp_buffer_map; + struct drm_agp_head *agp; + drm_sg_mem_t *sg; /* Scatter gather memory */ + atomic_t *ctx_bitmap; + void *dev_private; + unsigned int agp_buffer_token; + drm_local_map_t *agp_buffer_map; u_int drw_no; /* RB tree of drawable infos */ @@ -695,7 +689,8 @@ void drm_handle_vblank(struct drm_device *, int); /* AGP/PCI Express/GART support (drm_agpsupport.c) */ int drm_device_is_agp(struct drm_device *); int drm_device_is_pcie(struct drm_device *); -drm_agp_head_t *drm_agp_init(void); +struct drm_agp_head *drm_agp_init(void); +void drm_agp_takedown(struct drm_device *); int drm_agp_acquire(struct drm_device *); int drm_agp_release(struct drm_device *); int drm_agp_info(struct drm_device *, struct drm_agp_info *); diff --git a/sys/dev/pci/drm/drm_agpsupport.c b/sys/dev/pci/drm/drm_agpsupport.c index 03784c0b35b..be3f368c4c8 100644 --- a/sys/dev/pci/drm/drm_agpsupport.c +++ b/sys/dev/pci/drm/drm_agpsupport.c @@ -36,6 +36,8 @@ #include "drmP.h" struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device *, void *); +void drm_agp_remove_entry(struct drm_device *, + struct drm_agp_mem *); int drm_device_is_agp(struct drm_device *dev) @@ -185,7 +187,8 @@ drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) type = (u_int32_t)request->type; DRM_UNLOCK(); - handle = drm_agp_allocate_memory(pages, type); + handle = agp_alloc_memory(dev->agp->agpdev, type, + pages << AGP_PAGE_SHIFT); DRM_LOCK(); if (handle == NULL) { drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); @@ -245,7 +248,7 @@ drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) return (EINVAL); DRM_UNLOCK(); - retcode = drm_agp_unbind_memory(entry->handle); + retcode = agp_unbind_memory(dev->agp->agpdev, entry->handle); DRM_LOCK(); if (retcode == 0) @@ -286,7 +289,8 @@ drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; DRM_UNLOCK(); - retcode = drm_agp_bind_memory(entry->handle, page); + retcode = agp_bind_memory(dev->agp->agpdev, entry->handle, + page * PAGE_SIZE); DRM_LOCK(); if (retcode == 0) entry->bound = dev->agp->base + (page << PAGE_SHIFT); @@ -308,6 +312,43 @@ drm_agp_bind_ioctl(struct drm_device *dev, void *data, return (retcode); } +/* + * Remove entry from list and free. Call locked. + */ +void +drm_agp_remove_entry(struct drm_device *dev, struct drm_agp_mem *entry) +{ + TAILQ_REMOVE(&dev->agp->memory, entry, link); + + DRM_UNLOCK(); + if (entry->bound) + agp_unbind_memory(dev->agp->agpdev, entry->handle); + agp_free_memory(dev->agp->agpdev, entry->handle); + drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); + DRM_LOCK(); +} + +void +drm_agp_takedown(struct drm_device *dev) +{ + struct drm_agp_mem *entry; + + if (dev->agp == NULL) + return; + + /* + * Remove AGP resources, but leave dev->agp intact until + * we detach the device + */ + DRM_LOCK(); + while ((entry = TAILQ_FIRST(&dev->agp->memory)) != NULL) + drm_agp_remove_entry(dev, entry); + DRM_UNLOCK(); + + drm_agp_release(dev); + dev->agp->enabled = 0; +} + int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) { @@ -319,19 +360,10 @@ drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) entry = drm_agp_lookup_entry(dev, (void*)request->handle); if (entry == NULL) return (EINVAL); - - TAILQ_REMOVE(&dev->agp->memory, entry, link); - - DRM_UNLOCK(); - if (entry->bound) - drm_agp_unbind_memory(entry->handle); - drm_agp_free_memory(entry->handle); - DRM_LOCK(); - - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); + drm_agp_remove_entry(dev, entry); + return (0); - } int @@ -348,15 +380,15 @@ drm_agp_free_ioctl(struct drm_device *dev, void *data, return (retcode); } -drm_agp_head_t * +struct drm_agp_head * drm_agp_init(void) { #ifndef DRM_NO_AGP - struct device *agpdev; - drm_agp_head_t *head = NULL; - int agp_available = 1; + struct device *agpdev; + struct drm_agp_head *head = NULL; + int agp_available = 1; - agpdev = DRM_AGP_FIND_DEVICE(); + agpdev = agp_find_device(0); if (agpdev == NULL) agp_available = 0; @@ -376,60 +408,3 @@ drm_agp_init(void) return (NULL); #endif } - -void * -drm_agp_allocate_memory(size_t pages, u32 type) -{ - struct device *agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (agpdev == NULL) - return (NULL); - - return (agp_alloc_memory(agpdev, type, pages << AGP_PAGE_SHIFT)); -} - -int -drm_agp_free_memory(void *handle) -{ - struct device *agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (agpdev == NULL || handle == NULL) - return (0); - - agp_free_memory(agpdev, handle); - return (1); -} - -int -drm_agp_bind_memory(void *handle, off_t start) -{ -#ifndef DRM_NO_AGP - struct device *agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (agpdev == NULL || handle == NULL) - return (EINVAL); - - return (agp_bind_memory(agpdev, handle, start * PAGE_SIZE)); -#else - return (0); -#endif -} - -int -drm_agp_unbind_memory(void *handle) -{ -#ifndef DRM_NO_AGP - struct device *agpdev; - - agpdev = DRM_AGP_FIND_DEVICE(); - if (agpdev == NULL || handle == NULL) - return (EINVAL); - - return (agp_unbind_memory(agpdev, handle)); -#else - return (0); -#endif -} diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index fd8ad5519cc..7a39ee79b51 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -392,38 +392,25 @@ drm_lastclose(struct drm_device *dev) dev->unique_len = 0; } - drm_drawable_free_all(dev); /* Clear pid list */ while ((pt = SPLAY_ROOT(&dev->magiclist)) != NULL) { SPLAY_REMOVE(drm_magic_tree, &dev->magiclist, pt); drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); } - /* Clear AGP information */ - if (dev->agp != NULL) { - struct drm_agp_mem *entry; - - /* - * Remove AGP resources, but leave dev->agp intact until - * we detach the device - */ - while ((entry = TAILQ_FIRST(&dev->agp->memory)) != NULL) { - if (entry->bound) - drm_agp_unbind_memory(entry->handle); - drm_agp_free_memory(entry->handle); - TAILQ_REMOVE(&dev->agp->memory, entry, link); - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); - } - - if (dev->agp->acquired) - drm_agp_release(dev); + DRM_UNLOCK(); + drm_agp_takedown(dev); + drm_drawable_free_all(dev); + drm_dma_takedown(dev); + DRM_LOCK(); - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } if (dev->sg != NULL) { - drm_sg_cleanup(dev->sg); + drm_sg_mem_t *sg = dev->sg; dev->sg = NULL; + + DRM_UNLOCK(); + drm_sg_cleanup(sg); + DRM_LOCK(); } for (map = TAILQ_FIRST(&dev->maplist); map != TAILQ_END(&dev->maplist); @@ -433,7 +420,6 @@ drm_lastclose(struct drm_device *dev) drm_rmmap(dev, map); } - drm_dma_takedown(dev); if (dev->lock.hw_lock != NULL) { dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.file_priv = NULL; |