Attached is a patch to clean up setup and teardown of maps in Linux.  I
did it because in the process of making BSD compile again, I kept
finding things that needed to be cleaned up and were making it harder to
get BSD working again, and it was too much doing both OSes at once.  I'd
like to get it committed very soon so I can get BSD DRM CVS compiling
again.  The changes in this patch:

- Remove drm_initmap and replace its usage with drm_addmap.  This is
nicer in savage because we don't have to go back and find the map again
-- I suspect this would be the case in most drivers that used it.
- Remove the permanent maps flag.  Instead, for register and framebuffer
maps, we always check whether there's already a map of that type and
offset around.
- Remove the split cleanup of maps between driver takedown (last close)
and cleanup (module unload).  Instead, always tear down maps on
takedown, and drivers can recreate them on first open.
- Make MGA always use addmap, instead of allocating consistent memory in
the PCI case and then faking up a map for it, which accomplished nearly
the same thing, in a different order.  Note that the maps are exposed to
the user again: we may want to expose a flag to avoid this, but it's not
a security concern, and saves us a lot of code.
- Remove rmmaps in the MGA driver.  Since the function is only called
during takedown anyway, we can let them die a natural death.
- Make removal of maps happen in one function, which is called by both
drm_takedown and drm_rmmap_ioctl.

Places to go from here:
- Remove the hack of setting up dmahs on the stack in order to
drm_pci_free, by storing the real dmah in the drm_local_map_t.
- Remove the rmmap ioctl calls from the X Server (I think this would be
safe: a number of the rmmaps are for framebuffer/registers, which never
get rmmapped anyways, and takedown should clean up the rest.  I don't
think you would be able to successfully start DRI again anyway if
someone's still holding the device open).

This was tested by starting/glxgears/stopping on mga, savage, and
radeon.  In the MGA case it was with and without old-dma, and also with
ForcePCIDMA.

The diff is about +190, -390 lines.  Anyone want to review it first,
since I have a tendency to under-test on linux?

-- 
Eric Anholt                                     [EMAIL PROTECTED]
http://people.freebsd.org/~anholt/              [EMAIL PROTECTED]
Index: linux-core/drmP.h
===================================================================
RCS file: /cvs/dri/drm/linux-core/drmP.h,v
retrieving revision 1.149
diff -u -r1.149 drmP.h
--- linux-core/drmP.h	17 Jun 2005 09:09:17 -0000	1.149
+++ linux-core/drmP.h	27 Jun 2005 02:55:54 -0000
@@ -571,7 +571,6 @@
 /* variables */
 	u32 driver_features;
 	int dev_priv_size;
-	int permanent_maps;
 	drm_ioctl_desc_t *ioctls;
 	int num_ioctls;
 	struct file_operations fops;
@@ -863,15 +862,13 @@
 extern int drm_addbufs_fb (drm_device_t * dev, drm_buf_desc_t * request);
 extern int drm_addmap(drm_device_t * dev, unsigned int offset,
 		      unsigned int size, drm_map_type_t type,
-		      drm_map_flags_t flags, drm_map_t ** map_ptr);
+		      drm_map_flags_t flags, drm_local_map_t ** map_ptr);
 extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
 			    unsigned int cmd, unsigned long arg);
-extern int drm_rmmap(drm_device_t *dev, void *handle);
+extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
+extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
 extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
 			   unsigned int cmd, unsigned long arg);
-extern int drm_initmap(drm_device_t * dev, unsigned int offset,
-		       unsigned int size, unsigned int resource, int type,
-		       int flags);
 extern int drm_addbufs(struct inode *inode, struct file *filp,
 		       unsigned int cmd, unsigned long arg);
 extern int drm_infobufs(struct inode *inode, struct file *filp,
Index: linux-core/drm_bufs.c
===================================================================
RCS file: /cvs/dri/drm/linux-core/drm_bufs.c,v
retrieving revision 1.59
diff -u -r1.59 drm_bufs.c
--- linux-core/drm_bufs.c	14 Jun 2005 22:34:10 -0000	1.59
+++ linux-core/drm_bufs.c	27 Jun 2005 03:03:55 -0000
@@ -48,66 +48,21 @@
 }
 EXPORT_SYMBOL(drm_get_resource_len);
 
- /**
- * Adjusts the memory offset to its absolute value according to the mapping
- * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
- * applicable and if supported by the kernel.
- */
-int drm_initmap(drm_device_t * dev, unsigned int offset, unsigned int size,
-		unsigned int resource, int type, int flags)
+static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
+					      drm_local_map_t *map)
 {
-	drm_map_t *map;
-	drm_map_list_t *list;
-
-	DRM_DEBUG("\n");
-
-	if ((offset & (~PAGE_MASK)) || (size & (~PAGE_MASK)))
-		return -EINVAL;
-#if !defined(__sparc__) && !defined(__alpha__)
-	if (offset + size < offset || offset < virt_to_phys(high_memory))
-		return -EINVAL;
-#endif
-	if (!(list = drm_alloc(sizeof(*list), DRM_MEM_MAPS)))
-		return -ENOMEM;
-	memset(list, 0, sizeof(*list));
-
-	if (!(map = drm_alloc(sizeof(*map), DRM_MEM_MAPS))) {
-		drm_free(list, sizeof(*list), DRM_MEM_MAPS);
-		return -ENOMEM;
-	}
-
-	*map = (drm_map_t) {
-	.offset = offset,.size = size,.type = type,.flags =
-		    flags,.mtrr = -1,.handle = 0,};
-	list->map = map;
-
-	DRM_DEBUG("initmap offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-		  map->offset, map->size, map->type);
+	struct list_head *list;
 
-#ifdef __alpha__
-	map->offset += dev->hose->mem_space->start;
-#endif
-	if (drm_core_has_MTRR(dev)) {
-		if (map->type == _DRM_FRAME_BUFFER ||
-		    (map->flags & _DRM_WRITE_COMBINING)) {
-			map->mtrr = mtrr_add(map->offset, map->size,
-					     MTRR_TYPE_WRCOMB, 1);
+	list_for_each(list, &dev->maplist->head) {
+		drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
+		if (entry->map && map->type == entry->map->type &&
+		    entry->map->offset == map->offset) {
+			return entry->map;
 		}
 	}
 
-	if (map->type == _DRM_REGISTERS)
-		map->handle = drm_ioremap(map->offset, map->size, dev);
-
-	down(&dev->struct_sem);
-	list_add(&list->head, &dev->maplist->head);
-	up(&dev->struct_sem);
-
-	dev->driver->permanent_maps = 1;
-	DRM_DEBUG("finished\n");
-
-	return 0;
+	return NULL;
 }
-EXPORT_SYMBOL(drm_initmap);
 
 /**
  * Ioctl to specify a range of memory that is available for mapping by a non-root process.
@@ -124,12 +79,12 @@
  */
 int drm_addmap(drm_device_t * dev, unsigned int offset,
 	       unsigned int size, drm_map_type_t type,
-	       drm_map_flags_t flags, drm_map_t ** map_ptr)
+	       drm_map_flags_t flags, drm_local_map_t ** map_ptr)
 {
 	drm_map_t *map;
 	drm_map_list_t *list;
 	drm_dma_handle_t *dmah;
-
+	drm_local_map_t *found_map;
 
 	map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
 	if (!map)
@@ -159,65 +114,45 @@
 
 	switch (map->type) {
 	case _DRM_REGISTERS:
-	case _DRM_FRAME_BUFFER:{
-			/* after all the drivers switch to permanent mapping this should just return an error */
-			struct list_head *_list;
-
-			/* If permanent maps are implemented, maps must match */
-			if (dev->driver->permanent_maps) {
-				DRM_DEBUG
-				    ("Looking for: offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-				     map->offset, map->size, map->type);
-				list_for_each(_list, &dev->maplist->head) {
-					drm_map_list_t *_entry =
-					    list_entry(_list, drm_map_list_t,
-						       head);
-					DRM_DEBUG
-					    ("Checking: offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-					     _entry->map->offset,
-					     _entry->map->size,
-					     _entry->map->type);
-					if (_entry->map
-					    && map->type == _entry->map->type
-					    && map->offset ==
-					    _entry->map->offset) {
-						_entry->map->size = map->size;
-						drm_free(map, sizeof(*map),
-							 DRM_MEM_MAPS);
-						map = _entry->map;
-						DRM_DEBUG
-						    ("Found existing: offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-						     map->offset, map->size,
-						     map->type);
-						goto found_it;
-					}
-				}
-				/* addmap didn't match an existing permanent map, that's an error */
-				return -EINVAL;
-			}
+	case _DRM_FRAME_BUFFER:
 #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
-			if (map->offset + map->size < map->offset ||
-			    map->offset < virt_to_phys(high_memory)) {
-				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-				return -EINVAL;
-			}
+		if (map->offset + map->size < map->offset ||
+		    map->offset < virt_to_phys(high_memory)) {
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			return -EINVAL;
+		}
 #endif
 #ifdef __alpha__
-			map->offset += dev->hose->mem_space->start;
+		map->offset += dev->hose->mem_space->start;
 #endif
-			if (drm_core_has_MTRR(dev)) {
-				if (map->type == _DRM_FRAME_BUFFER ||
-				    (map->flags & _DRM_WRITE_COMBINING)) {
-					map->mtrr =
-					    mtrr_add(map->offset, map->size,
-						     MTRR_TYPE_WRCOMB, 1);
-				}
+		/* Some drivers preinitialize some maps, without the X Server
+		 * needing to be aware of it.  Therefore, we just return success
+		 * when the server tries to create a duplicate map.
+		 */
+		found_map = drm_find_matching_map(dev, map);
+		if (found_map != NULL) {
+			if (found_map->size != map->size) {
+				DRM_DEBUG("Matching maps of type %d with "
+				   "mismatched sizes, (%ld vs %ld)\n",
+				    map->type, map->size, found_map->size);
+				found_map->size = map->size;
 			}
-			if (map->type == _DRM_REGISTERS)
-				map->handle =
-				    drm_ioremap(map->offset, map->size, dev);
-			break;
+
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			*map_ptr = found_map;
+			return 0;
 		}
+
+		if (drm_core_has_MTRR(dev)) {
+			if (map->type == _DRM_FRAME_BUFFER ||
+			    (map->flags & _DRM_WRITE_COMBINING)) {
+				map->mtrr =  mtrr_add(map->offset, map->size,
+						      MTRR_TYPE_WRCOMB, 1);
+			}
+		}
+		if (map->type == _DRM_REGISTERS)
+			map->handle = drm_ioremap(map->offset, map->size, dev);
+		break;
 	case _DRM_SHM:
 		map->handle = vmalloc_32(map->size);
 		DRM_DEBUG("%lu %d %p\n",
@@ -284,7 +219,7 @@
 	down(&dev->struct_sem);
 	list_add(&list->head, &dev->maplist->head);
 	up(&dev->struct_sem);
-      found_it:
+
 	*map_ptr = map;
 	return 0;
 }
@@ -340,88 +275,127 @@
  *
  * \sa drm_addmap
  */
-int drm_rmmap(drm_device_t *dev, void *handle)
+int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
 {
 	struct list_head *list;
 	drm_map_list_t *r_list = NULL;
-	drm_vma_entry_t *pt, *prev;
-	drm_map_t *map;
-	int found_maps = 0;
+	drm_dma_handle_t dmah;
 
-
-	down(&dev->struct_sem);
-	list = &dev->maplist->head;
+	/* Find the list entry for the map and remove it */
 	list_for_each(list, &dev->maplist->head) {
 		r_list = list_entry(list, drm_map_list_t, head);
 
-		if (r_list->map &&
-		    r_list->map->handle == handle &&
-		    r_list->map->flags & _DRM_REMOVABLE)
+		if (r_list->map == map) {
+			list_del(list);
+			drm_free(list, sizeof(*list), DRM_MEM_MAPS);
 			break;
+		}
 	}
 
-	/* List has wrapped around to the head pointer, or its empty we didn't
-	 * find anything.
+	/* List has wrapped around to the head pointer, or it's empty and we
+	 * didn't find anything.
 	 */
 	if (list == (&dev->maplist->head)) {
-		up(&dev->struct_sem);
 		return -EINVAL;
 	}
-	map = r_list->map;
 
-	/* Register and framebuffer maps are permanent */
-	if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
-		up(&dev->struct_sem);
-		return 0;
-	}
-	list_del(list);
-	drm_free(list, sizeof(*list), DRM_MEM_MAPS);
-
-	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-		if (pt->vma->vm_private_data == map)
-			found_maps++;
-	}
-
-	if (!found_maps) {
-		drm_dma_handle_t dmah;
-
-		switch (map->type) {
-		case _DRM_REGISTERS:
-		case _DRM_FRAME_BUFFER:
-			break;	/* Can't get here, make compiler happy */
-		case _DRM_SHM:
-			vfree(map->handle);
-			break;
-		case _DRM_AGP:
-		case _DRM_SCATTER_GATHER:
-			break;
-		case _DRM_CONSISTENT:
-			dmah.vaddr = map->handle;
-			dmah.busaddr = map->offset;
-			dmah.size = map->size;
-			__drm_pci_free(dev, &dmah);
-			break;
+	switch (map->type) {
+	case _DRM_REGISTERS:
+		drm_ioremapfree(map->handle, map->size, dev);
+		/* FALLTHROUGH */
+	case _DRM_FRAME_BUFFER:
+		if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
+			int retcode;
+			retcode = mtrr_del(map->mtrr, map->offset,
+					   map->size);
+			DRM_DEBUG ("mtrr_del=%d\n", retcode);
 		}
-		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+		break;
+	case _DRM_SHM:
+		vfree(map->handle);
+		break;
+	case _DRM_AGP:
+	case _DRM_SCATTER_GATHER:
+		break;
+	case _DRM_CONSISTENT:
+		dmah.vaddr = map->handle;
+		dmah.busaddr = map->offset;
+		dmah.size = map->size;
+		__drm_pci_free(dev, &dmah);
+		break;
 	}
-	up(&dev->struct_sem);
+	drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+
 	return 0;
 }
+EXPORT_SYMBOL(drm_rmmap_locked);
+
+int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
+{
+	int ret;
+
+	down(&dev->struct_sem);
+	ret = drm_rmmap_locked(dev, map);
+	up(&dev->struct_sem);
+
+	return ret;
+}
 EXPORT_SYMBOL(drm_rmmap);
 
+/* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
+ * the last close of the device, and this is necessary for cleanup when things
+ * exit uncleanly.  Therefore, having userland manually remove mappings seems
+ * like a pointless exercise since they're going away anyway.
+ *
+ * One use case might be after addmap is allowed for normal users for SHM and
+ * gets used by drivers that the server doesn't need to care about.  This seems
+ * unlikely.
+ */
 int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long arg)
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->head->dev;
 	drm_map_t request;
-
+	drm_local_map_t *map;
+	struct list_head *list;
+	int ret;
 
 	if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) {
 		return -EFAULT;
 	}
 
-	return drm_rmmap(dev, request.handle);
+	down(&dev->struct_sem);
+	list_for_each(list, &dev->maplist->head) {
+		drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
+
+		if (r_list->map &&
+		    r_list->map->handle == request.handle &&
+		    r_list->map->flags & _DRM_REMOVABLE) {
+			map = r_list->map;
+			break;
+		}
+	}
+
+	/* List has wrapped around to the head pointer, or its empty we didn't
+	 * find anything.
+	 */
+	if (list == (&dev->maplist->head)) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	/* Register and framebuffer maps are permanent */
+	if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
+		up(&dev->struct_sem);
+		return 0;
+	}
+
+	ret = drm_rmmap_locked(dev, map);
+
+	up(&dev->struct_sem);
+
+	return ret;
 }
 
 /**
Index: linux-core/drm_drv.c
===================================================================
RCS file: /cvs/dri/drm/linux-core/drm_drv.c,v
retrieving revision 1.118
diff -u -r1.118 drm_drv.c
--- linux-core/drm_drv.c	14 Jun 2005 22:34:10 -0000	1.118
+++ linux-core/drm_drv.c	27 Jun 2005 04:36:30 -0000
@@ -135,9 +135,7 @@
 int drm_takedown(drm_device_t * dev)
 {
 	drm_magic_entry_t *pt, *next;
-	drm_map_t *map;
 	drm_map_list_t *r_list;
-	struct list_head *list, *list_next;
 	drm_vma_entry_t *vma, *vma_next;
 	int i;
 
@@ -145,6 +143,7 @@
 
 	if (dev->driver->pretakedown)
 		dev->driver->pretakedown(dev);
+	DRM_DEBUG("driver pretakedown completed\n");
 
 	if (dev->unique) {
 		drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
@@ -195,6 +194,10 @@
 		dev->agp->acquired = 0;
 		dev->agp->enabled = 0;
 	}
+	if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
+		drm_sg_cleanup(dev->sg);
+		dev->sg = NULL;
+	}
 
 	/* Clear vma list (only built for debugging) */
 	if (dev->vmalist) {
@@ -206,45 +209,10 @@
 	}
 
 	if (dev->maplist) {
-		list_for_each_safe(list, list_next, &dev->maplist->head) {
-			r_list = (drm_map_list_t *) list;
-
-			if ((map = r_list->map)) {
-				drm_dma_handle_t dmah;
-
-				switch (map->type) {
-				case _DRM_REGISTERS:
-				case _DRM_FRAME_BUFFER:
-					continue;
-
-				case _DRM_SHM:
-					vfree(map->handle);
-					break;
-
-				case _DRM_AGP:
-					/* Do nothing here, because this is all
-					 * handled in the AGP/GART driver.
-					 */
-					break;
-				case _DRM_SCATTER_GATHER:
-					/* Handle it */
-					if (drm_core_check_feature
-					    (dev, DRIVER_SG) && dev->sg) {
-						drm_sg_cleanup(dev->sg);
-						dev->sg = NULL;
-					}
-					break;
-				case _DRM_CONSISTENT:
-					dmah.vaddr = map->handle;
-					dmah.busaddr = map->offset;
-					dmah.size = map->size;
-					__drm_pci_free(dev, &dmah);
-					break;
-				}
-				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-			}
-			list_del(list);
-			drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
+		while (!list_empty(&dev->maplist->head)) {
+			struct list_head *list = dev->maplist->head.next;
+			r_list = list_entry(list, drm_map_list_t, head);
+			drm_rmmap_locked(dev, r_list->map);
 		}
 	}
 
@@ -278,6 +246,7 @@
 	}
 	up(&dev->struct_sem);
 
+	DRM_DEBUG("takedown completed\n");
 	return 0;
 }
 
@@ -369,9 +338,6 @@
  */
 static void __exit drm_cleanup(drm_device_t * dev)
 {
-	drm_map_t *map;
-	drm_map_list_t *r_list;
-	struct list_head *list, *list_next;
 
 	DRM_DEBUG("\n");
 	if (!dev) {
@@ -382,44 +348,6 @@
 	drm_takedown(dev);
 
 	if (dev->maplist) {
-		list_for_each_safe(list, list_next, &dev->maplist->head) {
-			r_list = (drm_map_list_t *) list;
-
-			if ((map = r_list->map)) {
-				switch (map->type) {
-				case _DRM_REGISTERS:
-					drm_ioremapfree(map->handle, map->size,
-							dev);
-					break;
-
-				case _DRM_FRAME_BUFFER:
-					if (drm_core_has_MTRR(dev)) {
-						if (map->mtrr >= 0) {
-							int retcode;
-							retcode =
-							    mtrr_del(map->mtrr,
-								     map->
-								     offset,
-								     map->size);
-							DRM_DEBUG
-							    ("mtrr_del=%d\n",
-							     retcode);
-						}
-					}
-					break;
-
-				case _DRM_SHM:
-				case _DRM_AGP:
-				case _DRM_SCATTER_GATHER:
-				case _DRM_CONSISTENT:
-					DRM_DEBUG("Extra maplist item\n");
-					break;
-				}
-				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-			}
-			list_del(list);
-			drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
-		}
 		drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
 		dev->maplist = NULL;
 	}
Index: shared-core/mga_dma.c
===================================================================
RCS file: /cvs/dri/drm/shared-core/mga_dma.c,v
retrieving revision 1.26
diff -u -r1.26 mga_dma.c
--- shared-core/mga_dma.c	17 Jun 2005 09:09:17 -0000	1.26
+++ shared-core/mga_dma.c	26 Jun 2005 22:57:10 -0000
@@ -553,44 +553,6 @@
 }
 
 /**
- * Create a "fake" drm_map_t for a pre-mapped range of PCI consistent memory.
- *
- * Unlike \c drm_addmap, this function just creates a \c drm_map_t wrapper for
- * a block of PCI consistent memory.  \c drm_addmap, basically, converts a bus
- * address to a virtual address.  However, \c drm_pci_alloc gives both the bus
- * address and the virtual address for the memory region.  Not only is there
- * no need to map it again, but mapping it again will cause problems.
- * 
- * \param dmah  DRM DMA handle returned by \c drm_pci_alloc.
- * \param map_ptr  Location to store a pointer to the \c drm_map_t.
- * 
- * \returns
- * On success, zero is returned.  Otherwise and error code suitable for
- * returning from an ioctl is returned.
- */
-static int mga_fake_addmap(drm_dma_handle_t * dmah, drm_map_t ** map_ptr)
-{
-	drm_map_t * map;
-
-
-	map = drm_alloc(sizeof(drm_map_t), DRM_MEM_DRIVER);
-	if (map == NULL) {
-		return DRM_ERR(ENOMEM);
-	}
-
-	map->offset = dmah->busaddr;
-	map->size = dmah->size;
-	map->type = _DRM_CONSISTENT;
-	map->flags = _DRM_READ_ONLY;
-	map->handle = dmah->vaddr;
-	map->mtrr = 0;
-	
-	*map_ptr = map;
-	
-	return 0;
-}
-
-/**
  * Bootstrap the driver for PCI DMA.
  * 
  * \todo
@@ -620,52 +582,41 @@
 		return DRM_ERR(EFAULT);
 	}
 
-
-	/* The WARP microcode base address must be 256-byte aligned.
-	 */
-	dev_priv->warp_dmah = drm_pci_alloc(dev, warp_size, 0x100, 0x7fffffff);
-	err = mga_fake_addmap(dev_priv->warp_dmah, & dev_priv->warp);
-	if (err) {
-		DRM_ERROR("Unable to map WARP microcode\n");
+	/* The proper alignment is 0x100 for this mapping */
+	err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
+			 _DRM_READ_ONLY, &dev_priv->warp);
+	if (err != 0) {
+		DRM_ERROR("Unable to create mapping for WARP microcode\n");
 		return err;
 	}
 
-
 	/* Other than the bottom two bits being used to encode other
 	 * information, there don't appear to be any restrictions on the
 	 * alignment of the primary or secondary DMA buffers.
 	 */
 
-	dev_priv->primary_dmah = NULL;
 	for ( primary_size = dma_bs->primary_size
 	      ; primary_size != 0
 	      ; primary_size >>= 1 ) {
-		dev_priv->primary_dmah = drm_pci_alloc(dev, primary_size,
-					     0x04, 0x7fffffff);
-		if (dev_priv->primary_dmah != NULL) {
+		/* The proper alignment for this mapping is 0x04 */
+		err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
+				 _DRM_READ_ONLY, &dev_priv->primary);
+		if (!err)
 			break;
-		}
 	}
 
-	if (dev_priv->primary_dmah == NULL) {
+	if (err != 0) {
 		DRM_ERROR("Unable to allocate primary DMA region\n");
 		return DRM_ERR(ENOMEM);
 	}
 
-	if (dev_priv->primary_dmah->size != dma_bs->primary_size) {
+	if (dev_priv->primary->size != dma_bs->primary_size) {
 		DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
 			 dma_bs->primary_size, 
-			 (unsigned) dev_priv->primary_dmah->size);
-		dma_bs->primary_size = dev_priv->primary_dmah->size;
-	}
-
-	err = mga_fake_addmap(dev_priv->primary_dmah, & dev_priv->primary);
-	if (err) {
-		DRM_ERROR("Unable to map primary DMA region\n");
-		return err;
+			 (unsigned) dev_priv->primary->size);
+		dma_bs->primary_size = dev_priv->primary->size;
 	}
 
-
 	for ( bin_count = dma_bs->secondary_bin_count
 	      ; bin_count > 0 
 	      ; bin_count-- ) {
@@ -970,47 +921,8 @@
 			drm_core_ioremapfree(dev->agp_buffer_map, dev);
 
 		if (dev_priv->used_new_dma_init) {
-			if (dev_priv->warp != NULL) {
-				drm_rmmap(dev, (void *) dev_priv->warp->offset);
-			}
-
-			if (dev_priv->primary != NULL) {
-				if (dev_priv->primary->type != _DRM_CONSISTENT) {
-					drm_rmmap(dev, (void *) dev_priv->primary->offset);
-				}
-				else {
-					drm_free(dev_priv->primary, sizeof(drm_map_t), DRM_MEM_DRIVER);
-				}
-			}
-
-			if (dev_priv->warp_dmah != NULL) {
-				drm_pci_free(dev, dev_priv->warp_dmah);
-				dev_priv->warp_dmah = NULL;
-			}
-
-			if (dev_priv->primary_dmah != NULL) {
-				drm_pci_free(dev, dev_priv->primary_dmah);
-				dev_priv->primary_dmah = NULL;
-			}
-
-			if (dev_priv->mmio != NULL) {
-				drm_rmmap(dev, (void *) dev_priv->mmio->offset);
-			}
-
-			if (dev_priv->status != NULL) {
-				drm_rmmap(dev, (void *) dev_priv->status->offset);
-			}
-
 			if (dev_priv->agp_mem != NULL) {
-				if (dev->agp_buffer_map != NULL) {
-					drm_rmmap(dev, (void *) dev->agp_buffer_map->offset);
-				}
-
-				if (dev_priv->agp_textures != NULL) {
-					drm_rmmap(dev, (void *) dev_priv->agp_textures->offset);
-					dev_priv->agp_textures = NULL;
-				}
-
+				dev_priv->agp_textures = NULL;
 				drm_unbind_agp(dev_priv->agp_mem);
 
 				drm_free_agp(dev_priv->agp_mem, dev_priv->agp_pages);
Index: shared-core/mga_drv.h
===================================================================
RCS file: /cvs/dri/drm/shared-core/mga_drv.h,v
retrieving revision 1.20
diff -u -r1.20 mga_drv.h
--- shared-core/mga_drv.h	14 Jun 2005 22:34:11 -0000	1.20
+++ shared-core/mga_drv.h	21 Jun 2005 23:55:21 -0000
@@ -107,18 +107,6 @@
 	 */
 	u32 wagp_enable;
 
-	
-	/**
-	 * \name Handles for PCI consistent memory.
-	 * 
-	 * \sa drm_mga_private_t::primary, drm_mga_private_t::warp
-	 */
-	/[EMAIL PROTECTED]/
-	drm_dma_handle_t * warp_dmah;    /**< Handle for WARP ucode region. */
-	drm_dma_handle_t * primary_dmah; /**< Handle for primary DMA region. */
-	/[EMAIL PROTECTED]/
-
-
 	/**
 	 * \name MMIO region parameters.
 	 * 
Index: shared-core/radeon_cp.c
===================================================================
RCS file: /cvs/dri/drm/shared-core/radeon_cp.c,v
retrieving revision 1.58
diff -u -r1.58 radeon_cp.c
--- shared-core/radeon_cp.c	21 Jun 2005 23:07:24 -0000	1.58
+++ shared-core/radeon_cp.c	27 Jun 2005 02:59:40 -0000
@@ -2013,6 +2013,7 @@
 {
 	drm_radeon_private_t *dev_priv;
 	int ret = 0;
+	drm_local_map_t *map;
 
 	dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
 	if (dev_priv == NULL)
@@ -2034,14 +2035,15 @@
 		break;
 	}
 
-	ret = drm_initmap(dev, drm_get_resource_start(dev, 2),
-			  drm_get_resource_len(dev, 2), 2, _DRM_REGISTERS, _DRM_READ_ONLY);
+	ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
+			 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
+			 _DRM_READ_ONLY, &map);
 	if (ret != 0)
 		return ret;
 
-	ret = drm_initmap(dev, drm_get_resource_start(dev, 0),
-			  drm_get_resource_len(dev, 0), 0, _DRM_FRAME_BUFFER,
-			  _DRM_WRITE_COMBINING);
+	ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
+			 drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
+			 _DRM_WRITE_COMBINING, &map);
 	if (ret != 0)
 		return ret;
 
Index: shared-core/savage_bci.c
===================================================================
RCS file: /cvs/dri/drm/shared-core/savage_bci.c,v
retrieving revision 1.12
diff -u -r1.12 savage_bci.c
--- shared-core/savage_bci.c	21 Jun 2005 02:20:02 -0000	1.12
+++ shared-core/savage_bci.c	27 Jun 2005 04:38:07 -0000
@@ -537,18 +537,20 @@
 }
 
 /*
- * Initalize permanent mappings. On Savage4 and SavageIX the alignment
+ * Initalize mappings. On Savage4 and SavageIX the alignment
  * and size of the aperture is not suitable for automatic MTRR setup
- * in drm_initmap. Therefore we do it manually before the maps are
+ * in drm_addmap. Therefore we do it manually before the maps are
  * initialized. We also need to take care of deleting the MTRRs in
  * postcleanup.
- *
- * FIXME: this is linux-specific
  */
 int savage_preinit(drm_device_t *dev, unsigned long chipset)
 {
 	drm_savage_private_t *dev_priv;
 	unsigned long mmio_base, fb_base, fb_size, aperture_base;
+	/* fb_rsrc and aper_rsrc aren't really used currently, but still exist
+	 * in case we decide we need information on the BAR for BSD in the
+	 * future.
+	 */
 	unsigned int fb_rsrc, aper_rsrc;
 	int ret = 0;
 
@@ -623,24 +625,21 @@
 		/* Automatic MTRR setup will do the right thing. */
 	}
 
-	if ((ret = drm_initmap(dev, mmio_base, SAVAGE_MMIO_SIZE, 0,
-			       _DRM_REGISTERS, _DRM_READ_ONLY)))
+	ret = drm_addmap(dev, mmio_base, SAVAGE_MMIO_SIZE, _DRM_REGISTERS,
+			 _DRM_READ_ONLY, &dev_priv->mmio);
+	if (ret)
 		return ret;
-	if (!(dev_priv->mmio = drm_core_findmap (dev, mmio_base)))
-		return DRM_ERR(ENOMEM);
 
-	if ((ret = drm_initmap(dev, fb_base, fb_size, fb_rsrc,
-			       _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING)))
+	ret = drm_addmap(dev, fb_base, fb_size, _DRM_FRAME_BUFFER,
+			 _DRM_WRITE_COMBINING, &dev_priv->fb);
+	if (ret)
 		return ret;
-	if (!(dev_priv->fb = drm_core_findmap (dev, fb_base)))
-		return DRM_ERR(ENOMEM);
 
-	if ((ret = drm_initmap(dev, aperture_base, SAVAGE_APERTURE_SIZE,
-			       aper_rsrc,
-			       _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING)))
+	ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE,
+			 _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING,
+			 &dev_priv->aperture);
+	if (ret)
 		return ret;
-	if (!(dev_priv->aperture = drm_core_findmap (dev, aperture_base)))
-		return DRM_ERR(ENOMEM);
 
 	return ret;
 }

Reply via email to