diff options
author | anholt <anholt@FreeBSD.org> | 2003-10-24 01:48:17 +0000 |
---|---|---|
committer | anholt <anholt@FreeBSD.org> | 2003-10-24 01:48:17 +0000 |
commit | fffd429f130bdf80ca2848cffd6181a42663611c (patch) | |
tree | 0b507800113111f07b903adcbb43253df735be46 /sys/dev | |
parent | 841ffbf14af9b09c4c8844dc47d53fd486d236f9 (diff) | |
download | FreeBSD-src-fffd429f130bdf80ca2848cffd6181a42663611c.zip FreeBSD-src-fffd429f130bdf80ca2848cffd6181a42663611c.tar.gz |
Update to latest from DRI CVS. Primary new feature is mostly-complete smpng
locking, and the apparently unnecessary locking for -stable has been removed.
This may fix issues with missed interrupts since April, which manifested
themselves as slowdowns or hangs in radeon, in particular. Many cleanups also
took place. In the shared code, there are improvements to r128 driver
stability.
Diffstat (limited to 'sys/dev')
36 files changed, 1320 insertions, 1217 deletions
diff --git a/sys/dev/drm/ati_pcigart.h b/sys/dev/drm/ati_pcigart.h index c37c95f..dd1141f 100644 --- a/sys/dev/drm/ati_pcigart.h +++ b/sys/dev/drm/ati_pcigart.h @@ -60,7 +60,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, } address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, - DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0); + DRM(M_DRM), M_NOWAIT, 0ul, 0xfffffffful, PAGE_SIZE, 0); if ( !address ) { DRM_ERROR( "cannot allocate PCI GART page!\n" ); goto done; diff --git a/sys/dev/drm/drm.h b/sys/dev/drm/drm.h index 8430e1d..6026580 100644 --- a/sys/dev/drm/drm.h +++ b/sys/dev/drm/drm.h @@ -46,7 +46,7 @@ #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#if defined(__FreeBSD__) && defined(XFree86Server) +#if defined(__FreeBSD__) && defined(IN_MODULE) /* Prevent name collision when including sys/ioccom.h */ #undef ioctl #include <sys/ioccom.h> @@ -79,10 +79,6 @@ #define DRM_DEV_GID 0 #endif -#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0) -#define DRM_MAJOR 226 -#define DRM_MAX_MINOR 15 -#endif #define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */ #define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */ @@ -409,6 +405,13 @@ typedef struct drm_scatter_gather { unsigned long handle; /* Used for mapping / unmapping */ } drm_scatter_gather_t; +typedef struct drm_set_version { + int drm_di_major; + int drm_di_minor; + int drm_dd_major; + int drm_dd_minor; +} drm_set_version_t; + #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) @@ -422,6 +425,7 @@ typedef struct drm_scatter_gather { #define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t) #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t) #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t) +#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, drm_set_version_t) #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h index 8ecb2c4..adf9953 100644 --- a/sys/dev/drm/drmP.h +++ b/sys/dev/drm/drmP.h @@ -50,8 +50,8 @@ #ifndef __HAVE_DMA #define __HAVE_DMA 0 #endif -#ifndef __HAVE_DMA_IRQ -#define __HAVE_DMA_IRQ 0 +#ifndef __HAVE_IRQ +#define __HAVE_IRQ 0 #endif #define DRM_DEBUG_CODE 0 /* Include debugging code (if > 1, then @@ -119,15 +119,19 @@ typedef struct drm_file drm_file_t; #define DRM_MIN(a,b) ((a)<(b)?(a):(b)) #define DRM_MAX(a,b) ((a)>(b)?(a):(b)) -#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) -#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) -#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist) - #define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \ (_map) = (_dev)->context_sareas[_ctx]; \ } while(0) +typedef struct drm_pci_id_list +{ + int vendor; + int device; + long driver_private; + char *name; +} drm_pci_id_list_t; + typedef struct drm_ioctl_desc { int (*func)(DRM_IOCTL_ARGS); int auth_needed; @@ -170,17 +174,6 @@ typedef struct drm_buf { void *dev_private; /* Per-buffer private storage */ } drm_buf_t; - /* bufs is one longer than it has to be */ -typedef struct drm_waitlist { - int count; /* Number of possible buffers */ - drm_buf_t **bufs; /* List of pointers to buffers */ - drm_buf_t **rp; /* Read pointer */ - drm_buf_t **wp; /* Write pointer */ - drm_buf_t **end; /* End pointer */ - DRM_SPINTYPE read_lock; - DRM_SPINTYPE write_lock; -} drm_waitlist_t; - typedef struct drm_freelist { int initialized; /* Freelist in use */ atomic_t count; /* Number of free buffers */ @@ -188,7 +181,6 @@ typedef struct drm_freelist { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ - DRM_SPINTYPE lock; } drm_freelist_t; typedef struct drm_buf_entry { @@ -224,10 +216,17 @@ struct drm_file { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ - wait_queue_head_t lock_queue; /* Queue of blocked processes */ + int lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; +/* This structure, in the drm_device_t, is always initialized while the device + * is open. dev->dma_lock protects the incrementing of dev->buf_use, which + * when set marks that no further bufs may be allocated until device teardown + * occurs (when the last open of the device has closed). The high/low + * watermarks of bufs are only touched by the X Server, and thus not + * concurrently accessed, so no locking is needed. + */ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; @@ -319,8 +318,15 @@ struct drm_device { int flags; /* Flags to open(2) */ /* Locks */ - DRM_SPINTYPE count_lock; /* For open_count, buf_use, buf_alloc */ - struct lock dev_lock; /* For others */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#if __HAVE_DMA + struct mtx dma_lock; /* protects dev->dma */ +#endif +#if __HAVE_IRQ + struct mtx irq_lock; /* protects irq condition checks */ +#endif + struct mtx dev_lock; /* protects everything else */ +#endif /* Usage Counters */ int open_count; /* Outstanding files open */ int buf_use; /* Buffers in use -- cannot alloc */ @@ -335,8 +341,8 @@ struct drm_device { drm_file_list_t files; drm_magic_head_t magiclist[DRM_HASH_SIZE]; - /* Memory management */ - drm_map_list_t *maplist; /* Linked list of regions */ + /* Linked list of mappable regions. Protected by dev_lock */ + drm_map_list_t *maplist; drm_local_map_t **context_sareas; int max_context; @@ -357,18 +363,13 @@ struct drm_device { #endif void *irqh; /* Handle from bus_setup_intr */ atomic_t context_flag; /* Context swapping flag */ - struct callout timer; /* Timer for delaying ctx switch */ int last_context; /* Last current context */ #if __FreeBSD_version >= 400005 struct task task; #endif #if __HAVE_VBL_IRQ - wait_queue_head_t vbl_queue; /* vbl wait channel */ + int vbl_queue; /* vbl wait channel */ atomic_t vbl_received; -#if 0 /* vbl signals are untested */ - struct drm_vbl_sig_list vbl_sig_list; - DRM_SPINTYPE vbl_lock; -#endif #endif #ifdef __FreeBSD__ @@ -390,14 +391,6 @@ struct drm_device { extern int DRM(flags); - /* Authentication (drm_auth.h) */ -extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, - drm_magic_t magic); -extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); - - /* Driver support (drm_drv.h) */ -extern int DRM(version)( DRM_IOCTL_ARGS ); - /* Memory management support (drm_memory.h) */ extern void DRM(mem_init)(void); extern void DRM(mem_uninit)(void); @@ -408,6 +401,8 @@ extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, extern void DRM(free)(void *pt, size_t size, int area); extern void *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map); extern void DRM(ioremapfree)(drm_local_map_t *map); +extern int DRM(mtrr_add)(unsigned long offset, size_t size, int flags); +extern int DRM(mtrr_del)(unsigned long offset, size_t size, int flags); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); @@ -445,26 +440,21 @@ extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp); -#if __HAVE_DMA_IRQ +#endif + +#if __HAVE_IRQ + /* IRQ support (drm_irq.h) */ extern int DRM(irq_install)( drm_device_t *dev, int irq ); extern int DRM(irq_uninstall)( drm_device_t *dev ); -extern irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ); +extern irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ); extern void DRM(driver_irq_preinstall)( drm_device_t *dev ); extern void DRM(driver_irq_postinstall)( drm_device_t *dev ); extern void DRM(driver_irq_uninstall)( drm_device_t *dev ); -#if __HAVE_DMA_IRQ_BH -extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS ); +#if __HAVE_IRQ_BH +extern void DRM(irq_immediate_bh)( DRM_TASKQUEUE_ARGS ); #endif #endif - /* Buffer list support (drm_lists.h) */ -#if __HAVE_DMA_WAITLIST -extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count); -extern int DRM(waitlist_destroy)(drm_waitlist_t *bl); -extern int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf); -extern drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl); -#endif -#endif /* __HAVE_DMA */ #if __HAVE_VBL_IRQ extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); extern void DRM(vbl_send_signals)( drm_device_t *dev ); @@ -499,6 +489,8 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, /* Locking IOCTL support (drm_drv.h) */ extern int DRM(lock)(DRM_IOCTL_ARGS); extern int DRM(unlock)(DRM_IOCTL_ARGS); +extern int DRM(version)( DRM_IOCTL_ARGS ); +extern int DRM(setversion)( DRM_IOCTL_ARGS ); /* Misc. IOCTL support (drm_ioctl.h) */ extern int DRM(irq_busid)(DRM_IOCTL_ARGS); @@ -539,8 +531,8 @@ extern int DRM(freebufs)(DRM_IOCTL_ARGS); extern int DRM(mapbufs)(DRM_IOCTL_ARGS); #endif -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA +/* IRQ support (drm_irq.h) */ +#if __HAVE_IRQ || __HAVE_DMA extern int DRM(control)(DRM_IOCTL_ARGS); #endif #if __HAVE_VBL_IRQ diff --git a/sys/dev/drm/drm_auth.h b/sys/dev/drm/drm_auth.h index 03986c5..9141d57 100644 --- a/sys/dev/drm/drm_auth.h +++ b/sys/dev/drm/drm_auth.h @@ -44,18 +44,18 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) drm_magic_entry_t *pt; int hash = DRM(hash_magic)(magic); - DRM_LOCK; + DRM_LOCK(); for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { if (pt->magic == magic) { retval = pt->priv; break; } } - DRM_UNLOCK; + DRM_UNLOCK(); return retval; } -int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) +static int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) { int hash; drm_magic_entry_t *entry; @@ -70,7 +70,7 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) entry->priv = priv; entry->next = NULL; - DRM_LOCK; + DRM_LOCK(); if (dev->magiclist[hash].tail) { dev->magiclist[hash].tail->next = entry; dev->magiclist[hash].tail = entry; @@ -78,12 +78,12 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) dev->magiclist[hash].head = entry; dev->magiclist[hash].tail = entry; } - DRM_UNLOCK; + DRM_UNLOCK(); return 0; } -int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) +static int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) { drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; @@ -92,7 +92,7 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) DRM_DEBUG("%d\n", magic); hash = DRM(hash_magic)(magic); - DRM_LOCK; + DRM_LOCK(); for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { if (pt->magic == magic) { if (dev->magiclist[hash].head == pt) { @@ -104,11 +104,11 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) if (prev) { prev->next = pt->next; } - DRM_UNLOCK; + DRM_UNLOCK(); return 0; } } - DRM_UNLOCK; + DRM_UNLOCK(); DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC); return DRM_ERR(EINVAL); @@ -117,9 +117,11 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; - drm_auth_t auth; + drm_auth_t auth; + drm_file_t *priv; DRM_DEVICE; - DRM_PRIV; + + DRM_GET_PRIV_WITH_RETURN(priv, filp); /* Find unique magic */ if (priv->magic) { @@ -153,6 +155,7 @@ int DRM(authmagic)(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth)); DRM_DEBUG("%u\n", auth.magic); + if ((file = DRM(find_file)(dev, auth.magic))) { file->authenticated = 1; DRM(remove_magic)(dev, auth.magic); diff --git a/sys/dev/drm/drm_bufs.h b/sys/dev/drm/drm_bufs.h index e77b3bf..efb8ce7 100644 --- a/sys/dev/drm/drm_bufs.h +++ b/sys/dev/drm/drm_bufs.h @@ -116,25 +116,12 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) #if __REALLY_HAVE_MTRR if ( map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING) ) { -#ifdef __FreeBSD__ - int retcode = 0, act; - struct mem_range_desc mrdesc; - mrdesc.mr_base = map->offset; - mrdesc.mr_len = map->size; - mrdesc.mr_flags = MDF_WRITECOMBINE; - act = MEMRANGE_SET_UPDATE; - bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); - retcode = mem_range_attr_set(&mrdesc, &act); - map->mtrr=1; -#elif defined __NetBSD__ - struct mtrr mtrrmap; - int one = 1; - mtrrmap.base = map->offset; - mtrrmap.len = map->size; - mtrrmap.type = MTRR_TYPE_WC; - mtrrmap.flags = MTRR_VALID; - map->mtrr = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL ); -#endif + int mtrr; + + mtrr = DRM(mtrr_add)(map->offset, map->size, + DRM_MTRR_WC); + if (mtrr == 0) + map->mtrr = 1; } #endif /* __REALLY_HAVE_MTRR */ DRM_IOREMAP(map, dev); @@ -172,17 +159,16 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } - list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS); - if(!list) { + list = DRM(calloc)(1, sizeof(*list), DRM_MEM_MAPS); + if (list == NULL) { DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); return DRM_ERR(EINVAL); } - memset(list, 0, sizeof(*list)); list->map = map; - DRM_LOCK; + DRM_LOCK(); TAILQ_INSERT_TAIL(dev->maplist, list, link); - DRM_UNLOCK; + DRM_UNLOCK(); request.offset = map->offset; request.size = map->size; @@ -211,69 +197,49 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) drm_map_list_entry_t *list; drm_local_map_t *map; drm_map_t request; - int found_maps = 0; DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) ); - DRM_LOCK; + DRM_LOCK(); TAILQ_FOREACH(list, dev->maplist, link) { map = list->map; - if(map->handle == request.handle && - map->flags & _DRM_REMOVABLE) break; + if (map->handle == request.handle && + map->flags & _DRM_REMOVABLE) + break; } - /* List has wrapped around to the head pointer, or its empty we didn't - * find anything. - */ - if(list == NULL) { - DRM_UNLOCK; + /* No match found. */ + if (list == NULL) { + DRM_UNLOCK(); return DRM_ERR(EINVAL); } TAILQ_REMOVE(dev->maplist, list, link); - DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); + DRM_UNLOCK(); + DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); - if(!found_maps) { - switch (map->type) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: + switch (map->type) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: #if __REALLY_HAVE_MTRR - if (map->mtrr >= 0) { - int retcode; -#ifdef __FreeBSD__ - int act; - struct mem_range_desc mrdesc; - mrdesc.mr_base = map->offset; - mrdesc.mr_len = map->size; - mrdesc.mr_flags = MDF_WRITECOMBINE; - act = MEMRANGE_SET_REMOVE; - bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); - retcode = mem_range_attr_set(&mrdesc, &act); -#elif defined __NetBSD__ - struct mtrr mtrrmap; - int one = 1; - mtrrmap.base = map->offset; - mtrrmap.len = map->size; - mtrrmap.type = 0; - mtrrmap.flags = 0; - mtrrmap.owner = p->p_pid; - retcode = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL); - DRM_DEBUG("mtrr_del = %d\n", retcode); -#endif - } -#endif - DRM(ioremapfree)( map ); - break; - case _DRM_SHM: - DRM(free)( map->handle, map->size, DRM_MEM_SAREA ); - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; + if (map->mtrr >= 0) { + int __unused mtrr; + + mtrr = DRM(mtrr_del)(map->offset, map->size, + DRM_MTRR_WC); + DRM_DEBUG("mtrr_del = %d\n", mtrr); } - DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); +#endif + DRM(ioremapfree)(map); + break; + case _DRM_SHM: + DRM(free)(map->handle, map->size, DRM_MEM_SAREA); + break; + case _DRM_AGP: + case _DRM_SCATTER_GATHER: + break; } - DRM_UNLOCK; + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); return 0; } @@ -355,20 +321,11 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - - DRM_LOCK; entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK; - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_UNLOCK; return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -393,16 +350,14 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); - buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), - DRM_MEM_BUFS ); - if(!buf->dev_private) { + buf->dev_private = DRM(calloc)(1, buf->dev_priv_size, + DRM_MEM_BUFS); + if (buf->dev_private == NULL) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } - memset( buf->dev_private, 0, buf->dev_priv_size ); offset += alignment; entry->buf_count++; @@ -416,10 +371,9 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), DRM_MEM_BUFS ); - if(!temp_buflist) { + if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -434,8 +388,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); - DRM_UNLOCK; - request->count = entry->buf_count; request->size = size; @@ -473,20 +425,12 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "count=%d, size=%d (%d), order=%d\n", request->count, request->size, size, order ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - alignment = (request->flags & _DRM_PAGE_ALIGN) ? round_page(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; - DRM_LOCK; entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK; - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } entry->buflist = DRM(alloc)(count * sizeof(*entry->buflist), DRM_MEM_BUFS); @@ -509,7 +453,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM_MEM_SEGS); DRM(free)(entry->seglist_bus, count * sizeof(*entry->seglist_bus), DRM_MEM_SEGS); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } @@ -538,7 +481,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } @@ -577,7 +519,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES ); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } bzero(buf->dev_private, buf->dev_priv_size); @@ -599,7 +540,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -620,8 +560,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) dma->page_count += entry->seg_count << page_order; dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - DRM_UNLOCK; - request->count = entry->buf_count; request->size = size; @@ -668,23 +606,12 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - - DRM_LOCK; entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK; - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } - entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - if ( !entry->buflist ) { - DRM_UNLOCK; + entry->buflist = DRM(calloc)(1, count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (entry->buflist == NULL) return DRM_ERR(ENOMEM); - } - memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); entry->buf_size = size; entry->page_order = page_order; @@ -706,18 +633,15 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); - buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), - DRM_MEM_BUFS ); - if(!buf->dev_private) { + buf->dev_private = DRM(calloc)(1, buf->dev_priv_size, + DRM_MEM_BUFS); + if (buf->dev_private == NULL) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } - memset( buf->dev_private, 0, buf->dev_priv_size ); - DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); @@ -733,10 +657,9 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), DRM_MEM_BUFS ); - if(!temp_buflist) { + if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK; return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -751,8 +674,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); - DRM_UNLOCK; - request->count = entry->buf_count; request->size = size; @@ -767,25 +688,28 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_buf_desc_t request; int err; + int order; DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); - if (dev->dma == NULL) + if (request.count < 0 || request.count > 4096) return DRM_ERR(EINVAL); - if (request.count < 0 || request.count > 4096) + order = DRM(order)(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return DRM_ERR(EINVAL); - DRM_SPINLOCK(&dev->count_lock); - if (dev->buf_use) { - DRM_SPINUNLOCK(&dev->count_lock); + DRM_SPINLOCK(&dev->dma_lock); + /* No more allocations after first buffer-using ioctl. */ + if (dev->buf_use != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); return DRM_ERR(EBUSY); } - /* dev->buf_alloc acts as a lock to prevent infobufs/mapbufs from - * trying to read from the dma->bufs while buffers are being allocated */ - dev->buf_alloc++; - DRM_SPINUNLOCK(&dev->count_lock); - + /* No more than one allocation per order */ + if (dev->dma->bufs[order].buf_count != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(ENOMEM); + } #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) @@ -802,13 +726,10 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #else err = DRM_ERR(EINVAL); #endif + DRM_SPINUNLOCK(&dev->dma_lock); DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request, sizeof(request)); - DRM_SPINLOCK(&dev->count_lock); - dev->buf_alloc--; - DRM_SPINUNLOCK(&dev->count_lock); - return err; } @@ -819,18 +740,13 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) drm_buf_info_t request; int i; int count; + int retcode = 0; - if ( !dma ) return DRM_ERR(EINVAL); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); - DRM_SPINLOCK( &dev->count_lock ); - if (dev->buf_alloc != 0) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM_ERR(EBUSY); - } + DRM_SPINLOCK(&dev->dma_lock); ++dev->buf_use; /* Can't allocate more after this call */ - DRM_SPINUNLOCK( &dev->count_lock ); - - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); + DRM_SPINUNLOCK(&dev->dma_lock); for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { if ( dma->bufs[i].buf_count ) ++count; @@ -849,8 +765,10 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) from.high_mark = dma->bufs[i].freelist.high_mark; if (DRM_COPY_TO_USER(&request.list[count], &from, - sizeof(drm_buf_desc_t)) != 0) - return DRM_ERR(EFAULT); + sizeof(drm_buf_desc_t)) != 0) { + retcode = DRM_ERR(EFAULT); + break; + } DRM_DEBUG( "%d %d %d %d %d\n", i, @@ -866,7 +784,7 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) ); - return 0; + return retcode; } int DRM(markbufs)( DRM_IOCTL_ARGS ) @@ -875,26 +793,28 @@ int DRM(markbufs)( DRM_IOCTL_ARGS ) drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int order; - drm_buf_entry_t *entry; - - if ( !dma ) return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); DRM_DEBUG( "%d, %d, %d\n", request.size, request.low_mark, request.high_mark ); - order = DRM(order)( request.size ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - entry = &dma->bufs[order]; + - if ( request.low_mark < 0 || request.low_mark > entry->buf_count ) + order = DRM(order)(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER || + request.low_mark < 0 || request.high_mark < 0) { return DRM_ERR(EINVAL); - if ( request.high_mark < 0 || request.high_mark > entry->buf_count ) + } + + DRM_SPINLOCK(&dev->dma_lock); + if (request.low_mark > dma->bufs[order].buf_count || + request.high_mark > dma->bufs[order].buf_count) { return DRM_ERR(EINVAL); + } - entry->freelist.low_mark = request.low_mark; - entry->freelist.high_mark = request.high_mark; + dma->bufs[order].freelist.low_mark = request.low_mark; + dma->bufs[order].freelist.high_mark = request.high_mark; + DRM_SPINUNLOCK(&dev->dma_lock); return 0; } @@ -907,32 +827,36 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) int i; int idx; drm_buf_t *buf; - - if ( !dma ) return DRM_ERR(EINVAL); + int retcode = 0; DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) ); DRM_DEBUG( "%d\n", request.count ); + + DRM_SPINLOCK(&dev->dma_lock); for ( i = 0 ; i < request.count ; i++ ) { - if ( DRM_COPY_FROM_USER( &idx, - &request.list[i], - sizeof(idx) ) ) - return DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(&idx, &request.list[i], sizeof(idx))) { + retcode = DRM_ERR(EFAULT); + break; + } if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "Index %d (of %d max)\n", idx, dma->buf_count - 1 ); - return DRM_ERR(EINVAL); + retcode = DRM_ERR(EINVAL); + break; } buf = dma->buflist[idx]; if ( buf->filp != filp ) { DRM_ERROR("Process %d freeing buffer not owned\n", DRM_CURRENTPID); - return DRM_ERR(EINVAL); + retcode = DRM_ERR(EINVAL); + break; } DRM(free_buffer)( dev, buf ); } + DRM_SPINUNLOCK(&dev->dma_lock); - return 0; + return retcode; } int DRM(mapbufs)( DRM_IOCTL_ARGS ) @@ -941,130 +865,104 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) drm_device_dma_t *dma = dev->dma; int retcode = 0; const int zero = 0; - vm_offset_t virtual, address; + vm_offset_t address; + struct vmspace *vms; #ifdef __FreeBSD__ -#if __FreeBSD_version >= 500000 - struct vmspace *vms = p->td_proc->p_vmspace; -#else - struct vmspace *vms = p->p_vmspace; -#endif + vm_ooffset_t foff; + vm_size_t size; + vm_offset_t vaddr; #endif /* __FreeBSD__ */ #ifdef __NetBSD__ struct vnode *vn; - struct vmspace *vms = p->p_vmspace; + vm_size_t size; + vaddr_t vaddr; #endif /* __NetBSD__ */ drm_buf_map_t request; int i; - if ( !dma ) return DRM_ERR(EINVAL); - - DRM_SPINLOCK( &dev->count_lock ); - if (dev->buf_alloc != 0) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM_ERR(EBUSY); - } - dev->buf_use++; /* Can't allocate more after this call */ - DRM_SPINUNLOCK( &dev->count_lock ); - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) ); #ifdef __NetBSD__ - if(!vfinddev(kdev, VCHR, &vn)) + if (!vfinddev(kdev, VCHR, &vn)) return 0; /* FIXME: Shouldn't this be EINVAL or something? */ #endif /* __NetBSD__ */ - if ( request.count >= dma->buf_count ) { - if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) || - (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) { - drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev ); +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 + vms = p->td_proc->p_vmspace; +#else + vms = p->p_vmspace; +#endif - if ( !map ) { - retcode = EINVAL; - goto done; - } + DRM_SPINLOCK(&dev->dma_lock); + dev->buf_use++; /* Can't allocate more after this call */ + DRM_SPINUNLOCK(&dev->dma_lock); + + if (request.count < dma->buf_count) + goto done; + + if ((__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) || + (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG))) { + drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP(dev); + + if (map == NULL) { + retcode = EINVAL; + goto done; + } + size = round_page(map->size); + foff = map->offset; + } else { + size = round_page(dma->byte_count), + foff = 0; + } #ifdef __FreeBSD__ - virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); - retcode = vm_mmap(&vms->vm_map, - &virtual, - round_page(map->size), - PROT_READ|PROT_WRITE, VM_PROT_ALL, - MAP_SHARED, - SLIST_FIRST(&kdev->si_hlist), - (unsigned long)map->offset ); -#elif defined(__NetBSD__) - virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); - retcode = uvm_mmap(&vms->vm_map, - (vaddr_t *)&virtual, - round_page(map->size), - UVM_PROT_READ | UVM_PROT_WRITE, - UVM_PROT_ALL, MAP_SHARED, - &vn->v_uobj, map->offset, - p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); -#endif /* __NetBSD__ */ - } else { -#ifdef __FreeBSD__ - virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); - retcode = vm_mmap(&vms->vm_map, - &virtual, - round_page(dma->byte_count), - PROT_READ|PROT_WRITE, VM_PROT_ALL, - MAP_SHARED, - SLIST_FIRST(&kdev->si_hlist), - 0); + vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); + retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE, + VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), foff ); #elif defined(__NetBSD__) - virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); - retcode = uvm_mmap(&vms->vm_map, - (vaddr_t *)&virtual, - round_page(dma->byte_count), - UVM_PROT_READ | UVM_PROT_WRITE, - UVM_PROT_ALL, MAP_SHARED, - &vn->v_uobj, 0, - p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); + vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); + retcode = uvm_mmap(&vms->vm_map, &vaddr, size, + UVM_PROT_READ | UVM_PROT_WRITE, UVM_PROT_ALL, MAP_SHARED, + &vn->v_uobj, foff, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); #endif /* __NetBSD__ */ + if (retcode) + goto done; + + request.virtual = (void *)vaddr; + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + if (DRM_COPY_TO_USER(&request.list[i].idx, + &dma->buflist[i]->idx, sizeof(request.list[0].idx))) { + retcode = EFAULT; + goto done; } - if (retcode) + if (DRM_COPY_TO_USER(&request.list[i].total, + &dma->buflist[i]->total, sizeof(request.list[0].total))) { + retcode = EFAULT; + goto done; + } + if (DRM_COPY_TO_USER(&request.list[i].used, &zero, + sizeof(zero))) { + retcode = EFAULT; + goto done; + } + address = vaddr + dma->buflist[i]->offset; /* *** */ + if (DRM_COPY_TO_USER(&request.list[i].address, &address, + sizeof(address))) { + retcode = EFAULT; goto done; - request.virtual = (void *)virtual; - - for ( i = 0 ; i < dma->buf_count ; i++ ) { - if ( DRM_COPY_TO_USER( &request.list[i].idx, - &dma->buflist[i]->idx, - sizeof(request.list[0].idx) ) ) { - retcode = EFAULT; - goto done; - } - if ( DRM_COPY_TO_USER( &request.list[i].total, - &dma->buflist[i]->total, - sizeof(request.list[0].total) ) ) { - retcode = EFAULT; - goto done; - } - if ( DRM_COPY_TO_USER( &request.list[i].used, - &zero, - sizeof(zero) ) ) { - retcode = EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; /* *** */ - if ( DRM_COPY_TO_USER( &request.list[i].address, - &address, - sizeof(address) ) ) { - retcode = EFAULT; - goto done; - } } } + done: request.count = dma->buf_count; DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode ); - DRM_COPY_TO_USER_IOCTL( (drm_buf_map_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL((drm_buf_map_t *)data, request, sizeof(request)); return DRM_ERR(retcode); } #endif /* __HAVE_DMA */ - diff --git a/sys/dev/drm/drm_context.h b/sys/dev/drm/drm_context.h index 2c8b780..9d83264 100644 --- a/sys/dev/drm/drm_context.h +++ b/sys/dev/drm/drm_context.h @@ -43,70 +43,68 @@ void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle ) { - if ( ctx_handle < 0 ) goto failed; - if ( !dev->ctx_bitmap ) goto failed; - - if ( ctx_handle < DRM_MAX_CTXBITMAP ) { - DRM_LOCK; - clear_bit( ctx_handle, dev->ctx_bitmap ); - dev->context_sareas[ctx_handle] = NULL; - DRM_UNLOCK; + if (ctx_handle < 0 || ctx_handle >= DRM_MAX_CTXBITMAP || + dev->ctx_bitmap == NULL) { + DRM_ERROR("Attempt to free invalid context handle: %d\n", + ctx_handle); return; } -failed: - DRM_ERROR( "Attempt to free invalid context handle: %d\n", - ctx_handle ); - return; + + DRM_LOCK(); + clear_bit(ctx_handle, dev->ctx_bitmap); + dev->context_sareas[ctx_handle] = NULL; + DRM_UNLOCK(); + return; } int DRM(ctxbitmap_next)( drm_device_t *dev ) { int bit; - if(!dev->ctx_bitmap) return -1; + if (dev->ctx_bitmap == NULL) + return -1; - DRM_LOCK; + DRM_LOCK(); bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP ); - if ( bit < DRM_MAX_CTXBITMAP ) { - set_bit( bit, dev->ctx_bitmap ); - DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit ); - if((bit+1) > dev->max_context) { - dev->max_context = (bit+1); - if(dev->context_sareas) { - drm_local_map_t **ctx_sareas; - - ctx_sareas = DRM(realloc)(dev->context_sareas, - (dev->max_context - 1) * - sizeof(*dev->context_sareas), - dev->max_context * - sizeof(*dev->context_sareas), - DRM_MEM_MAPS); - if(!ctx_sareas) { - clear_bit(bit, dev->ctx_bitmap); - DRM_UNLOCK; - return -1; - } - dev->context_sareas = ctx_sareas; - dev->context_sareas[bit] = NULL; - } else { - /* max_context == 1 at this point */ - dev->context_sareas = DRM(alloc)( - dev->max_context * - sizeof(*dev->context_sareas), - DRM_MEM_MAPS); - if(!dev->context_sareas) { - clear_bit(bit, dev->ctx_bitmap); - DRM_UNLOCK; - return -1; - } - dev->context_sareas[bit] = NULL; + if (bit >= DRM_MAX_CTXBITMAP) { + DRM_UNLOCK(); + return -1; + } + + set_bit(bit, dev->ctx_bitmap); + DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit); + if ((bit+1) > dev->max_context) { + dev->max_context = (bit+1); + if (dev->context_sareas != NULL) { + drm_local_map_t **ctx_sareas; + + ctx_sareas = DRM(realloc)(dev->context_sareas, + (dev->max_context - 1) * + sizeof(*dev->context_sareas), + dev->max_context * + sizeof(*dev->context_sareas), + DRM_MEM_MAPS); + if (ctx_sareas == NULL) { + clear_bit(bit, dev->ctx_bitmap); + DRM_UNLOCK(); + return -1; + } + dev->context_sareas = ctx_sareas; + dev->context_sareas[bit] = NULL; + } else { + /* max_context == 1 at this point */ + dev->context_sareas = DRM(alloc)(dev->max_context * + sizeof(*dev->context_sareas), DRM_MEM_MAPS); + if (dev->context_sareas == NULL) { + clear_bit(bit, dev->ctx_bitmap); + DRM_UNLOCK(); + return -1; } + dev->context_sareas[bit] = NULL; } - DRM_UNLOCK; - return bit; } - DRM_UNLOCK; - return -1; + DRM_UNLOCK(); + return bit; } int DRM(ctxbitmap_init)( drm_device_t *dev ) @@ -114,17 +112,16 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) int i; int temp; - DRM_LOCK; - dev->ctx_bitmap = (atomic_t *) DRM(alloc)( PAGE_SIZE, - DRM_MEM_CTXBITMAP ); + DRM_LOCK(); + dev->ctx_bitmap = (atomic_t *)DRM(calloc)(1, PAGE_SIZE, + DRM_MEM_CTXBITMAP); if ( dev->ctx_bitmap == NULL ) { - DRM_UNLOCK; + DRM_UNLOCK(); return DRM_ERR(ENOMEM); } - memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE ); dev->context_sareas = NULL; dev->max_context = -1; - DRM_UNLOCK; + DRM_UNLOCK(); for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { temp = DRM(ctxbitmap_next)( dev ); @@ -136,13 +133,12 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) void DRM(ctxbitmap_cleanup)( drm_device_t *dev ) { - DRM_LOCK; - if( dev->context_sareas ) DRM(free)( dev->context_sareas, - sizeof(*dev->context_sareas) * - dev->max_context, - DRM_MEM_MAPS ); + DRM_LOCK(); + if (dev->context_sareas != NULL) + DRM(free)(dev->context_sareas, sizeof(*dev->context_sareas) * + dev->max_context, DRM_MEM_MAPS); DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP ); - DRM_UNLOCK; + DRM_UNLOCK(); } /* ================================================================ @@ -158,14 +154,14 @@ int DRM(getsareactx)( DRM_IOCTL_ARGS ) DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); - DRM_LOCK; + DRM_LOCK(); if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) { - DRM_UNLOCK; + DRM_UNLOCK(); return DRM_ERR(EINVAL); } map = dev->context_sareas[request.ctx_id]; - DRM_UNLOCK; + DRM_UNLOCK(); request.handle = map->handle; @@ -184,22 +180,22 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS ) DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); - DRM_LOCK; + DRM_LOCK(); TAILQ_FOREACH(list, dev->maplist, link) { map=list->map; - if(map->handle == request.handle) { + if (map->handle == request.handle) { if (dev->max_context < 0) goto bad; if (request.ctx_id >= (unsigned) dev->max_context) goto bad; dev->context_sareas[request.ctx_id] = map; - DRM_UNLOCK; + DRM_UNLOCK(); return 0; } } bad: - DRM_UNLOCK; + DRM_UNLOCK(); return DRM_ERR(EINVAL); } @@ -249,7 +245,7 @@ int DRM(resctx)( DRM_IOCTL_ARGS ) DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) ); if ( res.count >= DRM_RESERVED_CONTEXTS ) { - memset( &ctx, 0, sizeof(ctx) ); + bzero(&ctx, sizeof(ctx)); for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { ctx.handle = i; if ( DRM_COPY_TO_USER( &res.contexts[i], diff --git a/sys/dev/drm/drm_dma.h b/sys/dev/drm/drm_dma.h index b4bf9e4..9090a1b 100644 --- a/sys/dev/drm/drm_dma.h +++ b/sys/dev/drm/drm_dma.h @@ -47,16 +47,12 @@ int DRM(dma_setup)( drm_device_t *dev ) { - int i; - dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER ); - if ( !dev->dma ) + dev->dma = DRM(calloc)(1, sizeof(*dev->dma), DRM_MEM_DRIVER); + if (dev->dma == NULL) return DRM_ERR(ENOMEM); - memset( dev->dma, 0, sizeof(*dev->dma) ); - - for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ ) - memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0])); + DRM_SPININIT(dev->dma_lock, "drmdma"); return 0; } @@ -66,7 +62,8 @@ void DRM(dma_takedown)(drm_device_t *dev) drm_device_dma_t *dma = dev->dma; int i, j; - if (!dma) return; + if (dma == NULL) + return; /* Clear dma buffers */ for (i = 0; i <= DRM_MAX_ORDER; i++) { @@ -113,6 +110,7 @@ void DRM(dma_takedown)(drm_device_t *dev) DRM_MEM_PAGES); DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); dev->dma = NULL; + DRM_SPINUNINIT(dev->dma_lock); } @@ -150,227 +148,11 @@ void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp) } #endif - -#if __HAVE_DMA_IRQ - -int DRM(irq_install)( drm_device_t *dev, int irq ) -{ - int retcode; - - if ( !irq ) - return DRM_ERR(EINVAL); - - if (dev->dev_private == NULL) - return DRM_ERR(EINVAL); - - DRM_LOCK; - if ( dev->irq ) { - DRM_UNLOCK; - return DRM_ERR(EBUSY); - } - dev->irq = irq; - DRM_UNLOCK; - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - dev->context_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->this_buffer = NULL; - -#if __HAVE_DMA_IRQ_BH - TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); -#endif - -#if __HAVE_VBL_IRQ && 0 /* disabled */ - DRM_SPININIT( dev->vbl_lock, "vblsig" ); - TAILQ_INIT( &dev->vbl_sig_list ); -#endif - - /* Before installing handler */ - DRM(driver_irq_preinstall)( dev ); - - /* Install handler */ - dev->irqrid = 0; -#ifdef __FreeBSD__ - dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid, - 0, ~0, 1, RF_SHAREABLE); - if (!dev->irqr) { -#elif defined(__NetBSD__) - if (pci_intr_map(&dev->pa, &dev->ih) != 0) { -#endif - DRM_LOCK; - dev->irq = 0; - dev->irqrid = 0; - DRM_UNLOCK; - return ENOENT; - } - -#ifdef __FreeBSD__ -#if __FreeBSD_version < 500000 - retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, - DRM(dma_service), dev, &dev->irqh); -#else - retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, - DRM(dma_service), dev, &dev->irqh); -#endif - if ( retcode ) { -#elif defined(__NetBSD__) - dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, - (irqreturn_t (*)(DRM_IRQ_ARGS))DRM(dma_service), dev); - if ( !dev->irqh ) { -#endif - DRM_LOCK; -#ifdef __FreeBSD__ - bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); -#endif - dev->irq = 0; - dev->irqrid = 0; - DRM_UNLOCK; - return retcode; - } - - /* After installing handler */ - DRM(driver_irq_postinstall)( dev ); - - return 0; -} - -int DRM(irq_uninstall)( drm_device_t *dev ) -{ - int irq; - int irqrid; - - DRM_LOCK; - irq = dev->irq; - irqrid = dev->irqrid; - dev->irq = 0; - dev->irqrid = 0; - DRM_UNLOCK; - - if ( !irq ) - return DRM_ERR(EINVAL); - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - DRM(driver_irq_uninstall)( dev ); - -#ifdef __FreeBSD__ - bus_teardown_intr(dev->device, dev->irqr, dev->irqh); - bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); -#elif defined(__NetBSD__) - pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); -#endif - - return 0; -} - -int DRM(control)( DRM_IOCTL_ARGS ) -{ - DRM_DEVICE; - drm_control_t ctl; - - DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); - - switch ( ctl.func ) { - case DRM_INST_HANDLER: - return DRM(irq_install)( dev, ctl.irq ); - case DRM_UNINST_HANDLER: - return DRM(irq_uninstall)( dev ); - default: - return DRM_ERR(EINVAL); - } -} - -#if __HAVE_VBL_IRQ -int DRM(wait_vblank)( DRM_IOCTL_ARGS ) -{ - DRM_DEVICE; - drm_wait_vblank_t vblwait; - struct timeval now; - int ret; - - if (!dev->irq) - return DRM_ERR(EINVAL); - - DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, - sizeof(vblwait) ); - - if (vblwait.request.type & _DRM_VBLANK_RELATIVE) { - vblwait.request.sequence += atomic_read(&dev->vbl_received); - vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; - } - - flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; - if (flags & _DRM_VBLANK_SIGNAL) { -#if 0 /* disabled */ - drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); - if (vbl_sig == NULL) - return ENOMEM; - bzero(vbl_sig, sizeof(*vbl_sig)); - - vbl_sig->sequence = vblwait.request.sequence; - vbl_sig->signo = vblwait.request.signal; - vbl_sig->pid = DRM_CURRENTPID; - - vblwait.reply.sequence = atomic_read(&dev->vbl_received); - - DRM_SPINLOCK(&dev->vbl_lock); - TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); - DRM_SPINUNLOCK(&dev->vbl_lock); - ret = 0; -#endif - ret = EINVAL; - } else { - ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); - - microtime(&now); - vblwait.reply.tval_sec = now.tv_sec; - vblwait.reply.tval_usec = now.tv_usec; - } - - DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, - sizeof(vblwait) ); - - return ret; -} - -void DRM(vbl_send_signals)(drm_device_t *dev) -{ -} - -#if 0 /* disabled */ -void DRM(vbl_send_signals)( drm_device_t *dev ) -{ - drm_vbl_sig_t *vbl_sig; - unsigned int vbl_seq = atomic_read( &dev->vbl_received ); - struct proc *p; - - DRM_SPINLOCK(&dev->vbl_lock); - - vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list); - while (vbl_sig != NULL) { - drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link); - - if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { - p = pfind(vbl_sig->pid); - if (p != NULL) - psignal(p, vbl_sig->signo); - - TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); - DRM_FREE(vbl_sig,sizeof(*vbl_sig)); - } - vbl_sig = next; - } - - DRM_SPINUNLOCK(&dev->vbl_lock); -} -#endif - -#endif /* __HAVE_VBL_IRQ */ - -#else - +#if !__HAVE_IRQ +/* This stub DRM_IOCTL_CONTROL handler is for the drivers that used to require + * IRQs for DMA but no longer do. It maintains compatibility with the X Servers + * that try to use the control ioctl by simply returning success. + */ int DRM(control)( DRM_IOCTL_ARGS ) { drm_control_t ctl; @@ -385,8 +167,6 @@ int DRM(control)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } } - -#endif /* __HAVE_DMA_IRQ */ +#endif #endif /* __HAVE_DMA */ - diff --git a/sys/dev/drm/drm_drv.h b/sys/dev/drm/drm_drv.h index 6f8f8f4..f00d6de 100644 --- a/sys/dev/drm/drm_drv.h +++ b/sys/dev/drm/drm_drv.h @@ -56,8 +56,8 @@ #ifndef __HAVE_CTX_BITMAP #define __HAVE_CTX_BITMAP 0 #endif -#ifndef __HAVE_DMA_IRQ -#define __HAVE_DMA_IRQ 0 +#ifndef __HAVE_IRQ +#define __HAVE_IRQ 0 #endif #ifndef __HAVE_DMA_QUEUE #define __HAVE_DMA_QUEUE 0 @@ -112,7 +112,7 @@ int DRM(flags) = 0; #endif static int DRM(init)(device_t nbdev); -static void DRM(cleanup)(device_t nbdev); +static void DRM(cleanup)(drm_device_t *dev); #ifdef __FreeBSD__ #define DRIVER_SOFTC(unit) \ @@ -136,6 +136,7 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { DRM(setversion), 0, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(noop), 1, 1 }, @@ -171,9 +172,9 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 }, - - /* The DRM_IOCTL_DMA ioctl should be defined by the driver. - */ + /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ +#endif +#if __HAVE_IRQ || __HAVE_DMA [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, #endif @@ -220,16 +221,26 @@ static struct cdevsw DRM(cdevsw) = { #endif }; +static drm_pci_id_list_t DRM(pciidlist)[] = { + DRIVER_PCI_IDS +}; + static int DRM(probe)(device_t dev) { const char *s = NULL; + int pciid, vendor, device; + + /* XXX: Cope with agp bridge device? */ + if (!strcmp(device_get_name(dev), "drmsub")) + pciid = pci_get_devid(device_get_parent(dev)); + else + pciid = pci_get_devid(dev); - int pciid=pci_get_devid(dev); - int vendor = (pciid & 0x0000ffff); - int device = (pciid & 0xffff0000) >> 16; + vendor = (pciid & 0x0000ffff); + device = (pciid & 0xffff0000) >> 16; s = DRM(find_description)(vendor, device); - if (s) { + if (s != NULL) { device_set_desc(dev, s); return 0; } @@ -244,14 +255,14 @@ static int DRM(attach)(device_t dev) static int DRM(detach)(device_t dev) { - DRM(cleanup)(dev); + DRM(cleanup)(device_get_softc(dev)); return 0; } static device_method_t DRM(methods)[] = { /* Device interface */ - DEVMETHOD(device_probe, DRM( probe)), - DEVMETHOD(device_attach, DRM( attach)), - DEVMETHOD(device_detach, DRM( detach)), + DEVMETHOD(device_probe, DRM(probe)), + DEVMETHOD(device_attach, DRM(attach)), + DEVMETHOD(device_detach, DRM(detach)), { 0, 0 } }; @@ -343,7 +354,8 @@ int DRM(probe)(struct pci_attach_args *pa) { const char *desc; - desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); + desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), + PCI_PRODUCT(pa->pa_id)); if (desc != NULL) { return 1; } @@ -390,23 +402,18 @@ int DRM(activate)(struct device *self, enum devact act) #endif /* __NetBSD__ */ const char *DRM(find_description)(int vendor, int device) { - const char *s = NULL; - int i=0, done=0; + int i = 0; - while ( !done && (DRM(devicelist)[i].vendor != 0 ) ) { - if ( (DRM(devicelist)[i].vendor == vendor) && - (DRM(devicelist)[i].device == device) ) { - done=1; - if ( DRM(devicelist)[i].supported ) - s = DRM(devicelist)[i].name; - else - DRM_INFO("%s not supported\n", DRM(devicelist)[i].name); + for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) { + if ((DRM(pciidlist)[i].vendor == vendor) && + (DRM(pciidlist)[i].device == device)) { + return DRM(pciidlist)[i].name; } - i++; } - return s; + return NULL; } +/* Initialize the DRM on first open. Called with device's lock held */ static int DRM(setup)( drm_device_t *dev ) { int i; @@ -417,7 +424,7 @@ static int DRM(setup)( drm_device_t *dev ) #if __HAVE_DMA i = DRM(dma_setup)( dev ); - if ( i < 0 ) + if ( i != 0 ) return i; #endif @@ -467,22 +474,11 @@ static int DRM(setup)( drm_device_t *dev ) dev->magiclist[i].tail = NULL; } - dev->maplist = DRM(alloc)(sizeof(*dev->maplist), - DRM_MEM_MAPS); - if(dev->maplist == NULL) return DRM_ERR(ENOMEM); - memset(dev->maplist, 0, sizeof(*dev->maplist)); - TAILQ_INIT(dev->maplist); - dev->lock.hw_lock = NULL; dev->lock.lock_queue = 0; dev->irq = 0; dev->context_flag = 0; dev->last_context = 0; -#if __FreeBSD_version >= 500000 - callout_init( &dev->timer, 1 ); -#else - callout_init( &dev->timer ); -#endif #ifdef __FreeBSD__ dev->buf_sigio = NULL; @@ -496,7 +492,9 @@ static int DRM(setup)( drm_device_t *dev ) return 0; } - +/* Free resources associated with the DRM on the last close. + * Called with the device's lock held. + */ static int DRM(takedown)( drm_device_t *dev ) { drm_magic_entry_t *pt, *next; @@ -507,13 +505,11 @@ static int DRM(takedown)( drm_device_t *dev ) DRM_DEBUG( "\n" ); DRIVER_PRETAKEDOWN(); -#if __HAVE_DMA_IRQ - if ( dev->irq ) DRM(irq_uninstall)( dev ); +#if __HAVE_IRQ + if (dev->irq != 0) + DRM(irq_uninstall)( dev ); #endif - DRM_LOCK; - callout_stop( &dev->timer ); - if ( dev->unique ) { DRM(free)( dev->unique, strlen( dev->unique ) + 1, DRM_MEM_DRIVER ); @@ -536,7 +532,7 @@ static int DRM(takedown)( drm_device_t *dev ) drm_agp_mem_t *nexte; /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ + intact until DRM(cleanup) is called. */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; if ( entry->bound ) DRM(unbind_agp)( entry->handle ); @@ -551,8 +547,14 @@ static int DRM(takedown)( drm_device_t *dev ) dev->agp->enabled = 0; } #endif +#if __REALLY_HAVE_SG + if (dev->sg != NULL) { + DRM(sg_cleanup)(dev->sg); + dev->sg = NULL; + } +#endif - if( dev->maplist ) { + if (dev->maplist != NULL) { while ((list=TAILQ_FIRST(dev->maplist))) { map = list->map; switch ( map->type ) { @@ -560,28 +562,11 @@ static int DRM(takedown)( drm_device_t *dev ) case _DRM_FRAME_BUFFER: #if __REALLY_HAVE_MTRR if ( map->mtrr >= 0 ) { - int retcode; -#ifdef __FreeBSD__ - int act; - struct mem_range_desc mrdesc; - mrdesc.mr_base = map->offset; - mrdesc.mr_len = map->size; - mrdesc.mr_flags = MDF_WRITECOMBINE; - act = MEMRANGE_SET_REMOVE; - bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); - retcode = mem_range_attr_set(&mrdesc, &act); - map->mtrr=1; -#elif defined __NetBSD__ - struct mtrr mtrrmap; - int one = 1; - mtrrmap.base = map->offset; - mtrrmap.len = map->size; - mtrrmap.type = MTRR_TYPE_WC; - mtrrmap.flags = 0; - retcode = mtrr_set( &mtrrmap, &one, - DRM_CURPROC, MTRR_GETSET_KERNEL); -#endif - DRM_DEBUG( "mtrr_del=%d\n", retcode ); + int __unused mtrr; + + mtrr = DRM(mtrr_del)(map->offset, + map->size, DRM_MTRR_WC); + DRM_DEBUG("mtrr_del=%d\n", mtrr); } #endif DRM(ioremapfree)( map ); @@ -593,28 +578,16 @@ static int DRM(takedown)( drm_device_t *dev ) break; case _DRM_AGP: + case _DRM_SCATTER_GATHER: /* Do nothing here, because this is all - * handled in the AGP/GART driver. - */ - break; - case _DRM_SCATTER_GATHER: - /* Handle it, but do nothing, if REALLY_HAVE_SG - * isn't defined. + * handled in the AGP/GART/SG functions. */ -#if __REALLY_HAVE_SG - if(dev->sg) { - DRM(sg_cleanup)(dev->sg); - dev->sg = NULL; - } -#endif break; } TAILQ_REMOVE(dev->maplist, list, link); DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); } - DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); - dev->maplist = NULL; } #if __HAVE_DMA @@ -625,7 +598,6 @@ static int DRM(takedown)( drm_device_t *dev ) dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } - DRM_UNLOCK; return 0; } @@ -652,18 +624,32 @@ static int DRM(init)( device_t nbdev ) unit = device_get_unit(nbdev); dev = device_get_softc(nbdev); memset( (void *)dev, 0, sizeof(*dev) ); - dev->device = nbdev; + + if (!strcmp(device_get_name(nbdev), "drmsub")) + dev->device = device_get_parent(nbdev); + else + dev->device = nbdev; + dev->devnode = make_dev( &DRM(cdevsw), unit, DRM_DEV_UID, DRM_DEV_GID, DRM_DEV_MODE, "dri/card%d", unit ); +#if __FreeBSD_version >= 500000 + mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF); +#endif #elif defined(__NetBSD__) unit = minor(dev->device.dv_unit); #endif - DRM_SPININIT(dev->count_lock, "drm device"); - lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); + + dev->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS); + if (dev->maplist == NULL) { + retcode = ENOMEM; + goto error; + } + TAILQ_INIT(dev->maplist); + dev->name = DRIVER_NAME; DRM(mem_init)(); DRM(sysctl_init)(dev); @@ -674,51 +660,30 @@ static int DRM(init)( device_t nbdev ) #if __MUST_HAVE_AGP if ( dev->agp == NULL ) { DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(sysctl_cleanup)( dev ); -#ifdef __FreeBSD__ - destroy_dev(dev->devnode); -#endif - DRM(takedown)( dev ); - return DRM_ERR(ENOMEM); + retcode = DRM_ERR(ENOMEM); + goto error; } #endif /* __MUST_HAVE_AGP */ #if __REALLY_HAVE_MTRR if (dev->agp) { -#ifdef __FreeBSD__ - int retcode = 0, act; - struct mem_range_desc mrdesc; - mrdesc.mr_base = dev->agp->info.ai_aperture_base; - mrdesc.mr_len = dev->agp->info.ai_aperture_size; - mrdesc.mr_flags = MDF_WRITECOMBINE; - act = MEMRANGE_SET_UPDATE; - bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); - retcode = mem_range_attr_set(&mrdesc, &act); - dev->agp->agp_mtrr=1; -#elif defined __NetBSD__ - struct mtrr mtrrmap; - int one = 1; - mtrrmap.base = dev->agp->info.ai_aperture_base; - mtrrmap.len = dev->agp->info.ai_aperture_size; - mtrrmap.type = MTRR_TYPE_WC; - mtrrmap.flags = MTRR_VALID; - dev->agp->agp_mtrr = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); -#endif /* __NetBSD__ */ + int retcode; + + retcode = DRM(mtrr_add)(dev->agp->info.ai_aperture_base, + dev->agp->info.ai_aperture_size, DRM_MTRR_WC); + if (retcode == 0) + dev->agp->agp_mtrr=1; } #endif /* __REALLY_HAVE_MTRR */ #endif /* __REALLY_HAVE_AGP */ #if __HAVE_CTX_BITMAP retcode = DRM(ctxbitmap_init)( dev ); - if( retcode ) { + if (retcode != 0) { DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(sysctl_cleanup)( dev ); -#ifdef __FreeBSD__ - destroy_dev(dev->devnode); -#endif - DRM(takedown)( dev ); - return retcode; + goto error; } #endif + DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", DRIVER_NAME, DRIVER_MAJOR, @@ -730,28 +695,31 @@ static int DRM(init)( device_t nbdev ) DRIVER_POSTINIT(); return 0; + +error: + DRM(sysctl_cleanup)(dev); + DRM_LOCK(); + DRM(takedown)(dev); + DRM_UNLOCK(); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); +#if __FreeBSD_version >= 500000 + mtx_destroy(&dev->dev_lock); +#endif +#endif + DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + return retcode; } /* linux: drm_cleanup is called via cleanup_module at module unload time. * bsd: drm_cleanup is called per device at module unload time. * FIXME: NetBSD */ -static void DRM(cleanup)(device_t nbdev) +static void DRM(cleanup)(drm_device_t *dev) { - drm_device_t *dev; -#ifdef __NetBSD__ -#if __REALLY_HAVE_MTRR - struct mtrr mtrrmap; - int one = 1; -#endif /* __REALLY_HAVE_MTRR */ - dev = nbdev; -#endif /* __NetBSD__ */ DRM_DEBUG( "\n" ); -#ifdef __FreeBSD__ - dev = device_get_softc(nbdev); -#endif DRM(sysctl_cleanup)( dev ); #ifdef __FreeBSD__ destroy_dev(dev->devnode); @@ -762,17 +730,17 @@ static void DRM(cleanup)(device_t nbdev) #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR if ( dev->agp && dev->agp->agp_mtrr >= 0) { -#if defined(__NetBSD__) - mtrrmap.base = dev->agp->info.ai_aperture_base; - mtrrmap.len = dev->agp->info.ai_aperture_size; - mtrrmap.type = 0; - mtrrmap.flags = 0; - mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); -#endif + int __unused mtrr; + + mtrr = DRM(mtrr_del)(dev->agp->info.ai_aperture_base, + dev->agp->info.ai_aperture_size, DRM_MTRR_WC); + DRM_DEBUG("mtrr_del=%d\n", mtrr); } #endif + DRM_LOCK(); DRM(takedown)( dev ); + DRM_UNLOCK(); #if __REALLY_HAVE_AGP if ( dev->agp ) { @@ -783,7 +751,10 @@ static void DRM(cleanup)(device_t nbdev) #endif DRIVER_POSTCLEANUP(); DRM(mem_uninit)(); - DRM_SPINUNINIT(dev->count_lock); +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 + mtx_destroy(&dev->dev_lock); +#endif + DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); } @@ -829,13 +800,13 @@ int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); - DRM_SPINLOCK( &dev->count_lock ); + DRM_LOCK(); #ifdef __FreeBSD__ device_busy(dev->device); #endif if ( !dev->open_count++ ) retcode = DRM(setup)( dev ); - DRM_SPINUNLOCK( &dev->count_lock ); + DRM_UNLOCK(); } return retcode; @@ -846,12 +817,16 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) drm_file_t *priv; DRM_DEVICE; int retcode = 0; - DRMFILE __unused filp = (void *)(DRM_CURRENTPID); + DRMFILE filp = (void *)(DRM_CURRENTPID); DRM_DEBUG( "open_count = %d\n", dev->open_count ); + + DRM_LOCK(); + priv = DRM(find_file_by_proc)(dev, p); if (!priv) { - DRM_DEBUG("can't find authenticator\n"); + DRM_UNLOCK(); + DRM_ERROR("can't find authenticator\n"); return EINVAL; } @@ -870,11 +845,11 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.filp == (void *)DRM_CURRENTPID) { + && dev->lock.filp == filp) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); -#if HAVE_DRIVER_RELEASE +#if __HAVE_RELEASE DRIVER_RELEASE(); #endif DRM(lock_free)(dev, @@ -903,17 +878,17 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) break; /* Got lock */ } /* Contention */ -#if 0 - atomic_inc( &dev->total_sleeps ); -#endif +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + retcode = msleep((void *)&dev->lock.lock_queue, + dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); +#else retcode = tsleep((void *)&dev->lock.lock_queue, - PZERO|PCATCH, - "drmlk2", - 0); + PZERO | PCATCH, "drmlk2", 0); +#endif if (retcode) break; } - if( !retcode ) { + if (retcode == 0) { DRIVER_RELEASE(); DRM(lock_free)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); @@ -931,32 +906,24 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) dev->buf_pgid = 0; #endif /* __NetBSD__ */ - DRM_LOCK; - priv = DRM(find_file_by_proc)(dev, p); - if (priv) { - priv->refs--; - if (!priv->refs) { - TAILQ_REMOVE(&dev->files, priv, link); - DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); - } + if (--priv->refs == 0) { + TAILQ_REMOVE(&dev->files, priv, link); + DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); } - DRM_UNLOCK; - /* ======================================================== * End inline drm_release */ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); - DRM_SPINLOCK( &dev->count_lock ); #ifdef __FreeBSD__ device_unbusy(dev->device); #endif - if ( !--dev->open_count ) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM(takedown)( dev ); + if (--dev->open_count == 0) { + retcode = DRM(takedown)(dev); } - DRM_SPINUNLOCK( &dev->count_lock ); + + DRM_UNLOCK(); return retcode; } @@ -971,7 +938,9 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, drm_ioctl_desc_t *ioctl; int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); - DRM_PRIV; + drm_file_t *priv; + + DRM_GET_PRIV_WITH_RETURN(priv, (DRMFILE)DRM_CURRENTPID); atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; @@ -986,10 +955,7 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, switch (cmd) { case FIONBIO: - return 0; - case FIOASYNC: - dev->flags |= FASYNC; return 0; #ifdef __FreeBSD__ @@ -1015,22 +981,21 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, #endif /* __NetBSD__ */ } - if ( nr >= DRIVER_IOCTL_COUNT ) { - retcode = EINVAL; - } else { - ioctl = &DRM(ioctls)[nr]; - func = ioctl->func; - - if ( !func ) { - DRM_DEBUG( "no function\n" ); - retcode = EINVAL; - } else if ( ( ioctl->root_only && DRM_SUSER(p) ) - || ( ioctl->auth_needed && !priv->authenticated ) ) { - retcode = EACCES; - } else { - retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID); - } + if (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE) + return EINVAL; + + ioctl = &DRM(ioctls)[nr]; + func = ioctl->func; + + if (func == NULL) { + DRM_DEBUG( "no function\n" ); + return EINVAL; } + if ((ioctl->root_only && DRM_SUSER(p)) || (ioctl->auth_needed && + !priv->authenticated)) + return EACCES; + + retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID); return DRM_ERR(retcode); } @@ -1058,44 +1023,41 @@ int DRM(lock)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); #endif - if ( !ret ) { - for (;;) { - if ( !dev->lock.hw_lock ) { - /* Device has been unregistered */ - ret = EINTR; - break; - } - if ( DRM(lock_take)( &dev->lock.hw_lock->lock, - lock.context ) ) { - dev->lock.filp = (void *)DRM_CURRENTPID; - dev->lock.lock_time = jiffies; - atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); - break; /* Got lock */ - } - - /* Contention */ - ret = tsleep((void *)&dev->lock.lock_queue, - PZERO|PCATCH, - "drmlk2", - 0); - if (ret) - break; - } - } + DRM_LOCK(); + for (;;) { + if (DRM(lock_take)(&dev->lock.hw_lock->lock, lock.context)) { + dev->lock.filp = (void *)DRM_CURRENTPID; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); + break; /* Got lock */ + } - if ( !ret ) { - /* FIXME: Add signal blocking here */ + /* Contention */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock, + PZERO | PCATCH, "drmlk2", 0); +#else + ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH, + "drmlk2", 0); +#endif + if (ret != 0) + break; + } + DRM_UNLOCK(); + DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); + + if (ret != 0) + return ret; + + /* XXX: Add signal blocking here */ #if __HAVE_DMA_QUIESCENT - if ( lock.flags & _DRM_LOCK_QUIESCENT ) { - DRIVER_DMA_QUIESCENT(); - } + if (lock.flags & _DRM_LOCK_QUIESCENT) { + DRIVER_DMA_QUIESCENT(); + } #endif - } - - DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); - return DRM_ERR(ret); + return 0; } @@ -1114,20 +1076,18 @@ int DRM(unlock)( DRM_IOCTL_ARGS ) atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); + DRM_LOCK(); DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); #if __HAVE_DMA_SCHEDULE DRM(dma_schedule)( dev, 1 ); #endif - /* FIXME: Do we ever really need to check this? - */ - if ( 1 /* !dev->context_flag */ ) { - if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT ) ) { - DRM_ERROR( "\n" ); - } + if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT ) ) { + DRM_ERROR( "\n" ); } + DRM_UNLOCK(); return 0; } diff --git a/sys/dev/drm/drm_fops.h b/sys/dev/drm/drm_fops.h index 6ccfc74..eb44970 100644 --- a/sys/dev/drm/drm_fops.h +++ b/sys/dev/drm/drm_fops.h @@ -34,6 +34,7 @@ #include "dev/drm/drmP.h" +/* Requires device lock held */ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) { #if __FreeBSD_version >= 500021 @@ -51,8 +52,7 @@ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) return NULL; } -/* DRM(open) is called whenever a process opens /dev/drm. */ - +/* DRM(open_helper) is called whenever a process opens /dev/drm. */ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, drm_device_t *dev) { @@ -65,12 +65,16 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); - /* FIXME: linux mallocs and bzeros here */ + DRM_LOCK(); priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); if (priv) { priv->refs++; } else { priv = (drm_file_t *) DRM(alloc)(sizeof(*priv), DRM_MEM_FILES); + if (priv == NULL) { + DRM_UNLOCK(); + return DRM_ERR(ENOMEM); + } bzero(priv, sizeof(*priv)); #if __FreeBSD_version >= 500000 priv->uid = p->td_ucred->cr_svuid; @@ -85,10 +89,9 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, priv->devXX = dev; priv->ioctl_count = 0; priv->authenticated = !DRM_SUSER(p); - DRM_LOCK; TAILQ_INSERT_TAIL(&dev->files, priv, link); - DRM_UNLOCK; } + DRM_UNLOCK(); #ifdef __FreeBSD__ kdev->si_drv1 = dev; #endif diff --git a/sys/dev/drm/drm_ioctl.h b/sys/dev/drm/drm_ioctl.h index 88074b4..83953c7 100644 --- a/sys/dev/drm/drm_ioctl.h +++ b/sys/dev/drm/drm_ioctl.h @@ -80,6 +80,12 @@ int DRM(irq_busid)( DRM_IOCTL_ARGS ) #endif } +/* + * Beginning in revision 1.1 of the DRM interface, getunique will return + * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function) + * before setunique has been called. The format for the bus-specific part of + * the unique is not defined for any other bus. + */ int DRM(getunique)( DRM_IOCTL_ARGS ) { DRM_DEVICE; @@ -98,6 +104,9 @@ int DRM(getunique)( DRM_IOCTL_ARGS ) return 0; } +/* Deprecated in DRM version 1.1, and will return EBUSY when setversion has + * requested version 1.1 or greater. + */ int DRM(setunique)( DRM_IOCTL_ARGS ) { DRM_DEVICE; @@ -114,7 +123,8 @@ int DRM(setunique)( DRM_IOCTL_ARGS ) dev->unique_len = u.unique_len; dev->unique = DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER); - if(!dev->unique) return DRM_ERR(ENOMEM); + if (dev->unique == NULL) + return DRM_ERR(ENOMEM); if (DRM_COPY_FROM_USER(dev->unique, u.unique, dev->unique_len)) return DRM_ERR(EFAULT); @@ -125,6 +135,26 @@ int DRM(setunique)( DRM_IOCTL_ARGS ) } +static int +DRM(set_busid)(drm_device_t *dev) +{ + + if (dev->unique != NULL) + return EBUSY; + + dev->unique_len = 20; + dev->unique = DRM(alloc)(dev->unique_len + 1, DRM_MEM_DRIVER); + if (dev->unique == NULL) + return ENOMEM; + + /* XXX Fix domain number (alpha hoses) */ + snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x", + 0, pci_get_bus(dev->device), pci_get_slot(dev->device), + pci_get_function(dev->device)); + + return 0; +} + int DRM(getmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; @@ -138,9 +168,9 @@ int DRM(getmap)( DRM_IOCTL_ARGS ) idx = map.offset; - DRM_LOCK; + DRM_LOCK(); if (idx < 0) { - DRM_UNLOCK; + DRM_UNLOCK(); return DRM_ERR(EINVAL); } @@ -158,7 +188,7 @@ int DRM(getmap)( DRM_IOCTL_ARGS ) i++; } - DRM_UNLOCK; + DRM_UNLOCK(); if (!list) return EINVAL; @@ -179,7 +209,7 @@ int DRM(getclient)( DRM_IOCTL_ARGS ) DRM_COPY_FROM_USER_IOCTL( client, (drm_client_t *)data, sizeof(client) ); idx = client.idx; - DRM_LOCK; + DRM_LOCK(); TAILQ_FOREACH(pt, &dev->files, link) { if (i==idx) { @@ -188,14 +218,14 @@ int DRM(getclient)( DRM_IOCTL_ARGS ) client.uid = pt->uid; client.magic = pt->magic; client.iocs = pt->ioctl_count; - DRM_UNLOCK; + DRM_UNLOCK(); *(drm_client_t *)data = client; return 0; } i++; } - DRM_UNLOCK; + DRM_UNLOCK(); DRM_COPY_TO_USER_IOCTL( (drm_client_t *)data, client, sizeof(client) ); @@ -210,7 +240,7 @@ int DRM(getstats)( DRM_IOCTL_ARGS ) memset(&stats, 0, sizeof(stats)); - DRM_LOCK; + DRM_LOCK(); for (i = 0; i < dev->counters; i++) { if (dev->types[i] == _DRM_STAT_LOCK) @@ -224,13 +254,54 @@ int DRM(getstats)( DRM_IOCTL_ARGS ) stats.count = dev->counters; - DRM_UNLOCK; + DRM_UNLOCK(); DRM_COPY_TO_USER_IOCTL( (drm_stats_t *)data, stats, sizeof(stats) ); return 0; } +int DRM(setversion)(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_set_version_t sv; + drm_set_version_t retv; + + DRM_COPY_FROM_USER_IOCTL(sv, (drm_set_version_t *)data, sizeof(sv)); + + retv.drm_di_major = 1; + retv.drm_di_minor = 1; + retv.drm_dd_major = DRIVER_MAJOR; + retv.drm_dd_minor = DRIVER_MINOR; + + DRM_COPY_TO_USER_IOCTL((drm_set_version_t *)data, retv, sizeof(sv)); + + if (sv.drm_di_major != -1) { + if (sv.drm_di_major != 1 || sv.drm_di_minor < 0) + return EINVAL; + if (sv.drm_di_minor > 1) + return EINVAL; + if (sv.drm_di_minor >= 1) { + /* + * Version 1.1 includes tying of DRM to specific device + */ + DRM(set_busid)(dev); + } + } + + if (sv.drm_dd_major != -1) { + if (sv.drm_dd_major != DRIVER_MAJOR || sv.drm_dd_minor < 0) + return EINVAL; + if (sv.drm_dd_minor > DRIVER_MINOR) + return EINVAL; +#ifdef DRIVER_SETVERSION + DRIVER_SETVERSION(dev, sv); +#endif + } + return 0; +} + + int DRM(noop)(DRM_IOCTL_ARGS) { DRM_DEBUG("\n"); diff --git a/sys/dev/drm/drm_irq.h b/sys/dev/drm/drm_irq.h new file mode 100644 index 0000000..e062f6c --- /dev/null +++ b/sys/dev/drm/drm_irq.h @@ -0,0 +1,255 @@ +/* drm_dma.c -- DMA IOCTL and function support + * Created: Fri Oct 18 2003 by anholt@FreeBSD.org + * + * Copyright 2003 Eric Anholt + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <anholt@FreeBSD.org> + * + * $FreeBSD$ + */ + +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 +static irqreturn_t +DRM(irq_handler_wrap)(DRM_IRQ_ARGS) +{ + drm_device_t *dev = (drm_device_t *)arg; + + DRM_SPINLOCK(&dev->irq_lock); + DRM(irq_handler)(arg); + DRM_SPINUNLOCK(&dev->irq_lock); +} +#endif + +int DRM(irq_install)( drm_device_t *dev, int irq ) +{ + int retcode; + + if ( irq == 0 || dev->dev_private == NULL) + return DRM_ERR(EINVAL); + + DRM_LOCK(); + if ( dev->irq ) { + DRM_UNLOCK(); + return DRM_ERR(EBUSY); + } + dev->irq = irq; + DRM_UNLOCK(); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + dev->context_flag = 0; + + dev->dma->next_buffer = NULL; + dev->dma->this_buffer = NULL; + +#if __HAVE_IRQ_BH + TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); +#endif + + DRM_SPININIT(dev->irq_lock, "DRM IRQ lock"); + +#if __HAVE_VBL_IRQ && 0 /* disabled */ + TAILQ_INIT( &dev->vbl_sig_list ); +#endif + + /* Before installing handler */ + DRM(driver_irq_preinstall)( dev ); + + /* Install handler */ + dev->irqrid = 0; +#ifdef __FreeBSD__ + dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid, + 0, ~0, 1, RF_SHAREABLE); + if (!dev->irqr) { +#elif defined(__NetBSD__) + if (pci_intr_map(&dev->pa, &dev->ih) != 0) { +#endif + DRM_LOCK(); + DRM_SPINUNINIT(dev->irq_lock); + dev->irq = 0; + dev->irqrid = 0; + DRM_UNLOCK(); + return ENOENT; + } + +#ifdef __FreeBSD__ +#if __FreeBSD_version < 500000 + retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, + DRM(irq_handler), dev, &dev->irqh); +#else + retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, + DRM(irq_handler_wrap), dev, &dev->irqh); +#endif + if ( retcode ) { +#elif defined(__NetBSD__) + dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, + (irqreturn_t (*)(DRM_IRQ_ARGS))DRM(irq_handler), dev); + if ( !dev->irqh ) { +#endif + DRM_LOCK(); +#ifdef __FreeBSD__ + bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); +#endif + DRM_SPINUNINIT(dev->irq_lock); + dev->irq = 0; + dev->irqrid = 0; + DRM_UNLOCK(); + return retcode; + } + + /* After installing handler */ + DRM(driver_irq_postinstall)( dev ); + + return 0; +} + +int DRM(irq_uninstall)( drm_device_t *dev ) +{ + int irq; + int irqrid; + + DRM_LOCK(); + irq = dev->irq; + irqrid = dev->irqrid; + dev->irq = 0; + dev->irqrid = 0; + DRM_UNLOCK(); + + if ( !irq ) + return DRM_ERR(EINVAL); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + DRM(driver_irq_uninstall)( dev ); + +#ifdef __FreeBSD__ + bus_teardown_intr(dev->device, dev->irqr, dev->irqh); + bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); +#elif defined(__NetBSD__) + pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); +#endif + DRM_SPINUNINIT(dev->irq_lock); + + return 0; +} + +int DRM(control)( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_control_t ctl; + + DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + return DRM(irq_install)( dev, ctl.irq ); + case DRM_UNINST_HANDLER: + return DRM(irq_uninstall)( dev ); + default: + return DRM_ERR(EINVAL); + } +} + +#if __HAVE_VBL_IRQ +int DRM(wait_vblank)( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret; + + if (!dev->irq) + return DRM_ERR(EINVAL); + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + if (vblwait.request.type & _DRM_VBLANK_RELATIVE) { + vblwait.request.sequence += atomic_read(&dev->vbl_received); + vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; + } + + flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; + if (flags & _DRM_VBLANK_SIGNAL) { +#if 0 /* disabled */ + drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); + if (vbl_sig == NULL) + return ENOMEM; + bzero(vbl_sig, sizeof(*vbl_sig)); + + vbl_sig->sequence = vblwait.request.sequence; + vbl_sig->signo = vblwait.request.signal; + vbl_sig->pid = DRM_CURRENTPID; + + vblwait.reply.sequence = atomic_read(&dev->vbl_received); + + DRM_SPINLOCK(&dev->irq_lock); + TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); + DRM_SPINUNLOCK(&dev->irq_lock); + ret = 0; +#endif + ret = EINVAL; + } else { + ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); + + microtime(&now); + vblwait.reply.tval_sec = now.tv_sec; + vblwait.reply.tval_usec = now.tv_usec; + } + + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} + +void DRM(vbl_send_signals)(drm_device_t *dev) +{ +} + +#if 0 /* disabled */ +void DRM(vbl_send_signals)( drm_device_t *dev ) +{ + drm_vbl_sig_t *vbl_sig; + unsigned int vbl_seq = atomic_read( &dev->vbl_received ); + struct proc *p; + + vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list); + while (vbl_sig != NULL) { + drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link); + + if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + p = pfind(vbl_sig->pid); + if (p != NULL) + psignal(p, vbl_sig->signo); + + TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); + DRM_FREE(vbl_sig,sizeof(*vbl_sig)); + } + vbl_sig = next; + } +} +#endif + +#endif /* __HAVE_VBL_IRQ */ diff --git a/sys/dev/drm/drm_memory.h b/sys/dev/drm/drm_memory.h index a0e88ee..917cb1e 100644 --- a/sys/dev/drm/drm_memory.h +++ b/sys/dev/drm/drm_memory.h @@ -126,4 +126,61 @@ int DRM(unbind_agp)(agp_memory *handle) return DRM(agp_unbind_memory)(handle); } #endif /* __REALLY_HAVE_AGP */ + +#ifdef __FreeBSD__ +int +DRM(mtrr_add)(unsigned long offset, size_t size, int flags) +{ + int act; + struct mem_range_desc mrdesc; + + mrdesc.mr_base = offset; + mrdesc.mr_len = size; + mrdesc.mr_flags = flags; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + return mem_range_attr_set(&mrdesc, &act); +} + +int +DRM(mtrr_del)(unsigned long offset, size_t size, int flags) +{ + int act; + struct mem_range_desc mrdesc; + + mrdesc.mr_base = offset; + mrdesc.mr_len = size; + mrdesc.mr_flags = flags; + act = MEMRANGE_SET_REMOVE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + return mem_range_attr_set(&mrdesc, &act); +} +#elif defined(__NetBSD__) +int +DRM(mtrr_add)(unsigned long offset, size_t size, int flags) +{ + struct mtrr mtrrmap; + int one = 1; + + mtrrmap.base = offset; + mtrrmap.len = size; + mtrrmap.type = flags; + mtrrmap.flags = MTRR_VALID; + return mtrr_set(&mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); +} + +int +DRM(mtrr_del)(unsigned long offset, size_t size, int flags) +{ + struct mtrr mtrrmap; + int one = 1; + + mtrrmap.base = offset; + mtrrmap.len = size; + mtrrmap.type = flags; + mtrrmap.flags = 0; + return mtrr_set(&mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); +} +#endif + #endif /* DEBUG_MEMORY */ diff --git a/sys/dev/drm/drm_memory_debug.h b/sys/dev/drm/drm_memory_debug.h index 3047f92..a627fb4 100644 --- a/sys/dev/drm/drm_memory_debug.h +++ b/sys/dev/drm/drm_memory_debug.h @@ -33,6 +33,14 @@ #include "drmP.h" +#define DRM_SYSCTL_PRINT(fmt, arg...) \ +do { \ + snprintf(buf, sizeof(buf), fmt, ##arg); \ + error = SYSCTL_OUT(req, buf, strlen(buf)); \ + if (error) \ + return error; \ +} while (0) + typedef struct drm_mem_stats { const char *name; int succeed_count; diff --git a/sys/dev/drm/drm_os_freebsd.h b/sys/dev/drm/drm_os_freebsd.h index bfcdce9..664b8f7 100644 --- a/sys/dev/drm/drm_os_freebsd.h +++ b/sys/dev/drm/drm_os_freebsd.h @@ -57,7 +57,9 @@ #include <machine/pmap.h> #include <machine/bus.h> #include <machine/resource.h> +#if __FreeBSD_version >= 480000 #include <sys/endian.h> +#endif #include <sys/mman.h> #include <sys/rman.h> #include <sys/memrange.h> @@ -81,10 +83,11 @@ #endif #ifdef __i386__ -#define __REALLY_HAVE_MTRR (__HAVE_MTRR) && (__FreeBSD_version >= 500000) +#define __REALLY_HAVE_MTRR (__HAVE_MTRR) && (__FreeBSD_version >= 460000) #else #define __REALLY_HAVE_MTRR 0 #endif + #define __REALLY_HAVE_SG (__HAVE_SG) #if __REALLY_HAVE_AGP @@ -122,15 +125,23 @@ #define DRM_SPINLOCK(l) mtx_lock(l) #define DRM_SPINUNLOCK(u) mtx_unlock(u); #define DRM_CURRENTPID curthread->td_proc->p_pid +#define DRM_LOCK() mtx_lock(&dev->dev_lock) +#define DRM_UNLOCK() mtx_unlock(&dev->dev_lock) #else +/* There is no need for locking on FreeBSD 4.x. Synchronization is handled by + * the fact that there is no reentrancy of the kernel except for interrupt + * handlers, and the interrupt handler synchronization is managed by spls. + */ #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc -#define DRM_SPINTYPE struct simplelock -#define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPINTYPE +#define DRM_SPININIT(l,name) #define DRM_SPINUNINIT(l) -#define DRM_SPINLOCK(l) simple_lock(l) -#define DRM_SPINUNLOCK(u) simple_unlock(u); +#define DRM_SPINLOCK(l) +#define DRM_SPINUNLOCK(u) #define DRM_CURRENTPID curproc->p_pid +#define DRM_LOCK() +#define DRM_UNLOCK() #endif /* Currently our DRMFILE (filp) is a void * which is actually the pid @@ -138,8 +149,6 @@ * code for that is not yet written */ #define DRMFILE void * #define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp -#define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, DRM_CURPROC) -#define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, DRM_CURPROC) #define DRM_SUSER(p) suser(p) #define DRM_TASKQUEUE_ARGS void *arg, int pending #define DRM_IRQ_ARGS void *arg @@ -164,12 +173,22 @@ typedef void irqreturn_t; #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_ERR(v) v -#define DRM_PRIV \ - drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ - if (!priv) { \ - DRM_DEBUG("can't find authenticator\n"); \ +#define DRM_MTRR_WC MDF_WRITECOMBINE + +#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) \ +do { \ + if (_filp != (DRMFILE)DRM_CURRENTPID) { \ + DRM_ERROR("filp doesn't match curproc\n"); \ return EINVAL; \ - } + } \ + DRM_LOCK(); \ + _priv = DRM(find_file_by_proc)(dev, DRM_CURPROC); \ + DRM_UNLOCK(); \ + if (_priv == NULL) { \ + DRM_ERROR("can't find authenticator\n"); \ + return EINVAL; \ + } \ +} while (0) #define LOCK_TEST_WITH_RETURN(dev, filp) \ do { \ @@ -206,12 +225,25 @@ do { \ #define DRM_HZ hz -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -while (!condition) { \ - ret = tsleep( &(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ - if ( ret ) \ - return ret; \ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +for ( ret = 0 ; !ret && !(condition) ; ) { \ + mtx_lock(&dev->irq_lock); \ + if (!(condition)) \ + ret = msleep(&(queue), &dev->irq_lock, \ + PZERO | PCATCH, "drmwtq", (timeout)); \ + mtx_unlock(&dev->irq_lock); \ +} +#else +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +for ( ret = 0 ; !ret && !(condition) ; ) { \ + int s = spldrm(); \ + if (!(condition)) \ + ret = tsleep( &(queue), PZERO | PCATCH, \ + "drmwtq", (timeout) ); \ + splx(s); \ } +#endif #define DRM_WAKEUP( queue ) wakeup( queue ) #define DRM_WAKEUP_INT( queue ) wakeup( queue ) @@ -267,16 +299,13 @@ while (!condition) { \ MALLOC_DECLARE(malloctype); #undef malloctype -typedef struct drm_chipinfo -{ - int vendor; - int device; - int supported; - char *name; -} drm_chipinfo_t; - +#if __FreeBSD_version >= 480000 #define cpu_to_le32(x) htole32(x) #define le32_to_cpu(x) le32toh(x) +#else +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#endif typedef unsigned long dma_addr_t; typedef u_int32_t atomic_t; @@ -379,17 +408,21 @@ find_first_zero_bit(volatile void *p, int max) /* Macros to make printf easier */ #define DRM_ERROR(fmt, arg...) \ - printf("error: " "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ## arg) + printf("error: [" DRM_NAME ":pid%d:%s] *ERROR* " fmt, \ + DRM_CURRENTPID, __func__ , ## arg) + #define DRM_MEM_ERROR(area, fmt, arg...) \ - printf("error: " "[" DRM_NAME ":%s:%s] *ERROR* " fmt , \ - __func__, DRM(mem_stats)[area].name , ##arg) -#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt , ## arg) + printf("error: [" DRM_NAME ":pid%d:%s:%s] *ERROR* " fmt, \ + DRM_CURRENTPID , __func__, DRM(mem_stats)[area].name , ##arg) + +#define DRM_INFO(fmt, arg...) printf("info: [" DRM_NAME "] " fmt , ## arg) #if DRM_DEBUG_CODE -#define DRM_DEBUG(fmt, arg...) \ - do { \ - if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":%s] " fmt , __func__ , ## arg); \ +#define DRM_DEBUG(fmt, arg...) \ + do { \ + if (DRM(flags) & DRM_FLAG_DEBUG) \ + printf("[" DRM_NAME ":pid%d:%s] " fmt, \ + DRM_CURRENTPID, __func__ , ## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -401,14 +434,6 @@ find_first_zero_bit(volatile void *p, int max) #define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS #endif -#define DRM_SYSCTL_PRINT(fmt, arg...) \ -do { \ - snprintf(buf, sizeof(buf), fmt, ##arg); \ - error = SYSCTL_OUT(req, buf, strlen(buf)); \ - if (error) return error; \ -} while (0) - - #define DRM_FIND_MAP(dest, o) \ do { \ drm_map_list_entry_t *listentry; \ diff --git a/sys/dev/drm/drm_pci.h b/sys/dev/drm/drm_pci.h index b853c2a..2a0569d 100644 --- a/sys/dev/drm/drm_pci.h +++ b/sys/dev/drm/drm_pci.h @@ -46,7 +46,7 @@ DRM(pci_alloc)(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr, { void *vaddr; - vaddr = contigmalloc(size, DRM(M_DRM), M_WAITOK, 0ul, maxaddr, align, + vaddr = contigmalloc(size, DRM(M_DRM), M_NOWAIT, 0ul, maxaddr, align, 0); *busaddr = vtophys(vaddr); diff --git a/sys/dev/drm/drm_sysctl.h b/sys/dev/drm/drm_sysctl.h index aae8fc0..00bf90e 100644 --- a/sys/dev/drm/drm_sysctl.h +++ b/sys/dev/drm/drm_sysctl.h @@ -1,4 +1,26 @@ -/* +/* + * Copyright 2003 Eric Anholt + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * * $FreeBSD$ */ @@ -9,7 +31,9 @@ static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS; +#if __HAVE_DMA static int DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS; +#endif struct DRM(sysctl_list) { const char *name; @@ -21,7 +45,9 @@ struct DRM(sysctl_list) { #endif { "vm", DRM(vm_info) }, { "clients", DRM(clients_info) }, +#if __HAVE_DMA { "bufs", DRM(bufs_info) }, +#endif }; #define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0])) @@ -92,90 +118,128 @@ int DRM(sysctl_cleanup)(drm_device_t *dev) return error; } +#define DRM_SYSCTL_PRINT(fmt, arg...) \ +do { \ + snprintf(buf, sizeof(buf), fmt, ##arg); \ + retcode = SYSCTL_OUT(req, buf, strlen(buf)); \ + if (retcode) \ + goto done; \ +} while (0) + static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; char buf[128]; - int error; + int retcode; + int hasunique = 0; + DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode)); + + DRM_LOCK(); if (dev->unique) { - DRM_SYSCTL_PRINT("%s 0x%x %s", - dev->name, dev2udev(dev->devnode), dev->unique); - } else { - DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode)); + snprintf(buf, sizeof(buf), " %s", dev->unique); + hasunique = 1; } + DRM_UNLOCK(); + + if (hasunique) + SYSCTL_OUT(req, buf, strlen(buf)); SYSCTL_OUT(req, "", 1); - return 0; +done: + return retcode; } -static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS +static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; - drm_local_map_t *map; + drm_local_map_t *map, *tempmaps; drm_map_list_entry_t *listentry; const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" }; - const char *type; - int i=0; - char buf[128]; - int error; + const char *type, *yesno; + int i, mapcount; + char buf[128]; + int retcode; - DRM_SYSCTL_PRINT("\nslot offset size type flags " - "address mtrr\n"); + /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a + * temporary copy of all the map entries and then SYSCTL_OUT that. + */ + DRM_LOCK(); + + mapcount = 0; + TAILQ_FOREACH(listentry, dev->maplist, link) + mapcount++; - if (dev->maplist != NULL) { - TAILQ_FOREACH(listentry, dev->maplist, link) { - map = listentry->map; - if (map->type < 0 || map->type > 4) - type = "??"; - else - type = types[map->type]; - DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", - i, - map->offset, - map->size, - type, - map->flags, - (unsigned long)map->handle); - if (map->mtrr < 0) { - DRM_SYSCTL_PRINT("no\n"); - } else { - DRM_SYSCTL_PRINT("yes\n"); - } - i++; - } + tempmaps = DRM(alloc)(sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS); + if (tempmaps == NULL) { + DRM_UNLOCK(); + return ENOMEM; } - SYSCTL_OUT(req, "", 1); - return 0; -} + i = 0; + TAILQ_FOREACH(listentry, dev->maplist, link) + tempmaps[i++] = *listentry->map; -static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - int ret; + DRM_UNLOCK(); - DRM_LOCK; - ret = DRM(_vm_info)(oidp, arg1, arg2, req); - DRM_UNLOCK; + DRM_SYSCTL_PRINT("\nslot offset size type flags " + "address mtrr\n"); - return ret; -} + for (i = 0; i < mapcount; i++) { + map = &tempmaps[i]; + if (map->type < 0 || map->type > 4) + type = "??"; + else + type = types[map->type]; -/* drm_bufs_info is called whenever a process reads - hw.dri.0.bufs. */ + if (map->mtrr <= 0) + yesno = "no"; + else + yesno = "yes"; + + DRM_SYSCTL_PRINT( + "%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx %s\n", i, + map->offset, map->size, type, map->flags, + (unsigned long)map->handle, yesno); + } + SYSCTL_OUT(req, "", 1); -static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS +done: + DRM(free)(tempmaps, sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS); + return retcode; +} + +#if __HAVE_DMA +static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; drm_device_dma_t *dma = dev->dma; - int i; - char buf[128]; - int error; + drm_device_dma_t tempdma; + int *templists; + int i; + char buf[128]; + int retcode; + + /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary + * copy of the whole structure and the relevant data from buflist. + */ + DRM_LOCK(); + DRM_SPINLOCK(&dev->dma_lock); + if (dma == NULL) { + DRM_SPINUNLOCK(&dev->dma_lock); + DRM_UNLOCK(); + return 0; + } + tempdma = *dma; + templists = DRM(alloc)(sizeof(int) * dma->buf_count, DRM_MEM_BUFS); + for (i = 0; i < dma->buf_count; i++) + templists[i] = dma->buflist[i]->list; + dma = &tempdma; + DRM_SPINUNLOCK(&dev->dma_lock); + DRM_UNLOCK(); - if (!dma) return 0; DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n"); for (i = 0; i <= DRM_MAX_ORDER; i++) { if (dma->bufs[i].buf_count) @@ -195,35 +259,45 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS DRM_SYSCTL_PRINT("\n"); for (i = 0; i < dma->buf_count; i++) { if (i && !(i%32)) DRM_SYSCTL_PRINT("\n"); - DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list); + DRM_SYSCTL_PRINT(" %d", templists[i]); } DRM_SYSCTL_PRINT("\n"); SYSCTL_OUT(req, "", 1); - return 0; +done: + DRM(free)(templists, sizeof(int) * dma->buf_count, DRM_MEM_BUFS); + return retcode; } +#endif -static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS +static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; - int ret; + drm_file_t *priv, *tempprivs; + char buf[128]; + int retcode; + int privcount, i; - DRM_LOCK; - ret = DRM(_bufs_info)(oidp, arg1, arg2, req); - DRM_UNLOCK; - return ret; -} + DRM_LOCK(); + privcount = 0; + TAILQ_FOREACH(priv, &dev->files, link) + privcount++; -static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - drm_file_t *priv; - char buf[128]; - int error; + tempprivs = DRM(alloc)(sizeof(drm_file_t) * privcount, DRM_MEM_FILES); + if (tempprivs == NULL) { + DRM_UNLOCK(); + return ENOMEM; + } + i = 0; + TAILQ_FOREACH(priv, &dev->files, link) + tempprivs[i++] = *priv; + + DRM_UNLOCK(); DRM_SYSCTL_PRINT("\na dev pid uid magic ioctls\n"); - TAILQ_FOREACH(priv, &dev->files, link) { + for (i = 0; i < privcount; i++) { + priv = &tempprivs[i]; DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n", priv->authenticated ? 'y' : 'n', priv->minor, @@ -234,21 +308,11 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS } SYSCTL_OUT(req, "", 1); - return 0; -} - -static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - int ret; - - DRM_LOCK; - ret = DRM(_clients_info)(oidp, arg1, arg2, req); - DRM_UNLOCK; - return ret; +done: + DRM(free)(tempprivs, sizeof(drm_file_t) * privcount, DRM_MEM_FILES); + return retcode; } - #elif defined(__NetBSD__) /* stub it out for now, sysctl is only for debugging */ int DRM(sysctl_init)(drm_device_t *dev) diff --git a/sys/dev/drm/drm_vm.h b/sys/dev/drm/drm_vm.h index d50f3a7..9d3bb98 100644 --- a/sys/dev/drm/drm_vm.h +++ b/sys/dev/drm/drm_vm.h @@ -1,4 +1,27 @@ -/* +/* + * Copyright 2003 Eric Anholt + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * * $FreeBSD$ */ @@ -12,12 +35,12 @@ static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) #endif { DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; - unsigned long physical; - unsigned long page; + drm_device_dma_t *dma = dev->dma; + unsigned long physical; + unsigned long page; - if (!dma) return -1; /* Error */ - if (!dma->pagelist) return -1; /* Nothing allocated */ + if (dma == NULL || dma->pagelist == NULL) + return -1; page = offset >> PAGE_SHIFT; physical = dma->pagelist[page]; @@ -41,15 +64,11 @@ 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 = NULL; + drm_map_list_entry_t *listentry = NULL; drm_file_t *priv; - priv = DRM(find_file_by_proc)(dev, DRM_CURPROC); - if (!priv) { - DRM_DEBUG("can't find authenticator\n"); - return EINVAL; - } + DRM_GET_PRIV_WITH_RETURN(priv, (DRMFILE)DRM_CURRENTPID); if (!priv->authenticated) return DRM_ERR(EACCES); diff --git a/sys/dev/drm/mga.h b/sys/dev/drm/mga.h index 5a4bec9..a9dd031 100644 --- a/sys/dev/drm/mga.h +++ b/sys/dev/drm/mga.h @@ -66,6 +66,12 @@ [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_GETPARAM)]= { mga_getparam, 1, 0 }, +#define DRIVER_PCI_IDS \ + {0x102b, 0x0521, 0, "Matrox G200 (AGP)"}, \ + {0x102b, 0x0525, 0, "Matrox G400/G450 (AGP)"}, \ + {0x102b, 0x2527, 0, "Matrox G550 (AGP)"}, \ + {0, 0, 0, NULL} + #define __HAVE_COUNTERS 3 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY @@ -80,7 +86,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 diff --git a/sys/dev/drm/mga_dma.c b/sys/dev/drm/mga_dma.c index 45e6406..6745d65 100644 --- a/sys/dev/drm/mga_dma.c +++ b/sys/dev/drm/mga_dma.c @@ -641,7 +641,7 @@ int mga_do_cleanup_dma( drm_device_t *dev ) { DRM_DEBUG( "\n" ); -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. diff --git a/sys/dev/drm/mga_drv.c b/sys/dev/drm/mga_drv.c index e4850af..cbec299 100644 --- a/sys/dev/drm/mga_drv.c +++ b/sys/dev/drm/mga_drv.c @@ -37,17 +37,6 @@ #include "dev/drm/mga_drm.h" #include "dev/drm/mga_drv.h" -/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h - * Please report to anholt@teleport.com inaccuracies or if a chip you have works that is marked unsupported here. - */ -drm_chipinfo_t DRM(devicelist)[] = { - {0x102b, 0x0520, 0, "Matrox G200 (PCI)"}, - {0x102b, 0x0521, 1, "Matrox G200 (AGP)"}, - {0x102b, 0x0525, 1, "Matrox G400/G450 (AGP)"}, - {0x102b, 0x2527, 1, "Matrox G550 (AGP)"}, - {0, 0, 0, NULL} -}; - #include "dev/drm/drm_agpsupport.h" #include "dev/drm/drm_auth.h" #include "dev/drm/drm_bufs.h" @@ -57,6 +46,7 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "dev/drm/drm_drv.h" #include "dev/drm/drm_fops.h" #include "dev/drm/drm_ioctl.h" +#include "dev/drm/drm_irq.h" #include "dev/drm/drm_lock.h" #include "dev/drm/drm_memory.h" #include "dev/drm/drm_vm.h" diff --git a/sys/dev/drm/mga_irq.c b/sys/dev/drm/mga_irq.c index 1f8f2c8..1c9a93f 100644 --- a/sys/dev/drm/mga_irq.c +++ b/sys/dev/drm/mga_irq.c @@ -38,7 +38,7 @@ #include "dev/drm/mga_drm.h" #include "dev/drm/mga_drv.h" -irqreturn_t mga_dma_service( DRM_IRQ_ARGS ) +irqreturn_t mga_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_mga_private_t *dev_priv = diff --git a/sys/dev/drm/r128.h b/sys/dev/drm/r128.h index 6d616d5..c94e329 100644 --- a/sys/dev/drm/r128.h +++ b/sys/dev/drm/r128.h @@ -81,6 +81,26 @@ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_GETPARAM)] = { r128_getparam, 1, 0 }, +#define DRIVER_PCI_IDS \ + {0x1002, 0x4c45, 0, "ATI Rage 128 Mobility LE (PCI)"}, \ + {0x1002, 0x4c46, 0, "ATI Rage 128 Mobility LF (AGP)"}, \ + {0x1002, 0x4d46, 0, "ATI Rage 128 Mobility MF (AGP)"}, \ + {0x1002, 0x4d4c, 0, "ATI Rage 128 Mobility ML (AGP)"}, \ + {0x1002, 0x5044, 0, "ATI Rage 128 Pro PD (PCI)"}, \ + {0x1002, 0x5046, 0, "ATI Rage 128 Pro PF (AGP)"}, \ + {0x1002, 0x5050, 0, "ATI Rage 128 Pro PP (PCI)"}, \ + {0x1002, 0x5052, 0, "ATI Rage 128 Pro PR (PCI)"}, \ + {0x1002, 0x5245, 0, "ATI Rage 128 RE (PCI)"}, \ + {0x1002, 0x5246, 0, "ATI Rage 128 RF (AGP)"}, \ + {0x1002, 0x5247, 0, "ATI Rage 128 RG (AGP)"}, \ + {0x1002, 0x524b, 0, "ATI Rage 128 RK (PCI)"}, \ + {0x1002, 0x524c, 0, "ATI Rage 128 RL (AGP)"}, \ + {0x1002, 0x534d, 0, "ATI Rage 128 SM (AGP)"}, \ + {0x1002, 0x5446, 0, "ATI Rage 128 Pro Ultra TF (AGP)"}, \ + {0x1002, 0x544C, 0, "ATI Rage 128 Pro Ultra TL (AGP)"}, \ + {0x1002, 0x5452, 0, "ATI Rage 128 Pro Ultra TR (AGP)"}, \ + {0, 0, 0, NULL} + /* Driver customization: */ #define DRIVER_PRERELEASE() do { \ @@ -99,7 +119,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 diff --git a/sys/dev/drm/r128_cce.c b/sys/dev/drm/r128_cce.c index bec4e23..87c4d81 100644 --- a/sys/dev/drm/r128_cce.c +++ b/sys/dev/drm/r128_cce.c @@ -214,7 +214,7 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv ) int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) { + if ( GET_RING_HEAD( dev_priv ) == dev_priv->ring.tail ) { int pm4stat = R128_READ( R128_PM4_STAT ); if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size ) && @@ -240,7 +240,8 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv ) r128_do_wait_for_idle( dev_priv ); R128_WRITE( R128_PM4_BUFFER_CNTL, - dev_priv->cce_mode | dev_priv->ring.size_l2qw ); + dev_priv->cce_mode | dev_priv->ring.size_l2qw + | R128_PM4_BUFFER_CNTL_NOUPDATE ); R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */ R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN ); @@ -255,7 +256,6 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) { R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); - SET_RING_HEAD( &dev_priv->ring, 0 ); dev_priv->ring.tail = 0; } @@ -266,7 +266,8 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) static void r128_do_cce_stop( drm_r128_private_t *dev_priv ) { R128_WRITE( R128_PM4_MICRO_CNTL, 0 ); - R128_WRITE( R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4 ); + R128_WRITE( R128_PM4_BUFFER_CNTL, + R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE ); dev_priv->cce_running = 0; } @@ -335,26 +336,6 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev, R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); - /* DL_RPTR_ADDR is a physical address in AGP space. */ - SET_RING_HEAD( &dev_priv->ring, 0 ); - - if ( !dev_priv->is_pci ) { - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - dev_priv->ring_rptr->offset ); - } else { - drm_sg_mem_t *entry = dev->sg; - unsigned long tmp_ofs, page_ofs; - - tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; - page_ofs = tmp_ofs >> PAGE_SHIFT; - - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", - (unsigned long) entry->busaddr[page_ofs], - entry->handle + tmp_ofs ); - } - /* Set watermark control */ R128_WRITE( R128_PM4_BUFFER_WM_CNTL, ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) @@ -569,9 +550,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) #endif dev_priv->cce_buffers_offset = dev->sg->handle; - dev_priv->ring.head = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle); - dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle + init->ring_size / sizeof(u32)); @@ -582,7 +560,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = 128; - dev_priv->ring.ring_rptr = dev_priv->ring_rptr; dev_priv->sarea_priv->last_frame = 0; R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); @@ -591,8 +568,9 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) R128_WRITE( R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch ); -#if __REALLY_HAVE_SG +#if __REALLY_HAVE_AGP if ( dev_priv->is_pci ) { +#endif if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart) ) { DRM_ERROR( "failed to init PCI GART!\n" ); @@ -601,6 +579,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) return DRM_ERR(ENOMEM); } R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); +#if __REALLY_HAVE_AGP } #endif @@ -617,7 +596,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) int r128_do_cleanup_cce( drm_device_t *dev ) { -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. @@ -903,7 +882,7 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - r128_update_ring_snapshot( ring ); + r128_update_ring_snapshot( dev_priv ); if ( ring->space >= n ) return 0; DRM_UDELAY( 1 ); diff --git a/sys/dev/drm/r128_drv.c b/sys/dev/drm/r128_drv.c index b2d6fbc..b9df5ec 100644 --- a/sys/dev/drm/r128_drv.c +++ b/sys/dev/drm/r128_drv.c @@ -40,30 +40,6 @@ #include "dev/drm/ati_pcigart.h" #endif -/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h - * Please report to eta@lclark.edu inaccuracies or if a chip you have works that is marked unsupported here. - */ -drm_chipinfo_t DRM(devicelist)[] = { - {0x1002, 0x4c45, __REALLY_HAVE_SG, "ATI Rage 128 Mobility LE (PCI)"}, - {0x1002, 0x4c46, 1, "ATI Rage 128 Mobility LF (AGP)"}, - {0x1002, 0x4d46, 1, "ATI Rage 128 Mobility MF (AGP)"}, - {0x1002, 0x4d4c, 1, "ATI Rage 128 Mobility ML (AGP)"}, - {0x1002, 0x5044, __REALLY_HAVE_SG, "ATI Rage 128 Pro PD (PCI)"}, - {0x1002, 0x5046, 1, "ATI Rage 128 Pro PF (AGP)"}, - {0x1002, 0x5050, __REALLY_HAVE_SG, "ATI Rage 128 Pro PP (PCI)"}, - {0x1002, 0x5052, __REALLY_HAVE_SG, "ATI Rage 128 Pro PR (PCI)"}, - {0x1002, 0x5245, __REALLY_HAVE_SG, "ATI Rage 128 RE (PCI)"}, - {0x1002, 0x5246, 1, "ATI Rage 128 RF (AGP)"}, - {0x1002, 0x5247, 1, "ATI Rage 128 RG (AGP)"}, - {0x1002, 0x524b, __REALLY_HAVE_SG, "ATI Rage 128 RK (PCI)"}, - {0x1002, 0x524c, 1, "ATI Rage 128 RL (AGP)"}, - {0x1002, 0x534d, 1, "ATI Rage 128 SM (AGP)"}, - {0x1002, 0x5446, 1, "ATI Rage 128 Pro Ultra TF (AGP)"}, - {0x1002, 0x544C, 1, "ATI Rage 128 Pro Ultra TL (AGP)"}, - {0x1002, 0x5452, 1, "ATI Rage 128 Pro Ultra TR (AGP)"}, - {0, 0, 0, NULL} -}; - #include "dev/drm/drm_agpsupport.h" #include "dev/drm/drm_auth.h" #include "dev/drm/drm_bufs.h" @@ -73,6 +49,7 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "dev/drm/drm_drv.h" #include "dev/drm/drm_fops.h" #include "dev/drm/drm_ioctl.h" +#include "dev/drm/drm_irq.h" #include "dev/drm/drm_lock.h" #include "dev/drm/drm_memory.h" #include "dev/drm/drm_pci.h" diff --git a/sys/dev/drm/r128_drv.h b/sys/dev/drm/r128_drv.h index 14118ff..e465dc5 100644 --- a/sys/dev/drm/r128_drv.h +++ b/sys/dev/drm/r128_drv.h @@ -36,8 +36,7 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ -#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */ -#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */ +#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) typedef struct drm_r128_freelist { unsigned int age; @@ -52,13 +51,11 @@ typedef struct drm_r128_ring_buffer { int size; int size_l2qw; - volatile u32 *head; u32 tail; u32 tail_mask; int space; int high_mark; - drm_local_map_t *ring_rptr; } drm_r128_ring_buffer_t; typedef struct drm_r128_private { @@ -134,14 +131,6 @@ extern drm_buf_t *r128_freelist_get( drm_device_t *dev ); extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n ); -static __inline__ void -r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring ) -{ - ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32); - if ( ring->space <= 0 ) - ring->space += ring->size; -} - extern int r128_do_cce_idle( drm_r128_private_t *dev_priv ); extern int r128_do_cleanup_cce( drm_device_t *dev ); extern int r128_do_cleanup_pageflip( drm_device_t *dev ); @@ -281,6 +270,7 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS ); # define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) # define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) # define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) +# define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27) #define R128_PM4_BUFFER_WM_CNTL 0x0708 # define R128_WMA_SHIFT 0 @@ -405,6 +395,15 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); (pkt) | ((n) << 16)) +static __inline__ void +r128_update_ring_snapshot( drm_r128_private_t *dev_priv ) +{ + drm_r128_ring_buffer_t *ring = &dev_priv->ring; + ring->space = (GET_RING_HEAD( dev_priv ) - ring->tail) * sizeof(u32); + if ( ring->space <= 0 ) + ring->space += ring->size; +} + /* ================================================================ * Misc helper macros */ @@ -414,7 +413,7 @@ do { \ drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ if ( ring->space < ring->high_mark ) { \ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ - r128_update_ring_snapshot( ring ); \ + r128_update_ring_snapshot( dev_priv ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ DRM_UDELAY(1); \ @@ -447,17 +446,10 @@ do { \ * Ring control */ -#if defined(__powerpc__) -#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) -#else -#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER() -#endif - - #define R128_VERBOSE 0 #define RING_LOCALS \ - int write; unsigned int tail_mask; volatile u32 *ring; + int write, _nr; unsigned int tail_mask; volatile u32 *ring; #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ @@ -465,9 +457,10 @@ do { \ (n), __FUNCTION__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + COMMIT_RING(); \ r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ - dev_priv->ring.space -= (n) * sizeof(u32); \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ tail_mask = dev_priv->ring.tail_mask; \ @@ -490,9 +483,23 @@ do { \ dev_priv->ring.start, \ write * sizeof(u32) ); \ } \ - r128_flush_write_combine(); \ - dev_priv->ring.tail = write; \ - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \ + if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ + ((dev_priv->ring.tail + _nr) & tail_mask), \ + write, __LINE__); \ + } else \ + dev_priv->ring.tail = write; \ +} while (0) + +#define COMMIT_RING() do { \ + if ( R128_VERBOSE ) { \ + DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \ + dev_priv->ring.tail ); \ + } \ + DRM_MEMORYBARRIER(); \ + R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \ + R128_READ( R128_PM4_BUFFER_DL_WPTR ); \ } while (0) #define OUT_RING( x ) do { \ diff --git a/sys/dev/drm/r128_irq.c b/sys/dev/drm/r128_irq.c index df82942..2da58d6 100644 --- a/sys/dev/drm/r128_irq.c +++ b/sys/dev/drm/r128_irq.c @@ -38,7 +38,7 @@ #include "dev/drm/r128_drm.h" #include "dev/drm/r128_drv.h" -irqreturn_t r128_dma_service( DRM_IRQ_ARGS ) +irqreturn_t r128_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_r128_private_t *dev_priv = diff --git a/sys/dev/drm/r128_state.c b/sys/dev/drm/r128_state.c index b7b05e2..9481d3c 100644 --- a/sys/dev/drm/r128_state.c +++ b/sys/dev/drm/r128_state.c @@ -47,7 +47,7 @@ static void r128_emit_clip_rects( drm_r128_private_t *dev_priv, RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 17 ); + BEGIN_RING( (count < 3? count: 3) * 5 + 2 ); if ( count >= 1 ) { OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) ); @@ -1271,6 +1271,7 @@ int r128_cce_clear( DRM_IOCTL_ARGS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; r128_cce_dispatch_clear( dev, &clear ); + COMMIT_RING(); /* Make sure we restore the 3D state next time. */ @@ -1306,8 +1307,10 @@ int r128_do_cleanup_pageflip( drm_device_t *dev ) R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); - if (dev_priv->current_page != 0) + if (dev_priv->current_page != 0) { r128_cce_dispatch_flip( dev ); + COMMIT_RING(); + } dev_priv->page_flipping = 0; return 0; @@ -1332,6 +1335,7 @@ int r128_cce_flip( DRM_IOCTL_ARGS ) r128_cce_dispatch_flip( dev ); + COMMIT_RING(); return 0; } @@ -1353,6 +1357,7 @@ int r128_cce_swap( DRM_IOCTL_ARGS ) dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS); + COMMIT_RING(); return 0; } @@ -1412,6 +1417,7 @@ int r128_cce_vertex( DRM_IOCTL_ARGS ) r128_cce_dispatch_vertex( dev, buf ); + COMMIT_RING(); return 0; } @@ -1483,6 +1489,7 @@ int r128_cce_indices( DRM_IOCTL_ARGS ) r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); + COMMIT_RING(); return 0; } @@ -1492,6 +1499,7 @@ int r128_cce_blit( DRM_IOCTL_ARGS ) drm_device_dma_t *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; + int ret; LOCK_TEST_WITH_RETURN( dev, filp ); @@ -1509,7 +1517,10 @@ int r128_cce_blit( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return r128_cce_dispatch_blit( filp, dev, &blit ); + ret = r128_cce_dispatch_blit( filp, dev, &blit ); + + COMMIT_RING(); + return ret; } int r128_cce_depth( DRM_IOCTL_ARGS ) @@ -1517,6 +1528,7 @@ int r128_cce_depth( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; + int ret; LOCK_TEST_WITH_RETURN( dev, filp ); @@ -1525,18 +1537,20 @@ int r128_cce_depth( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); + ret = DRM_ERR(EINVAL); switch ( depth.func ) { case R128_WRITE_SPAN: - return r128_cce_dispatch_write_span( dev, &depth ); + ret = r128_cce_dispatch_write_span( dev, &depth ); case R128_WRITE_PIXELS: - return r128_cce_dispatch_write_pixels( dev, &depth ); + ret = r128_cce_dispatch_write_pixels( dev, &depth ); case R128_READ_SPAN: - return r128_cce_dispatch_read_span( dev, &depth ); + ret = r128_cce_dispatch_read_span( dev, &depth ); case R128_READ_PIXELS: - return r128_cce_dispatch_read_pixels( dev, &depth ); + ret = r128_cce_dispatch_read_pixels( dev, &depth ); } - return DRM_ERR(EINVAL); + COMMIT_RING(); + return ret; } int r128_cce_stipple( DRM_IOCTL_ARGS ) @@ -1559,6 +1573,7 @@ int r128_cce_stipple( DRM_IOCTL_ARGS ) r128_cce_dispatch_stipple( dev, mask ); + COMMIT_RING(); return 0; } @@ -1634,6 +1649,7 @@ int r128_cce_indirect( DRM_IOCTL_ARGS ) */ r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + COMMIT_RING(); return 0; } diff --git a/sys/dev/drm/radeon.h b/sys/dev/drm/radeon.h index 99c6d8a..3dbf9a1 100644 --- a/sys/dev/drm/radeon.h +++ b/sys/dev/drm/radeon.h @@ -111,6 +111,43 @@ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, +#define DRIVER_PCI_IDS \ + {0x1002, 0x4242, 0, "ATI Radeon BB R200 AIW 8500DV"}, \ + {0x1002, 0x4964, 0, "ATI Radeon Id R250 9000"}, \ + {0x1002, 0x4965, 0, "ATI Radeon Ie R250 9000"}, \ + {0x1002, 0x4966, 0, "ATI Radeon If R250 9000"}, \ + {0x1002, 0x4967, 0, "ATI Radeon Ig R250 9000"}, \ + {0x1002, 0x4C57, 0, "ATI Radeon LW Mobility 7500 M7"}, \ + {0x1002, 0x4C58, 0, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"}, \ + {0x1002, 0x4C59, 0, "ATI Radeon LY Mobility M6"}, \ + {0x1002, 0x4C5A, 0, "ATI Radeon LZ Mobility M6"}, \ + {0x1002, 0x4C64, 0, "ATI Radeon Ld R250 Mobility 9000 M9"}, \ + {0x1002, 0x4C65, 0, "ATI Radeon Le R250 Mobility 9000 M9"}, \ + {0x1002, 0x4C66, 0, "ATI Radeon Lf R250 Mobility 9000 M9"}, \ + {0x1002, 0x4C67, 0, "ATI Radeon Lg R250 Mobility 9000 M9"}, \ + {0x1002, 0x5144, 0, "ATI Radeon QD R100"}, \ + {0x1002, 0x5145, 0, "ATI Radeon QE R100"}, \ + {0x1002, 0x5146, 0, "ATI Radeon QF R100"}, \ + {0x1002, 0x5147, 0, "ATI Radeon QG R100"}, \ + {0x1002, 0x5148, 0, "ATI Radeon QH R200 8500"}, \ + {0x1002, 0x5149, 0, "ATI Radeon QI R200"}, \ + {0x1002, 0x514A, 0, "ATI Radeon QJ R200"}, \ + {0x1002, 0x514B, 0, "ATI Radeon QK R200"}, \ + {0x1002, 0x514C, 0, "ATI Radeon QL R200 8500 LE"}, \ + {0x1002, 0x514D, 0, "ATI Radeon QM R200 9100"}, \ + {0x1002, 0x514E, 0, "ATI Radeon QN R200 8500 LE"}, \ + {0x1002, 0x514F, 0, "ATI Radeon QO R200 8500 LE"}, \ + {0x1002, 0x5157, 0, "ATI Radeon QW RV200 7500"}, \ + {0x1002, 0x5158, 0, "ATI Radeon QX RV200 7500"}, \ + {0x1002, 0x5159, 0, "ATI Radeon QY RV100 7000/VE"}, \ + {0x1002, 0x515A, 0, "ATI Radeon QZ RV100 7000/VE"}, \ + {0x1002, 0x5168, 0, "ATI Radeon Qh R200"}, \ + {0x1002, 0x5169, 0, "ATI Radeon Qi R200"}, \ + {0x1002, 0x516A, 0, "ATI Radeon Qj R200"}, \ + {0x1002, 0x516B, 0, "ATI Radeon Qk R200"}, \ + {0x1002, 0x516C, 0, "ATI Radeon Ql R200"}, \ + {0x1002, 0x5961, 0, "ATI Radeon RV280 9200"}, \ + {0, 0, 0, NULL} /* When a client dies: @@ -126,8 +163,8 @@ do { \ if ( dev_priv->page_flipping ) { \ radeon_do_cleanup_pageflip( dev ); \ } \ - radeon_mem_release( filp, dev_priv->gart_heap ); \ - radeon_mem_release( filp, dev_priv->fb_heap ); \ + radeon_mem_release( filp, dev_priv->gart_heap ); \ + radeon_mem_release( filp, dev_priv->fb_heap ); \ } \ } while (0) @@ -144,7 +181,7 @@ do { \ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 diff --git a/sys/dev/drm/radeon_cp.c b/sys/dev/drm/radeon_cp.c index 7fb205d..b134f95 100644 --- a/sys/dev/drm/radeon_cp.c +++ b/sys/dev/drm/radeon_cp.c @@ -1273,7 +1273,7 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) { DRM_DEBUG( "\n" ); -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. diff --git a/sys/dev/drm/radeon_drv.c b/sys/dev/drm/radeon_drv.c index c8f23c4..3541675 100644 --- a/sys/dev/drm/radeon_drv.c +++ b/sys/dev/drm/radeon_drv.c @@ -38,45 +38,6 @@ #include "dev/drm/ati_pcigart.h" #endif -drm_chipinfo_t DRM(devicelist)[] = { - {0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"}, - {0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"}, - {0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"}, - {0x1002, 0x4966, 1, "ATI Radeon If R250 9000"}, - {0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"}, - {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"}, - {0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"}, - {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"}, - {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"}, - {0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"}, - {0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"}, - {0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"}, - {0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"}, - {0x1002, 0x5144, 1, "ATI Radeon QD R100"}, - {0x1002, 0x5145, 1, "ATI Radeon QE R100"}, - {0x1002, 0x5146, 1, "ATI Radeon QF R100"}, - {0x1002, 0x5147, 1, "ATI Radeon QG R100"}, - {0x1002, 0x5148, 1, "ATI Radeon QH R200 8500"}, - {0x1002, 0x5149, 1, "ATI Radeon QI R200"}, - {0x1002, 0x514A, 1, "ATI Radeon QJ R200"}, - {0x1002, 0x514B, 1, "ATI Radeon QK R200"}, - {0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"}, - {0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"}, - {0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"}, - {0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"}, - {0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"}, - {0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"}, - {0x1002, 0x5159, 1, "ATI Radeon QY RV100 7000/VE"}, - {0x1002, 0x515A, 1, "ATI Radeon QZ RV100 7000/VE"}, - {0x1002, 0x5168, 1, "ATI Radeon Qh R200"}, - {0x1002, 0x5169, 1, "ATI Radeon Qi R200"}, - {0x1002, 0x516A, 1, "ATI Radeon Qj R200"}, - {0x1002, 0x516B, 1, "ATI Radeon Qk R200"}, - {0x1002, 0x516C, 1, "ATI Radeon Ql R200"}, - {0x1002, 0x5961, 1, "ATI Radeon RV280 9200"}, - {0, 0, 0, NULL} -}; - #include "dev/drm/drm_agpsupport.h" #include "dev/drm/drm_auth.h" #include "dev/drm/drm_bufs.h" @@ -86,6 +47,7 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "dev/drm/drm_drv.h" #include "dev/drm/drm_fops.h" #include "dev/drm/drm_ioctl.h" +#include "dev/drm/drm_irq.h" #include "dev/drm/drm_lock.h" #include "dev/drm/drm_memory.h" #include "dev/drm/drm_pci.h" diff --git a/sys/dev/drm/radeon_irq.c b/sys/dev/drm/radeon_irq.c index bd35bf4..636653c 100644 --- a/sys/dev/drm/radeon_irq.c +++ b/sys/dev/drm/radeon_irq.c @@ -56,7 +56,7 @@ * tied to dma at all, this is just a hangover from dri prehistory. */ -irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ) +irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_radeon_private_t *dev_priv = diff --git a/sys/dev/drm/sis.h b/sys/dev/drm/sis.h index 23fc413..59a439f 100644 --- a/sys/dev/drm/sis.h +++ b/sys/dev/drm/sis.h @@ -63,6 +63,13 @@ [DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_INIT)] = { sis_fb_init, 1, 1 } +#define DRIVER_PCI_IDS \ + {0x1039, 0x0300, 0, "SiS 300/305"}, \ + {0x1039, 0x5300, 0, "SiS 540"}, \ + {0x1039, 0x6300, 0, "SiS 630"}, \ + {0x1039, 0x7300, 0, "SiS 730"}, \ + {0, 0, 0, NULL} + #define __HAVE_COUNTERS 5 /* Buffer customization: diff --git a/sys/dev/drm/sis_drv.c b/sys/dev/drm/sis_drv.c index fdf0f16..c6aae19 100644 --- a/sys/dev/drm/sis_drv.c +++ b/sys/dev/drm/sis_drv.c @@ -31,13 +31,6 @@ #include "dev/drm/sis_drm.h" #include "dev/drm/sis_drv.h" -drm_chipinfo_t DRM(devicelist)[] = { - {0x1039, 0x0300, 1, "SiS 300"}, - {0x1039, 0x5300, 1, "SiS 540"}, - {0x1039, 0x6300, 1, "SiS 630"}, - {0, 0, 0, NULL} -}; - #include "dev/drm/drm_auth.h" #include "dev/drm/drm_agpsupport.h" #include "dev/drm/drm_bufs.h" diff --git a/sys/dev/drm/sis_mm.c b/sys/dev/drm/sis_mm.c index 7065b95..26c5905 100644 --- a/sys/dev/drm/sis_mm.c +++ b/sys/dev/drm/sis_mm.c @@ -133,7 +133,7 @@ int sis_fb_free( DRM_IOCTL_ARGS ) retval = DRM_ERR(EINVAL); sis_free(fb.free); - DRM_DEBUG("free fb, offset = %d\n", fb.free); + DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free); return retval; } diff --git a/sys/dev/drm/tdfx.h b/sys/dev/drm/tdfx.h index 39333ea..f9b91a9 100644 --- a/sys/dev/drm/tdfx.h +++ b/sys/dev/drm/tdfx.h @@ -41,4 +41,22 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "tdfx" +#define DRIVER_DESC "3dfx Banshee/Voodoo3+" +#define DRIVER_DATE "20010216" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_PCI_IDS \ + {0x121a, 0x0003, 0, "3dfx Voodoo Banshee"}, \ + {0x121a, 0x0004, 0, "3dfx Voodoo3 2000"}, \ + {0x121a, 0x0005, 0, "3dfx Voodoo3 3000"}, \ + {0x121a, 0x0007, 0, "3dfx Voodoo4"}, \ + {0x121a, 0x0009, 0, "3dfx Voodoo5"}, \ + {0, 0, 0, NULL} + #endif diff --git a/sys/dev/drm/tdfx_drv.c b/sys/dev/drm/tdfx_drv.c index 6552773..93083fd 100644 --- a/sys/dev/drm/tdfx_drv.c +++ b/sys/dev/drm/tdfx_drv.c @@ -35,56 +35,12 @@ #include "dev/drm/tdfx.h" #include "dev/drm/drmP.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "tdfx" -#define DRIVER_DESC "3dfx Banshee/Voodoo3+" -#define DRIVER_DATE "20010216" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#ifndef PCI_VENDOR_ID_3DFX -#define PCI_VENDOR_ID_3DFX 0x121A -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO5 -#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO4 -#define PCI_DEVICE_ID_3DFX_VOODOO4 0x0007 -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_3000 /* Voodoo3 3000 */ -#define PCI_DEVICE_ID_3DFX_VOODOO3_3000 0x0005 -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_2000 /* Voodoo3 3000 */ -#define PCI_DEVICE_ID_3DFX_VOODOO3_2000 0x0004 -#endif -#ifndef PCI_DEVICE_ID_3DFX_BANSHEE -#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 -#endif - -/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h - * Please report to anholt@teleport.com inaccuracies or if a chip you have works that is marked unsupported here. - */ -drm_chipinfo_t DRM(devicelist)[] = { - {0x121a, 0x0003, 1, "3dfx Voodoo Banshee"}, - {0x121a, 0x0004, 1, "3dfx Voodoo3 2000"}, - {0x121a, 0x0005, 1, "3dfx Voodoo3 3000"}, - {0x121a, 0x0007, 1, "3dfx Voodoo4"}, - {0x121a, 0x0009, 1, "3dfx Voodoo5"}, - {0, 0, 0, NULL} -}; - - #include "dev/drm/drm_auth.h" #include "dev/drm/drm_bufs.h" #include "dev/drm/drm_context.h" #include "dev/drm/drm_dma.h" #include "dev/drm/drm_drawable.h" #include "dev/drm/drm_drv.h" - - #include "dev/drm/drm_fops.h" #include "dev/drm/drm_ioctl.h" #include "dev/drm/drm_lock.h" |