summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2005-06-28 20:58:34 +0000
committerEric Anholt <anholt@freebsd.org>2005-06-28 20:58:34 +0000
commit5d96c74ff1fe9b2d37e22dbea9882791aae389bf (patch)
tree598019eecfc3d9c964a79d7b9841a1c86829d14b
parent6397722f1990856a9ee268cadd65d78b44b24835 (diff)
- Remove drm_initmap and replace its usage with drm_addmap. This reduces
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
-rw-r--r--linux-core/drmP.h9
-rw-r--r--linux-core/drm_bufs.c290
-rw-r--r--linux-core/drm_drv.c92
-rw-r--r--linux-core/radeon_drv.c1
-rw-r--r--shared-core/mga_dma.c116
-rw-r--r--shared-core/mga_drv.h12
-rw-r--r--shared-core/radeon_cp.c43
-rw-r--r--shared-core/radeon_drv.h1
-rw-r--r--shared-core/savage_bci.c33
9 files changed, 198 insertions, 399 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 9c0e5b84..5ada94ef 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -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,
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index d60d0823..e5d4c6bf 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -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;
}
/**
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 6ed5ce1e..d72d1c37 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -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;
}
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index 7b1aa59e..c26d887d 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -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,
diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c
index a632f35a..cb2b2561 100644
--- a/shared-core/mga_dma.c
+++ b/shared-core/mga_dma.c
@@ -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);
diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h
index 7a1799b9..8f3ff5ca 100644
--- a/shared-core/mga_drv.h
+++ b/shared-core/mga_drv.h
@@ -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.
*
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index b5e74451..7da83960 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -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;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 8b05aab8..b613f4c0 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -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 ) \
diff --git a/shared-core/savage_bci.c b/shared-core/savage_bci.c
index 150f74b4..bfd760ea 100644
--- a/shared-core/savage_bci.c
+++ b/shared-core/savage_bci.c
@@ -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;
}