diff options
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drmP.h | 121 | ||||
-rw-r--r-- | linux-core/drm_bufs.c | 83 | ||||
-rw-r--r-- | linux-core/drm_context.c | 14 | ||||
-rw-r--r-- | linux-core/drm_dma.c | 23 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 229 | ||||
-rw-r--r-- | linux-core/drm_fops.c | 7 | ||||
-rw-r--r-- | linux-core/drm_memory.h | 1 | ||||
-rw-r--r-- | linux-core/ffb.h | 4 | ||||
-rw-r--r-- | linux-core/ffb_context.c | 60 | ||||
-rw-r--r-- | linux-core/ffb_drv.c | 56 | ||||
-rw-r--r-- | linux-core/ffb_drv.h | 7 | ||||
-rw-r--r-- | linux-core/i810_dma.c | 31 | ||||
-rw-r--r-- | linux-core/i810_drv.h | 1 | ||||
-rw-r--r-- | linux-core/i830_dma.c | 32 | ||||
-rw-r--r-- | linux-core/i830_drv.h | 1 | ||||
-rw-r--r-- | linux-core/savage_dma.c | 4 | ||||
-rw-r--r-- | linux-core/sis_drv.c | 2 | ||||
-rw-r--r-- | linux-core/tdfx_drv.c | 5 |
18 files changed, 340 insertions, 341 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 1928fabd3..75fb999a5 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 ef7c37567..d3d0b83cd 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 0cf345496..dd280e53b 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 04467342b..811d768df 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 b841427da..744fd14cb 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 869736a45..d21f7898e 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 c6ea1fcc5..d1c4b23a6 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 af35783b2..3691c8652 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 ffc9b0906..add2a7432 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 d75226c29..fe0d129ba 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 c0eec5a1f..3948c08a0 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 c58a88517..d558988f7 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 736c20d76..67c5c88bf 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 55bf1b72d..1a8c6336d 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 c6d805fc7..ad4de4c3b 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 87f8bbbaa..344101160 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 3dd075d30..fce5470b9 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 fafa1f922..f3fcdf847 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) +{ +} + |