Update to latest from DRI CVS. Primary new feature is mostly-complete smpng

locking, and the apparently unnecessary locking for -stable has been removed.
This may fix issues with missed interrupts since April, which manifested
themselves as slowdowns or hangs in radeon, in particular. Many cleanups also
took place.  In the shared code, there are improvements to r128 driver
stability.
This commit is contained in:
Eric Anholt 2003-10-24 01:48:17 +00:00
parent ac6b0748be
commit 1d0d7f3ee4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121447
36 changed files with 1333 additions and 1230 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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_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)
return DRM_ERR(EINVAL);
if (request.count < 0 || request.count > 4096)
return DRM_ERR(EINVAL);
DRM_SPINLOCK(&dev->count_lock);
if (dev->buf_use) {
DRM_SPINUNLOCK(&dev->count_lock);
order = DRM(order)(request.size);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return DRM_ERR(EINVAL);
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,19 +740,14 @@ int DRM(infobufs)( DRM_IOCTL_ARGS )
drm_buf_info_t request;
int i;
int count;
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 );
int retcode = 0;
DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) );
DRM_SPINLOCK(&dev->dma_lock);
++dev->buf_use; /* Can't allocate more after this call */
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 )
return DRM_ERR(EINVAL);
if ( request.high_mark < 0 || request.high_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);
}
entry->freelist.low_mark = request.low_mark;
entry->freelist.high_mark = request.high_mark;
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);
}
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);
#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);
#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);
#endif /* __NetBSD__ */
}
if (retcode)
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;
request.virtual = (void *)virtual;
}
size = round_page(map->size);
foff = map->offset;
} else {
size = round_page(dma->byte_count),
foff = 0;
}
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;
}
#ifdef __FreeBSD__
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__)
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 (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;
}
}
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 */

View File

@ -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;
}
}
DRM_UNLOCK;
return bit;
if (bit >= DRM_MAX_CTXBITMAP) {
DRM_UNLOCK();
return -1;
}
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;
}
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],

View File

@ -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 */

View File

@ -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;
int pciid=pci_get_devid(dev);
int vendor = (pciid & 0x0000ffff);
int device = (pciid & 0xffff0000) >> 16;
/* 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);
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.
* handled in the AGP/GART/SG functions.
*/
break;
case _DRM_SCATTER_GATHER:
/* Handle it, but do nothing, if REALLY_HAVE_SG
* isn't defined.
*/
#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 (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE)
return EINVAL;
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);
}
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 */
}
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 */
}
/* Contention */
ret = tsleep((void *)&dev->lock.lock_queue,
PZERO|PCATCH,
"drmlk2",
0);
if (ret)
break;
}
}
/* 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 ) {
/* FIXME: Add signal blocking here */
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;
}

View File

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

View File

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

255
sys/dev/drm/drm_irq.h Normal file
View File

@ -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 */

View File

@ -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 */

View File

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

View File

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

View File

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

View File

@ -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;
}
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_local_map_t *map;
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;
DRM_SYSCTL_PRINT("\nslot offset size type flags "
"address mtrr\n");
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++;
}
}
SYSCTL_OUT(req, "", 1);
return 0;
done:
return retcode;
}
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
int ret;
drm_local_map_t *map, *tempmaps;
drm_map_list_entry_t *listentry;
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type, *yesno;
int i, mapcount;
char buf[128];
int retcode;
DRM_LOCK;
ret = DRM(_vm_info)(oidp, arg1, arg2, req);
DRM_UNLOCK;
/* 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();
return ret;
mapcount = 0;
TAILQ_FOREACH(listentry, dev->maplist, link)
mapcount++;
tempmaps = DRM(alloc)(sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
if (tempmaps == NULL) {
DRM_UNLOCK();
return ENOMEM;
}
i = 0;
TAILQ_FOREACH(listentry, dev->maplist, link)
tempmaps[i++] = *listentry->map;
DRM_UNLOCK();
DRM_SYSCTL_PRINT("\nslot offset size type flags "
"address mtrr\n");
for (i = 0; i < mapcount; i++) {
map = &tempmaps[i];
if (map->type < 0 || map->type > 4)
type = "??";
else
type = types[map->type];
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);
done:
DRM(free)(tempmaps, sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
return retcode;
}
/* drm_bufs_info is called whenever a process reads
hw.dri.0.bufs. */
static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
#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;
done:
DRM(free)(tempprivs, sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
return retcode;
}
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;
}
#elif defined(__NetBSD__)
/* stub it out for now, sysctl is only for debugging */
int DRM(sysctl_init)(drm_device_t *dev)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 { \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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