diff options
Diffstat (limited to 'sys/dev/drm')
36 files changed, 1320 insertions, 1217 deletions
diff --git a/sys/dev/drm/ati_pcigart.h b/sys/dev/drm/ati_pcigart.h index c37c95fd8842..dd1141f5303a 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 8430e1db8440..60265808a347 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 8ecb2c47cff9..adf9953dd389 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 03986c52aa87..9141d5778b06 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 e77b3bf875b6..efb8ce7d308c 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 2c8b780ca3db..9d832641fb7d 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 b4bf9e4688a1..9090a1ba3b96 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 6f8f8f4b767a..f00d6dea87f8 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 6ccfc747a066..eb449707f71f 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 88074b43fcd1..83953c79bd1c 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 000000000000..e062f6c7bd78 --- /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 a0e88eef05fe..917cb1e15e7a 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 3047f9275d8e..a627fb4281de 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 bfcdce97b35d..664b8f7fc892 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 b853c2a6d32e..2a0569d06d0c 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 aae8fc05cd74..00bf90ebd5fe 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 d50f3a736a17..9d3bb988c95c 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 5a4bec9ded97..a9dd031d79b3 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 45e6406f205d..6745d65cac5d 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 e4850afa6ba2..cbec2999beb5 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 1f8f2c89fdc2..1c9a93f5940a 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 6d616d50e3ab..c94e32976689 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 bec4e23579fb..87c4d811a0aa 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 b2d6fbcabd8f..b9df5ecf9708 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 14118ffb1de6..e465dc593509 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 df829428430e..2da58d61b4bf 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 b7b05e23752b..9481d3c8831d 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 99c6d8a72275..3dbf9a1cca5f 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 7fb205d8e423..b134f95d6081 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 c8f23c458455..354167560863 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 bd35bf4625b8..636653c2ae1e 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 23fc413026ab..59a439fffa56 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 fdf0f163f0b2..c6aae1928f1a 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 7065b95e70bc..26c5905a6170 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 39333ea9a4c0..f9b91a9a5eb8 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 655277336bdd..93083fdeea23 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" |