- Remove drm_initmap and replace its usage with drm_addmap. This reduces
authorEric Anholt <anholt@freebsd.org>
Tue, 28 Jun 2005 20:58:34 +0000 (20:58 +0000)
committerEric Anholt <anholt@freebsd.org>
Tue, 28 Jun 2005 20:58:34 +0000 (20:58 +0000)
    code duplication, and it also hands you the map pointer so you don't
    need to re-find 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. Move the Radeon map initialization into presetup (first
    open) so it happens again after every takedown.
- 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.
Reviewed by: idr (previous revision) Tested on: mga (old/new/pci dma),
    radeon, savage

linux-core/drmP.h
linux-core/drm_bufs.c
linux-core/drm_drv.c
linux-core/radeon_drv.c
shared-core/mga_dma.c
shared-core/mga_drv.h
shared-core/radeon_cp.c
shared-core/radeon_drv.h
shared-core/savage_bci.c

index 9c0e5b8..5ada94e 100644 (file)
@@ -572,7 +572,6 @@ struct drm_driver {
 /* variables */
        u32 driver_features;
        int dev_priv_size;
-       int permanent_maps;
        drm_ioctl_desc_t *ioctls;
        int num_ioctls;
        struct file_operations fops;
@@ -864,15 +863,13 @@ extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
 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 d60d082..e5d4c6b 100644 (file)
@@ -48,66 +48,21 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
 }
 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);
 
 #ifdef CONFIG_COMPAT
 /*
@@ -133,12 +88,12 @@ static unsigned int map32_handle = 0x10000000;
  */
 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)
@@ -168,65 +123,45 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
 
        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",
@@ -300,7 +235,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
 #endif
 
        up(&dev->struct_sem);
-      found_it:
+
        *map_ptr = map;
        return 0;
 }
@@ -356,88 +291,127 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
  *
  * \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;
+       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);
+               }
+               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;
        }
-       list_del(list);
-       drm_free(list, sizeof(*list), DRM_MEM_MAPS);
+       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
 
-       for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-               if (pt->vma->vm_private_data == map)
-                       found_maps++;
-       }
+       return 0;
+}
+EXPORT_SYMBOL(drm_rmmap_locked);
 
-       if (!found_maps) {
-               drm_dma_handle_t dmah;
+int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
+{
+       int ret;
 
-               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;
-               }
-               drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-       }
+       down(&dev->struct_sem);
+       ret = drm_rmmap_locked(dev, map);
        up(&dev->struct_sem);
-       return 0;
+
+       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 6ed5ce1..d72d1c3 100644 (file)
@@ -135,9 +135,7 @@ drm_ioctl_desc_t drm_ioctls[] = {
 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 @@ int drm_takedown(drm_device_t * dev)
 
        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 @@ int drm_takedown(drm_device_t * dev)
                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 @@ int drm_takedown(drm_device_t * 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)) {
-                               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);
                }
        }
 
@@ -275,6 +243,7 @@ int drm_takedown(drm_device_t * dev)
        }
        up(&dev->struct_sem);
 
+       DRM_DEBUG("takedown completed\n");
        return 0;
 }
 
@@ -368,9 +337,6 @@ EXPORT_SYMBOL(drm_init);
  */
 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) {
@@ -381,44 +347,6 @@ static void __exit drm_cleanup(drm_device_t * dev)
        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 7b1aa59..c26d887 100644 (file)
@@ -77,6 +77,7 @@ static struct drm_driver driver = {
            DRIVER_IRQ_VBL,
        .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
        .preinit = radeon_preinit,
+       .presetup = radeon_presetup,
        .postcleanup = radeon_postcleanup,
        .prerelease = radeon_driver_prerelease,
        .pretakedown = radeon_driver_pretakedown,
index a632f35..cb2b256 100644 (file)
@@ -553,44 +553,6 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
 }
 
 /**
- * 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 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
                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 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
                        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 7a1799b..8f3ff5c 100644 (file)
@@ -107,18 +107,6 @@ typedef struct drm_mga_private {
         */
        u32 wagp_enable;
 
-       
-       /**
-        * \name Handles for PCI consistent memory.
-        * 
-        * \sa drm_mga_private_t::primary, drm_mga_private_t::warp
-        */
-       /*@{*/
-       drm_dma_handle_t * warp_dmah;    /**< Handle for WARP ucode region. */
-       drm_dma_handle_t * primary_dmah; /**< Handle for primary DMA region. */
-       /*@}*/
-
-
        /**
         * \name MMIO region parameters.
         * 
index b5e7445..7da8396 100644 (file)
@@ -2034,37 +2034,36 @@ int radeon_preinit(struct drm_device *dev, unsigned long flags)
                break;
        }
 
-       ret = drm_initmap(dev, drm_get_resource_start(dev, 2),
-                         drm_get_resource_len(dev, 2), 2, _DRM_REGISTERS, _DRM_READ_ONLY);
-       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);
-       if (ret != 0)
-               return ret;
-
-       /* The original method of detecting AGP is known to not work correctly,
-        * according to Mike Harris.  The solution is to walk the capabilities
-        * list, which should be done in drm_device_is_agp().
-        */
        if (drm_device_is_agp(dev))
                dev_priv->flags |= CHIP_IS_AGP;
 
        DRM_DEBUG("%s card detected\n",
                  ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
 
-#if defined(__linux__)
-       /* Check if we need a reset */
-       if (!
-           (dev_priv->mmio =
-            drm_core_findmap(dev, pci_resource_start(dev->pdev, 2))))
-               return DRM_ERR(ENOMEM);
-#endif
        return ret;
 }
 
+int radeon_presetup(struct drm_device *dev)
+{
+       int ret;
+       drm_local_map_t *map;
+       drm_radeon_private_t *dev_priv = dev->dev_private;
+
+       ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
+                        drm_get_resource_len(dev, 2), _DRM_REGISTERS,
+                        _DRM_READ_ONLY, &dev_priv->mmio);
+       if (ret != 0)
+               return ret;
+
+       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;
+
+       return 0;
+}
+
 int radeon_postcleanup(struct drm_device *dev)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
index 8b05aab..b613f4c 100644 (file)
@@ -883,6 +883,7 @@ do {                                                                        \
 } while (0)
 
 extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
+extern int radeon_presetup(struct drm_device *dev);
 extern int radeon_postcleanup(struct drm_device *dev);
 
 #define CP_PACKET0( reg, n )                                           \
index 150f74b..bfd760e 100644 (file)
@@ -537,18 +537,20 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
 }
 
 /*
- * 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 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
                /* 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;
 }