aboutsummaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drmP.h121
-rw-r--r--linux-core/drm_bufs.c83
-rw-r--r--linux-core/drm_context.c14
-rw-r--r--linux-core/drm_dma.c23
-rw-r--r--linux-core/drm_drv.c229
-rw-r--r--linux-core/drm_fops.c7
-rw-r--r--linux-core/drm_memory.h1
-rw-r--r--linux-core/ffb.h4
-rw-r--r--linux-core/ffb_context.c60
-rw-r--r--linux-core/ffb_drv.c56
-rw-r--r--linux-core/ffb_drv.h7
-rw-r--r--linux-core/i810_dma.c31
-rw-r--r--linux-core/i810_drv.h1
-rw-r--r--linux-core/i830_dma.c32
-rw-r--r--linux-core/i830_drv.h1
-rw-r--r--linux-core/savage_dma.c4
-rw-r--r--linux-core/sis_drv.c2
-rw-r--r--linux-core/tdfx_drv.c5
18 files changed, 340 insertions, 341 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 1928fabd..75fb999a 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -105,12 +105,6 @@
#ifndef __HAVE_IRQ
#define __HAVE_IRQ 0
#endif
-#ifndef __HAVE_DMA_WAITLIST
-#define __HAVE_DMA_WAITLIST 0
-#endif
-#ifndef __HAVE_DMA_FREELIST
-#define __HAVE_DMA_FREELIST 0
-#endif
#define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \
defined(CONFIG_AGP_MODULE)))
@@ -225,54 +219,6 @@
/***********************************************************************/
-/** \name Mapping helper macros */
-/*@{*/
-
-#define DRM_IOREMAP(map, dev) \
- (map)->handle = DRM(ioremap)( (map)->offset, (map)->size, (dev) )
-
-#define DRM_IOREMAP_NOCACHE(map, dev) \
- (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev))
-
-#define DRM_IOREMAPFREE(map, dev) \
- do { \
- if ( (map)->handle && (map)->size ) \
- DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \
- } while (0)
-
-/**
- * Find mapping.
- *
- * \param _map matching mapping if found, untouched otherwise.
- * \param _o offset.
- *
- * Expects the existence of a local variable named \p dev pointing to the
- * drm_device structure.
- */
-#define DRM_FIND_MAP(_map, _o) \
-do { \
- struct list_head *_list; \
- list_for_each( _list, &dev->maplist->head ) { \
- drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head ); \
- if ( _entry->map && \
- _entry->map->offset == (_o) ) { \
- (_map) = _entry->map; \
- break; \
- } \
- } \
-} while(0)
-
-/**
- * Drop mapping.
- *
- * \sa #DRM_FIND_MAP.
- */
-#define DRM_DROP_MAP(_map)
-
-/*@}*/
-
-
-/***********************************************************************/
/** \name Internal types and structures */
/*@{*/
@@ -569,6 +515,35 @@ typedef struct drm_vbl_sig {
#endif
+/**
+ * DRM device functions structure
+ */
+struct drm_device;
+
+struct drm_driver_fn {
+ int (*preinit)(struct drm_device *, unsigned long flags);
+ int (*postinit)(struct drm_device *, unsigned long flags);
+ void (*prerelease)(struct drm_device *, struct file *filp);
+ void (*pretakedown)(struct drm_device *);
+ int (*postcleanup)(struct drm_device *);
+ int (*presetup)(struct drm_device *);
+ int (*postsetup)(struct drm_device *);
+ void (*open_helper)(struct drm_device *, drm_file_t *);
+ void (*release)(struct drm_device *, struct file *filp);
+ void (*dma_ready)(struct drm_device *);
+ int (*dma_quiescent)(struct drm_device *);
+ int (*dma_flush_block_and_flush)(struct drm_device *, int context, drm_lock_flags_t flags);
+ int (*dma_flush_unblock)(struct drm_device *, int context, drm_lock_flags_t flags);
+ int (*context_ctor)(struct drm_device *dev, int context);
+ int (*context_dtor)(struct drm_device *dev, int context);
+ int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
+ int (*kernel_context_switch_unlock)(struct drm_device *dev);
+ int (*dma_schedule)(struct drm_device *dev, int locked);
+ int (*waitlist_destroy)(drm_waitlist_t *bl);
+ int (*freelist_create)(drm_freelist_t *bl, int count);
+ int (*freelist_put)(struct drm_device *dev, drm_freelist_t *bl, drm_buf_t *buf);
+ int (*freelist_destroy)(drm_freelist_t *bl);
+};
/**
* DRM device structure.
@@ -704,8 +679,12 @@ typedef struct drm_device {
sigset_t sigmask;
int need_reset; /**< secondary device needing reset */
+ struct drm_driver_fn fn_tbl;
+ drm_local_map_t *agp_buffer_map;
+ int dev_priv_size;
} drm_device_t;
+extern void DRM(driver_register_fns)(struct drm_device *dev);
/******************************************************************/
/** \name Internal function definitions */
@@ -960,6 +939,40 @@ extern void *DRM(pci_alloc)(drm_device_t *dev, size_t size,
extern void DRM(pci_free)(drm_device_t *dev, size_t size,
void *vaddr, dma_addr_t busaddr);
+
+/* Inline replacements for DRM_IOREMAP macros */
+static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
+{
+ map->handle = DRM(ioremap)( map->offset, map->size, dev );
+}
+
+static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev)
+{
+ map->handle = DRM(ioremap_nocache)(map->offset, map->size, dev);
+}
+
+static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
+{
+ if ( map->handle && map->size )
+ DRM(ioremapfree)( map->handle, map->size, dev );
+}
+
+static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset)
+{
+ struct list_head *_list;
+ list_for_each( _list, &dev->maplist->head ) {
+ drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head );
+ if ( _entry->map &&
+ _entry->map->offset == offset ) {
+ return _entry->map;
+ }
+ }
+ return NULL;
+}
+
+static __inline__ void drm_core_dropmap(struct drm_map *map)
+{
+}
/*@}*/
#endif /* __KERNEL__ */
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index ef7c3756..d3d0b83c 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -45,18 +45,6 @@
#define __HAVE_SG 0
#endif
-#ifndef DRIVER_BUF_PRIV_T
-#define DRIVER_BUF_PRIV_T u32
-#endif
-#ifndef DRIVER_AGP_BUFFERS_MAP
-#if __HAVE_AGP && __HAVE_DMA
-#error "You must define DRIVER_AGP_BUFFERS_MAP()"
-#else
-#define DRIVER_AGP_BUFFERS_MAP( dev ) NULL
-#endif
-#endif
-
-
/**
* Compute size order. Returns the exponent of the smaller power of two which
* is greater or equal to given number.
@@ -316,7 +304,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
*
* Frees any pages and buffers associated with the given entry.
*/
-static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
+static void DRM(cleanup_buf_error)(drm_device_t *dev, drm_buf_entry_t *entry)
{
int i;
@@ -349,9 +337,8 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
sizeof(*entry->buflist),
DRM_MEM_BUFS);
-#if __HAVE_DMA_FREELIST
- DRM(freelist_destroy)(&entry->freelist);
-#endif
+ if (dev->fn_tbl.freelist_destroy)
+ dev->fn_tbl.freelist_destroy(&entry->freelist);
entry->buf_count = 0;
}
@@ -474,13 +461,13 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
init_waitqueue_head( &buf->dma_wait );
buf->filp = NULL;
- buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
- buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
+ buf->dev_priv_size = dev->dev_priv_size;
+ buf->dev_private = DRM(alloc)( buf->dev_priv_size,
DRM_MEM_BUFS );
if(!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
up( &dev->struct_sem );
atomic_dec( &dev->buf_alloc );
return -ENOMEM;
@@ -504,7 +491,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
DRM_MEM_BUFS );
if(!temp_buflist) {
/* Free the entry because it isn't valid */
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
up( &dev->struct_sem );
atomic_dec( &dev->buf_alloc );
return -ENOMEM;
@@ -521,12 +508,14 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-#if __HAVE_DMA_FREELIST
- DRM(freelist_create)( &entry->freelist, entry->buf_count );
- for ( i = 0 ; i < entry->buf_count ; i++ ) {
- DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
+ if (dev->fn_tbl.freelist_create)
+ {
+ dev->fn_tbl.freelist_create( &entry->freelist, entry->buf_count);
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dev->fn_tbl.freelist_put( dev, &entry->freelist, &entry->buflist[i] );
+ }
}
-#endif
+
up( &dev->struct_sem );
request.count = entry->buf_count;
@@ -665,7 +654,7 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
entry->seg_count = count;
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
DRM(free)( temp_pagelist,
(dma->page_count + (count << page_order))
* sizeof(*dma->pagelist),
@@ -699,14 +688,14 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
init_waitqueue_head( &buf->dma_wait );
buf->filp = NULL;
- buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
- buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
+ buf->dev_priv_size = dev->dev_priv_size;
+ buf->dev_private = DRM(alloc)( dev->dev_priv_size,
DRM_MEM_BUFS );
if(!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
entry->seg_count = count;
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
DRM(free)( temp_pagelist,
(dma->page_count + (count << page_order))
* sizeof(*dma->pagelist),
@@ -730,7 +719,7 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
DRM_MEM_BUFS );
if (!temp_buflist) {
/* Free the entry because it isn't valid */
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
DRM(free)( temp_pagelist,
(dma->page_count + (count << page_order))
* sizeof(*dma->pagelist),
@@ -760,12 +749,14 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
dma->page_count += entry->seg_count << page_order;
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-#if __HAVE_DMA_FREELIST
- DRM(freelist_create)( &entry->freelist, entry->buf_count );
- for ( i = 0 ; i < entry->buf_count ; i++ ) {
- DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
+ if (dev->fn_tbl.freelist_create)
+ {
+ dev->fn_tbl.freelist_create( &entry->freelist, entry->buf_count);
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dev->fn_tbl.freelist_put( dev, &entry->freelist, &entry->buflist[i] );
+ }
}
-#endif
+
up( &dev->struct_sem );
request.count = entry->buf_count;
@@ -883,13 +874,13 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
init_waitqueue_head( &buf->dma_wait );
buf->filp = NULL;
- buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
- buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
+ buf->dev_priv_size = dev->dev_priv_size;
+ buf->dev_private = DRM(alloc)( dev->dev_priv_size,
DRM_MEM_BUFS );
if(!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
up( &dev->struct_sem );
atomic_dec( &dev->buf_alloc );
return -ENOMEM;
@@ -914,7 +905,7 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
DRM_MEM_BUFS );
if(!temp_buflist) {
/* Free the entry because it isn't valid */
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev,entry);
up( &dev->struct_sem );
atomic_dec( &dev->buf_alloc );
return -ENOMEM;
@@ -931,12 +922,14 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-#if __HAVE_DMA_FREELIST
- DRM(freelist_create)( &entry->freelist, entry->buf_count );
- for ( i = 0 ; i < entry->buf_count ; i++ ) {
- DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
+ if (dev->fn_tbl.freelist_create)
+ {
+ dev->fn_tbl.freelist_create( &entry->freelist, entry->buf_count);
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dev->fn_tbl.freelist_put( dev, &entry->freelist, &entry->buflist[i] );
+ }
}
-#endif
+
up( &dev->struct_sem );
request.count = entry->buf_count;
@@ -1222,7 +1215,7 @@ int DRM(mapbufs)( struct inode *inode, struct file *filp,
if ( request.count >= dma->buf_count ) {
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
- drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
+ drm_map_t *map = dev->agp_buffer_map;
if ( !map ) {
retcode = -EINVAL;
diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c
index 0cf34549..dd280e53 100644
--- a/linux-core/drm_context.c
+++ b/linux-core/drm_context.c
@@ -420,10 +420,13 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
/* Should this return -EBUSY instead? */
return -ENOMEM;
}
-#ifdef DRIVER_CTX_CTOR
+
if ( ctx.handle != DRM_KERNEL_CONTEXT )
- DRIVER_CTX_CTOR(dev, ctx.handle);
-#endif
+ {
+ if (dev->fn_tbl.context_ctor)
+ dev->fn_tbl.context_ctor(dev, ctx.handle);
+ }
+
ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
if ( !ctx_entry ) {
DRM_DEBUG("out of memory\n");
@@ -555,9 +558,8 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
priv->remove_auth_on_close = 1;
}
if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
-#ifdef DRIVER_CTX_DTOR
- DRIVER_CTX_DTOR(dev, ctx.handle);
-#endif
+ if (dev->fn_tbl.context_ctor)
+ dev->fn_tbl.context_ctor(dev, ctx.handle);
DRM(ctxbitmap_free)( dev, ctx.handle );
}
diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c
index 04467342..811d768d 100644
--- a/linux-core/drm_dma.c
+++ b/linux-core/drm_dma.c
@@ -117,9 +117,9 @@ void DRM(dma_takedown)(drm_device_t *dev)
dma->bufs[i].buf_count *
sizeof(*dma->bufs[0].buflist),
DRM_MEM_BUFS);
-#if __HAVE_DMA_FREELIST
- DRM(freelist_destroy)(&dma->bufs[i].freelist);
-#endif
+
+ if (dev->fn_tbl.freelist_destroy)
+ dev->fn_tbl.freelist_destroy(&dma->bufs[i].freelist);
}
}
@@ -159,16 +159,13 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
if ( __HAVE_DMA_WAITQUEUE && waitqueue_active(&buf->dma_wait)) {
wake_up_interruptible(&buf->dma_wait);
}
-#if __HAVE_DMA_FREELIST
- else {
- drm_device_dma_t *dma = dev->dma;
- /* If processes are waiting, the last one
- to wake will put the buffer on the free
- list. If no processes are waiting, we
- put the buffer on the freelist here. */
- DRM(freelist_put)(dev, &dma->bufs[buf->order].freelist, buf);
- }
-#endif
+ /* If processes are waiting, the last one
+ to wake will put the buffer on the free
+ list. If no processes are waiting, we
+ put the buffer on the freelist here. */
+ else if (dev->fn_tbl.freelist_put)
+ dev->fn_tbl.freelist_put(dev, &dev->dma->bufs[buf->order].freelist, buf);
+
}
#if !__HAVE_DMA_RECLAIM
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index b841427d..744fd14c 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -67,82 +67,16 @@
#ifndef __HAVE_MULTIPLE_DMA_QUEUES
#define __HAVE_MULTIPLE_DMA_QUEUES 0
#endif
-#ifndef __HAVE_DMA_SCHEDULE
-#define __HAVE_DMA_SCHEDULE 0
-#endif
-#ifndef __HAVE_DMA_FLUSH
-#define __HAVE_DMA_FLUSH 0
-#endif
-#ifndef __HAVE_DMA_READY
-#define __HAVE_DMA_READY 0
-#endif
-#ifndef __HAVE_DMA_QUIESCENT
-#define __HAVE_DMA_QUIESCENT 0
-#endif
-#ifndef __HAVE_RELEASE
-#define __HAVE_RELEASE 0
-#endif
#ifndef __HAVE_COUNTERS
#define __HAVE_COUNTERS 0
#endif
#ifndef __HAVE_SG
#define __HAVE_SG 0
#endif
-/* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm modules in
- * the DRI cvs tree, but it is required by the kernel tree's sparc
- * driver.
- */
-#ifndef __HAVE_KERNEL_CTX_SWITCH
-#define __HAVE_KERNEL_CTX_SWITCH 0
-#endif
-#ifndef __HAVE_DRIVER_FOPS_READ
-#define __HAVE_DRIVER_FOPS_READ 0
-#endif
-#ifndef __HAVE_DRIVER_FOPS_POLL
-#define __HAVE_DRIVER_FOPS_POLL 0
-#endif
-#ifndef DRIVER_PREINIT
-#define DRIVER_PREINIT(dev, flags) 0
-#endif
-#ifndef DRIVER_POSTINIT
-#define DRIVER_POSTINIT(dev, flags) 0
-#endif
-#ifndef DRIVER_PRERELEASE
-#define DRIVER_PRERELEASE()
-#endif
-#ifndef DRIVER_PRETAKEDOWN
-#define DRIVER_PRETAKEDOWN(dev)
-#endif
-#ifndef DRIVER_POSTCLEANUP
-#define DRIVER_POSTCLEANUP(dev)
-#endif
-#ifndef DRIVER_PRESETUP
-#define DRIVER_PRESETUP()
-#endif
-#ifndef DRIVER_POSTSETUP
-#define DRIVER_POSTSETUP()
-#endif
#ifndef DRIVER_IOCTLS
#define DRIVER_IOCTLS
#endif
-#ifndef DRIVER_OPEN_HELPER
-#define DRIVER_OPEN_HELPER( priv, dev )
-#endif
-#ifndef DRIVER_FOPS
-#define DRIVER_FOPS \
-struct file_operations DRM(fops) = { \
- .owner = THIS_MODULE, \
- .open = DRM(open), \
- .flush = DRM(flush), \
- .release = DRM(release), \
- .ioctl = DRM(ioctl), \
- .mmap = DRM(mmap), \
- .fasync = DRM(fasync), \
- .poll = DRM(poll), \
- .read = DRM(read), \
-}
-#endif
static void __exit drm_cleanup( drm_device_t *dev );
@@ -180,10 +114,20 @@ drm_device_t DRM(device)[MAX_DEVICES];
int DRM(numdevs) = 0;
int DRM(fb_loaded) = 0;
-DRIVER_FOPS;
+struct file_operations DRM(fops) = {
+ .owner = THIS_MODULE,
+ .open = DRM(open),
+ .flush = DRM(flush),
+ .release = DRM(release),
+ .ioctl = DRM(ioctl),
+ .mmap = DRM(mmap),
+ .fasync = DRM(fasync),
+ .poll = DRM(poll),
+ .read = DRM(read),
+};
/** Ioctl table */
-static drm_ioctl_desc_t DRM(ioctls)[] = {
+drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 },
@@ -222,12 +166,7 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 },
-#if __HAVE_DMA_FLUSH
- /* Gamma only, really */
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 },
-#else
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(noop), 1, 0 },
-#endif
#if __HAVE_DMA
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 },
@@ -279,7 +218,9 @@ static int DRM(setup)( drm_device_t *dev )
{
int i;
- DRIVER_PRESETUP();
+ if (dev->fn_tbl.presetup)
+ dev->fn_tbl.presetup(dev);
+
atomic_set( &dev->ioctl_count, 0 );
atomic_set( &dev->vma_count, 0 );
dev->buf_use = 0;
@@ -325,9 +266,6 @@ static int DRM(setup)( drm_device_t *dev )
#ifdef __HAVE_COUNTER14
dev->types[14] = __HAVE_COUNTER14;
#endif
-#ifdef __HAVE_COUNTER15
- dev->types[14] = __HAVE_COUNTER14;
-#endif
for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
atomic_set( &dev->counts[i], 0 );
@@ -385,7 +323,9 @@ static int DRM(setup)( drm_device_t *dev )
* drm_select_queue fails between the time the interrupt is
* initialized and the time the queues are initialized.
*/
- DRIVER_POSTSETUP();
+ if (dev->fn_tbl.postsetup)
+ dev->fn_tbl.postsetup(dev);
+
return 0;
}
@@ -410,7 +350,8 @@ static int DRM(takedown)( drm_device_t *dev )
DRM_DEBUG( "\n" );
- DRIVER_PRETAKEDOWN(dev);
+ if (dev->fn_tbl.pretakedown)
+ dev->fn_tbl.pretakedown(dev);
#if __HAVE_IRQ
if ( dev->irq_enabled ) DRM(irq_uninstall)( dev );
#endif
@@ -523,9 +464,9 @@ static int DRM(takedown)( drm_device_t *dev )
#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES
if ( dev->queuelist ) {
for ( i = 0 ; i < dev->queue_count ; i++ ) {
-#if __HAVE_DMA_WAITLIST
- DRM(waitlist_destroy)( &dev->queuelist[i]->waitlist );
-#endif
+ if (dev->fn_tbl.waitlist_destroy)
+ dev->fn_tbl.waitlist_destroy( &dev->queuelist[i]->waitlist);
+
if ( dev->queuelist[i] ) {
DRM(free)( dev->queuelist[i],
sizeof(*dev->queuelist[0]),
@@ -596,8 +537,13 @@ static int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->pci_func = PCI_FUNC(pdev->devfn);
dev->irq = pdev->irq;
- if ((retcode = DRIVER_PREINIT(dev, ent->driver_data)))
- goto error_out_unreg;
+ /* dev_priv_size can be changed by a driver in driver_register_fns */
+ dev->dev_priv_size = sizeof(u32);
+ DRM(driver_register_fns)(dev);
+
+ if (dev->fn_tbl.preinit)
+ if ((retcode = dev->fn_tbl.preinit(dev, ent->driver_data)))
+ goto error_out_unreg;
#if __REALLY_HAVE_AGP
dev->agp = DRM(agp_init)();
@@ -643,9 +589,11 @@ static int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->minor,
pci_pretty_name(pdev)
);
+
/* drivers add secondary heads here if needed */
- if ((retcode = DRIVER_POSTINIT(dev, ent->driver_data)))
- goto error_out_unreg;
+ if (dev->fn_tbl.postinit)
+ if ((retcode = dev->fn_tbl.postinit(dev, ent->driver_data)))
+ goto error_out_unreg;
return 0;
@@ -765,7 +713,8 @@ static void __exit drm_cleanup( drm_device_t *dev )
dev->agp = NULL;
}
#endif
- DRIVER_POSTCLEANUP(dev);
+ if (dev->fn_tbl.postcleanup)
+ dev->fn_tbl.postcleanup(dev);
}
static void __exit drm_exit (void)
@@ -901,7 +850,8 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_DEBUG( "open_count = %d\n", dev->open_count );
- DRIVER_PRERELEASE();
+ if (dev->fn_tbl.prerelease)
+ dev->fn_tbl.prerelease(dev, filp);
/* ========================================================
* Begin inline drm_release
@@ -916,9 +866,10 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_DEBUG( "File %p released, freeing lock for context %d\n",
filp,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-#if __HAVE_RELEASE
- DRIVER_RELEASE();
-#endif
+
+ if (dev->fn_tbl.release)
+ dev->fn_tbl.release(dev, filp);
+
DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
@@ -927,8 +878,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
processed via a callback to the X
server. */
}
-#if __HAVE_RELEASE
- else if ( priv->lock_count && dev->lock.hw_lock ) {
+ else if ( dev->fn_tbl.release && priv->lock_count && dev->lock.hw_lock ) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE( entry, current );
@@ -957,12 +907,14 @@ int DRM(release)( struct inode *inode, struct file *filp )
current->state = TASK_RUNNING;
remove_wait_queue( &dev->lock.lock_queue, &entry );
if( !retcode ) {
- DRIVER_RELEASE();
+ if (dev->fn_tbl.release)
+ dev->fn_tbl.release(dev, filp);
DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT );
}
}
-#elif __HAVE_DMA
+
+#if __HAVE_DMA
DRM(reclaim_buffers)( filp );
#endif
@@ -975,9 +927,8 @@ int DRM(release)( struct inode *inode, struct file *filp )
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
if ( pos->tag == priv &&
pos->handle != DRM_KERNEL_CONTEXT ) {
-#ifdef DRIVER_CTX_DTOR
- DRIVER_CTX_DTOR( dev, pos->handle);
-#endif
+ if (dev->fn_tbl.context_dtor)
+ dev->fn_tbl.context_dtor(dev, pos->handle);
#if __HAVE_CTX_BITMAP
DRM(ctxbitmap_free)( dev, pos->handle );
#endif
@@ -1134,9 +1085,8 @@ int DRM(lock)( struct inode *inode, struct file *filp,
q = dev->queuelist[lock.context];
#endif
-#if __HAVE_DMA_FLUSH
- ret = DRM(flush_block_and_flush)( dev, lock.context, lock.flags );
-#endif
+ if (dev->fn_tbl.dma_flush_block_and_flush)
+ ret = dev->fn_tbl.dma_flush_block_and_flush(dev, lock.context, lock.flags);
if ( !ret ) {
add_wait_queue( &dev->lock.lock_queue, &entry );
for (;;) {
@@ -1165,9 +1115,8 @@ int DRM(lock)( struct inode *inode, struct file *filp,
remove_wait_queue( &dev->lock.lock_queue, &entry );
}
-#if __HAVE_DMA_FLUSH
- DRM(flush_unblock)( dev, lock.context, lock.flags ); /* cleanup phase */
-#endif
+ if (dev->fn_tbl.dma_flush_unblock)
+ dev->fn_tbl.dma_flush_unblock(dev, lock.context, lock.flags);
if ( !ret ) {
sigemptyset( &dev->sigmask );
@@ -1180,26 +1129,17 @@ int DRM(lock)( struct inode *inode, struct file *filp,
block_all_signals( DRM(notifier),
&dev->sigdata, &dev->sigmask );
-#if __HAVE_DMA_READY
- if ( lock.flags & _DRM_LOCK_READY ) {
- DRIVER_DMA_READY();
- }
-#endif
-#if __HAVE_DMA_QUIESCENT
- if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
- DRIVER_DMA_QUIESCENT();
- }
-#endif
- /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the
- * drm modules in the DRI cvs tree, but it is required
- * by the Sparc driver.
- */
-#if __HAVE_KERNEL_CTX_SWITCH
- if ( dev->last_context != lock.context ) {
- DRM(context_switch)(dev, dev->last_context,
- lock.context);
+ if (dev->fn_tbl.dma_ready && (lock.flags & _DRM_LOCK_READY))
+ dev->fn_tbl.dma_ready(dev);
+
+ if ( dev->fn_tbl.dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
+ return dev->fn_tbl.dma_quiescent(dev);
+
+
+ if ( dev->fn_tbl.kernel_context_switch && dev->last_context != lock.context ) {
+ dev->fn_tbl.kernel_context_switch(dev, dev->last_context,
+ lock.context);
}
-#endif
}
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
@@ -1236,40 +1176,21 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
- /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm
- * modules in the DRI cvs tree, but it is required by the
- * Sparc driver.
- */
-#if __HAVE_KERNEL_CTX_SWITCH
- /* We no longer really hold it, but if we are the next
- * agent to request it then we should just be able to
- * take it immediately and not eat the ioctl.
- */
- dev->lock.filp = 0;
+ if (dev->fn_tbl.kernel_context_switch_unlock)
+ dev->fn_tbl.kernel_context_switch_unlock(dev);
+ else
{
- __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
- unsigned int old, new, prev, ctx;
-
- ctx = lock.context;
- do {
- old = *plock;
- new = ctx;
- prev = cmpxchg(plock, old, new);
- } while (prev != old);
- }
- wake_up_interruptible(&dev->lock.lock_queue);
-#else
- DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT );
-#if __HAVE_DMA_SCHEDULE
- DRM(dma_schedule)( dev, 1 );
-#endif
+ DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT );
+
+ if (dev->fn_tbl.dma_schedule)
+ dev->fn_tbl.dma_schedule(dev, 1);
- 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" );
+ }
}
-#endif /* !__HAVE_KERNEL_CTX_SWITCH */
unblock_all_signals();
return 0;
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index 869736a4..d21f7898 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -73,7 +73,8 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
priv->authenticated = capable(CAP_SYS_ADMIN);
priv->lock_count = 0;
- DRIVER_OPEN_HELPER( priv, dev );
+ if (dev->fn_tbl.open_helper)
+ dev->fn_tbl.open_helper(dev, priv);
down(&dev->struct_sem);
if (!dev->file_last) {
@@ -131,19 +132,15 @@ int DRM(fasync)(int fd, struct file *filp, int on)
return 0;
}
-#if !__HAVE_DRIVER_FOPS_POLL
/** No-op. */
unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
{
return 0;
}
-#endif
-#if !__HAVE_DRIVER_FOPS_READ
/** No-op. */
ssize_t DRM(read)(struct file *filp, char __user *buf, size_t count, loff_t *off)
{
return 0;
}
-#endif
diff --git a/linux-core/drm_memory.h b/linux-core/drm_memory.h
index c6ea1fcc..d1c4b23a 100644
--- a/linux-core/drm_memory.h
+++ b/linux-core/drm_memory.h
@@ -199,6 +199,7 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
iounmap(pt);
}
+
#if DEBUG_MEMORY
#include "drm_memory_debug.h"
#else
diff --git a/linux-core/ffb.h b/linux-core/ffb.h
index af35783b..3691c865 100644
--- a/linux-core/ffb.h
+++ b/linux-core/ffb.h
@@ -8,9 +8,5 @@
*/
#define DRM(x) ffb_##x
-/* General customization:
- */
-#define __HAVE_KERNEL_CTX_SWITCH 1
-#define __HAVE_RELEASE 1
#endif
diff --git a/linux-core/ffb_context.c b/linux-core/ffb_context.c
index ffc9b090..add2a743 100644
--- a/linux-core/ffb_context.c
+++ b/linux-core/ffb_context.c
@@ -537,3 +537,63 @@ int DRM(rmctx)(struct inode *inode, struct file *filp, unsigned int cmd,
}
return 0;
}
+
+static void ffb_driver_release(drm_device_t *dev)
+{
+ ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
+ int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
+ int idx;
+
+ idx = context - 1;
+ if (fpriv &&
+ context != DRM_KERNEL_CONTEXT &&
+ fpriv->hw_state[idx] != NULL) {
+ kfree(fpriv->hw_state[idx]);
+ fpriv->hw_state[idx] = NULL;
+ }
+}
+
+static int ffb_driver_presetup(drm_device_t *dev)
+{
+ int ret;
+ ret = ffb_presetup(dev);
+ if (_ret != 0) return ret;
+}
+
+static void ffb_driver_pretakedown(drm_device_t *dev)
+{
+ if (dev->dev_private) kfree(dev->dev_private);
+}
+
+static void ffb_driver_postcleanup(drm_device_t *dev)
+{
+ if (ffb_position != NULL) kfree(ffb_position);
+}
+
+static int ffb_driver_kernel_context_switch_unlock(struct drm_device *dev)
+{
+ dev->lock.filp = 0;
+ {
+ __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
+ unsigned int old, new, prev, ctx;
+
+ ctx = lock.context;
+ do {
+ old = *plock;
+ new = ctx;
+ prev = cmpxchg(plock, old, new);
+ } while (prev != old);
+ }
+ wake_up_interruptible(&dev->lock.lock_queue);
+}
+
+static void ffb_driver_register_fns(drm_device_t *dev)
+{
+ DRM(fops).get_unmapped_area = ffb_get_unmapped_area;
+ dev->fn_tbl.release = ffb_driver_release;
+ dev->fn_tbl.presetup = ffb_driver_presetup;
+ dev->fn_tbl.pretakedown = ffb_driver_pretakedown;
+ dev->fn_tbl.postcleanup = ffb_driver_postcleanup;
+ dev->fn_tbl.kernel_context_switch = ffb_context_switch;
+ dev->fn_tbl.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock;
+}
diff --git a/linux-core/ffb_drv.c b/linux-core/ffb_drv.c
index d75226c2..fe0d129b 100644
--- a/linux-core/ffb_drv.c
+++ b/linux-core/ffb_drv.c
@@ -26,53 +26,7 @@
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 1
-#define DRIVER_FOPS \
-static struct file_operations DRM(fops) = { \
- .owner = THIS_MODULE, \
- .open = DRM(open), \
- .flush = DRM(flush), \
- .release = DRM(release), \
- .ioctl = DRM(ioctl), \
- .mmap = DRM(mmap), \
- .read = DRM(read), \
- .fasync = DRM(fasync), \
- .poll = DRM(poll), \
- .get_unmapped_area = ffb_get_unmapped_area, \
-}
-
#define DRIVER_COUNT_CARDS() ffb_count_card_instances()
-/* Allocate private structure and fill it */
-#define DRIVER_PRESETUP() do { \
- int _ret; \
- _ret = ffb_presetup(dev); \
- if (_ret != 0) return _ret; \
-} while(0)
-
-/* Free private structure */
-#define DRIVER_PRETAKEDOWN() do { \
- if (dev->dev_private) kfree(dev->dev_private); \
-} while(0)
-
-#define DRIVER_POSTCLEANUP() do { \
- if (ffb_position != NULL) kfree(ffb_position); \
-} while(0)
-
-/* We have to free up the rogue hw context state holding error or
- * else we will leak it.
- */
-#define DRIVER_RELEASE() do { \
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; \
- int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock); \
- int idx; \
- \
- idx = context - 1; \
- if (fpriv && \
- context != DRM_KERNEL_CONTEXT && \
- fpriv->hw_state[idx] != NULL) { \
- kfree(fpriv->hw_state[idx]); \
- fpriv->hw_state[idx] = NULL; \
- } \
-} while(0)
/* For mmap customization */
#define DRIVER_GET_MAP_OFS() (map->offset & 0xffffffff)
@@ -275,11 +229,11 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
return NULL;
}
-static unsigned long ffb_get_unmapped_area(struct file *filp,
- unsigned long hint,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
+unsigned long ffb_get_unmapped_area(struct file *filp,
+ unsigned long hint,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
{
drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
unsigned long addr = -ENOMEM;
diff --git a/linux-core/ffb_drv.h b/linux-core/ffb_drv.h
index c0eec5a1..3948c08a 100644
--- a/linux-core/ffb_drv.h
+++ b/linux-core/ffb_drv.h
@@ -274,3 +274,10 @@ typedef struct ffb_dev_priv {
/* Context table. */
struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
} ffb_dev_priv_t;
+
+extern struct file_operations DRM(fops);
+extern unsigned long ffb_get_unmapped_area(struct file *filp,
+ unsigned long hint,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags);
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c
index c58a8851..d558988f 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -371,15 +371,15 @@ static int i810_dma_initialize(drm_device_t *dev,
DRM_ERROR("can not find sarea!\n");
return -EINVAL;
}
- DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset );
+ dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
if (!dev_priv->mmio_map) {
dev->dev_private = (void *)dev_priv;
i810_dma_cleanup(dev);
DRM_ERROR("can not find mmio map!\n");
return -EINVAL;
}
- DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset );
- if (!dev_priv->buffer_map) {
+ dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ if (!dev->agp_buffer_map) {
dev->dev_private = (void *)dev_priv;
i810_dma_cleanup(dev);
DRM_ERROR("can not find dma buffer map!\n");
@@ -1394,3 +1394,28 @@ int i810_flip_bufs(struct inode *inode, struct file *filp,
i810_dma_dispatch_flip( dev );
return 0;
}
+
+static void i810_driver_pretakedown(drm_device_t *dev)
+{
+ i810_dma_cleanup( dev );
+}
+
+static void i810_driver_release(drm_device_t *dev, struct file *filp)
+{
+ i810_reclaim_buffers(filp);
+}
+
+static int i810_driver_dma_quiescent(drm_device_t *dev)
+{
+ i810_dma_quiescent( dev );
+ return 0;
+}
+
+void i810_driver_register_fns(drm_device_t *dev)
+{
+ dev->dev_priv_size = sizeof(drm_i810_buf_priv_t);
+ dev->fn_tbl.pretakedown = i810_driver_pretakedown;
+ dev->fn_tbl.release = i810_driver_release;
+ dev->fn_tbl.dma_quiescent = i810_driver_dma_quiescent;
+}
+
diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h
index 736c20d7..67c5c88b 100644
--- a/linux-core/i810_drv.h
+++ b/linux-core/i810_drv.h
@@ -53,7 +53,6 @@ typedef struct _drm_i810_ring_buffer{
typedef struct drm_i810_private {
drm_map_t *sarea_map;
- drm_map_t *buffer_map;
drm_map_t *mmio_map;
drm_i810_sarea_t *sarea_priv;
diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c
index 55bf1b72..1a8c6336 100644
--- a/linux-core/i830_dma.c
+++ b/linux-core/i830_dma.c
@@ -378,15 +378,15 @@ static int i830_dma_initialize(drm_device_t *dev,
DRM_ERROR("can not find sarea!\n");
return -EINVAL;
}
- DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset );
+ dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
if(!dev_priv->mmio_map) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
DRM_ERROR("can not find mmio map!\n");
return -EINVAL;
}
- DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset );
- if(!dev_priv->buffer_map) {
+ dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ if(!dev->agp_buffer_map) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
DRM_ERROR("can not find dma buffer map!\n");
@@ -1589,3 +1589,29 @@ int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd,
return 0;
}
+
+
+static void i830_driver_pretakedown(drm_device_t *dev)
+{
+ i830_dma_cleanup( dev );
+}
+
+static void i830_driver_release(drm_device_t *dev, struct file *filp)
+{
+ i830_reclaim_buffers(filp);
+}
+
+static int i830_driver_dma_quiescent(drm_device_t *dev)
+{
+ i830_dma_quiescent( dev );
+ return 0;
+}
+
+void i830_driver_register_fns(drm_device_t *dev)
+{
+ dev->dev_priv_size = sizeof(drm_i830_buf_priv_t);
+ dev->fn_tbl.pretakedown = i830_driver_pretakedown;
+ dev->fn_tbl.release = i830_driver_release;
+ dev->fn_tbl.dma_quiescent = i830_driver_dma_quiescent;
+}
+
diff --git a/linux-core/i830_drv.h b/linux-core/i830_drv.h
index c6d805fc..ad4de4c3 100644
--- a/linux-core/i830_drv.h
+++ b/linux-core/i830_drv.h
@@ -53,7 +53,6 @@ typedef struct _drm_i830_ring_buffer{
typedef struct drm_i830_private {
drm_map_t *sarea_map;
- drm_map_t *buffer_map;
drm_map_t *mmio_map;
drm_i830_sarea_t *sarea_priv;
diff --git a/linux-core/savage_dma.c b/linux-core/savage_dma.c
index 87f8bbba..34410116 100644
--- a/linux-core/savage_dma.c
+++ b/linux-core/savage_dma.c
@@ -35,4 +35,6 @@
#define SAVAGE_DEFAULT_USEC_TIMEOUT 10000
#define SAVAGE_FREELIST_DEBUG 0
-
+void DRM(driver_register_fns)(drm_device_t *dev)
+{
+}
diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c
index 3dd075d3..fce5470b 100644
--- a/linux-core/sis_drv.c
+++ b/linux-core/sis_drv.c
@@ -46,3 +46,5 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
+
+
diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c
index fafa1f92..f3fcdf84 100644
--- a/linux-core/tdfx_drv.c
+++ b/linux-core/tdfx_drv.c
@@ -49,3 +49,8 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
+
+void DRM(driver_register_fns)(drm_device_t *dev)
+{
+}
+