- 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.
This commit is contained in:
Eric Anholt 2005-02-05 08:00:14 +00:00
parent 270ca5f3ce
commit 080a547d4d
14 changed files with 335 additions and 187 deletions

View file

@ -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;
}

View file

@ -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,40 +282,17 @@ int drm_addmap(DRM_IOCTL_ARGS)
return 0;
}
/* Remove a map private from list and deallocate resources if the mapping
* isn't in use.
*/
int drm_rmmap(DRM_IOCTL_ARGS)
void drm_remove_map(drm_device_t *dev, drm_local_map_t *map)
{
DRM_DEVICE;
drm_map_list_entry_t *list;
drm_local_map_t *map;
drm_map_t request;
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) );
DRM_LOCK();
TAILQ_FOREACH(list, dev->maplist, link) {
map = list->map;
if (map->handle == request.handle &&
map->flags & _DRM_REMOVABLE)
break;
}
/* No match found. */
if (list == NULL) {
DRM_UNLOCK();
return DRM_ERR(EINVAL);
}
TAILQ_REMOVE(dev->maplist, list, link);
DRM_UNLOCK();
free(list, M_DRM);
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;
@ -208,7 +301,6 @@ int drm_rmmap(DRM_IOCTL_ARGS)
DRM_MTRR_WC);
DRM_DEBUG("mtrr_del = %d\n", retcode);
}
drm_ioremapfree(map);
break;
case _DRM_SHM:
free(map->handle, M_DRM);
@ -216,8 +308,48 @@ int drm_rmmap(DRM_IOCTL_ARGS)
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.
*/
int drm_rmmap(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
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(map, &dev->maplist, link) {
if (map->handle == request.handle &&
map->flags & _DRM_REMOVABLE)
break;
}
/* No match found. */
if (map == NULL) {
DRM_UNLOCK();
return DRM_ERR(EINVAL);
}
drm_remove_map(dev, map);
DRM_UNLOCK();
return 0;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) );

View file

@ -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
}

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -36,13 +36,25 @@
#include <linux/vmalloc.h>
#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;

View file

@ -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"));

View file

@ -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)))