summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-04-12 13:56:00 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-04-12 13:56:00 +0000
commit56dfab7d84b243c6ba045f42d898bd29215413cb (patch)
tree2ed66342f72a2cae0759231aa6e1e4e147091843
parenta73334e9bdae2e7afd3a9ce357cbdd66192dbbd7 (diff)
Convert the list of agp memory over to a TAILQ instead of using a hand-
rolled list. Tested by many
-rw-r--r--sys/dev/pci/drm/drmP.h9
-rw-r--r--sys/dev/pci/drm/drm_agpsupport.c31
-rw-r--r--sys/dev/pci/drm/drm_bufs.c30
-rw-r--r--sys/dev/pci/drm/drm_drv.c8
4 files changed, 41 insertions, 37 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index f60c46e277d..a90b9188d96 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -653,19 +653,18 @@ typedef struct drm_device_dma {
} flags;
} drm_device_dma_t;
-typedef struct drm_agp_mem {
+struct drm_agp_mem {
void *handle;
unsigned long bound; /* address */
int pages;
- struct drm_agp_mem *prev;
- struct drm_agp_mem *next;
-} drm_agp_mem_t;
+ TAILQ_ENTRY(drm_agp_mem) link;
+};
typedef struct drm_agp_head {
device_t agpdev;
struct agp_info info;
const char *chipset;
- drm_agp_mem_t *memory;
+ TAILQ_HEAD(agp_memlist, drm_agp_mem) memory;
unsigned long mode;
int enabled;
int acquired;
diff --git a/sys/dev/pci/drm/drm_agpsupport.c b/sys/dev/pci/drm/drm_agpsupport.c
index ac88123efd7..f81fd56de81 100644
--- a/sys/dev/pci/drm/drm_agpsupport.c
+++ b/sys/dev/pci/drm/drm_agpsupport.c
@@ -41,7 +41,7 @@
#endif
int drm_device_find_capability(drm_device_t *, int);
-drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *, void *);
+struct drm_agp_mem *drm_agp_lookup_entry(drm_device_t *, void *);
/* Returns 1 if AGP or 0 if not. */
int
@@ -223,7 +223,7 @@ int
drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
{
#ifndef DRM_NO_AGP
- drm_agp_mem_t *entry;
+ struct drm_agp_mem *entry;
void *handle;
unsigned long pages;
u_int32_t type;
@@ -250,11 +250,7 @@ drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
entry->handle = handle;
entry->bound = 0;
entry->pages = pages;
- entry->prev = NULL;
- entry->next = dev->agp->memory;
- if (dev->agp->memory)
- dev->agp->memory->prev = entry;
- dev->agp->memory = entry;
+ TAILQ_INSERT_HEAD(&dev->agp->memory, entry, link);
agp_memory_info(dev->agp->agpdev, entry->handle, &info);
@@ -282,12 +278,12 @@ drm_agp_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
return retcode;
}
-drm_agp_mem_t *
+struct drm_agp_mem *
drm_agp_lookup_entry(drm_device_t *dev, void *handle)
{
- drm_agp_mem_t *entry;
+ struct drm_agp_mem *entry;
- for (entry = dev->agp->memory; entry; entry = entry->next) {
+ TAILQ_FOREACH(entry, &dev->agp->memory, link) {
if (entry->handle == handle) return entry;
}
return NULL;
@@ -296,7 +292,7 @@ drm_agp_lookup_entry(drm_device_t *dev, void *handle)
int
drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
{
- drm_agp_mem_t *entry;
+ struct drm_agp_mem *entry;
int retcode;
if (!dev->agp || !dev->agp->acquired)
@@ -334,7 +330,7 @@ drm_agp_unbind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
int
drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
{
- drm_agp_mem_t *entry;
+ struct drm_agp_mem *entry;
int retcode;
int page;
@@ -376,7 +372,7 @@ drm_agp_bind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
int
drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
{
- drm_agp_mem_t *entry;
+ struct drm_agp_mem *entry;
if (!dev->agp || !dev->agp->acquired)
return EINVAL;
@@ -385,12 +381,7 @@ drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
if (entry == NULL)
return EINVAL;
- if (entry->prev)
- entry->prev->next = entry->next;
- else
- dev->agp->memory = entry->next;
- if (entry->next)
- entry->next->prev = entry->prev;
+ TAILQ_REMOVE(&dev->agp->memory, entry, link);
DRM_UNLOCK();
if (entry->bound)
@@ -441,7 +432,7 @@ drm_agp_init(void)
agp_get_info(agpdev, &head->info);
#endif
head->base = head->info.ai_aperture_base;
- head->memory = NULL;
+ TAILQ_INIT(&head->memory);
DRM_INFO("AGP at 0x%08lx %dMB\n",
(long)head->info.ai_aperture_base,
(int)(head->info.ai_aperture_size >> 20));
diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c
index 258962091cc..64e32082e22 100644
--- a/sys/dev/pci/drm/drm_bufs.c
+++ b/sys/dev/pci/drm/drm_bufs.c
@@ -151,6 +151,10 @@ drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
{
drm_local_map_t *map;
int align;
+#if 0 /* disabled for now */
+ struct drm_agp_mem *entry;
+ int valid;
+#endif
/* Only allow shared memory to be removable since we only keep enough
* book keeping information about shared memory to allow for removal
@@ -259,8 +263,15 @@ drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
map->offset += dev->agp->base;
}
map->mtrr = dev->agp->mtrr; /* for getmap */
-#if 0 /* disabled */
- for (entry = dev->agp->memory; entry; entry = entry->next) {
+#if 0 /* disabled for now */
+ /*
+ * If agp is in control of userspace (some intel drivers for
+ * example. In which case ignore this loop.
+ */
+ TAILQ_FOREACH(entry, &dev->agp->memory, link) {
+ DRM_DEBUG("bound = %p, pages = %p, %p\n",
+ entry->bound, entry->pages,
+ entry->pages * PAGE_SIZE);
if ((map->offset >= entry->bound) &&
(map->offset + map->size <=
entry->bound + entry->pages * PAGE_SIZE)) {
@@ -268,9 +279,10 @@ drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
break;
}
}
- if (!valid) {
+ if (!TAILQ_EMPTY(&dev->agp->memory) && !valid) {
free(map, M_DRM);
DRM_LOCK();
+ DRM_ERROR("invalid agp map requested\n");
return EACCES;
}
#endif
@@ -478,6 +490,10 @@ drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
int byte_count;
int i;
drm_buf_t **temp_buflist;
+#if 0 /* disabled for now */
+ struct drm_agp_mem *agp_entry;
+ int valid;
+#endif
count = request->count;
order = drm_order(request->size);
@@ -500,14 +516,14 @@ drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
DRM_DEBUG( "total: %d\n", total );
/* Make sure buffers are located in AGP memory that we own */
+
/* Breaks MGA due to drm_alloc_agp not setting up entries for the
* memory. Safe to ignore for now because these ioctls are still
* root-only.
*/
-#if 0 /* disabled */
+#if 0 /* disabled for now */
valid = 0;
- for (agp_entry = dev->agp->memory; agp_entry;
- agp_entry = agp_entry->next) {
+ TAILQ_FOREACH(agp_entry, &dev->agp->memory, link) {
if ((agp_offset >= agp_entry->bound) &&
(agp_offset + total * count <=
agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
@@ -515,7 +531,7 @@ drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
break;
}
}
- if (!valid) {
+ if (!TAILQ_EMPTY(&dev->agp->memory) && !valid) {
DRM_DEBUG("zone invalid\n");
return EINVAL;
}
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index 390d54d73da..d72c71adb74 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -446,20 +446,18 @@ drm_lastclose(drm_device_t *dev)
/* Clear AGP information */
if ( dev->agp ) {
- drm_agp_mem_t *entry;
- drm_agp_mem_t *nexte;
+ struct drm_agp_mem *entry;
/* Remove AGP resources, but leave dev->agp intact until
* drm_unload is called.
*/
- for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
- nexte = entry->next;
+ 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);
free(entry, M_DRM);
}
- dev->agp->memory = NULL;
if (dev->agp->acquired)
drm_agp_release(dev);