From 5d96c74ff1fe9b2d37e22dbea9882791aae389bf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 28 Jun 2005 20:58:34 +0000 Subject: - 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 --- linux-core/drmP.h | 9 +- linux-core/drm_bufs.c | 290 +++++++++++++++++++++-------------------------- linux-core/drm_drv.c | 92 ++------------- linux-core/radeon_drv.c | 1 + shared-core/mga_dma.c | 116 +++---------------- shared-core/mga_drv.h | 12 -- shared-core/radeon_cp.c | 43 ++++--- shared-core/radeon_drv.h | 1 + shared-core/savage_bci.c | 33 +++--- 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 @@ -552,44 +552,6 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, return 0; } -/** - * 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. * @@ -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; } -- cgit v1.2.3