From 080a547d4d42d42e08a525aca9a62b5ece7616d5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 5 Feb 2005 08:00:14 +0000 Subject: - Implement drm_initmap, and extend it with the resource number to help FreeBSD. Add drm_get_resource_{start|len} so linux-specific stuff doesn't need to be in shared code. - Fix mach64 build by using __DECONST to work around passing a const pointer to useracc, which is unfortunately not marked const. - Get rid of a lot of maplist code by not having dev->maplist be a pointer, and by sticking the link entries directly in drm_local_map_t rather than having a separate structure for the linked list. - Factor out map uninit and removal into its own routine, rather than duplicating in both drm_takedown() and drm_rmmap(). - Hook up more driver functions, and correct FreeBSD-specific bits of radeon_cp.c, making radeon work. - Baby steps towards using bus_space as we should. --- bsd-core/drmP.h | 56 ++++++----- bsd-core/drm_bufs.c | 254 +++++++++++++++++++++++++++++++++++------------ bsd-core/drm_context.c | 4 +- bsd-core/drm_drv.c | 75 +++++--------- bsd-core/drm_fops.c | 11 +- bsd-core/drm_ioctl.c | 6 +- bsd-core/drm_memory.c | 10 +- bsd-core/drm_sysctl.c | 7 +- bsd-core/drm_vm.c | 8 +- bsd-core/radeon_drv.c | 4 + linux-core/drmP.h | 7 +- linux-core/drm_bufs.c | 14 ++- shared-core/radeon_cp.c | 26 +++-- shared-core/savage_bci.c | 34 ++++--- 14 files changed, 332 insertions(+), 184 deletions(-) diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 43e22039..b32a4422 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -292,24 +292,24 @@ typedef u_int8_t u8; *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val #define DRM_VERIFYAREA_READ( uaddr, size ) \ - (!useracc((caddr_t)uaddr, size, VM_PROT_READ)) + (!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ)) #else /* __FreeBSD__ */ typedef vaddr_t vm_offset_t; #define DRM_READ8(map, offset) \ - bus_space_read_1( (map)->iot, (map)->ioh, (offset)) + bus_space_read_1( (map)->bst, (map)->bsh, (offset)) #define DRM_READ16(map, offset) \ - bus_space_read_2( (map)->iot, (map)->ioh, (offset)) + bus_space_read_2( (map)->bst, (map)->bsh, (offset)) #define DRM_READ32(map, offset) \ - bus_space_read_4( (map)->iot, (map)->ioh, (offset)) + bus_space_read_4( (map)->bst, (map)->bsh, (offset)) #define DRM_WRITE8(map, offset, val) \ - bus_space_write_1((map)->iot, (map)->ioh, (offset), (val)) + bus_space_write_1((map)->bst, (map)->bsh, (offset), (val)) #define DRM_WRITE16(map, offset, val) \ - bus_space_write_2((map)->iot, (map)->ioh, (offset), (val)) + bus_space_write_2((map)->bst, (map)->bsh, (offset), (val)) #define DRM_WRITE32(map, offset, val) \ - bus_space_write_4((map)->iot, (map)->ioh, (offset), (val)) + bus_space_write_4((map)->bst, (map)->bsh, (offset), (val)) #define DRM_VERIFYAREA_READ( uaddr, size ) \ (!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ)) @@ -373,10 +373,9 @@ do { \ #define DRM_GETSAREA() \ do { \ - drm_map_list_entry_t *listentry; \ + drm_local_map_t *map; \ DRM_SPINLOCK_ASSERT(&dev->dev_lock); \ - TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_local_map_t *map = listentry->map; \ + TAILQ_FOREACH(map, &dev->maplist, link) { \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -560,6 +559,8 @@ typedef struct drm_sg_mem { dma_addr_t *busaddr; } drm_sg_mem_t; +typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; + typedef struct drm_local_map { unsigned long offset; /* Physical address (0 for SAREA)*/ unsigned long size; /* Physical size (bytes) */ @@ -569,16 +570,14 @@ typedef struct drm_local_map { /* Kernel-space: kernel-virtual address */ int mtrr; /* Boolean: MTRR used */ /* Private data */ - bus_space_tag_t iot; - bus_space_handle_t ioh; + int rid; /* PCI resource ID for bus_space */ + int kernel_owned; /* Boolean: 1 = initmapped, 0 = addmapped */ + struct resource *bsr; + bus_space_tag_t bst; + bus_space_handle_t bsh; + TAILQ_ENTRY(drm_local_map) link; } drm_local_map_t; -typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t; -typedef struct drm_map_list_entry { - TAILQ_ENTRY(drm_map_list_entry) link; - drm_local_map_t *map; -} drm_map_list_entry_t; - TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig); typedef struct drm_vbl_sig { TAILQ_ENTRY(drm_vbl_sig) link; @@ -603,7 +602,8 @@ struct drm_device { int (*postcleanup)(struct drm_device *); int (*presetup)(struct drm_device *); int (*postsetup)(struct drm_device *); - void (*open_helper)(struct drm_device *, drm_file_t *); + int (*open_helper)(struct drm_device *, drm_file_t *); + void (*free_filp_priv)(struct drm_device *, drm_file_t *); void (*release)(struct drm_device *, void *filp); int (*dma_ioctl)(DRM_IOCTL_ARGS); void (*dma_ready)(struct drm_device *); @@ -676,7 +676,7 @@ struct drm_device { drm_magic_head_t magiclist[DRM_HASH_SIZE]; /* Linked list of mappable regions. Protected by dev_lock */ - drm_map_list_t *maplist; + drm_map_list_t maplist; drm_local_map_t **context_sareas; int max_context; @@ -793,6 +793,11 @@ int drm_lock_free(drm_device_t *dev, unsigned int context); /* Buffer management support (drm_bufs.c) */ +unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource); +unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource); +int drm_initmap(drm_device_t *dev, unsigned long start, unsigned long len, + unsigned int resource, int type, int flags); +void drm_remove_map(drm_device_t *dev, drm_local_map_t *map); int drm_order(unsigned long size); /* DMA support (drm_dma.c) */ @@ -919,11 +924,12 @@ static __inline__ void drm_core_ioremapfree(struct drm_local_map *map, struct dr static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev, unsigned long offset) { - drm_map_list_entry_t *listentry; - TAILQ_FOREACH(listentry, dev->maplist, link) { - if ( listentry->map->offset == offset ) { - return listentry->map; - } + drm_local_map_t *map; + + DRM_SPINLOCK_ASSERT(&dev->dev_lock); + TAILQ_FOREACH(map, &dev->maplist, link) { + if (map->offset == offset) + return map; } return NULL; } diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 26007a4d..0fefb8f5 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -48,19 +48,151 @@ int drm_order(unsigned long size) return order; } +unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +{ + struct resource *bsr; + unsigned long offset; + + resource = resource * 4 + 0x10; + + bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &resource, + RF_ACTIVE | RF_SHAREABLE); + if (bsr == NULL) { + DRM_ERROR("Couldn't find resource 0x%x\n", resource); + return 0; + } + + offset = rman_get_start(bsr); + + bus_release_resource(dev->device, SYS_RES_MEMORY, resource, bsr); + + return offset; +} + +unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) +{ + struct resource *bsr; + unsigned long len; + + resource = resource * 4 + 0x10; + + bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &resource, + RF_ACTIVE | RF_SHAREABLE); + if (bsr == NULL) { + DRM_ERROR("Couldn't find resource 0x%x\n", resource); + return ENOMEM; + } + + len = rman_get_size(bsr); + + bus_release_resource(dev->device, SYS_RES_MEMORY, resource, bsr); + + return len; +} + +int drm_initmap(drm_device_t *dev, unsigned long start, unsigned long len, + unsigned int resource, int type, int flags) +{ + drm_local_map_t *map; + struct resource *bsr; + + if (type != _DRM_REGISTERS && type != _DRM_FRAME_BUFFER) + return EINVAL; + if (len == 0) + return EINVAL; + + map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT); + if (map == NULL) + return ENOMEM; + + map->rid = resource * 4 + 0x10; + bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &map->rid, + RF_ACTIVE | RF_SHAREABLE); + if (bsr == NULL) { + DRM_ERROR("Couldn't allocate %s resource\n", + ((type == _DRM_REGISTERS) ? "mmio" : "framebuffer")); + free(map, M_DRM); + return ENOMEM; + } + + map->kernel_owned = 1; + map->type = type; + map->flags = flags; + map->bsr = bsr; + map->bst = rman_get_bustag(bsr); + map->bsh = rman_get_bushandle(bsr); + map->offset = start; + map->size = len; + + if (type == _DRM_REGISTERS) + map->handle = rman_get_virtual(bsr); + + DRM_DEBUG("initmap %d,0x%x@0x%lx/0x%lx\n", map->type, map->flags, + map->offset, map->size); + + if (map->flags & _DRM_WRITE_COMBINING) { + int err; + + err = drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC); + if (err == 0) + map->mtrr = 1; + } + + DRM_LOCK(); + TAILQ_INSERT_TAIL(&dev->maplist, map, link); + DRM_UNLOCK(); + + return 0; +} + int drm_addmap(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_map_t request; drm_local_map_t *map; - drm_map_list_entry_t *list; + dma_addr_t bus_addr; if (!(dev->flags & (FREAD|FWRITE))) return DRM_ERR(EACCES); /* Require read/write */ DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(drm_map_t) ); - map = malloc(sizeof(*map), M_DRM, M_NOWAIT); + /* Only allow shared memory to be removable since we only keep enough + * book keeping information about shared memory to allow for removal + * when processes fork. + */ + if ((request.flags & _DRM_REMOVABLE) && request.type != _DRM_SHM) + return EINVAL; + if ((request.offset & PAGE_MASK) || (request.size & PAGE_MASK)) + return EINVAL; + if (request.offset + request.size < request.offset) + return EINVAL; + + DRM_ERROR("offset = 0x%08lx, size = 0x%08lx, type = %d\n", + request.offset, request.size, request.type); + + /* Check if this is just another version of a kernel-allocated map, and + * just hand that back if so. + */ + if (request.type == _DRM_REGISTERS || request.type == _DRM_FRAME_BUFFER) + { + DRM_LOCK(); + TAILQ_FOREACH(map, &dev->maplist, link) { + if (map->kernel_owned && map->type == request.type && + map->offset == request.offset) { + /* XXX: this size setting is questionable. */ + map->size = request.size; + DRM_DEBUG("Found kernel map %d\n", request.type); + goto done; + } + } + DRM_UNLOCK(); + } + + /* Allocate a new map structure, fill it in, and do any type-specific + * initialization necessary. + */ + map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT); if ( !map ) return DRM_ERR(ENOMEM); @@ -68,31 +200,10 @@ int drm_addmap(DRM_IOCTL_ARGS) map->size = request.size; map->type = request.type; map->flags = request.flags; - map->mtrr = 0; - map->handle = 0; - - /* Only allow shared memory to be removable since we only keep enough - * book keeping information about shared memory to allow for removal - * when processes fork. - */ - if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) { - free(map, M_DRM); - return DRM_ERR(EINVAL); - } - DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n", - map->offset, map->size, map->type ); - if ( (map->offset & PAGE_MASK) || (map->size & PAGE_MASK) ) { - free(map, M_DRM); - return DRM_ERR(EINVAL); - } - if (map->offset + map->size < map->offset) { - free(map, M_DRM); - return DRM_ERR(EINVAL); - } switch ( map->type ) { case _DRM_REGISTERS: - drm_core_ioremap(map, dev); + drm_ioremap(dev, map); if (!(map->flags & _DRM_WRITE_COMBINING)) break; /* FALLTHROUGH */ @@ -133,29 +244,34 @@ int drm_addmap(DRM_IOCTL_ARGS) } map->offset = map->offset + dev->sg->handle; break; - + case _DRM_CONSISTENT: + map->handle = drm_pci_alloc(dev, map->size, map->size, + 0xfffffffful, &bus_addr); + if (map->handle == NULL) { + free(map, M_DRM); + return ENOMEM; + } + map->offset = (unsigned long)bus_addr; + break; default: free(map, M_DRM); return DRM_ERR(EINVAL); } - list = malloc(sizeof(*list), M_DRM, M_NOWAIT | M_ZERO); - if (list == NULL) { - free(map, M_DRM); - return DRM_ERR(EINVAL); - } - list->map = map; - DRM_LOCK(); - TAILQ_INSERT_TAIL(dev->maplist, list, link); - DRM_UNLOCK(); + TAILQ_INSERT_TAIL(&dev->maplist, map, link); +done: + /* Jumped to, with lock held, when a kernel map is found. */ request.offset = map->offset; request.size = map->size; request.type = map->type; request.flags = map->flags; request.mtrr = map->mtrr; request.handle = map->handle; + DRM_UNLOCK(); + + DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", request.type, request.offset, request.size); if ( request.type != _DRM_SHM ) { request.handle = (void *)request.offset; @@ -166,6 +282,44 @@ int drm_addmap(DRM_IOCTL_ARGS) return 0; } +void drm_remove_map(drm_device_t *dev, drm_local_map_t *map) +{ + DRM_SPINLOCK_ASSERT(&dev->dev_lock); + + TAILQ_REMOVE(&dev->maplist, map, link); + + switch (map->type) { + case _DRM_REGISTERS: + if (map->bsr == NULL) + drm_ioremapfree(map); + /* FALLTHROUGH */ + case _DRM_FRAME_BUFFER: + if (map->mtrr) { + int __unused retcode; + + retcode = drm_mtrr_del(map->offset, map->size, + DRM_MTRR_WC); + DRM_DEBUG("mtrr_del = %d\n", retcode); + } + break; + case _DRM_SHM: + free(map->handle, M_DRM); + break; + case _DRM_AGP: + case _DRM_SCATTER_GATHER: + break; + case _DRM_CONSISTENT: + drm_pci_free(dev, map->size, map->handle, map->offset); + break; + } + + if (map->bsr != NULL) { + bus_release_resource(dev->device, SYS_RES_MEMORY, map->rid, + map->bsr); + } + + free(map, M_DRM); +} /* Remove a map private from list and deallocate resources if the mapping * isn't in use. @@ -174,50 +328,28 @@ int drm_addmap(DRM_IOCTL_ARGS) int drm_rmmap(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_map_list_entry_t *list; drm_local_map_t *map; drm_map_t request; DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) ); DRM_LOCK(); - TAILQ_FOREACH(list, dev->maplist, link) { - map = list->map; + TAILQ_FOREACH(map, &dev->maplist, link) { if (map->handle == request.handle && map->flags & _DRM_REMOVABLE) break; } /* No match found. */ - if (list == NULL) { + if (map == NULL) { DRM_UNLOCK(); return DRM_ERR(EINVAL); } - TAILQ_REMOVE(dev->maplist, list, link); - DRM_UNLOCK(); - free(list, M_DRM); + drm_remove_map(dev, map); + + DRM_UNLOCK(); - switch (map->type) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: - if (map->mtrr) { - int __unused retcode; - - retcode = drm_mtrr_del(map->offset, map->size, - DRM_MTRR_WC); - DRM_DEBUG("mtrr_del = %d\n", retcode); - } - drm_ioremapfree(map); - break; - case _DRM_SHM: - free(map->handle, M_DRM); - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; - } - free(map, M_DRM); return 0; } diff --git a/bsd-core/drm_context.c b/bsd-core/drm_context.c index 714edccc..368bdfb4 100644 --- a/bsd-core/drm_context.c +++ b/bsd-core/drm_context.c @@ -165,14 +165,12 @@ int drm_setsareactx( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_ctx_priv_map_t request; drm_local_map_t *map = NULL; - drm_map_list_entry_t *list; DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); DRM_LOCK(); - TAILQ_FOREACH(list, dev->maplist, link) { - map=list->map; + TAILQ_FOREACH(map, &dev->maplist, link) { if (map->handle == request.handle) { if (dev->max_context < 0) goto bad; diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index fb9313af..102045c7 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -377,8 +377,7 @@ static int drm_setup(drm_device_t *dev) static int drm_takedown(drm_device_t *dev) { drm_magic_entry_t *pt, *next; - drm_local_map_t *map; - drm_map_list_entry_t *list; + drm_local_map_t *map, *mapsave; int i; DRM_SPINLOCK_ASSERT(&dev->dev_lock); @@ -432,38 +431,11 @@ static int drm_takedown(drm_device_t *dev) dev->sg = NULL; } - if (dev->maplist != NULL) { - while ((list=TAILQ_FIRST(dev->maplist))) { - map = list->map; - switch ( map->type ) { - case _DRM_REGISTERS: - drm_ioremapfree(map); - /* FALLTHROUGH */ - case _DRM_FRAME_BUFFER: - if (map->mtrr) { - int __unused retcode; - - retcode = drm_mtrr_del(map->offset, - map->size, DRM_MTRR_WC); - DRM_DEBUG("mtrr_del = %d", retcode); - } - break; - case _DRM_SHM: - free(map->handle, M_DRM); - break; - - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - /* Do nothing here, because this is all - * handled in the AGP/GART/SG functions. - */ - break; - } - TAILQ_REMOVE(dev->maplist, list, link); - free(list, M_DRM); - free(map, M_DRM); - } - } + /* Clean up maps that weren't set up by the driver. */ + TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) { + if (!map->kernel_owned) + drm_remove_map(dev, map); + } drm_dma_takedown(dev); if ( dev->lock.hw_lock ) { @@ -495,9 +467,6 @@ static int drm_init(device_t nbdev) else dev->device = nbdev; - if (dev->preinit != NULL) - dev->preinit(dev, 0); - dev->devnode = make_dev(&drm_cdevsw, unit, DRM_DEV_UID, @@ -510,9 +479,6 @@ static int drm_init(device_t nbdev) #elif defined(__NetBSD__) || defined(__OpenBSD__) dev = nbdev; unit = minor(dev->device.dv_unit); - - if (dev->preinit != NULL) - dev->preinit(dev, 0); #endif dev->irq = pci_get_irq(dev->device); @@ -522,12 +488,7 @@ static int drm_init(device_t nbdev) dev->pci_slot = pci_get_slot(dev->device); dev->pci_func = pci_get_function(dev->device); - dev->maplist = malloc(sizeof(*dev->maplist), M_DRM, M_WAITOK); - if (dev->maplist == NULL) { - retcode = ENOMEM; - goto error; - } - TAILQ_INIT(dev->maplist); + TAILQ_INIT(&dev->maplist); drm_mem_init(); #ifdef __FreeBSD__ @@ -535,10 +496,18 @@ static int drm_init(device_t nbdev) #endif TAILQ_INIT(&dev->files); + if (dev->preinit != NULL) { + retcode = dev->preinit(dev, 0); + if (retcode != 0) + goto error; + } + if (dev->use_agp) { - dev->agp = drm_agp_init(); + if (drm_device_is_agp(dev)) + dev->agp = drm_agp_init(); if (dev->require_agp && dev->agp == NULL) { - DRM_ERROR("Cannot initialize the agpgart module.\n"); + DRM_ERROR("Card isn't AGP, or couldn't initialize " + "AGP.\n"); retcode = DRM_ERR(ENOMEM); goto error; } @@ -581,7 +550,6 @@ error: mtx_destroy(&dev->dev_lock); #endif #endif - free(dev->maplist, M_DRM); return retcode; } @@ -591,6 +559,7 @@ error: */ static void drm_cleanup(drm_device_t *dev) { + drm_local_map_t *map; DRM_DEBUG( "\n" ); @@ -613,6 +582,11 @@ static void drm_cleanup(drm_device_t *dev) drm_takedown(dev); DRM_UNLOCK(); + /* Clean up any maps left over that had been allocated by the driver. */ + while ((map = TAILQ_FIRST(&dev->maplist)) != NULL) { + drm_remove_map(dev, map); + } + if ( dev->agp ) { drm_agp_uninit(); free(dev->agp, M_DRM); @@ -626,7 +600,6 @@ static void drm_cleanup(drm_device_t *dev) #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 mtx_destroy(&dev->dev_lock); #endif - free(dev->maplist, M_DRM); } @@ -778,6 +751,8 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) #endif /* __NetBSD__ || __OpenBSD__ */ if (--priv->refs == 0) { + if (dev->free_filp_priv != NULL) + dev->free_filp_priv(dev, priv); TAILQ_REMOVE(&dev->files, priv, link); free(priv, M_DRM); } diff --git a/bsd-core/drm_fops.c b/bsd-core/drm_fops.c index eeb4847a..44c2b8de 100644 --- a/bsd-core/drm_fops.c +++ b/bsd-core/drm_fops.c @@ -58,6 +58,7 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, { int m = minor(kdev); drm_file_t *priv; + int retcode; if (flags & O_EXCL) return EBUSY; /* No exclusive opens */ @@ -88,8 +89,14 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, priv->ioctl_count = 0; priv->authenticated = !DRM_SUSER(p); - if (dev->open_helper) - dev->open_helper(dev, priv); + if (dev->open_helper) { + retcode = dev->open_helper(dev, priv); + if (retcode != 0) { + free(priv, M_DRM); + DRM_UNLOCK(); + return retcode; + } + } TAILQ_INSERT_TAIL(&dev->files, priv, link); } diff --git a/bsd-core/drm_ioctl.c b/bsd-core/drm_ioctl.c index d40a7c90..62f42210 100644 --- a/bsd-core/drm_ioctl.c +++ b/bsd-core/drm_ioctl.c @@ -147,7 +147,6 @@ int drm_getmap(DRM_IOCTL_ARGS) DRM_DEVICE; drm_map_t map; drm_local_map_t *mapinlist; - drm_map_list_entry_t *list; int idx; int i = 0; @@ -161,8 +160,7 @@ int drm_getmap(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } - TAILQ_FOREACH(list, dev->maplist, link) { - mapinlist = list->map; + TAILQ_FOREACH(mapinlist, &dev->maplist, link) { if (i==idx) { map.offset = mapinlist->offset; map.size = mapinlist->size; @@ -177,7 +175,7 @@ int drm_getmap(DRM_IOCTL_ARGS) DRM_UNLOCK(); - if (!list) + if (mapinlist == NULL) return EINVAL; DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, map, sizeof(map) ); diff --git a/bsd-core/drm_memory.c b/bsd-core/drm_memory.c index 8a49d40e..497cd83f 100644 --- a/bsd-core/drm_memory.c +++ b/bsd-core/drm_memory.c @@ -79,11 +79,11 @@ void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map) #ifdef __FreeBSD__ return pmap_mapdev(map->offset, map->size); #elif defined(__NetBSD__) || defined(__OpenBSD__) - map->iot = dev->pa.pa_memt; - if (bus_space_map(map->iot, map->offset, map->size, - BUS_SPACE_MAP_LINEAR, &map->ioh)) + map->bst = dev->pa.pa_memt; + if (bus_space_map(map->bst, map->offset, map->size, + BUS_SPACE_MAP_LINEAR, &map->bsh)) return NULL; - return bus_space_vaddr(map->iot, map->ioh); + return bus_space_vaddr(map->bst, map->bsh); #endif } @@ -92,7 +92,7 @@ void drm_ioremapfree(drm_local_map_t *map) #ifdef __FreeBSD__ pmap_unmapdev((vm_offset_t) map->handle, map->size); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_unmap(map->iot, map->ioh, map->size); + bus_space_unmap(map->bst, map->bsh, map->size); #endif } diff --git a/bsd-core/drm_sysctl.c b/bsd-core/drm_sysctl.c index 220559d9..e4e336b4 100644 --- a/bsd-core/drm_sysctl.c +++ b/bsd-core/drm_sysctl.c @@ -150,7 +150,6 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; drm_local_map_t *map, *tempmaps; - drm_map_list_entry_t *listentry; const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" }; const char *type, *yesno; int i, mapcount; @@ -163,7 +162,7 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS DRM_LOCK(); mapcount = 0; - TAILQ_FOREACH(listentry, dev->maplist, link) + TAILQ_FOREACH(map, &dev->maplist, link) mapcount++; tempmaps = malloc(sizeof(drm_local_map_t) * mapcount, M_DRM, M_NOWAIT); @@ -173,8 +172,8 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS } i = 0; - TAILQ_FOREACH(listentry, dev->maplist, link) - tempmaps[i++] = *listentry->map; + TAILQ_FOREACH(map, &dev->maplist, link) + tempmaps[i++] = *map; DRM_UNLOCK(); diff --git a/bsd-core/drm_vm.c b/bsd-core/drm_vm.c index 1b5d4d3f..2b5f0ef4 100644 --- a/bsd-core/drm_vm.c +++ b/bsd-core/drm_vm.c @@ -35,8 +35,7 @@ paddr_t drm_mmap(dev_t kdev, off_t offset, int prot) #endif { DRM_DEVICE; - drm_local_map_t *map = NULL; - drm_map_list_entry_t *listentry = NULL; + drm_local_map_t *map; drm_file_t *priv; drm_map_type_t type; @@ -81,13 +80,12 @@ paddr_t drm_mmap(dev_t kdev, off_t offset, int prot) for performance, even if the list was a bit longer. */ DRM_LOCK(); - TAILQ_FOREACH(listentry, dev->maplist, link) { - map = listentry->map; + TAILQ_FOREACH(map, &dev->maplist, link) { if (offset >= map->offset && offset < map->offset + map->size) break; } - if (!listentry) { + if (map == NULL) { DRM_UNLOCK(); DRM_DEBUG("can't find map\n"); return -1; diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c index 57ab3b9d..bac6205d 100644 --- a/bsd-core/radeon_drv.c +++ b/bsd-core/radeon_drv.c @@ -45,8 +45,12 @@ extern int radeon_max_ioctl; static void radeon_configure(drm_device_t *dev) { dev->dev_priv_size = sizeof(drm_radeon_buf_priv_t); + dev->preinit = radeon_preinit; + dev->postcleanup = radeon_postcleanup; dev->prerelease = radeon_driver_prerelease; dev->pretakedown = radeon_driver_pretakedown; + dev->open_helper = radeon_driver_open_helper; + dev->free_filp_priv = radeon_driver_free_filp_priv; dev->vblank_wait = radeon_driver_vblank_wait; dev->irq_preinstall = radeon_driver_irq_preinstall; dev->irq_postinstall = radeon_driver_irq_postinstall; diff --git a/linux-core/drmP.h b/linux-core/drmP.h index bbc7a237..e5789c65 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -851,7 +851,8 @@ extern int drm_addmap(struct inode *inode, struct file *filp, extern int drm_rmmap(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, int type, int flags); + 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, @@ -863,6 +864,10 @@ extern int drm_freebufs(struct inode *inode, struct file *filp, extern int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_order(unsigned long size); +extern unsigned long drm_get_resource_start(drm_device_t *dev, + unsigned int resource); +extern unsigned long drm_get_resource_len(drm_device_t *dev, + unsigned int resource); /* DMA support (drm_dma.h) */ extern int drm_dma_setup(drm_device_t * dev); diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 97574a37..6339ac21 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -36,13 +36,25 @@ #include #include "drmP.h" +unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +{ + return pci_resource_start(dev->pdev, resource); +} +EXPORT_SYMBOL(drm_get_resource_start); + +unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) +{ + return pci_resource_len(dev->pdev, 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, - int type, int flags) + unsigned int resource, int type, int flags) { drm_map_t *map; drm_map_list_t *list; diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9eaa2d76..4606a332 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2006,7 +2006,9 @@ int radeon_cp_buffers(DRM_IOCTL_ARGS) /* Always create a map record for MMIO and FB memory, done from DRIVER_POSTINIT */ int radeon_preinit(struct drm_device *dev, unsigned long flags) { +#if defined(__linux__) u32 save, temp; +#endif drm_radeon_private_t *dev_priv; int ret = 0; @@ -2030,19 +2032,18 @@ int radeon_preinit(struct drm_device *dev, unsigned long flags) break; } -#ifdef __linux__ - /* registers */ - if ((ret = drm_initmap(dev, pci_resource_start(dev->pdev, 2), - pci_resource_len(dev->pdev, 2), _DRM_REGISTERS, - 0))) + ret = drm_initmap(dev, drm_get_resource_start(dev, 2), + drm_get_resource_len(dev, 2), 2, _DRM_REGISTERS, 0); + if (ret != 0) return ret; - /* framebuffer */ - if ((ret = drm_initmap(dev, pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0), - _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING))) + 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; +#if defined(__linux__) /* There are signatures in BIOS and PCI-SSID for a PCI card, but they are not very reliable. Following detection method works for all cards tested so far. Note, checking AGP_ENABLE bit after drmAgpEnable call can also give the correct result. @@ -2057,9 +2058,14 @@ int radeon_preinit(struct drm_device *dev, unsigned long flags) if (temp & RADEON_AGP_ENABLE) dev_priv->flags |= CHIP_IS_AGP; #else + /* The above 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; + dev_priv->flags |= CHIP_IS_AGP; #endif + DRM_DEBUG("%s card detected\n", ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); diff --git a/shared-core/savage_bci.c b/shared-core/savage_bci.c index 4656a902..36fb8737 100644 --- a/shared-core/savage_bci.c +++ b/shared-core/savage_bci.c @@ -296,6 +296,7 @@ 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; + unsigned int fb_rsrc, aper_rsrc; int ret = 0; dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); @@ -310,12 +311,14 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset) dev_priv->mtrr[1].handle = -1; dev_priv->mtrr[2].handle = -1; if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - fb_base = pci_resource_start(dev->pdev, 0); + fb_rsrc = 0; + fb_base = drm_get_resource_start(dev, 0); fb_size = SAVAGE_FB_SIZE_S3; mmio_base = fb_base + SAVAGE_FB_SIZE_S3; + aper_rsrc = 0; aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; /* this should always be true */ - if (pci_resource_len(dev->pdev, 0) == 0x08000000) { + if (drm_get_resource_len(dev, 0) == 0x08000000) { /* Don't make MMIO write-cobining! We need 3 * MTRRs. */ dev_priv->mtrr[0].base = fb_base; @@ -335,15 +338,17 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset) MTRR_TYPE_WRCOMB, 1); } else { DRM_ERROR("strange pci_resource_len %08lx\n", - pci_resource_len(dev->pdev, 0)); + drm_get_resource_len(dev, 0)); } } else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) { - mmio_base = pci_resource_start(dev->pdev, 0); - fb_base = pci_resource_start(dev->pdev, 1); + mmio_base = drm_get_resource_start(dev, 0); + fb_rsrc = 1; + fb_base = drm_get_resource_start(dev, 1); fb_size = SAVAGE_FB_SIZE_S4; + aper_rsrc = 1; aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; /* this should always be true */ - if (pci_resource_len(dev->pdev, 1) == 0x08000000) { + if (drm_get_resource_len(dev, 1) == 0x08000000) { /* Can use one MTRR to cover both fb and * aperture. */ dev_priv->mtrr[0].base = fb_base; @@ -353,29 +358,32 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset) MTRR_TYPE_WRCOMB, 1); } else { DRM_ERROR("strange pci_resource_len %08lx\n", - pci_resource_len(dev->pdev, 1)); + drm_get_resource_len(dev, 1)); } } else { - mmio_base = pci_resource_start(dev->pdev, 0); - fb_base = pci_resource_start(dev->pdev, 1); - fb_size = pci_resource_len(dev->pdev, 1); - aperture_base = pci_resource_start(dev->pdev, 2); + mmio_base = drm_get_resource_start(dev, 0); + fb_rsrc = 1; + fb_base = drm_get_resource_start(dev, 1); + fb_size = drm_get_resource_len(dev, 1); + aper_rsrc = 2; + aperture_base = drm_get_resource_start(dev, 2); /* Automatic MTRR setup will do the right thing. */ } - if ((ret = drm_initmap(dev, mmio_base, SAVAGE_MMIO_SIZE, + if ((ret = drm_initmap(dev, mmio_base, SAVAGE_MMIO_SIZE, 0, _DRM_REGISTERS, 0))) 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, + if ((ret = drm_initmap(dev, fb_base, fb_size, fb_rsrc, _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING))) 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))) return ret; if (!(dev_priv->aperture = drm_core_findmap (dev, aperture_base))) -- cgit v1.2.3