From 189ad4f724036aeb37ef4e7b5b7d25e3f3250bd8 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 23 Apr 2003 02:20:25 +0000 Subject: Merge from trunk. --- linux-core/Config.in | 19 +- linux-core/Makefile.kernel | 43 +++- linux-core/drmP.h | 121 ++++------- linux-core/drm_agpsupport.c | 8 +- linux-core/drm_bufs.c | 20 +- linux-core/drm_context.c | 396 +---------------------------------- linux-core/drm_dma.c | 341 +------------------------------ linux-core/drm_drv.c | 55 ++--- linux-core/drm_fops.c | 95 +-------- linux-core/drm_init.c | 5 - linux-core/drm_ioctl.c | 2 +- linux-core/drm_lock.c | 115 +---------- linux-core/drm_os_linux.h | 47 +++-- linux-core/drm_proc.c | 149 +------------- linux-core/drm_vm.c | 6 +- linux-core/i810_dma.c | 7 +- linux-core/i810_drv.c | 1 - linux-core/i830_dma.c | 7 +- linux-core/i830_drv.c | 1 - linux-core/sis_drv.c | 1 - linux/Config.in | 19 +- linux/Makefile.kernel | 43 +++- linux/Makefile.linux | 488 ++++++++++++++++++++++---------------------- linux/drmP.h | 121 ++++------- linux/drm_agpsupport.h | 8 +- linux/drm_bufs.h | 20 +- linux/drm_context.h | 396 +---------------------------------- linux/drm_dma.h | 341 +------------------------------ linux/drm_drv.h | 55 ++--- linux/drm_fops.h | 95 +-------- linux/drm_init.h | 5 - linux/drm_ioctl.h | 2 +- linux/drm_lists.h | 230 --------------------- linux/drm_lock.h | 115 +---------- linux/drm_os_linux.h | 47 +++-- linux/drm_proc.h | 149 +------------- linux/drm_vm.h | 6 +- linux/gamma.h | 65 ++---- linux/gamma_dma.c | 70 ++++--- linux/gamma_drv.c | 6 +- linux/gamma_drv.h | 23 +++ linux/i810.h | 2 +- linux/i810_dma.c | 7 +- linux/i810_drv.c | 1 - linux/i830.h | 2 +- linux/i830_dma.c | 7 +- linux/i830_drv.c | 1 - linux/picker.c | 30 --- linux/sis_drv.c | 1 - shared-core/mga_dma.c | 9 +- shared-core/r128_cce.c | 9 +- shared-core/radeon_cp.c | 56 +++-- shared-core/radeon_drm.h | 4 + shared-core/radeon_drv.h | 19 +- shared-core/radeon_state.c | 13 ++ shared/mga_dma.c | 9 +- shared/r128_cce.c | 9 +- shared/radeon.h | 1 + shared/radeon_cp.c | 56 +++-- shared/radeon_drm.h | 4 + shared/radeon_drv.h | 19 +- shared/radeon_state.c | 13 ++ 62 files changed, 776 insertions(+), 3239 deletions(-) delete mode 100644 linux/drm_lists.h delete mode 100644 linux/picker.c diff --git a/linux-core/Config.in b/linux-core/Config.in index 5cc13e84d..45bba136d 100644 --- a/linux-core/Config.in +++ b/linux-core/Config.in @@ -5,13 +5,12 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # -bool 'Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)' CONFIG_DRM -if [ "$CONFIG_DRM" != "n" ]; then - tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX - tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA - tristate ' ATI Rage 128' CONFIG_DRM_R128 - dep_tristate ' ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP - dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP - dep_tristate ' Intel 830M' CONFIG_DRM_I830 $CONFIG_AGP - dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP -fi +tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX +#tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA +tristate ' ATI Rage 128' CONFIG_DRM_R128 +tristate ' ATI Radeon' CONFIG_DRM_RADEON +dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP +dep_tristate ' Intel 830M/845G/852GM/855GM/865G' CONFIG_DRM_I830 $CONFIG_AGP +dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP +tristate ' SiS' CONFIG_DRM_SIS + diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 7e659dfde..5f79e430a 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -1,19 +1,41 @@ # # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -O_TARGET := drm.o -list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o +# +# Based on David Woodhouse's mtd build. +# +# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel,v 1.17 2003/04/12 17:18:17 dawes Exp $ +# gamma-objs := gamma_drv.o gamma_dma.o tdfx-objs := tdfx_drv.o -r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o -mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o +r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o +mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o i810-objs := i810_drv.o i810_dma.o i830-objs := i830_drv.o i830_dma.o i830_irq.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o +sis-objs := sis_drv.o sis_ds.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o +# Kernel version checks + +BELOW25 := $(shell if [ $(PATCHLEVEL) -lt 5 ]; then echo y; fi) + +# There were major build changes starting with 2.5.52 +ifneq ($(BELOW25),y) +BELOW2552 := $(shell if [ $(SUBLEVEL) -lt 52 ]; then echo y; fi) +else +BELOW2552 := y +endif + +ifeq ($(BELOW25),y) +O_TARGET := drm.o +list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o ffb.o radeon.o +obj-m := +obj-n := +obj- := +endif + obj-$(CONFIG_DRM_GAMMA) += gamma.o obj-$(CONFIG_DRM_TDFX) += tdfx.o obj-$(CONFIG_DRM_R128) += r128.o @@ -21,10 +43,14 @@ obj-$(CONFIG_DRM_RADEON)+= radeon.o obj-$(CONFIG_DRM_MGA) += mga.o obj-$(CONFIG_DRM_I810) += i810.o obj-$(CONFIG_DRM_I830) += i830.o +obj-$(CONFIG_DRM_SIS) += sis.o obj-$(CONFIG_DRM_FFB) += ffb.o +ifeq ($(BELOW2552),y) include $(TOPDIR)/Rules.make +endif +ifeq ($(BELOW25),y) gamma.o: $(gamma-objs) $(lib) $(LD) -r -o $@ $(gamma-objs) $(lib) @@ -46,5 +72,10 @@ r128.o: $(r128-objs) $(lib) radeon.o: $(radeon-objs) $(lib) $(LD) -r -o $@ $(radeon-objs) $(lib) +sis.o: $(sis-objs) $(lib) + $(LD) -r -o $@ $(sis-objs) $(lib) + ffb.o: $(ffb-objs) $(lib) $(LD) -r -o $@ $(ffb-objs) $(lib) +endif + diff --git a/linux-core/drmP.h b/linux-core/drmP.h index a6b322855..2cdc5f09d 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -67,7 +67,16 @@ #include #include #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) +#define HAS_WORKQUEUE 0 +#else +#define HAS_WORKQUEUE 1 +#endif +#if !HAS_WORKQUEUE #include +#else +#include +#endif #include #include #include "drm.h" @@ -97,9 +106,6 @@ #ifndef __HAVE_DMA_FREELIST #define __HAVE_DMA_FREELIST 0 #endif -#ifndef __HAVE_DMA_HISTOGRAM -#define __HAVE_DMA_HISTOGRAM 0 -#endif #define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \ defined(CONFIG_AGP_MODULE))) @@ -121,7 +127,6 @@ #define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */ #define DRM_FLAG_DEBUG 0x01 -#define DRM_FLAG_NOCTX 0x02 #define DRM_MEM_DMA 0 #define DRM_MEM_SAREA 1 @@ -172,6 +177,15 @@ pos = n, n = pos->next) #endif +#ifndef list_for_each_entry +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) static inline struct page * vmalloc_to_page(void * vmalloc_addr) { @@ -197,7 +211,7 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#ifndef REMAP_PAGE_RANGE_5_ARGS #define DRM_RPR_ARG(vma) #else #define DRM_RPR_ARG(vma) vma, @@ -249,17 +263,17 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr) DRM(ioremapfree)( (map)->handle, (map)->size ); \ } while (0) -#define DRM_FIND_MAP(_map, _o) \ -do { \ - struct list_head *_list; \ - list_for_each( _list, &dev->maplist->head ) { \ - drm_map_list_t *_entry = (drm_map_list_t *)_list; \ - if ( _entry->map && \ - _entry->map->offset == (_o) ) { \ - (_map) = _entry->map; \ - break; \ - } \ - } \ +#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) #define DRM_DROP_MAP(_map) @@ -347,38 +361,11 @@ typedef struct drm_buf { DRM_LIST_RECLAIM = 5 } list; /* Which list we're on */ -#if DRM_DMA_HISTOGRAM - cycles_t time_queued; /* Queued to kernel DMA queue */ - cycles_t time_dispatched; /* Dispatched to hardware */ - cycles_t time_completed; /* Completed by hardware */ - cycles_t time_freed; /* Back on freelist */ -#endif int dev_priv_size; /* Size of buffer private stoarge */ void *dev_private; /* Per-buffer private storage */ } drm_buf_t; -#if DRM_DMA_HISTOGRAM -#define DRM_DMA_HISTOGRAM_SLOTS 9 -#define DRM_DMA_HISTOGRAM_INITIAL 10 -#define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10) -typedef struct drm_histogram { - atomic_t total; - - atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - - atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - - atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t lacq[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t lhld[DRM_DMA_HISTOGRAM_SLOTS]; -} drm_histogram_t; -#endif /* bufs is one longer than it has to be */ typedef struct drm_waitlist { @@ -430,6 +417,7 @@ typedef struct drm_file { struct drm_file *prev; struct drm_device *dev; int remove_auth_on_close; + unsigned long lock_count; } drm_file_t; @@ -606,7 +594,11 @@ typedef struct drm_device { int last_checked; /* Last context checked for DMA */ int last_context; /* Last current context */ unsigned long last_switch; /* jiffies at last context switch */ +#if !HAS_WORKQUEUE struct tq_struct tq; +#else + struct work_struct work; +#endif #if __HAVE_VBL_IRQ wait_queue_head_t vbl_queue; atomic_t vbl_received; @@ -616,9 +608,6 @@ typedef struct drm_device { #endif cycles_t ctx_start; cycles_t lck_start; -#if __HAVE_DMA_HISTOGRAM - drm_histogram_t histo; -#endif /* Callback to X server for context switch and for heavy-handed reset. */ @@ -674,13 +663,7 @@ extern int DRM(unlock)(struct inode *inode, struct file *filp, extern int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev); extern int DRM(flush)(struct file *filp); -extern int DRM(release_fuck)(struct inode *inode, struct file *filp); extern int DRM(fasync)(int fd, struct file *filp, int on); -extern ssize_t DRM(read)(struct file *filp, char *buf, size_t count, - loff_t *off); -extern int DRM(write_string)(drm_device_t *dev, const char *s); -extern unsigned int DRM(poll)(struct file *filp, - struct poll_table_struct *wait); /* Mapping support (drm_vm.h) */ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, @@ -785,12 +768,11 @@ extern int DRM(getmagic)(struct inode *inode, struct file *filp, extern int DRM(authmagic)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + /* Placeholder for ioctls past */ +extern int DRM(noop)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* Locking IOCTL support (drm_lock.h) */ -extern int DRM(block)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int DRM(unblock)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context); extern int DRM(lock_transfer)(drm_device_t *dev, @@ -830,15 +812,6 @@ 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)( struct file *filp ); -#if __HAVE_OLD_DMA -/* GH: This is a dirty hack for now... - */ -extern void DRM(clear_next_buffer)(drm_device_t *dev); -extern int DRM(select_queue)(drm_device_t *dev, - void (*wrapper)(unsigned long)); -extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma); -extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma); -#endif #if __HAVE_DMA_IRQ extern int DRM(control)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -858,26 +831,8 @@ extern void DRM(vbl_send_signals)( drm_device_t *dev ); #if __HAVE_DMA_IRQ_BH extern void DRM(dma_immediate_bh)( void *dev ); #endif -#endif -#if DRM_DMA_HISTOGRAM -extern int DRM(histogram_slot)(unsigned long count); -extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf); #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 -#if __HAVE_DMA_FREELIST -extern int DRM(freelist_create)(drm_freelist_t *bl, int count); -extern int DRM(freelist_destroy)(drm_freelist_t *bl); -extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, - drm_buf_t *buf); -extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); -#endif #endif /* __HAVE_DMA */ #if __REALLY_HAVE_AGP diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 35dd866ff..22790900e 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -147,7 +147,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, return -ENOMEM; } - entry->handle = (unsigned long)memory->memory; + entry->handle = (unsigned long)memory->key; entry->memory = memory; entry->bound = 0; entry->pages = pages; @@ -187,6 +187,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_agp_binding_t request; drm_agp_mem_t *entry; + int ret; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) @@ -194,7 +195,10 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; - return DRM(unbind_agp)(entry->memory); + ret = DRM(unbind_agp)(entry->memory); + if (ret == 0) + entry->bound = 0; + return ret; } int DRM(agp_bind)(struct inode *inode, struct file *filp, diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index b4e73699c..97997dc17 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -211,7 +211,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp, down(&dev->struct_sem); list = &dev->maplist->head; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *) list; + r_list = list_entry(list, drm_map_list_t, head); if(r_list->map && r_list->map->handle == request.handle && @@ -416,12 +416,6 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, } memset( buf->dev_private, 0, buf->dev_priv_size ); -#if __HAVE_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -#endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); @@ -618,12 +612,6 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); buf->filp = 0; -#if __HAVE_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -#endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); } @@ -790,12 +778,6 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp, memset( buf->dev_private, 0, buf->dev_priv_size ); -# if __HAVE_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -# endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c index 39267b14b..3853a7c64 100644 --- a/linux-core/drm_context.c +++ b/linux-core/drm_context.c @@ -36,7 +36,10 @@ #define __NO_VERSION__ #include "drmP.h" -#if __HAVE_CTX_BITMAP +#if !__HAVE_CTX_BITMAP +#error "__HAVE_CTX_BITMAP must be defined" +#endif + /* ================================================================ * Context bitmap support @@ -195,7 +198,7 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp, down(&dev->struct_sem); list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); if(r_list->map && r_list->map->handle == request.handle) goto found; @@ -222,16 +225,11 @@ found: int DRM(context_switch)( drm_device_t *dev, int old, int new ) { - char buf[64]; - if ( test_and_set_bit( 0, &dev->context_flag ) ) { DRM_ERROR( "Reentering -- FIXME\n" ); return -EBUSY; } -#if __HAVE_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); -#endif DRM_DEBUG( "Context switch from %d to %d\n", old, new ); @@ -240,13 +238,6 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) return 0; } - if ( DRM(flags) & DRM_FLAG_NOCTX ) { - DRM(context_switch_complete)( dev, new ); - } else { - sprintf( buf, "C %d %d\n", old, new ); - DRM(write_string)( dev, buf ); - } - return 0; } @@ -262,11 +253,6 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) /* If a context switch is ever initiated when the kernel holds the lock, release that lock here. */ -#if __HAVE_DMA_HISTOGRAM - atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles() - - dev->ctx_start)] ); - -#endif clear_bit( 0, &dev->context_flag ); wake_up( &dev->context_wait ); @@ -407,375 +393,3 @@ int DRM(rmctx)( struct inode *inode, struct file *filp, return 0; } - -#else /* __HAVE_CTX_BITMAP */ - -/* ================================================================ - * Old-style context support - */ - - -int DRM(context_switch)(drm_device_t *dev, int old, int new) -{ - char buf[64]; - drm_queue_t *q; - -#if 0 - atomic_inc(&dev->total_ctx); -#endif - - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return -EBUSY; - } - -#if __HAVE_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); -#endif - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new >= dev->queue_count) { - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - q = dev->queuelist[new]; - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - atomic_dec(&q->use_count); - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (DRM(flags) & DRM_FLAG_NOCTX) { - DRM(context_switch_complete)(dev, new); - } else { - sprintf(buf, "C %d %d\n", old, new); - DRM(write_string)(dev, buf); - } - - atomic_dec(&q->use_count); - - return 0; -} - -int DRM(context_switch_complete)(drm_device_t *dev, int new) -{ - drm_device_dma_t *dma = dev->dma; - - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) { - if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("Cannot free lock\n"); - } - } - -#if __HAVE_DMA_HISTOGRAM - atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles() - - dev->ctx_start)]); - -#endif - clear_bit(0, &dev->context_flag); - wake_up_interruptible(&dev->context_wait); - - return 0; -} - -static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) -{ - DRM_DEBUG("\n"); - - if (atomic_read(&q->use_count) != 1 - || atomic_read(&q->finalization) - || atomic_read(&q->block_count)) { - DRM_ERROR("New queue is already in use: u%d f%d b%d\n", - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count)); - } - - atomic_set(&q->finalization, 0); - atomic_set(&q->block_count, 0); - atomic_set(&q->block_read, 0); - atomic_set(&q->block_write, 0); - atomic_set(&q->total_queued, 0); - atomic_set(&q->total_flushed, 0); - atomic_set(&q->total_locks, 0); - - init_waitqueue_head(&q->write_queue); - init_waitqueue_head(&q->read_queue); - init_waitqueue_head(&q->flush_queue); - - q->flags = ctx->flags; - - DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count); - - return 0; -} - - -/* drm_alloc_queue: -PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not - disappear (so all deallocation must be done after IOCTLs are off) - 2) dev->queue_count < dev->queue_slots - 3) dev->queuelist[i].use_count == 0 and - dev->queuelist[i].finalization == 0 if i not in use -POST: 1) dev->queuelist[i].use_count == 1 - 2) dev->queue_count < dev->queue_slots */ - -static int DRM(alloc_queue)(drm_device_t *dev) -{ - int i; - drm_queue_t *queue; - int oldslots; - int newslots; - /* Check for a free queue */ - for (i = 0; i < dev->queue_count; i++) { - atomic_inc(&dev->queuelist[i]->use_count); - if (atomic_read(&dev->queuelist[i]->use_count) == 1 - && !atomic_read(&dev->queuelist[i]->finalization)) { - DRM_DEBUG("%d (free)\n", i); - return i; - } - atomic_dec(&dev->queuelist[i]->use_count); - } - /* Allocate a new queue */ - down(&dev->struct_sem); - - queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES); - memset(queue, 0, sizeof(*queue)); - atomic_set(&queue->use_count, 1); - - ++dev->queue_count; - if (dev->queue_count >= dev->queue_slots) { - oldslots = dev->queue_slots * sizeof(*dev->queuelist); - if (!dev->queue_slots) dev->queue_slots = 1; - dev->queue_slots *= 2; - newslots = dev->queue_slots * sizeof(*dev->queuelist); - - dev->queuelist = DRM(realloc)(dev->queuelist, - oldslots, - newslots, - DRM_MEM_QUEUES); - if (!dev->queuelist) { - up(&dev->struct_sem); - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - } - dev->queuelist[dev->queue_count-1] = queue; - - up(&dev->struct_sem); - DRM_DEBUG("%d (new)\n", dev->queue_count - 1); - return dev->queue_count - 1; -} - -int DRM(resctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_ctx_res_t res; - drm_ctx_t ctx; - int i; - - DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) - return -EFAULT; - if (res.count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res.contexts[i], - &i, - sizeof(i))) - return -EFAULT; - } - } - res.count = DRM_RESERVED_CONTEXTS; - if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) - return -EFAULT; - return 0; -} - -int DRM(addctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) { - /* Init kernel's context and get a new one. */ - DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); - ctx.handle = DRM(alloc_queue)(dev); - } - DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); - DRM_DEBUG("%d\n", ctx.handle); - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - return 0; -} - -int DRM(modctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - if (DRM_BUFCOUNT(&q->waitlist)) { - atomic_dec(&q->use_count); - return -EBUSY; - } - - q->flags = ctx.flags; - - atomic_dec(&q->use_count); - return 0; -} - -int DRM(getctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - ctx.flags = q->flags; - atomic_dec(&q->use_count); - - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - - return 0; -} - -int DRM(switchctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - return DRM(context_switch)(dev, dev->last_context, ctx.handle); -} - -int DRM(newctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - DRM(context_switch_complete)(dev, ctx.handle); - - return 0; -} - -int DRM(rmctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - drm_buf_t *buf; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - atomic_inc(&q->finalization); /* Mark queue in finalization state */ - atomic_sub(2, &q->use_count); /* Mark queue as unused (pending - finalization) */ - - while (test_and_set_bit(0, &dev->interrupt_flag)) { - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - /* Remove queued buffers */ - while ((buf = DRM(waitlist_get)(&q->waitlist))) { - DRM(free_buffer)(dev, buf); - } - clear_bit(0, &dev->interrupt_flag); - - /* Wakeup blocked processes */ - wake_up_interruptible(&q->read_queue); - wake_up_interruptible(&q->write_queue); - wake_up_interruptible(&q->flush_queue); - - /* Finalization over. Queue is made - available when both use_count and - finalization become 0, which won't - happen until all the waiting processes - stop waiting. */ - atomic_dec(&q->finalization); - return 0; -} - -#endif /* __HAVE_CTX_BITMAP */ diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c index 4ea6b07d9..640e245da 100644 --- a/linux-core/drm_dma.c +++ b/linux-core/drm_dma.c @@ -127,61 +127,6 @@ void DRM(dma_takedown)(drm_device_t *dev) } -#if __HAVE_DMA_HISTOGRAM -/* This is slow, but is useful for debugging. */ -int DRM(histogram_slot)(unsigned long count) -{ - int value = DRM_DMA_HISTOGRAM_INITIAL; - int slot; - - for (slot = 0; - slot < DRM_DMA_HISTOGRAM_SLOTS; - ++slot, value = DRM_DMA_HISTOGRAM_NEXT(value)) { - if (count < value) return slot; - } - return DRM_DMA_HISTOGRAM_SLOTS - 1; -} - -void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf) -{ - cycles_t queued_to_dispatched; - cycles_t dispatched_to_completed; - cycles_t completed_to_freed; - int q2d, d2c, c2f, q2c, q2f; - - if (buf->time_queued) { - queued_to_dispatched = (buf->time_dispatched - - buf->time_queued); - dispatched_to_completed = (buf->time_completed - - buf->time_dispatched); - completed_to_freed = (buf->time_freed - - buf->time_completed); - - q2d = DRM(histogram_slot)(queued_to_dispatched); - d2c = DRM(histogram_slot)(dispatched_to_completed); - c2f = DRM(histogram_slot)(completed_to_freed); - - q2c = DRM(histogram_slot)(queued_to_dispatched - + dispatched_to_completed); - q2f = DRM(histogram_slot)(queued_to_dispatched - + dispatched_to_completed - + completed_to_freed); - - atomic_inc(&dev->histo.total); - atomic_inc(&dev->histo.queued_to_dispatched[q2d]); - atomic_inc(&dev->histo.dispatched_to_completed[d2c]); - atomic_inc(&dev->histo.completed_to_freed[c2f]); - - atomic_inc(&dev->histo.queued_to_completed[q2c]); - atomic_inc(&dev->histo.queued_to_freed[q2f]); - - } - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -} -#endif void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) { @@ -191,9 +136,6 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->pending = 0; buf->filp = 0; buf->used = 0; -#if __HAVE_DMA_HISTOGRAM - buf->time_completed = get_cycles(); -#endif if ( __HAVE_DMA_WAITQUEUE && waitqueue_active(&buf->dma_wait)) { wake_up_interruptible(&buf->dma_wait); @@ -238,276 +180,6 @@ void DRM(reclaim_buffers)( struct file *filp ) #endif -/* GH: This is a big hack for now... - */ -#if __HAVE_OLD_DMA - -void DRM(clear_next_buffer)(drm_device_t *dev) -{ - drm_device_dma_t *dma = dev->dma; - - dma->next_buffer = NULL; - if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) { - wake_up_interruptible(&dma->next_queue->flush_queue); - } - dma->next_queue = NULL; -} - -int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)) -{ - int i; - int candidate = -1; - int j = jiffies; - - if (!dev) { - DRM_ERROR("No device\n"); - return -1; - } - if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) { - /* This only happens between the time the - interrupt is initialized and the time - the queues are initialized. */ - return -1; - } - - /* Doing "while locked" DMA? */ - if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) { - return DRM_KERNEL_CONTEXT; - } - - /* If there are buffers on the last_context - queue, and we have not been executing - this context very long, continue to - execute this context. */ - if (dev->last_switch <= j - && dev->last_switch + DRM_TIME_SLICE > j - && DRM_WAITCOUNT(dev, dev->last_context)) { - return dev->last_context; - } - - /* Otherwise, find a candidate */ - for (i = dev->last_checked + 1; i < dev->queue_count; i++) { - if (DRM_WAITCOUNT(dev, i)) { - candidate = dev->last_checked = i; - break; - } - } - - if (candidate < 0) { - for (i = 0; i < dev->queue_count; i++) { - if (DRM_WAITCOUNT(dev, i)) { - candidate = dev->last_checked = i; - break; - } - } - } - - if (wrapper - && candidate >= 0 - && candidate != dev->last_context - && dev->last_switch <= j - && dev->last_switch + DRM_TIME_SLICE > j) { - if (dev->timer.expires != dev->last_switch + DRM_TIME_SLICE) { - del_timer(&dev->timer); - dev->timer.function = wrapper; - dev->timer.data = (unsigned long)dev; - dev->timer.expires = dev->last_switch+DRM_TIME_SLICE; - add_timer(&dev->timer); - } - return -1; - } - - return candidate; -} - - -int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int i; - drm_queue_t *q; - drm_buf_t *buf; - int idx; - int while_locked = 0; - drm_device_dma_t *dma = dev->dma; - DECLARE_WAITQUEUE(entry, current); - - DRM_DEBUG("%d\n", d->send_count); - - if (d->flags & _DRM_DMA_WHILE_LOCKED) { - int context = dev->lock.hw_lock->lock; - - if (!_DRM_LOCK_IS_HELD(context)) { - DRM_ERROR("No lock held during \"while locked\"" - " request\n"); - return -EINVAL; - } - if (d->context != _DRM_LOCKING_CONTEXT(context) - && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) { - DRM_ERROR("Lock held by %d while %d makes" - " \"while locked\" request\n", - _DRM_LOCKING_CONTEXT(context), - d->context); - return -EINVAL; - } - q = dev->queuelist[DRM_KERNEL_CONTEXT]; - while_locked = 1; - } else { - q = dev->queuelist[d->context]; - } - - - atomic_inc(&q->use_count); - if (atomic_read(&q->block_write)) { - add_wait_queue(&q->write_queue, &entry); - atomic_inc(&q->block_count); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!atomic_read(&q->block_write)) break; - schedule(); - if (signal_pending(current)) { - atomic_dec(&q->use_count); - remove_wait_queue(&q->write_queue, &entry); - return -EINTR; - } - } - atomic_dec(&q->block_count); - current->state = TASK_RUNNING; - remove_wait_queue(&q->write_queue, &entry); - } - - for (i = 0; i < d->send_count; i++) { - idx = d->send_indices[i]; - if (idx < 0 || idx >= dma->buf_count) { - atomic_dec(&q->use_count); - DRM_ERROR("Index %d (of %d max)\n", - d->send_indices[i], dma->buf_count - 1); - return -EINVAL; - } - buf = dma->buflist[ idx ]; - if (buf->filp != filp) { - atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer not owned\n", - current->pid); - return -EINVAL; - } - if (buf->list != DRM_LIST_NONE) { - atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer %d on list %d\n", - current->pid, buf->idx, buf->list); - } - buf->used = d->send_sizes[i]; - buf->while_locked = while_locked; - buf->context = d->context; - if (!buf->used) { - DRM_ERROR("Queueing 0 length buffer\n"); - } - if (buf->pending) { - atomic_dec(&q->use_count); - DRM_ERROR("Queueing pending buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - return -EINVAL; - } - if (buf->waiting) { - atomic_dec(&q->use_count); - DRM_ERROR("Queueing waiting buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - return -EINVAL; - } - buf->waiting = 1; - if (atomic_read(&q->use_count) == 1 - || atomic_read(&q->finalization)) { - DRM(free_buffer)(dev, buf); - } else { - DRM(waitlist_put)(&q->waitlist, buf); - atomic_inc(&q->total_queued); - } - } - atomic_dec(&q->use_count); - - return 0; -} - -static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d, - int order) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int i; - drm_buf_t *buf; - drm_device_dma_t *dma = dev->dma; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = DRM(freelist_get)(&dma->bufs[order].freelist, - d->flags & _DRM_DMA_WAIT); - if (!buf) break; - if (buf->pending || buf->waiting) { - DRM_ERROR("Free buffer %d in use: filp %p (w%d, p%d)\n", - buf->idx, - buf->filp, - buf->waiting, - buf->pending); - } - buf->filp = filp; - if (copy_to_user(&d->request_indices[i], - &buf->idx, - sizeof(buf->idx))) - return -EFAULT; - - if (copy_to_user(&d->request_sizes[i], - &buf->total, - sizeof(buf->total))) - return -EFAULT; - - ++d->granted_count; - } - return 0; -} - - -int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma) -{ - int order; - int retcode = 0; - int tmp_order; - - order = DRM(order)(dma->request_size); - - dma->granted_count = 0; - retcode = DRM(dma_get_buffers_of_order)(filp, dma, order); - - if (dma->granted_count < dma->request_count - && (dma->flags & _DRM_DMA_SMALLER_OK)) { - for (tmp_order = order - 1; - !retcode - && dma->granted_count < dma->request_count - && tmp_order >= DRM_MIN_ORDER; - --tmp_order) { - - retcode = DRM(dma_get_buffers_of_order)(filp, dma, - tmp_order); - } - } - - if (dma->granted_count < dma->request_count - && (dma->flags & _DRM_DMA_LARGER_OK)) { - for (tmp_order = order + 1; - !retcode - && dma->granted_count < dma->request_count - && tmp_order <= DRM_MAX_ORDER; - ++tmp_order) { - - retcode = DRM(dma_get_buffers_of_order)(filp, dma, - tmp_order); - } - } - return 0; -} - -#endif /* __HAVE_OLD_DMA */ #if __HAVE_DMA_IRQ @@ -538,10 +210,14 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) dev->dma->this_buffer = NULL; #if __HAVE_DMA_IRQ_BH +#if !HAS_WORKQUEUE INIT_LIST_HEAD( &dev->tq.list ); dev->tq.sync = 0; dev->tq.routine = DRM(dma_immediate_bh); dev->tq.data = dev; +#else + INIT_WORK(&dev->work, DRM(dma_immediate_bh), dev); +#endif #endif #if __HAVE_VBL_IRQ @@ -655,7 +331,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) * for the same vblank sequence number; nothing to be done in * that case */ - list_for_each( ( (struct list_head *) vbl_sig ), &dev->vbl_sigs.head ) { + list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) { if (vbl_sig->sequence == vblwait.request.sequence && vbl_sig->info.si_signo == vblwait.request.signal && vbl_sig->task == current) @@ -706,19 +382,20 @@ done: void DRM(vbl_send_signals)( drm_device_t *dev ) { - struct list_head *tmp; + struct list_head *list, *tmp; drm_vbl_sig_t *vbl_sig; unsigned int vbl_seq = atomic_read( &dev->vbl_received ); unsigned long flags; spin_lock_irqsave( &dev->vbl_lock, flags ); - list_for_each_safe( ( (struct list_head *) vbl_sig ), tmp, &dev->vbl_sigs.head ) { + list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) { + vbl_sig = list_entry( list, drm_vbl_sig_t, head ); if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { vbl_sig->info.si_code = vbl_seq; send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); - list_del( (struct list_head *) vbl_sig ); + list_del( list ); DRM_FREE( vbl_sig, sizeof(*vbl_sig) ); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 0a4f3aeb6..036cee35c 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -84,9 +84,6 @@ #ifndef __HAVE_SG #define __HAVE_SG 0 #endif -#ifndef __HAVE_KERNEL_CTX_SWITCH -#define __HAVE_KERNEL_CTX_SWITCH 0 -#endif #ifndef DRIVER_PREINIT #define DRIVER_PREINIT() @@ -121,9 +118,7 @@ static struct file_operations DRM(fops) = { \ .release = DRM(release), \ .ioctl = DRM(ioctl), \ .mmap = DRM(mmap), \ - .read = DRM(read), \ .fasync = DRM(fasync), \ - .poll = DRM(poll), \ } #endif @@ -167,8 +162,8 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(noop), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(noop), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 }, @@ -192,7 +187,13 @@ 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 }, @@ -475,7 +476,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->queuelist[i] ) { DRM(free)( dev->queuelist[i], sizeof(*dev->queuelist[0]), @@ -766,7 +769,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", current->pid, (long)dev->device, dev->open_count ); - if ( dev->lock.hw_lock && + if ( priv->lock_count && dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.filp == filp ) { DRM_DEBUG( "File %p released, freeing lock for context %d\n", @@ -784,7 +787,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) server. */ } #if __HAVE_RELEASE - else if ( dev->lock.hw_lock ) { + else if ( priv->lock_count && dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); @@ -927,11 +930,8 @@ int DRM(lock)( struct inode *inode, struct file *filp, #if __HAVE_MULTIPLE_DMA_QUEUES drm_queue_t *q; #endif -#if __HAVE_DMA_HISTOGRAM - cycles_t start; - dev->lck_start = start = get_cycles(); -#endif + ++priv->lock_count; if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) ) return -EFAULT; @@ -1010,20 +1010,11 @@ int DRM(lock)( struct inode *inode, struct file *filp, if ( lock.flags & _DRM_LOCK_QUIESCENT ) { DRIVER_DMA_QUIESCENT(); } -#endif -#if __HAVE_KERNEL_CTX_SWITCH - if ( dev->last_context != lock.context ) { - DRM(context_switch)(dev, dev->last_context, - lock.context); - } #endif } DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); -#if __HAVE_DMA_HISTOGRAM - atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]); -#endif return ret; } @@ -1046,25 +1037,6 @@ int DRM(unlock)( struct inode *inode, struct file *filp, atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); -#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; - { - __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 @@ -1079,7 +1051,6 @@ int DRM(unlock)( struct inode *inode, struct file *filp, 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 10d1aed11..3baac693b 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -57,6 +57,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) priv->dev = dev; priv->ioctl_count = 0; priv->authenticated = capable(CAP_SYS_ADMIN); + priv->lock_count = 0; down(&dev->struct_sem); if (!dev->file_last) { @@ -113,97 +114,3 @@ int DRM(fasync)(int fd, struct file *filp, int on) } -/* The drm_read and drm_write_string code (especially that which manages - the circular buffer), is based on Alessandro Rubini's LINUX DEVICE - DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */ - -ssize_t DRM(read)(struct file *filp, char *buf, size_t count, loff_t *off) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int left; - int avail; - int send; - int cur; - - DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp); - - while (dev->buf_rp == dev->buf_wp) { - DRM_DEBUG(" sleeping\n"); - if (filp->f_flags & O_NONBLOCK) { - return -EAGAIN; - } - interruptible_sleep_on(&dev->buf_readers); - if (signal_pending(current)) { - DRM_DEBUG(" interrupted\n"); - return -ERESTARTSYS; - } - DRM_DEBUG(" awake\n"); - } - - left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; - avail = DRM_BSZ - left; - send = DRM_MIN(avail, count); - - while (send) { - if (dev->buf_wp > dev->buf_rp) { - cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp); - } else { - cur = DRM_MIN(send, dev->buf_end - dev->buf_rp); - } - if (copy_to_user(buf, dev->buf_rp, cur)) - return -EFAULT; - dev->buf_rp += cur; - if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf; - send -= cur; - } - - wake_up_interruptible(&dev->buf_writers); - return DRM_MIN(avail, count);; -} - -int DRM(write_string)(drm_device_t *dev, const char *s) -{ - int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; - int send = strlen(s); - int count; - - DRM_DEBUG("%d left, %d to send (%p, %p)\n", - left, send, dev->buf_rp, dev->buf_wp); - - if (left == 1 || dev->buf_wp != dev->buf_rp) { - DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n", - left, - dev->buf_wp, - dev->buf_rp); - } - - while (send) { - if (dev->buf_wp >= dev->buf_rp) { - count = DRM_MIN(send, dev->buf_end - dev->buf_wp); - if (count == left) --count; /* Leave a hole */ - } else { - count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1); - } - strncpy(dev->buf_wp, s, count); - dev->buf_wp += count; - if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf; - send -= count; - } - - if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN); - - DRM_DEBUG("waking\n"); - wake_up_interruptible(&dev->buf_readers); - return 0; -} - -unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - - poll_wait(filp, &dev->buf_readers, wait); - if (dev->buf_wp != dev->buf_rp) return POLLIN | POLLRDNORM; - return 0; -} diff --git a/linux-core/drm_init.c b/linux-core/drm_init.c index 2d6b6a3c9..3aa4ad591 100644 --- a/linux-core/drm_init.c +++ b/linux-core/drm_init.c @@ -50,11 +50,6 @@ static void DRM(parse_option)(char *s) for (c = s; *c && *c != ':'; c++); /* find : or \0 */ if (*c) r = c + 1; else r = NULL; /* remember remainder */ *c = '\0'; /* terminate */ - if (!strcmp(s, "noctx")) { - DRM(flags) |= DRM_FLAG_NOCTX; - DRM_INFO("Server-mediated context switching OFF\n"); - return; - } if (!strcmp(s, "debug")) { DRM(flags) |= DRM_FLAG_DEBUG; DRM_INFO("Debug messages ON\n"); diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index d753cce0d..9b1069a15 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -205,7 +205,7 @@ int DRM(getmap)( struct inode *inode, struct file *filp, i = 0; list_for_each(list, &dev->maplist->head) { if(i == idx) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); break; } i++; diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c index e9b17cc40..cc9571ed8 100644 --- a/linux-core/drm_lock.c +++ b/linux-core/drm_lock.c @@ -32,19 +32,13 @@ #define __NO_VERSION__ #include "drmP.h" -int DRM(block)(struct inode *inode, struct file *filp, unsigned int cmd, +int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { DRM_DEBUG("\n"); return 0; } -int DRM(unblock)(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - DRM_DEBUG("\n"); - return 0; -} int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) { @@ -109,113 +103,6 @@ int DRM(lock_free)(drm_device_t *dev, return 0; } -static int DRM(flush_queue)(drm_device_t *dev, int context) -{ - DECLARE_WAITQUEUE(entry, current); - int ret = 0; - drm_queue_t *q = dev->queuelist[context]; - - DRM_DEBUG("\n"); - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) > 1) { - atomic_inc(&q->block_write); - add_wait_queue(&q->flush_queue, &entry); - atomic_inc(&q->block_count); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!DRM_BUFCOUNT(&q->waitlist)) break; - schedule(); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } - atomic_dec(&q->block_count); - current->state = TASK_RUNNING; - remove_wait_queue(&q->flush_queue, &entry); - } - atomic_dec(&q->use_count); - - /* NOTE: block_write is still incremented! - Use drm_flush_unlock_queue to decrement. */ - return ret; -} - -static int DRM(flush_unblock_queue)(drm_device_t *dev, int context) -{ - drm_queue_t *q = dev->queuelist[context]; - - DRM_DEBUG("\n"); - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) > 1) { - if (atomic_read(&q->block_write)) { - atomic_dec(&q->block_write); - wake_up_interruptible(&q->write_queue); - } - } - atomic_dec(&q->use_count); - return 0; -} - -int DRM(flush_block_and_flush)(drm_device_t *dev, int context, - drm_lock_flags_t flags) -{ - int ret = 0; - int i; - - DRM_DEBUG("\n"); - - if (flags & _DRM_LOCK_FLUSH) { - ret = DRM(flush_queue)(dev, DRM_KERNEL_CONTEXT); - if (!ret) ret = DRM(flush_queue)(dev, context); - } - if (flags & _DRM_LOCK_FLUSH_ALL) { - for (i = 0; !ret && i < dev->queue_count; i++) { - ret = DRM(flush_queue)(dev, i); - } - } - return ret; -} - -int DRM(flush_unblock)(drm_device_t *dev, int context, drm_lock_flags_t flags) -{ - int ret = 0; - int i; - - DRM_DEBUG("\n"); - - if (flags & _DRM_LOCK_FLUSH) { - ret = DRM(flush_unblock_queue)(dev, DRM_KERNEL_CONTEXT); - if (!ret) ret = DRM(flush_unblock_queue)(dev, context); - } - if (flags & _DRM_LOCK_FLUSH_ALL) { - for (i = 0; !ret && i < dev->queue_count; i++) { - ret = DRM(flush_unblock_queue)(dev, i); - } - } - - return ret; -} - -int DRM(finish)(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int ret = 0; - drm_lock_t lock; - - DRM_DEBUG("\n"); - - if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) - return -EFAULT; - ret = DRM(flush_block_and_flush)(dev, lock.context, lock.flags); - DRM(flush_unblock)(dev, lock.context, lock.flags); - return ret; -} - /* If we get here, it means that the process has called DRM_IOCTL_LOCK without calling DRM_IOCTL_UNLOCK. diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h index b57efd348..b760c1694 100644 --- a/linux-core/drm_os_linux.h +++ b/linux-core/drm_os_linux.h @@ -47,9 +47,8 @@ #define DRM_GETSAREA() \ do { \ - struct list_head *list; \ - list_for_each( list, &dev->maplist->head ) { \ - drm_map_list_t *entry = (drm_map_list_t *)list; \ + drm_map_list_t *entry; \ + list_for_each_entry( entry, &dev->maplist->head, head ) { \ if ( entry->map && \ entry->map->type == _DRM_SHM && \ (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \ @@ -61,28 +60,28 @@ do { \ #define DRM_HZ HZ -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -do { \ - DECLARE_WAITQUEUE(entry, current); \ - unsigned long end = jiffies + (timeout); \ - add_wait_queue(&(queue), &entry); \ - \ - for (;;) { \ - current->state = TASK_INTERRUPTIBLE; \ - if (condition) \ - break; \ - if((signed)(end - jiffies) <= 0) { \ - ret = -EBUSY; \ - break; \ - } \ +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +do { \ + DECLARE_WAITQUEUE(entry, current); \ + unsigned long end = jiffies + (timeout); \ + add_wait_queue(&(queue), &entry); \ + \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if((signed)(end - jiffies) <= 0) { \ + ret = -EBUSY; \ + break; \ + } \ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \ - if (signal_pending(current)) { \ - ret = -EINTR; \ - break; \ - } \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&(queue), &entry); \ + if (signal_pending(current)) { \ + ret = -EINTR; \ + break; \ + } \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&(queue), &entry); \ } while (0) diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index 8524d2048..148137223 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -50,10 +50,6 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset, static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); #endif -#if __HAVE_DMA_HISTOGRAM -static int DRM(histo_info)(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -#endif struct drm_proc_list { const char *name; @@ -68,9 +64,6 @@ struct drm_proc_list { #if DRM_DEBUG_CODE { "vma", DRM(vma_info) }, #endif -#if __HAVE_DMA_HISTOGRAM - { "histo", DRM(histo_info) }, -#endif }; #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0])) @@ -187,7 +180,7 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, "address mtrr\n\n"); i = 0; if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; if(!map) continue; if (map->type < 0 || map->type > 4) type = "??"; @@ -491,143 +484,3 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, #endif -#if __HAVE_DMA_HISTOGRAM -static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - drm_device_t *dev = (drm_device_t *)data; - int len = 0; - drm_device_dma_t *dma = dev->dma; - int i; - unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL; - unsigned long prev_value = 0; - drm_buf_t *buffer; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT("general statistics:\n"); - DRM_PROC_PRINT("total %10u\n", atomic_read(&dev->histo.total)); - DRM_PROC_PRINT("open %10u\n", - atomic_read(&dev->counts[_DRM_STAT_OPENS])); - DRM_PROC_PRINT("close %10u\n", - atomic_read(&dev->counts[_DRM_STAT_CLOSES])); - DRM_PROC_PRINT("ioctl %10u\n", - atomic_read(&dev->counts[_DRM_STAT_IOCTLS])); - - DRM_PROC_PRINT("\nlock statistics:\n"); - DRM_PROC_PRINT("locks %10u\n", - atomic_read(&dev->counts[_DRM_STAT_LOCKS])); - DRM_PROC_PRINT("unlocks %10u\n", - atomic_read(&dev->counts[_DRM_STAT_UNLOCKS])); - - if (dma) { -#if 0 - DRM_PROC_PRINT("\ndma statistics:\n"); - DRM_PROC_PRINT("prio %10u\n", - atomic_read(&dma->total_prio)); - DRM_PROC_PRINT("bytes %10u\n", - atomic_read(&dma->total_bytes)); - DRM_PROC_PRINT("dmas %10u\n", - atomic_read(&dma->total_dmas)); - DRM_PROC_PRINT("missed:\n"); - DRM_PROC_PRINT(" dma %10u\n", - atomic_read(&dma->total_missed_dma)); - DRM_PROC_PRINT(" lock %10u\n", - atomic_read(&dma->total_missed_lock)); - DRM_PROC_PRINT(" free %10u\n", - atomic_read(&dma->total_missed_free)); - DRM_PROC_PRINT(" sched %10u\n", - atomic_read(&dma->total_missed_sched)); - DRM_PROC_PRINT("tried %10u\n", - atomic_read(&dma->total_tried)); - DRM_PROC_PRINT("hit %10u\n", - atomic_read(&dma->total_hit)); - DRM_PROC_PRINT("lost %10u\n", - atomic_read(&dma->total_lost)); -#endif - - buffer = dma->next_buffer; - if (buffer) { - DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx); - } else { - DRM_PROC_PRINT("next_buffer none\n"); - } - buffer = dma->this_buffer; - if (buffer) { - DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx); - } else { - DRM_PROC_PRINT("this_buffer none\n"); - } - } - - - DRM_PROC_PRINT("\nvalues:\n"); - if (dev->lock.hw_lock) { - DRM_PROC_PRINT("lock 0x%08x\n", - dev->lock.hw_lock->lock); - } else { - DRM_PROC_PRINT("lock none\n"); - } - DRM_PROC_PRINT("context_flag 0x%08lx\n", dev->context_flag); - DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag); - DRM_PROC_PRINT("dma_flag 0x%08lx\n", dev->dma_flag); - - DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count); - DRM_PROC_PRINT("last_context %10d\n", dev->last_context); - DRM_PROC_PRINT("last_switch %10lu\n", dev->last_switch); - DRM_PROC_PRINT("last_checked %10d\n", dev->last_checked); - - - DRM_PROC_PRINT("\n q2d d2c c2f" - " q2c q2f dma sch" - " ctx lacq lhld\n\n"); - for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) { - DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u" - " %10u %10u %10u %10u %10u\n", - i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ", - i == DRM_DMA_HISTOGRAM_SLOTS - 1 - ? prev_value : slot_value , - - atomic_read(&dev->histo - .queued_to_dispatched[i]), - atomic_read(&dev->histo - .dispatched_to_completed[i]), - atomic_read(&dev->histo - .completed_to_freed[i]), - - atomic_read(&dev->histo - .queued_to_completed[i]), - atomic_read(&dev->histo - .queued_to_freed[i]), - atomic_read(&dev->histo.dma[i]), - atomic_read(&dev->histo.schedule[i]), - atomic_read(&dev->histo.ctx[i]), - atomic_read(&dev->histo.lacq[i]), - atomic_read(&dev->histo.lhld[i])); - prev_value = slot_value; - slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value); - } - - if (len > request + offset) return request; - *eof = 1; - return len - offset; -} - -static int DRM(histo_info)(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - drm_device_t *dev = (drm_device_t *)data; - int ret; - - down(&dev->struct_sem); - ret = DRM(_histo_info)(buf, start, offset, request, eof, data); - up(&dev->struct_sem); - return ret; -} -#endif diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 9101e1365..76a10cf54 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -74,7 +74,7 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; if (!map) continue; if (map->offset == VM_OFFSET(vma)) break; @@ -190,7 +190,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma) found_maps = 0; list = &dev->maplist->head; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *) list; + r_list = list_entry(list, drm_map_list_t, head); if (r_list->map == map) found_maps++; } @@ -393,7 +393,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) list_for_each(list, &dev->maplist->head) { unsigned long off; - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; if (!map) continue; off = DRIVER_GET_MAP_OFS(); diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index de9345e3b..a37271643 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -122,9 +122,7 @@ static struct file_operations i810_buffer_fops = { .release = DRM(release), .ioctl = DRM(ioctl), .mmap = i810_mmap_buffers, - .read = DRM(read), .fasync = DRM(fasync), - .poll = DRM(poll), }; int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -263,7 +261,8 @@ static int i810_dma_cleanup(drm_device_t *dev) for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + if ( buf_priv->kernel_virtual && buf->total ) + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); } } return 0; @@ -347,7 +346,7 @@ static int i810_dma_initialize(drm_device_t *dev, memset(dev_priv, 0, sizeof(drm_i810_private_t)); list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; + drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if( r_list->map && r_list->map->type == _DRM_SHM && r_list->map->flags & _DRM_CONTAINS_LOCK ) { diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index 439d7887a..0bc793864 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -49,7 +49,6 @@ #include "drm_init.h" #include "drm_ioctl.h" #include "drm_lock.h" -#include "drm_lists.h" #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c index 47f10d56f..df58e9900 100644 --- a/linux-core/i830_dma.c +++ b/linux-core/i830_dma.c @@ -130,9 +130,7 @@ static struct file_operations i830_buffer_fops = { .release = DRM(release), .ioctl = DRM(ioctl), .mmap = i830_mmap_buffers, - .read = DRM(read), .fasync = DRM(fasync), - .poll = DRM(poll), }; int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -280,7 +278,8 @@ static int i830_dma_cleanup(drm_device_t *dev) for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + if ( buf_priv->kernel_virtual && buf->total ) + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); } } return 0; @@ -370,7 +369,7 @@ static int i830_dma_initialize(drm_device_t *dev, memset(dev_priv, 0, sizeof(drm_i830_private_t)); list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; + drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if( r_list->map && r_list->map->type == _DRM_SHM && r_list->map->flags & _DRM_CONTAINS_LOCK ) { diff --git a/linux-core/i830_drv.c b/linux-core/i830_drv.c index d9a659a44..0735c94db 100644 --- a/linux-core/i830_drv.c +++ b/linux-core/i830_drv.c @@ -51,7 +51,6 @@ #include "drm_init.h" #include "drm_ioctl.h" #include "drm_lock.h" -#include "drm_lists.h" #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index 0c917bd4e..3dd075d30 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -41,7 +41,6 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" -#include "drm_lists.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" diff --git a/linux/Config.in b/linux/Config.in index 5cc13e84d..45bba136d 100644 --- a/linux/Config.in +++ b/linux/Config.in @@ -5,13 +5,12 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # -bool 'Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)' CONFIG_DRM -if [ "$CONFIG_DRM" != "n" ]; then - tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX - tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA - tristate ' ATI Rage 128' CONFIG_DRM_R128 - dep_tristate ' ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP - dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP - dep_tristate ' Intel 830M' CONFIG_DRM_I830 $CONFIG_AGP - dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP -fi +tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX +#tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA +tristate ' ATI Rage 128' CONFIG_DRM_R128 +tristate ' ATI Radeon' CONFIG_DRM_RADEON +dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP +dep_tristate ' Intel 830M/845G/852GM/855GM/865G' CONFIG_DRM_I830 $CONFIG_AGP +dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP +tristate ' SiS' CONFIG_DRM_SIS + diff --git a/linux/Makefile.kernel b/linux/Makefile.kernel index 7e659dfde..5f79e430a 100644 --- a/linux/Makefile.kernel +++ b/linux/Makefile.kernel @@ -1,19 +1,41 @@ # # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -O_TARGET := drm.o -list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o +# +# Based on David Woodhouse's mtd build. +# +# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel,v 1.17 2003/04/12 17:18:17 dawes Exp $ +# gamma-objs := gamma_drv.o gamma_dma.o tdfx-objs := tdfx_drv.o -r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o -mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o +r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o +mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o i810-objs := i810_drv.o i810_dma.o i830-objs := i830_drv.o i830_dma.o i830_irq.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o +sis-objs := sis_drv.o sis_ds.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o +# Kernel version checks + +BELOW25 := $(shell if [ $(PATCHLEVEL) -lt 5 ]; then echo y; fi) + +# There were major build changes starting with 2.5.52 +ifneq ($(BELOW25),y) +BELOW2552 := $(shell if [ $(SUBLEVEL) -lt 52 ]; then echo y; fi) +else +BELOW2552 := y +endif + +ifeq ($(BELOW25),y) +O_TARGET := drm.o +list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o ffb.o radeon.o +obj-m := +obj-n := +obj- := +endif + obj-$(CONFIG_DRM_GAMMA) += gamma.o obj-$(CONFIG_DRM_TDFX) += tdfx.o obj-$(CONFIG_DRM_R128) += r128.o @@ -21,10 +43,14 @@ obj-$(CONFIG_DRM_RADEON)+= radeon.o obj-$(CONFIG_DRM_MGA) += mga.o obj-$(CONFIG_DRM_I810) += i810.o obj-$(CONFIG_DRM_I830) += i830.o +obj-$(CONFIG_DRM_SIS) += sis.o obj-$(CONFIG_DRM_FFB) += ffb.o +ifeq ($(BELOW2552),y) include $(TOPDIR)/Rules.make +endif +ifeq ($(BELOW25),y) gamma.o: $(gamma-objs) $(lib) $(LD) -r -o $@ $(gamma-objs) $(lib) @@ -46,5 +72,10 @@ r128.o: $(r128-objs) $(lib) radeon.o: $(radeon-objs) $(lib) $(LD) -r -o $@ $(radeon-objs) $(lib) +sis.o: $(sis-objs) $(lib) + $(LD) -r -o $@ $(sis-objs) $(lib) + ffb.o: $(ffb-objs) $(lib) $(LD) -r -o $@ $(ffb-objs) $(lib) +endif + diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 065d6f62b..b50859190 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -1,308 +1,316 @@ # Makefile -- For the Direct Rendering Manager module (drm) -# Created: Mon Jan 4 09:26:53 1999 by faith@precisioninsight.com # -# Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. -# Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. -# All rights reserved. +# Based on David Woodhouse's mtd build. # -# 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: +# Modified to handle the DRM requirements and builds on a wider range of +# platforms in a flexible way by David Dawes. It's not clear, however, +# that this approach is simpler than the old one. # -# 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 purpose of this Makefile.linux file is to handle setting up everything +# needed for an out-of-kernel source build. Makefile.kernel contains +# everything required for in-kernel source builds. It is included into +# this file, so none of that should be duplicated here. # -# 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. +# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux,v 1.34 2003/04/16 15:42:19 dawes Exp $ # + +# +# By default, the build is done against the running linux kernel source. +# To build against a different kernel source tree, set LINUXDIR: +# +# make -f Makefile.linux LINUXDIR=/path/to/kernel/source + # -# ***** NOTE NOTE NOTE NOTE NOTE ***** -# To override the automatic Linux source tree determination, pass the -# pathname for the kernel that you want to compile on the command line, -# like this: -# make TREE=/usr/my-kernel-tree/include +# To build only some modules, either set DRM_MODULES to the list of modules, +# or specify the modules as targets: +# +# make -f Makefile.linux r128.o radeon.o +# +# or: +# +# make -f Makefile.linux DRM_MODULES="r128 radeon" # SHELL=/bin/sh .SUFFIXES: -# *** Setup +ifndef LINUXDIR +RUNNING_REL := $(shell uname -r) + +LINUXDIR := /lib/modules/$(RUNNING_REL)/build +endif + +MACHINE := $(shell uname -m) -# **** End of SMP/MODVERSIONS detection +# Modules for all architectures +MODULE_LIST := gamma.o tdfx.o r128.o radeon.o mga.o #sis.o + +# Modules only for ix86 architectures +ifneq (,$(findstring 86,$(MACHINE))) +MODULE_LIST += i830.o i810.o +endif -MODS = gamma.o tdfx.o r128.o radeon.o -LIBS = +# Add ffb.o for sparc?? -DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ - drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \ - drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h -DRMSHARED = drm_sarea.h -DRMHEADERS = drm.h drmP.h $(DRMSHARED) +DRM_MODULES ?= $(MODULE_LIST) -GAMMAOBJS = gamma_drv.o gamma_dma.o -GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +# These definitions are for handling dependencies in the out of kernel build. -TDFXOBJS = tdfx_drv.o -TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES) +DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ + drm_drv.h drm_fops.h drm_init.h drm_ioctl.h \ + drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h -R128OBJS = r128_drv.o r128_cce.o r128_state.o r128_irq.o -R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -R128SHARED = r128.h r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c +DRMSHARED = drm_sarea.h +DRMHEADERS = drm.h drmP.h $(DRMSHARED) -RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ - radeon_irq.o -RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ +GAMMAHEADERS = gamma.h gamma_context.h gamma_drm.h gamma_drv.h gamma_lists.h gamma_old_dma.h gamma_lock.h $(DRMHEADERS) $(DRMTEMPLATES) +TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES) +R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +R128SHARED = r128.h r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c +RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ + $(DRMTEMPLATES) +RADEONSHARED = radeon.h radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \ + radeon_mem.c radeon_state.c +MGAHEADERS = mga.h mga_drv.h mga_drm.h mga_ucode.h $(DRMHEADERS) \ $(DRMTEMPLATES) -RADEONSHARED = radeon.h radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \ - radeon_mem.c radeon_state.c - -INC = /usr/include - -CFLAGS = -O2 $(WARNINGS) -WARNINGS = -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ - -Wstrict-prototypes -Wnested-externs \ - -Wpointer-arith -# -Wshadow -Winline -- make output too noisy -MODCFLAGS = $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer -fno-strict-aliasing -PRGCFLAGS = $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ - -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \ - -I../../../../../../include -I../../../../../../../../include \ - -I../../../../../../../../programs/Xserver/hw/xfree86/common \ - -I. -I../../.. -I../../../../../../../../lib/X11 -PRGLIBS = - -# **** Start of SMP/MODVERSIONS detection - -# First, locate correct tree for this kernel version. If we find a -# matching tree, we assume that we can rely on that tree's autoconf.h. -# This may not be correct, but it is the best assumption we can make. - -VERSION := $(shell uname -r) -# For Red Hat... -RHVERS := $(shell uname -r)custom - -A := /lib/modules/$(VERSION)/build/include -B := /usr/src/linux-$(VERSION)/include -C := /usr/src/linux/include -D := /usr/include - -V := $(shell gcc -E -nostdinc -I$A picker.c 2>/dev/null \ - | grep -s 'RELEASE = ' | cut -d' ' -f3) -ifeq ($(V),"$(VERSION)") -TREE := $A -else -ifeq ($(V),"$(RHVERS)") - TREE := $A -else - V := $(shell gcc -E -nostdinc -I$B picker.c 2>/dev/null \ - | grep -s 'RELEASE = ' | cut -d' ' -f3) -ifeq ($(V),"$(VERSION)") - TREE := $B -else -ifeq ($(V),"$(RHVERS)") - TREE := $B -else - V := $(shell gcc -E -nostdinc -I$C picker.c 2>/dev/null \ - | grep -s 'RELEASE = ' | cut -d' ' -f3) -ifeq ($(V),"$(VERSION)") - TREE := $C -else - V := $(shell gcc -E -nostdinc -I$D picker.c 2>/dev/null \ - | grep -s 'RELEASE = ' | cut -d' ' -f3) -ifeq ($(V),"$(VERSION)") - TREE := $D -else - TREE := 0 -endif +MGASHARED = mga.h mga_dma.c mga_drm.h mga_drv.h mga_irq.c mga_state.c \ + mga_ucode.h mga_warp.c +I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +I830HEADERS = i830.h i830_drv.h i830_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +SISHEADERS= sis_drv.h sis_drm.h $(DRMHEADERS) + +SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED) + +CLEANFILES = *.o *.ko $(PROGS) .depend .*.flags .*.d .*.cmd + +# VERSION is not defined from the initial invocation. It is defined when +# this Makefile is invoked from the kernel's root Makefile. + +ifndef VERSION + +ifdef RUNNING_REL + +# SuSE has the version.h and autoconf.h headers for the current kernel +# in /boot as /boot/vmlinuz.version.h and /boot/vmlinuz.autoconf.h. +# Check these first to see if they match the running kernel. + +BOOTVERSION_PREFIX = /boot/vmlinuz. + +V := $(shell if [ -f $(BOOTVERSION_PREFIX)version.h ]; then \ + grep UTS_RELEASE $(BOOTVERSION_PREFIX)version.h | \ + cut -d' ' -f3; fi) + +ifeq ($(V),"$(RUNNING_REL)") +HEADERFROMBOOT := 1 +GETCONFIG := MAKEFILES=$(shell pwd)/.config +HAVECONFIG := y endif + +# On Red Hat we need to check if there is a .config file in the kernel +# source directory. If there isn't, we need to check if there's a +# matching file in the configs subdirectory. + +ifneq ($(HAVECONFIG),y) +HAVECONFIG := $(shell if [ -e $(LINUXDIR)/.config ]; then echo y; fi) endif + +ifneq ($(HAVECONFIG),y) +REL_BASE := $(shell echo $(RUNNING_REL) | sed 's/-.*//') +REL_TYPE := $(shell echo $(RUNNING_REL) | sed 's/[0-9.-]//g') +ifeq ($(REL_TYPE),) +RHCONFIG := configs/kernel-$(REL_BASE)-$(MACHINE).config +else +RHCONFIG := configs/kernel-$(REL_BASE)-$(MACHINE)-$(REL_TYPE).config endif +HAVECONFIG := $(shell if [ -e $(LINUXDIR)/$(RHCONFIG) ]; then echo y; fi) +ifneq ($(HAVECONFIG),y) +RHCONFIG := endif endif -ifeq ($(TREE),0) -all:; @echo Error: Could not locate kernel tree in $A $B $C $D -else -SMP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ - | grep -s 'SMP = ' | cut -d' ' -f3) -MODULES := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ - | grep -s 'MODULES = ' | cut -d' ' -f3) -MODVERSIONS := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ - | grep -s 'MODVERSIONS = ' | cut -d' ' -f3) -AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ - | grep -s 'AGP = ' | cut -d' ' -f3) -MACHINE := $(shell echo `uname -m`) -# Red Hat's kernels have 4 args to do_munmap() -DOMUNMAP := $(shell grep do_munmap $(TREE)/linux/mm.h | grep -c acct) -ifeq ($(AGP),0) -AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ - | grep -s 'AGP_MODULE = ' | cut -d' ' -f3) +ifneq ($(HAVECONFIG),y) +$(error Cannot find a kernel config file) endif -ifeq ($(DOMUNMAP),1) -MODCFLAGS += -DDO_MUNMAP_4_ARGS endif -ifeq ($(AGP),1) -MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE -DRMTEMPLATES += drm_agpsupport.h -MODS += mga.o -ifeq ($(MACHINE),i386) -MODS += i810.o -MODS += i830.o -endif -ifeq ($(MACHINE),i686) -MODS += i810.o -MODS += i830.o + +CLEANCONFIG := $(shell if cmp -s $(LINUXDIR)/.config .config; then echo y; fi) +ifeq ($(CLEANCONFIG),y) +CLEANFILES += $(LINUXDIR)/.config .config $(LINUXDIR)/tmp_include_depends endif -MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o -MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -MGASHARED = mga.h mga_dma.c mga_drm.h mga_drv.h mga_state.c \ - mga_ucode.h mga_warp.c +# The Makefile renaming hack is required because the standard kernel build, +# especially 2.5.52 and later, explicitly references the Makefile by the +# name "Makefile". For builds prior to 2.5.52, the name GNUmakefile could +# have been used. -I810OBJS = i810_drv.o i810_dma.o -I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +all: modules -I830OBJS = i830_drv.o i830_dma.o i830_irq.o -I830HEADERS = i830.h i830_drv.h i830_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +modules: includes + @if test -f Makefile && cmp -s Makefile Makefile.linux; then : ; \ + else \ + if [ -e Makefile ]; then \ + (set -x; mv -f Makefile Makefile._xx_); fi; \ + (set -x; ln -s Makefile.linux Makefile); fi + make -C $(LINUXDIR) $(GETCONFIG) SUBDIRS=`pwd` DRMSRCDIR=`pwd` modules + @if cmp -s Makefile Makefile.linux; then \ + (set -x; rm -f Makefile); \ + if [ -e Makefile._xx_ ]; then \ + (set -x; mv -f Makefile._xx_ Makefile); fi; fi -endif +ifeq ($(HEADERFROMBOOT),1) -ifeq ($(MACHINE),alpha) -MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6 -endif -ifeq ($(MACHINE),x86_64) -MODCFLAGS+= -mcmodel=kernel -endif +BOOTHEADERS = version.h autoconf.h +BOOTCONFIG = .config +CLEANFILES += $(BOOTHEADERS) $(BOOTCONFIG) -MODS += sis.o +includes:: $(BOOTHEADERS) $(BOOTCONFIG) -SISOBJS= sis_drv.o sis_mm.o sis_ds.o -SISHEADERS= sis_drv.h sis_drm.h $(DRMHEADERS) -MODCFLAGS += -DCONFIG_DRM_SIS +version.h: $(BOOTVERSION_PREFIX)version.h + rm -f $@ + ln -s $< $@ -all::;@echo === KERNEL HEADERS IN $(TREE) -all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${AGP} -all::;@echo === Compiling for machine $(MACHINE) -all::;@echo === WARNING -all::;@echo === WARNING Use 2.4.x kernels ONLY ! -all::;@echo === WARNING +autoconf.h: $(BOOTVERSION_PREFIX)autoconf.h + rm -f $@ + ln -s $< $@ -ifeq ($(MODULES),0) -all::;@echo -all::;@echo "*** Kernel modules must be configured. Build aborted." -all::;@echo -else -all:: $(LIBS) $(MODS) $(PROGS) +.config: $(BOOTVERSION_PREFIX)config + rm -f $@ + ln -s $< $@ endif -endif +# This prepares an unused Red Hat kernel tree for the build. +ifneq ($(RHCONFIG),) +includes:: $(LINUXDIR)/.config $(LINUXDIR)/tmp_include_depends .config -# **** End of SMP/MODVERSIONS detection +$(LINUXDIR)/.config: $(LINUXDIR)/$(RHCONFIG) + rm -f $@ + ln -s $< $@ -# **** Handle SMP/MODVERSIONS -ifeq ($(SMP),1) -MODCFLAGS += -D__SMP__ -endif -ifeq ($(MODVERSIONS),1) -MODCFLAGS += -DMODVERSIONS -include $(TREE)/linux/modversions.h +.config: $(LINUXDIR)/$(RHCONFIG) + rm -f $@ + ln -s $< $@ + +$(LINUXDIR)/tmp_include_depends: + echo all: > $@ endif -# **** End of configuration +# Make sure that the shared source files are linked into this directory. -# Link in shared headers if needed -SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED) -SHAREDDIR = ../../../shared/drm/kernel +SHAREDDIR := ../../../shared/drm/kernel + +HASSHARED := $(shell if [ -d $(SHAREDDIR) ]; then echo y; fi) + +ifeq ($(HASSHARED),y) +includes:: $(SHAREDSRC) $(SHAREDSRC): - @if [ ! -r $@ ]; then (rm -f $@; set -x; ln -s $(SHAREDDIR)/$@ .); fi + @if [ -r $(SHAREDDIR)/$@ ]; then \ + (rm -f $@; set -x; ln -s $(SHAREDDIR)/$@ $@); fi + +CLEANFILES += $(SHAREDSRC) +endif +includes:: linux -dristat: dristat.c - $(CC) $(PRGCFLAGS) $< -o $@ +linux: + rm -f linux + ln -s . linux -DRIsetup: DRIsetup.c - $(CC) $(PRGCFLAGS) $< -o $@ -L/usr/X11R6/lib -lGL -lm ../../../../parser/libxf86config.a ../libdrm.a +clean cleandir: + rm -f $(CLEANFILES) -gamma_drv.o: gamma_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -gamma.o: $(GAMMAOBJS) - $(LD) -r $^ -o $@ +$(MODULE_LIST):: + make -f Makefile.linux DRM_MODULES=$@ modules -tdfx_drv.o: tdfx_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -tdfx.o: $(TDFXOBJS) $(LIBS) - $(LD) -r $^ -o $@ +else + +# Check for kernel versions that we don't support. -sis.o: $(SISOBJS) $(LIBS) - $(LD) -r $^ -o $@ +BELOW24 := $(shell if [ $(VERSION) -lt 2 -o $(PATCHLEVEL) -lt 4 ]; then \ + echo y; fi) -r128_drv.o: r128_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -r128.o: $(R128OBJS) $(LIBS) - $(LD) -r $^ -o $@ +ifeq ($(BELOW24),y) +$(error Only 2.4.x and later kernels are supported \ + ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL))) +endif -radeon_drv.o: radeon_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -radeon.o: $(RADEONOBJS) $(LIBS) - $(LD) -r $^ -o $@ +# This needs to go before all other include paths. +CC += -I$(DRMSRCDIR) -ifeq ($(AGP),1) -mga_drv.o: mga_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -mga.o: $(MGAOBJS) - $(LD) -r $^ -o $@ +# Check for Red Hat's 4-argument do_munmap(). +DOMUNMAP := $(shell grep do_munmap $(LINUXDIR)/include/linux/mm.h | \ + grep -c acct) +# Check for 5-argument remap_page_range() in RH9 kernel, and 2.5.x kernels +RPR := $(shell grep remap_page_range $(LINUXDIR)/include/linux/mm.h | \ + grep -c vma) -i810_drv.o: i810_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -i810.o: $(I810OBJS) $(LIBS) - $(LD) -r $^ -o $@ +ifneq ($(DOMUNMAP),0) +EXTRA_CFLAGS += -DDO_MUNMAP_4_ARGS +endif -i830_drv.o: i830_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -i830.o: $(I830OBJS) $(LIBS) - $(LD) -r $^ -o $@ +ifneq ($(RPR),0) +EXTRA_CFLAGS += -DREMAP_PAGE_RANGE_5_ARGS +endif +# Start with all modules turned off. +CONFIG_DRM_GAMMA := n +CONFIG_DRM_TDFX := n +CONFIG_DRM_MGA := n +CONFIG_DRM_I810 := n +CONFIG_DRM_R128 := n +CONFIG_DRM_RADEON := n +CONFIG_DRM_I830 := n +CONFIG_DRM_SIS := n +CONFIG_DRM_FFB := n + +# Enable module builds for the modules requested/supported. + +ifneq (,$(findstring gamma,$(DRM_MODULES))) +CONFIG_DRM_GAMMA := m +endif +ifneq (,$(findstring tdfx,$(DRM_MODULES))) +CONFIG_DRM_TDFX := m +endif +ifneq (,$(findstring r128,$(DRM_MODULES))) +CONFIG_DRM_R128 := m +endif +ifneq (,$(findstring radeon,$(DRM_MODULES))) +CONFIG_DRM_RADEON := m endif +ifneq (,$(findstring sis,$(DRM_MODULES))) +CONFIG_DRM_SIS := m +endif + +# These require AGP support -.PHONY: ChangeLog -ChangeLog: - @rm -f Changelog - @rcs2log -i 2 -r -l \ - | sed 's,@.*light,,' \ - | sed 's,/cvsroot/.*/drm/kernel/,,g' \ - > ChangeLog - - -# .o files are used for modules -%.o: %.c - $(CC) $(MODCFLAGS) -I$(TREE) -c $< -o $@ - -$(GAMMAOBJS): $(GAMMAHEADERS) -$(TDFXOBJS): $(TDFXHEADERS) -$(R128OBJS): $(R128HEADERS) -$(RADEONOBJS): $(RADEONHEADERS) -ifeq ($(AGP),1) -$(MGAOBJS): $(MGAHEADERS) -$(I810OBJS): $(I810HEADERS) -$(I830OBJS): $(I830HEADERS) +ifdef CONFIG_AGP +ifneq (,$(findstring mga,$(DRM_MODULES))) +CONFIG_DRM_MGA := m +endif +ifneq (,$(findstring i810,$(DRM_MODULES))) +CONFIG_DRM_I810 := m +endif +ifneq (,$(findstring i830,$(DRM_MODULES))) +CONFIG_DRM_I830 := m endif +endif + +include $(DRMSRCDIR)/Makefile.kernel -clean cleandir:: - rm -f *.o *.a *~ core - @for i in $(SHAREDSRC); do \ - if [ -L $$i ]; then (set -x; rm -f $$i); fi; \ - done +# Depencencies +$(gamma-objs): $(GAMMAHEADERS) +$(tdfx-objs): $(TDFXHEADERS) +$(r128-objs): $(R128HEADERS) +$(mga-objs): $(MGAHEADERS) +$(i810-objs): $(I810HEADERS) +$(i830-objs): $(I830HEADERS) +$(radeon-objs): $(RADEONHEADERS) +$(sis-objs): $(SISHEADERS) +$(ffb-objs): $(FFBHEADERS) + +endif diff --git a/linux/drmP.h b/linux/drmP.h index a6b322855..2cdc5f09d 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -67,7 +67,16 @@ #include #include #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) +#define HAS_WORKQUEUE 0 +#else +#define HAS_WORKQUEUE 1 +#endif +#if !HAS_WORKQUEUE #include +#else +#include +#endif #include #include #include "drm.h" @@ -97,9 +106,6 @@ #ifndef __HAVE_DMA_FREELIST #define __HAVE_DMA_FREELIST 0 #endif -#ifndef __HAVE_DMA_HISTOGRAM -#define __HAVE_DMA_HISTOGRAM 0 -#endif #define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \ defined(CONFIG_AGP_MODULE))) @@ -121,7 +127,6 @@ #define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */ #define DRM_FLAG_DEBUG 0x01 -#define DRM_FLAG_NOCTX 0x02 #define DRM_MEM_DMA 0 #define DRM_MEM_SAREA 1 @@ -172,6 +177,15 @@ pos = n, n = pos->next) #endif +#ifndef list_for_each_entry +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) static inline struct page * vmalloc_to_page(void * vmalloc_addr) { @@ -197,7 +211,7 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#ifndef REMAP_PAGE_RANGE_5_ARGS #define DRM_RPR_ARG(vma) #else #define DRM_RPR_ARG(vma) vma, @@ -249,17 +263,17 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr) DRM(ioremapfree)( (map)->handle, (map)->size ); \ } while (0) -#define DRM_FIND_MAP(_map, _o) \ -do { \ - struct list_head *_list; \ - list_for_each( _list, &dev->maplist->head ) { \ - drm_map_list_t *_entry = (drm_map_list_t *)_list; \ - if ( _entry->map && \ - _entry->map->offset == (_o) ) { \ - (_map) = _entry->map; \ - break; \ - } \ - } \ +#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) #define DRM_DROP_MAP(_map) @@ -347,38 +361,11 @@ typedef struct drm_buf { DRM_LIST_RECLAIM = 5 } list; /* Which list we're on */ -#if DRM_DMA_HISTOGRAM - cycles_t time_queued; /* Queued to kernel DMA queue */ - cycles_t time_dispatched; /* Dispatched to hardware */ - cycles_t time_completed; /* Completed by hardware */ - cycles_t time_freed; /* Back on freelist */ -#endif int dev_priv_size; /* Size of buffer private stoarge */ void *dev_private; /* Per-buffer private storage */ } drm_buf_t; -#if DRM_DMA_HISTOGRAM -#define DRM_DMA_HISTOGRAM_SLOTS 9 -#define DRM_DMA_HISTOGRAM_INITIAL 10 -#define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10) -typedef struct drm_histogram { - atomic_t total; - - atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - - atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS]; - - atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t lacq[DRM_DMA_HISTOGRAM_SLOTS]; - atomic_t lhld[DRM_DMA_HISTOGRAM_SLOTS]; -} drm_histogram_t; -#endif /* bufs is one longer than it has to be */ typedef struct drm_waitlist { @@ -430,6 +417,7 @@ typedef struct drm_file { struct drm_file *prev; struct drm_device *dev; int remove_auth_on_close; + unsigned long lock_count; } drm_file_t; @@ -606,7 +594,11 @@ typedef struct drm_device { int last_checked; /* Last context checked for DMA */ int last_context; /* Last current context */ unsigned long last_switch; /* jiffies at last context switch */ +#if !HAS_WORKQUEUE struct tq_struct tq; +#else + struct work_struct work; +#endif #if __HAVE_VBL_IRQ wait_queue_head_t vbl_queue; atomic_t vbl_received; @@ -616,9 +608,6 @@ typedef struct drm_device { #endif cycles_t ctx_start; cycles_t lck_start; -#if __HAVE_DMA_HISTOGRAM - drm_histogram_t histo; -#endif /* Callback to X server for context switch and for heavy-handed reset. */ @@ -674,13 +663,7 @@ extern int DRM(unlock)(struct inode *inode, struct file *filp, extern int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev); extern int DRM(flush)(struct file *filp); -extern int DRM(release_fuck)(struct inode *inode, struct file *filp); extern int DRM(fasync)(int fd, struct file *filp, int on); -extern ssize_t DRM(read)(struct file *filp, char *buf, size_t count, - loff_t *off); -extern int DRM(write_string)(drm_device_t *dev, const char *s); -extern unsigned int DRM(poll)(struct file *filp, - struct poll_table_struct *wait); /* Mapping support (drm_vm.h) */ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, @@ -785,12 +768,11 @@ extern int DRM(getmagic)(struct inode *inode, struct file *filp, extern int DRM(authmagic)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + /* Placeholder for ioctls past */ +extern int DRM(noop)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); /* Locking IOCTL support (drm_lock.h) */ -extern int DRM(block)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int DRM(unblock)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context); extern int DRM(lock_transfer)(drm_device_t *dev, @@ -830,15 +812,6 @@ 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)( struct file *filp ); -#if __HAVE_OLD_DMA -/* GH: This is a dirty hack for now... - */ -extern void DRM(clear_next_buffer)(drm_device_t *dev); -extern int DRM(select_queue)(drm_device_t *dev, - void (*wrapper)(unsigned long)); -extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma); -extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma); -#endif #if __HAVE_DMA_IRQ extern int DRM(control)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -858,26 +831,8 @@ extern void DRM(vbl_send_signals)( drm_device_t *dev ); #if __HAVE_DMA_IRQ_BH extern void DRM(dma_immediate_bh)( void *dev ); #endif -#endif -#if DRM_DMA_HISTOGRAM -extern int DRM(histogram_slot)(unsigned long count); -extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf); #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 -#if __HAVE_DMA_FREELIST -extern int DRM(freelist_create)(drm_freelist_t *bl, int count); -extern int DRM(freelist_destroy)(drm_freelist_t *bl); -extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, - drm_buf_t *buf); -extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); -#endif #endif /* __HAVE_DMA */ #if __REALLY_HAVE_AGP diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h index 35dd866ff..22790900e 100644 --- a/linux/drm_agpsupport.h +++ b/linux/drm_agpsupport.h @@ -147,7 +147,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, return -ENOMEM; } - entry->handle = (unsigned long)memory->memory; + entry->handle = (unsigned long)memory->key; entry->memory = memory; entry->bound = 0; entry->pages = pages; @@ -187,6 +187,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_agp_binding_t request; drm_agp_mem_t *entry; + int ret; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) @@ -194,7 +195,10 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; - return DRM(unbind_agp)(entry->memory); + ret = DRM(unbind_agp)(entry->memory); + if (ret == 0) + entry->bound = 0; + return ret; } int DRM(agp_bind)(struct inode *inode, struct file *filp, diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h index b4e73699c..97997dc17 100644 --- a/linux/drm_bufs.h +++ b/linux/drm_bufs.h @@ -211,7 +211,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp, down(&dev->struct_sem); list = &dev->maplist->head; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *) list; + r_list = list_entry(list, drm_map_list_t, head); if(r_list->map && r_list->map->handle == request.handle && @@ -416,12 +416,6 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, } memset( buf->dev_private, 0, buf->dev_priv_size ); -#if __HAVE_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -#endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); @@ -618,12 +612,6 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); buf->filp = 0; -#if __HAVE_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -#endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); } @@ -790,12 +778,6 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp, memset( buf->dev_private, 0, buf->dev_priv_size ); -# if __HAVE_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -# endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); diff --git a/linux/drm_context.h b/linux/drm_context.h index 39267b14b..3853a7c64 100644 --- a/linux/drm_context.h +++ b/linux/drm_context.h @@ -36,7 +36,10 @@ #define __NO_VERSION__ #include "drmP.h" -#if __HAVE_CTX_BITMAP +#if !__HAVE_CTX_BITMAP +#error "__HAVE_CTX_BITMAP must be defined" +#endif + /* ================================================================ * Context bitmap support @@ -195,7 +198,7 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp, down(&dev->struct_sem); list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); if(r_list->map && r_list->map->handle == request.handle) goto found; @@ -222,16 +225,11 @@ found: int DRM(context_switch)( drm_device_t *dev, int old, int new ) { - char buf[64]; - if ( test_and_set_bit( 0, &dev->context_flag ) ) { DRM_ERROR( "Reentering -- FIXME\n" ); return -EBUSY; } -#if __HAVE_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); -#endif DRM_DEBUG( "Context switch from %d to %d\n", old, new ); @@ -240,13 +238,6 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) return 0; } - if ( DRM(flags) & DRM_FLAG_NOCTX ) { - DRM(context_switch_complete)( dev, new ); - } else { - sprintf( buf, "C %d %d\n", old, new ); - DRM(write_string)( dev, buf ); - } - return 0; } @@ -262,11 +253,6 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) /* If a context switch is ever initiated when the kernel holds the lock, release that lock here. */ -#if __HAVE_DMA_HISTOGRAM - atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles() - - dev->ctx_start)] ); - -#endif clear_bit( 0, &dev->context_flag ); wake_up( &dev->context_wait ); @@ -407,375 +393,3 @@ int DRM(rmctx)( struct inode *inode, struct file *filp, return 0; } - -#else /* __HAVE_CTX_BITMAP */ - -/* ================================================================ - * Old-style context support - */ - - -int DRM(context_switch)(drm_device_t *dev, int old, int new) -{ - char buf[64]; - drm_queue_t *q; - -#if 0 - atomic_inc(&dev->total_ctx); -#endif - - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return -EBUSY; - } - -#if __HAVE_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); -#endif - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new >= dev->queue_count) { - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - q = dev->queuelist[new]; - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - atomic_dec(&q->use_count); - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (DRM(flags) & DRM_FLAG_NOCTX) { - DRM(context_switch_complete)(dev, new); - } else { - sprintf(buf, "C %d %d\n", old, new); - DRM(write_string)(dev, buf); - } - - atomic_dec(&q->use_count); - - return 0; -} - -int DRM(context_switch_complete)(drm_device_t *dev, int new) -{ - drm_device_dma_t *dma = dev->dma; - - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) { - if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("Cannot free lock\n"); - } - } - -#if __HAVE_DMA_HISTOGRAM - atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles() - - dev->ctx_start)]); - -#endif - clear_bit(0, &dev->context_flag); - wake_up_interruptible(&dev->context_wait); - - return 0; -} - -static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) -{ - DRM_DEBUG("\n"); - - if (atomic_read(&q->use_count) != 1 - || atomic_read(&q->finalization) - || atomic_read(&q->block_count)) { - DRM_ERROR("New queue is already in use: u%d f%d b%d\n", - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count)); - } - - atomic_set(&q->finalization, 0); - atomic_set(&q->block_count, 0); - atomic_set(&q->block_read, 0); - atomic_set(&q->block_write, 0); - atomic_set(&q->total_queued, 0); - atomic_set(&q->total_flushed, 0); - atomic_set(&q->total_locks, 0); - - init_waitqueue_head(&q->write_queue); - init_waitqueue_head(&q->read_queue); - init_waitqueue_head(&q->flush_queue); - - q->flags = ctx->flags; - - DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count); - - return 0; -} - - -/* drm_alloc_queue: -PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not - disappear (so all deallocation must be done after IOCTLs are off) - 2) dev->queue_count < dev->queue_slots - 3) dev->queuelist[i].use_count == 0 and - dev->queuelist[i].finalization == 0 if i not in use -POST: 1) dev->queuelist[i].use_count == 1 - 2) dev->queue_count < dev->queue_slots */ - -static int DRM(alloc_queue)(drm_device_t *dev) -{ - int i; - drm_queue_t *queue; - int oldslots; - int newslots; - /* Check for a free queue */ - for (i = 0; i < dev->queue_count; i++) { - atomic_inc(&dev->queuelist[i]->use_count); - if (atomic_read(&dev->queuelist[i]->use_count) == 1 - && !atomic_read(&dev->queuelist[i]->finalization)) { - DRM_DEBUG("%d (free)\n", i); - return i; - } - atomic_dec(&dev->queuelist[i]->use_count); - } - /* Allocate a new queue */ - down(&dev->struct_sem); - - queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES); - memset(queue, 0, sizeof(*queue)); - atomic_set(&queue->use_count, 1); - - ++dev->queue_count; - if (dev->queue_count >= dev->queue_slots) { - oldslots = dev->queue_slots * sizeof(*dev->queuelist); - if (!dev->queue_slots) dev->queue_slots = 1; - dev->queue_slots *= 2; - newslots = dev->queue_slots * sizeof(*dev->queuelist); - - dev->queuelist = DRM(realloc)(dev->queuelist, - oldslots, - newslots, - DRM_MEM_QUEUES); - if (!dev->queuelist) { - up(&dev->struct_sem); - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - } - dev->queuelist[dev->queue_count-1] = queue; - - up(&dev->struct_sem); - DRM_DEBUG("%d (new)\n", dev->queue_count - 1); - return dev->queue_count - 1; -} - -int DRM(resctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_ctx_res_t res; - drm_ctx_t ctx; - int i; - - DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) - return -EFAULT; - if (res.count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res.contexts[i], - &i, - sizeof(i))) - return -EFAULT; - } - } - res.count = DRM_RESERVED_CONTEXTS; - if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) - return -EFAULT; - return 0; -} - -int DRM(addctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) { - /* Init kernel's context and get a new one. */ - DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); - ctx.handle = DRM(alloc_queue)(dev); - } - DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); - DRM_DEBUG("%d\n", ctx.handle); - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - return 0; -} - -int DRM(modctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - if (DRM_BUFCOUNT(&q->waitlist)) { - atomic_dec(&q->use_count); - return -EBUSY; - } - - q->flags = ctx.flags; - - atomic_dec(&q->use_count); - return 0; -} - -int DRM(getctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - ctx.flags = q->flags; - atomic_dec(&q->use_count); - - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - - return 0; -} - -int DRM(switchctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - return DRM(context_switch)(dev, dev->last_context, ctx.handle); -} - -int DRM(newctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - DRM(context_switch_complete)(dev, ctx.handle); - - return 0; -} - -int DRM(rmctx)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - drm_buf_t *buf; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - atomic_inc(&q->finalization); /* Mark queue in finalization state */ - atomic_sub(2, &q->use_count); /* Mark queue as unused (pending - finalization) */ - - while (test_and_set_bit(0, &dev->interrupt_flag)) { - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - /* Remove queued buffers */ - while ((buf = DRM(waitlist_get)(&q->waitlist))) { - DRM(free_buffer)(dev, buf); - } - clear_bit(0, &dev->interrupt_flag); - - /* Wakeup blocked processes */ - wake_up_interruptible(&q->read_queue); - wake_up_interruptible(&q->write_queue); - wake_up_interruptible(&q->flush_queue); - - /* Finalization over. Queue is made - available when both use_count and - finalization become 0, which won't - happen until all the waiting processes - stop waiting. */ - atomic_dec(&q->finalization); - return 0; -} - -#endif /* __HAVE_CTX_BITMAP */ diff --git a/linux/drm_dma.h b/linux/drm_dma.h index 4ea6b07d9..640e245da 100644 --- a/linux/drm_dma.h +++ b/linux/drm_dma.h @@ -127,61 +127,6 @@ void DRM(dma_takedown)(drm_device_t *dev) } -#if __HAVE_DMA_HISTOGRAM -/* This is slow, but is useful for debugging. */ -int DRM(histogram_slot)(unsigned long count) -{ - int value = DRM_DMA_HISTOGRAM_INITIAL; - int slot; - - for (slot = 0; - slot < DRM_DMA_HISTOGRAM_SLOTS; - ++slot, value = DRM_DMA_HISTOGRAM_NEXT(value)) { - if (count < value) return slot; - } - return DRM_DMA_HISTOGRAM_SLOTS - 1; -} - -void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf) -{ - cycles_t queued_to_dispatched; - cycles_t dispatched_to_completed; - cycles_t completed_to_freed; - int q2d, d2c, c2f, q2c, q2f; - - if (buf->time_queued) { - queued_to_dispatched = (buf->time_dispatched - - buf->time_queued); - dispatched_to_completed = (buf->time_completed - - buf->time_dispatched); - completed_to_freed = (buf->time_freed - - buf->time_completed); - - q2d = DRM(histogram_slot)(queued_to_dispatched); - d2c = DRM(histogram_slot)(dispatched_to_completed); - c2f = DRM(histogram_slot)(completed_to_freed); - - q2c = DRM(histogram_slot)(queued_to_dispatched - + dispatched_to_completed); - q2f = DRM(histogram_slot)(queued_to_dispatched - + dispatched_to_completed - + completed_to_freed); - - atomic_inc(&dev->histo.total); - atomic_inc(&dev->histo.queued_to_dispatched[q2d]); - atomic_inc(&dev->histo.dispatched_to_completed[d2c]); - atomic_inc(&dev->histo.completed_to_freed[c2f]); - - atomic_inc(&dev->histo.queued_to_completed[q2c]); - atomic_inc(&dev->histo.queued_to_freed[q2f]); - - } - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; -} -#endif void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) { @@ -191,9 +136,6 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->pending = 0; buf->filp = 0; buf->used = 0; -#if __HAVE_DMA_HISTOGRAM - buf->time_completed = get_cycles(); -#endif if ( __HAVE_DMA_WAITQUEUE && waitqueue_active(&buf->dma_wait)) { wake_up_interruptible(&buf->dma_wait); @@ -238,276 +180,6 @@ void DRM(reclaim_buffers)( struct file *filp ) #endif -/* GH: This is a big hack for now... - */ -#if __HAVE_OLD_DMA - -void DRM(clear_next_buffer)(drm_device_t *dev) -{ - drm_device_dma_t *dma = dev->dma; - - dma->next_buffer = NULL; - if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) { - wake_up_interruptible(&dma->next_queue->flush_queue); - } - dma->next_queue = NULL; -} - -int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)) -{ - int i; - int candidate = -1; - int j = jiffies; - - if (!dev) { - DRM_ERROR("No device\n"); - return -1; - } - if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) { - /* This only happens between the time the - interrupt is initialized and the time - the queues are initialized. */ - return -1; - } - - /* Doing "while locked" DMA? */ - if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) { - return DRM_KERNEL_CONTEXT; - } - - /* If there are buffers on the last_context - queue, and we have not been executing - this context very long, continue to - execute this context. */ - if (dev->last_switch <= j - && dev->last_switch + DRM_TIME_SLICE > j - && DRM_WAITCOUNT(dev, dev->last_context)) { - return dev->last_context; - } - - /* Otherwise, find a candidate */ - for (i = dev->last_checked + 1; i < dev->queue_count; i++) { - if (DRM_WAITCOUNT(dev, i)) { - candidate = dev->last_checked = i; - break; - } - } - - if (candidate < 0) { - for (i = 0; i < dev->queue_count; i++) { - if (DRM_WAITCOUNT(dev, i)) { - candidate = dev->last_checked = i; - break; - } - } - } - - if (wrapper - && candidate >= 0 - && candidate != dev->last_context - && dev->last_switch <= j - && dev->last_switch + DRM_TIME_SLICE > j) { - if (dev->timer.expires != dev->last_switch + DRM_TIME_SLICE) { - del_timer(&dev->timer); - dev->timer.function = wrapper; - dev->timer.data = (unsigned long)dev; - dev->timer.expires = dev->last_switch+DRM_TIME_SLICE; - add_timer(&dev->timer); - } - return -1; - } - - return candidate; -} - - -int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int i; - drm_queue_t *q; - drm_buf_t *buf; - int idx; - int while_locked = 0; - drm_device_dma_t *dma = dev->dma; - DECLARE_WAITQUEUE(entry, current); - - DRM_DEBUG("%d\n", d->send_count); - - if (d->flags & _DRM_DMA_WHILE_LOCKED) { - int context = dev->lock.hw_lock->lock; - - if (!_DRM_LOCK_IS_HELD(context)) { - DRM_ERROR("No lock held during \"while locked\"" - " request\n"); - return -EINVAL; - } - if (d->context != _DRM_LOCKING_CONTEXT(context) - && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) { - DRM_ERROR("Lock held by %d while %d makes" - " \"while locked\" request\n", - _DRM_LOCKING_CONTEXT(context), - d->context); - return -EINVAL; - } - q = dev->queuelist[DRM_KERNEL_CONTEXT]; - while_locked = 1; - } else { - q = dev->queuelist[d->context]; - } - - - atomic_inc(&q->use_count); - if (atomic_read(&q->block_write)) { - add_wait_queue(&q->write_queue, &entry); - atomic_inc(&q->block_count); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!atomic_read(&q->block_write)) break; - schedule(); - if (signal_pending(current)) { - atomic_dec(&q->use_count); - remove_wait_queue(&q->write_queue, &entry); - return -EINTR; - } - } - atomic_dec(&q->block_count); - current->state = TASK_RUNNING; - remove_wait_queue(&q->write_queue, &entry); - } - - for (i = 0; i < d->send_count; i++) { - idx = d->send_indices[i]; - if (idx < 0 || idx >= dma->buf_count) { - atomic_dec(&q->use_count); - DRM_ERROR("Index %d (of %d max)\n", - d->send_indices[i], dma->buf_count - 1); - return -EINVAL; - } - buf = dma->buflist[ idx ]; - if (buf->filp != filp) { - atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer not owned\n", - current->pid); - return -EINVAL; - } - if (buf->list != DRM_LIST_NONE) { - atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer %d on list %d\n", - current->pid, buf->idx, buf->list); - } - buf->used = d->send_sizes[i]; - buf->while_locked = while_locked; - buf->context = d->context; - if (!buf->used) { - DRM_ERROR("Queueing 0 length buffer\n"); - } - if (buf->pending) { - atomic_dec(&q->use_count); - DRM_ERROR("Queueing pending buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - return -EINVAL; - } - if (buf->waiting) { - atomic_dec(&q->use_count); - DRM_ERROR("Queueing waiting buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - return -EINVAL; - } - buf->waiting = 1; - if (atomic_read(&q->use_count) == 1 - || atomic_read(&q->finalization)) { - DRM(free_buffer)(dev, buf); - } else { - DRM(waitlist_put)(&q->waitlist, buf); - atomic_inc(&q->total_queued); - } - } - atomic_dec(&q->use_count); - - return 0; -} - -static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d, - int order) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int i; - drm_buf_t *buf; - drm_device_dma_t *dma = dev->dma; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = DRM(freelist_get)(&dma->bufs[order].freelist, - d->flags & _DRM_DMA_WAIT); - if (!buf) break; - if (buf->pending || buf->waiting) { - DRM_ERROR("Free buffer %d in use: filp %p (w%d, p%d)\n", - buf->idx, - buf->filp, - buf->waiting, - buf->pending); - } - buf->filp = filp; - if (copy_to_user(&d->request_indices[i], - &buf->idx, - sizeof(buf->idx))) - return -EFAULT; - - if (copy_to_user(&d->request_sizes[i], - &buf->total, - sizeof(buf->total))) - return -EFAULT; - - ++d->granted_count; - } - return 0; -} - - -int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma) -{ - int order; - int retcode = 0; - int tmp_order; - - order = DRM(order)(dma->request_size); - - dma->granted_count = 0; - retcode = DRM(dma_get_buffers_of_order)(filp, dma, order); - - if (dma->granted_count < dma->request_count - && (dma->flags & _DRM_DMA_SMALLER_OK)) { - for (tmp_order = order - 1; - !retcode - && dma->granted_count < dma->request_count - && tmp_order >= DRM_MIN_ORDER; - --tmp_order) { - - retcode = DRM(dma_get_buffers_of_order)(filp, dma, - tmp_order); - } - } - - if (dma->granted_count < dma->request_count - && (dma->flags & _DRM_DMA_LARGER_OK)) { - for (tmp_order = order + 1; - !retcode - && dma->granted_count < dma->request_count - && tmp_order <= DRM_MAX_ORDER; - ++tmp_order) { - - retcode = DRM(dma_get_buffers_of_order)(filp, dma, - tmp_order); - } - } - return 0; -} - -#endif /* __HAVE_OLD_DMA */ #if __HAVE_DMA_IRQ @@ -538,10 +210,14 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) dev->dma->this_buffer = NULL; #if __HAVE_DMA_IRQ_BH +#if !HAS_WORKQUEUE INIT_LIST_HEAD( &dev->tq.list ); dev->tq.sync = 0; dev->tq.routine = DRM(dma_immediate_bh); dev->tq.data = dev; +#else + INIT_WORK(&dev->work, DRM(dma_immediate_bh), dev); +#endif #endif #if __HAVE_VBL_IRQ @@ -655,7 +331,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) * for the same vblank sequence number; nothing to be done in * that case */ - list_for_each( ( (struct list_head *) vbl_sig ), &dev->vbl_sigs.head ) { + list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) { if (vbl_sig->sequence == vblwait.request.sequence && vbl_sig->info.si_signo == vblwait.request.signal && vbl_sig->task == current) @@ -706,19 +382,20 @@ done: void DRM(vbl_send_signals)( drm_device_t *dev ) { - struct list_head *tmp; + struct list_head *list, *tmp; drm_vbl_sig_t *vbl_sig; unsigned int vbl_seq = atomic_read( &dev->vbl_received ); unsigned long flags; spin_lock_irqsave( &dev->vbl_lock, flags ); - list_for_each_safe( ( (struct list_head *) vbl_sig ), tmp, &dev->vbl_sigs.head ) { + list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) { + vbl_sig = list_entry( list, drm_vbl_sig_t, head ); if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { vbl_sig->info.si_code = vbl_seq; send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); - list_del( (struct list_head *) vbl_sig ); + list_del( list ); DRM_FREE( vbl_sig, sizeof(*vbl_sig) ); diff --git a/linux/drm_drv.h b/linux/drm_drv.h index 0a4f3aeb6..036cee35c 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -84,9 +84,6 @@ #ifndef __HAVE_SG #define __HAVE_SG 0 #endif -#ifndef __HAVE_KERNEL_CTX_SWITCH -#define __HAVE_KERNEL_CTX_SWITCH 0 -#endif #ifndef DRIVER_PREINIT #define DRIVER_PREINIT() @@ -121,9 +118,7 @@ static struct file_operations DRM(fops) = { \ .release = DRM(release), \ .ioctl = DRM(ioctl), \ .mmap = DRM(mmap), \ - .read = DRM(read), \ .fasync = DRM(fasync), \ - .poll = DRM(poll), \ } #endif @@ -167,8 +162,8 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(noop), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(noop), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 }, @@ -192,7 +187,13 @@ 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 }, @@ -475,7 +476,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->queuelist[i] ) { DRM(free)( dev->queuelist[i], sizeof(*dev->queuelist[0]), @@ -766,7 +769,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", current->pid, (long)dev->device, dev->open_count ); - if ( dev->lock.hw_lock && + if ( priv->lock_count && dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.filp == filp ) { DRM_DEBUG( "File %p released, freeing lock for context %d\n", @@ -784,7 +787,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) server. */ } #if __HAVE_RELEASE - else if ( dev->lock.hw_lock ) { + else if ( priv->lock_count && dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); @@ -927,11 +930,8 @@ int DRM(lock)( struct inode *inode, struct file *filp, #if __HAVE_MULTIPLE_DMA_QUEUES drm_queue_t *q; #endif -#if __HAVE_DMA_HISTOGRAM - cycles_t start; - dev->lck_start = start = get_cycles(); -#endif + ++priv->lock_count; if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) ) return -EFAULT; @@ -1010,20 +1010,11 @@ int DRM(lock)( struct inode *inode, struct file *filp, if ( lock.flags & _DRM_LOCK_QUIESCENT ) { DRIVER_DMA_QUIESCENT(); } -#endif -#if __HAVE_KERNEL_CTX_SWITCH - if ( dev->last_context != lock.context ) { - DRM(context_switch)(dev, dev->last_context, - lock.context); - } #endif } DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); -#if __HAVE_DMA_HISTOGRAM - atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]); -#endif return ret; } @@ -1046,25 +1037,6 @@ int DRM(unlock)( struct inode *inode, struct file *filp, atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); -#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; - { - __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 @@ -1079,7 +1051,6 @@ int DRM(unlock)( struct inode *inode, struct file *filp, DRM_ERROR( "\n" ); } } -#endif /* !__HAVE_KERNEL_CTX_SWITCH */ unblock_all_signals(); return 0; diff --git a/linux/drm_fops.h b/linux/drm_fops.h index 10d1aed11..3baac693b 100644 --- a/linux/drm_fops.h +++ b/linux/drm_fops.h @@ -57,6 +57,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) priv->dev = dev; priv->ioctl_count = 0; priv->authenticated = capable(CAP_SYS_ADMIN); + priv->lock_count = 0; down(&dev->struct_sem); if (!dev->file_last) { @@ -113,97 +114,3 @@ int DRM(fasync)(int fd, struct file *filp, int on) } -/* The drm_read and drm_write_string code (especially that which manages - the circular buffer), is based on Alessandro Rubini's LINUX DEVICE - DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */ - -ssize_t DRM(read)(struct file *filp, char *buf, size_t count, loff_t *off) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int left; - int avail; - int send; - int cur; - - DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp); - - while (dev->buf_rp == dev->buf_wp) { - DRM_DEBUG(" sleeping\n"); - if (filp->f_flags & O_NONBLOCK) { - return -EAGAIN; - } - interruptible_sleep_on(&dev->buf_readers); - if (signal_pending(current)) { - DRM_DEBUG(" interrupted\n"); - return -ERESTARTSYS; - } - DRM_DEBUG(" awake\n"); - } - - left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; - avail = DRM_BSZ - left; - send = DRM_MIN(avail, count); - - while (send) { - if (dev->buf_wp > dev->buf_rp) { - cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp); - } else { - cur = DRM_MIN(send, dev->buf_end - dev->buf_rp); - } - if (copy_to_user(buf, dev->buf_rp, cur)) - return -EFAULT; - dev->buf_rp += cur; - if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf; - send -= cur; - } - - wake_up_interruptible(&dev->buf_writers); - return DRM_MIN(avail, count);; -} - -int DRM(write_string)(drm_device_t *dev, const char *s) -{ - int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; - int send = strlen(s); - int count; - - DRM_DEBUG("%d left, %d to send (%p, %p)\n", - left, send, dev->buf_rp, dev->buf_wp); - - if (left == 1 || dev->buf_wp != dev->buf_rp) { - DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n", - left, - dev->buf_wp, - dev->buf_rp); - } - - while (send) { - if (dev->buf_wp >= dev->buf_rp) { - count = DRM_MIN(send, dev->buf_end - dev->buf_wp); - if (count == left) --count; /* Leave a hole */ - } else { - count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1); - } - strncpy(dev->buf_wp, s, count); - dev->buf_wp += count; - if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf; - send -= count; - } - - if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN); - - DRM_DEBUG("waking\n"); - wake_up_interruptible(&dev->buf_readers); - return 0; -} - -unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - - poll_wait(filp, &dev->buf_readers, wait); - if (dev->buf_wp != dev->buf_rp) return POLLIN | POLLRDNORM; - return 0; -} diff --git a/linux/drm_init.h b/linux/drm_init.h index 2d6b6a3c9..3aa4ad591 100644 --- a/linux/drm_init.h +++ b/linux/drm_init.h @@ -50,11 +50,6 @@ static void DRM(parse_option)(char *s) for (c = s; *c && *c != ':'; c++); /* find : or \0 */ if (*c) r = c + 1; else r = NULL; /* remember remainder */ *c = '\0'; /* terminate */ - if (!strcmp(s, "noctx")) { - DRM(flags) |= DRM_FLAG_NOCTX; - DRM_INFO("Server-mediated context switching OFF\n"); - return; - } if (!strcmp(s, "debug")) { DRM(flags) |= DRM_FLAG_DEBUG; DRM_INFO("Debug messages ON\n"); diff --git a/linux/drm_ioctl.h b/linux/drm_ioctl.h index d753cce0d..9b1069a15 100644 --- a/linux/drm_ioctl.h +++ b/linux/drm_ioctl.h @@ -205,7 +205,7 @@ int DRM(getmap)( struct inode *inode, struct file *filp, i = 0; list_for_each(list, &dev->maplist->head) { if(i == idx) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); break; } i++; diff --git a/linux/drm_lists.h b/linux/drm_lists.h deleted file mode 100644 index 4a64df718..000000000 --- a/linux/drm_lists.h +++ /dev/null @@ -1,230 +0,0 @@ -/* drm_lists.h -- Buffer list handling routines -*- linux-c -*- - * Created: Mon Apr 19 20:54:22 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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: - * Rickard E. (Rik) Faith - * Gareth Hughes - */ - -#define __NO_VERSION__ -#include "drmP.h" - -#if __HAVE_DMA_WAITLIST - -int DRM(waitlist_create)(drm_waitlist_t *bl, int count) -{ - if (bl->count) return -EINVAL; - - bl->bufs = DRM(alloc)((bl->count + 2) * sizeof(*bl->bufs), - DRM_MEM_BUFLISTS); - - if(!bl->bufs) return -ENOMEM; - memset(bl->bufs, 0, sizeof(*bl->bufs)); - bl->count = count; - bl->rp = bl->bufs; - bl->wp = bl->bufs; - bl->end = &bl->bufs[bl->count+1]; - bl->write_lock = SPIN_LOCK_UNLOCKED; - bl->read_lock = SPIN_LOCK_UNLOCKED; - return 0; -} - -int DRM(waitlist_destroy)(drm_waitlist_t *bl) -{ - if (bl->rp != bl->wp) return -EINVAL; - if (bl->bufs) DRM(free)(bl->bufs, - (bl->count + 2) * sizeof(*bl->bufs), - DRM_MEM_BUFLISTS); - bl->count = 0; - bl->bufs = NULL; - bl->rp = NULL; - bl->wp = NULL; - bl->end = NULL; - return 0; -} - -int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf) -{ - int left; - unsigned long flags; - - left = DRM_LEFTCOUNT(bl); - if (!left) { - DRM_ERROR("Overflow while adding buffer %d from filp %p\n", - buf->idx, buf->filp); - return -EINVAL; - } -#if __HAVE_DMA_HISTOGRAM - buf->time_queued = get_cycles(); -#endif - buf->list = DRM_LIST_WAIT; - - spin_lock_irqsave(&bl->write_lock, flags); - *bl->wp = buf; - if (++bl->wp >= bl->end) bl->wp = bl->bufs; - spin_unlock_irqrestore(&bl->write_lock, flags); - - return 0; -} - -drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl) -{ - drm_buf_t *buf; - unsigned long flags; - - spin_lock_irqsave(&bl->read_lock, flags); - buf = *bl->rp; - if (bl->rp == bl->wp) { - spin_unlock_irqrestore(&bl->read_lock, flags); - return NULL; - } - if (++bl->rp >= bl->end) bl->rp = bl->bufs; - spin_unlock_irqrestore(&bl->read_lock, flags); - - return buf; -} - -#endif /* __HAVE_DMA_WAITLIST */ - - -#if __HAVE_DMA_FREELIST - -int DRM(freelist_create)(drm_freelist_t *bl, int count) -{ - atomic_set(&bl->count, 0); - bl->next = NULL; - init_waitqueue_head(&bl->waiting); - bl->low_mark = 0; - bl->high_mark = 0; - atomic_set(&bl->wfh, 0); - bl->lock = SPIN_LOCK_UNLOCKED; - ++bl->initialized; - return 0; -} - -int DRM(freelist_destroy)(drm_freelist_t *bl) -{ - atomic_set(&bl->count, 0); - bl->next = NULL; - return 0; -} - -int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) -{ - drm_device_dma_t *dma = dev->dma; - - if (!dma) { - DRM_ERROR("No DMA support\n"); - return 1; - } - - if (buf->waiting || buf->pending || buf->list == DRM_LIST_FREE) { - DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n", - buf->idx, buf->waiting, buf->pending, buf->list); - } - if (!bl) return 1; -#if __HAVE_DMA_HISTOGRAM - buf->time_freed = get_cycles(); - DRM(histogram_compute)(dev, buf); -#endif - buf->list = DRM_LIST_FREE; - - spin_lock(&bl->lock); - buf->next = bl->next; - bl->next = buf; - spin_unlock(&bl->lock); - - atomic_inc(&bl->count); - if (atomic_read(&bl->count) > dma->buf_count) { - DRM_ERROR("%d of %d buffers free after addition of %d\n", - atomic_read(&bl->count), dma->buf_count, buf->idx); - return 1; - } - /* Check for high water mark */ - if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) { - atomic_set(&bl->wfh, 0); - wake_up_interruptible(&bl->waiting); - } - return 0; -} - -static drm_buf_t *DRM(freelist_try)(drm_freelist_t *bl) -{ - drm_buf_t *buf; - - if (!bl) return NULL; - - /* Get buffer */ - spin_lock(&bl->lock); - if (!bl->next) { - spin_unlock(&bl->lock); - return NULL; - } - buf = bl->next; - bl->next = bl->next->next; - spin_unlock(&bl->lock); - - atomic_dec(&bl->count); - buf->next = NULL; - buf->list = DRM_LIST_NONE; - if (buf->waiting || buf->pending) { - DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n", - buf->idx, buf->waiting, buf->pending, buf->list); - } - - return buf; -} - -drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block) -{ - drm_buf_t *buf = NULL; - DECLARE_WAITQUEUE(entry, current); - - if (!bl || !bl->initialized) return NULL; - - /* Check for low water mark */ - if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */ - atomic_set(&bl->wfh, 1); - if (atomic_read(&bl->wfh)) { - if (block) { - add_wait_queue(&bl->waiting, &entry); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!atomic_read(&bl->wfh) - && (buf = DRM(freelist_try)(bl))) break; - schedule(); - if (signal_pending(current)) break; - } - current->state = TASK_RUNNING; - remove_wait_queue(&bl->waiting, &entry); - } - return buf; - } - - return DRM(freelist_try)(bl); -} - -#endif /* __HAVE_DMA_FREELIST */ diff --git a/linux/drm_lock.h b/linux/drm_lock.h index e9b17cc40..cc9571ed8 100644 --- a/linux/drm_lock.h +++ b/linux/drm_lock.h @@ -32,19 +32,13 @@ #define __NO_VERSION__ #include "drmP.h" -int DRM(block)(struct inode *inode, struct file *filp, unsigned int cmd, +int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { DRM_DEBUG("\n"); return 0; } -int DRM(unblock)(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - DRM_DEBUG("\n"); - return 0; -} int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) { @@ -109,113 +103,6 @@ int DRM(lock_free)(drm_device_t *dev, return 0; } -static int DRM(flush_queue)(drm_device_t *dev, int context) -{ - DECLARE_WAITQUEUE(entry, current); - int ret = 0; - drm_queue_t *q = dev->queuelist[context]; - - DRM_DEBUG("\n"); - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) > 1) { - atomic_inc(&q->block_write); - add_wait_queue(&q->flush_queue, &entry); - atomic_inc(&q->block_count); - for (;;) { - current->state = TASK_INTERRUPTIBLE; - if (!DRM_BUFCOUNT(&q->waitlist)) break; - schedule(); - if (signal_pending(current)) { - ret = -EINTR; /* Can't restart */ - break; - } - } - atomic_dec(&q->block_count); - current->state = TASK_RUNNING; - remove_wait_queue(&q->flush_queue, &entry); - } - atomic_dec(&q->use_count); - - /* NOTE: block_write is still incremented! - Use drm_flush_unlock_queue to decrement. */ - return ret; -} - -static int DRM(flush_unblock_queue)(drm_device_t *dev, int context) -{ - drm_queue_t *q = dev->queuelist[context]; - - DRM_DEBUG("\n"); - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) > 1) { - if (atomic_read(&q->block_write)) { - atomic_dec(&q->block_write); - wake_up_interruptible(&q->write_queue); - } - } - atomic_dec(&q->use_count); - return 0; -} - -int DRM(flush_block_and_flush)(drm_device_t *dev, int context, - drm_lock_flags_t flags) -{ - int ret = 0; - int i; - - DRM_DEBUG("\n"); - - if (flags & _DRM_LOCK_FLUSH) { - ret = DRM(flush_queue)(dev, DRM_KERNEL_CONTEXT); - if (!ret) ret = DRM(flush_queue)(dev, context); - } - if (flags & _DRM_LOCK_FLUSH_ALL) { - for (i = 0; !ret && i < dev->queue_count; i++) { - ret = DRM(flush_queue)(dev, i); - } - } - return ret; -} - -int DRM(flush_unblock)(drm_device_t *dev, int context, drm_lock_flags_t flags) -{ - int ret = 0; - int i; - - DRM_DEBUG("\n"); - - if (flags & _DRM_LOCK_FLUSH) { - ret = DRM(flush_unblock_queue)(dev, DRM_KERNEL_CONTEXT); - if (!ret) ret = DRM(flush_unblock_queue)(dev, context); - } - if (flags & _DRM_LOCK_FLUSH_ALL) { - for (i = 0; !ret && i < dev->queue_count; i++) { - ret = DRM(flush_unblock_queue)(dev, i); - } - } - - return ret; -} - -int DRM(finish)(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - int ret = 0; - drm_lock_t lock; - - DRM_DEBUG("\n"); - - if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) - return -EFAULT; - ret = DRM(flush_block_and_flush)(dev, lock.context, lock.flags); - DRM(flush_unblock)(dev, lock.context, lock.flags); - return ret; -} - /* If we get here, it means that the process has called DRM_IOCTL_LOCK without calling DRM_IOCTL_UNLOCK. diff --git a/linux/drm_os_linux.h b/linux/drm_os_linux.h index b57efd348..b760c1694 100644 --- a/linux/drm_os_linux.h +++ b/linux/drm_os_linux.h @@ -47,9 +47,8 @@ #define DRM_GETSAREA() \ do { \ - struct list_head *list; \ - list_for_each( list, &dev->maplist->head ) { \ - drm_map_list_t *entry = (drm_map_list_t *)list; \ + drm_map_list_t *entry; \ + list_for_each_entry( entry, &dev->maplist->head, head ) { \ if ( entry->map && \ entry->map->type == _DRM_SHM && \ (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \ @@ -61,28 +60,28 @@ do { \ #define DRM_HZ HZ -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -do { \ - DECLARE_WAITQUEUE(entry, current); \ - unsigned long end = jiffies + (timeout); \ - add_wait_queue(&(queue), &entry); \ - \ - for (;;) { \ - current->state = TASK_INTERRUPTIBLE; \ - if (condition) \ - break; \ - if((signed)(end - jiffies) <= 0) { \ - ret = -EBUSY; \ - break; \ - } \ +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +do { \ + DECLARE_WAITQUEUE(entry, current); \ + unsigned long end = jiffies + (timeout); \ + add_wait_queue(&(queue), &entry); \ + \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if((signed)(end - jiffies) <= 0) { \ + ret = -EBUSY; \ + break; \ + } \ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \ - if (signal_pending(current)) { \ - ret = -EINTR; \ - break; \ - } \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&(queue), &entry); \ + if (signal_pending(current)) { \ + ret = -EINTR; \ + break; \ + } \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&(queue), &entry); \ } while (0) diff --git a/linux/drm_proc.h b/linux/drm_proc.h index 8524d2048..148137223 100644 --- a/linux/drm_proc.h +++ b/linux/drm_proc.h @@ -50,10 +50,6 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset, static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); #endif -#if __HAVE_DMA_HISTOGRAM -static int DRM(histo_info)(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -#endif struct drm_proc_list { const char *name; @@ -68,9 +64,6 @@ struct drm_proc_list { #if DRM_DEBUG_CODE { "vma", DRM(vma_info) }, #endif -#if __HAVE_DMA_HISTOGRAM - { "histo", DRM(histo_info) }, -#endif }; #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0])) @@ -187,7 +180,7 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, "address mtrr\n\n"); i = 0; if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; if(!map) continue; if (map->type < 0 || map->type > 4) type = "??"; @@ -491,143 +484,3 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, #endif -#if __HAVE_DMA_HISTOGRAM -static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - drm_device_t *dev = (drm_device_t *)data; - int len = 0; - drm_device_dma_t *dma = dev->dma; - int i; - unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL; - unsigned long prev_value = 0; - drm_buf_t *buffer; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT("general statistics:\n"); - DRM_PROC_PRINT("total %10u\n", atomic_read(&dev->histo.total)); - DRM_PROC_PRINT("open %10u\n", - atomic_read(&dev->counts[_DRM_STAT_OPENS])); - DRM_PROC_PRINT("close %10u\n", - atomic_read(&dev->counts[_DRM_STAT_CLOSES])); - DRM_PROC_PRINT("ioctl %10u\n", - atomic_read(&dev->counts[_DRM_STAT_IOCTLS])); - - DRM_PROC_PRINT("\nlock statistics:\n"); - DRM_PROC_PRINT("locks %10u\n", - atomic_read(&dev->counts[_DRM_STAT_LOCKS])); - DRM_PROC_PRINT("unlocks %10u\n", - atomic_read(&dev->counts[_DRM_STAT_UNLOCKS])); - - if (dma) { -#if 0 - DRM_PROC_PRINT("\ndma statistics:\n"); - DRM_PROC_PRINT("prio %10u\n", - atomic_read(&dma->total_prio)); - DRM_PROC_PRINT("bytes %10u\n", - atomic_read(&dma->total_bytes)); - DRM_PROC_PRINT("dmas %10u\n", - atomic_read(&dma->total_dmas)); - DRM_PROC_PRINT("missed:\n"); - DRM_PROC_PRINT(" dma %10u\n", - atomic_read(&dma->total_missed_dma)); - DRM_PROC_PRINT(" lock %10u\n", - atomic_read(&dma->total_missed_lock)); - DRM_PROC_PRINT(" free %10u\n", - atomic_read(&dma->total_missed_free)); - DRM_PROC_PRINT(" sched %10u\n", - atomic_read(&dma->total_missed_sched)); - DRM_PROC_PRINT("tried %10u\n", - atomic_read(&dma->total_tried)); - DRM_PROC_PRINT("hit %10u\n", - atomic_read(&dma->total_hit)); - DRM_PROC_PRINT("lost %10u\n", - atomic_read(&dma->total_lost)); -#endif - - buffer = dma->next_buffer; - if (buffer) { - DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx); - } else { - DRM_PROC_PRINT("next_buffer none\n"); - } - buffer = dma->this_buffer; - if (buffer) { - DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx); - } else { - DRM_PROC_PRINT("this_buffer none\n"); - } - } - - - DRM_PROC_PRINT("\nvalues:\n"); - if (dev->lock.hw_lock) { - DRM_PROC_PRINT("lock 0x%08x\n", - dev->lock.hw_lock->lock); - } else { - DRM_PROC_PRINT("lock none\n"); - } - DRM_PROC_PRINT("context_flag 0x%08lx\n", dev->context_flag); - DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag); - DRM_PROC_PRINT("dma_flag 0x%08lx\n", dev->dma_flag); - - DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count); - DRM_PROC_PRINT("last_context %10d\n", dev->last_context); - DRM_PROC_PRINT("last_switch %10lu\n", dev->last_switch); - DRM_PROC_PRINT("last_checked %10d\n", dev->last_checked); - - - DRM_PROC_PRINT("\n q2d d2c c2f" - " q2c q2f dma sch" - " ctx lacq lhld\n\n"); - for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) { - DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u" - " %10u %10u %10u %10u %10u\n", - i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ", - i == DRM_DMA_HISTOGRAM_SLOTS - 1 - ? prev_value : slot_value , - - atomic_read(&dev->histo - .queued_to_dispatched[i]), - atomic_read(&dev->histo - .dispatched_to_completed[i]), - atomic_read(&dev->histo - .completed_to_freed[i]), - - atomic_read(&dev->histo - .queued_to_completed[i]), - atomic_read(&dev->histo - .queued_to_freed[i]), - atomic_read(&dev->histo.dma[i]), - atomic_read(&dev->histo.schedule[i]), - atomic_read(&dev->histo.ctx[i]), - atomic_read(&dev->histo.lacq[i]), - atomic_read(&dev->histo.lhld[i])); - prev_value = slot_value; - slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value); - } - - if (len > request + offset) return request; - *eof = 1; - return len - offset; -} - -static int DRM(histo_info)(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - drm_device_t *dev = (drm_device_t *)data; - int ret; - - down(&dev->struct_sem); - ret = DRM(_histo_info)(buf, start, offset, request, eof, data); - up(&dev->struct_sem); - return ret; -} -#endif diff --git a/linux/drm_vm.h b/linux/drm_vm.h index 9101e1365..76a10cf54 100644 --- a/linux/drm_vm.h +++ b/linux/drm_vm.h @@ -74,7 +74,7 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; if (!map) continue; if (map->offset == VM_OFFSET(vma)) break; @@ -190,7 +190,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma) found_maps = 0; list = &dev->maplist->head; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *) list; + r_list = list_entry(list, drm_map_list_t, head); if (r_list->map == map) found_maps++; } @@ -393,7 +393,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) list_for_each(list, &dev->maplist->head) { unsigned long off; - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); map = r_list->map; if (!map) continue; off = DRIVER_GET_MAP_OFS(); diff --git a/linux/gamma.h b/linux/gamma.h index 44d8d5bce..a5090c843 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -95,54 +95,25 @@ #define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_IRQ_BH 1 -#if 1 -#define DRIVER_PREINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); \ - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ -} while (0) -#define DRIVER_POSTINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ -} while (0) -#else -#define DRIVER_POSTINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); \ -} while (0) - -#define DRIVER_PREINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );\ - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );\ -} while (0) -#endif - -#define DRIVER_UNINSTALL() do { \ - drm_gamma_private_t *dev_priv = \ - (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ -} while (0) - #define DRIVER_AGP_BUFFERS_MAP( dev ) \ ((drm_gamma_private_t *)((dev)->dev_private))->buffers +/* Gamma makes use of a wierd mechanism to get the DDX driver to do + * context switches on behalf of the 3d clients via a trip to the + * kernel module. This requires read/poll functionality on the drm + * file descriptor not normally present: + */ +#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), \ +} + #endif /* __GAMMA_H__ */ diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index a3c21d110..baa6b287c 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.c @@ -127,9 +127,13 @@ void gamma_dma_service(int irq, void *device, struct pt_regs *regs) } clear_bit(0, &dev->dma_flag); +#if !HAS_WORKQUEUE /* Dispatch new buffer */ queue_task(&dev->tq, &tq_immediate); mark_bh(IMMEDIATE_BH); +#else + schedule_work(&dev->work); +#endif } } @@ -141,15 +145,9 @@ static int gamma_do_dma(drm_device_t *dev, int locked) drm_buf_t *buf; int retcode = 0; drm_device_dma_t *dma = dev->dma; -#if DRM_DMA_HISTOGRAM - cycles_t dma_start, dma_stop; -#endif if (test_and_set_bit(0, &dev->dma_flag)) return -EBUSY; -#if DRM_DMA_HISTOGRAM - dma_start = get_cycles(); -#endif if (!dma->next_buffer) { DRM_ERROR("No next_buffer\n"); @@ -223,9 +221,6 @@ static int gamma_do_dma(drm_device_t *dev, int locked) buf->pending = 1; buf->waiting = 0; buf->list = DRM_LIST_PEND; -#if DRM_DMA_HISTOGRAM - buf->time_dispatched = get_cycles(); -#endif /* WE NOW ARE ON LOGICAL PAGES!!! - overriding address */ address = buf->idx << 12; @@ -247,10 +242,6 @@ cleanup: clear_bit(0, &dev->dma_flag); -#if DRM_DMA_HISTOGRAM - dma_stop = get_cycles(); - atomic_inc(&dev->histo.dma[gamma_histogram_slot(dma_stop - dma_start)]); -#endif return retcode; } @@ -275,9 +266,6 @@ int gamma_dma_schedule(drm_device_t *dev, int locked) int missed; int expire = 20; drm_device_dma_t *dma = dev->dma; -#if DRM_DMA_HISTOGRAM - cycles_t schedule_start; -#endif if (test_and_set_bit(0, &dev->interrupt_flag)) { /* Not reentrant */ @@ -286,9 +274,6 @@ int gamma_dma_schedule(drm_device_t *dev, int locked) } missed = atomic_read(&dev->counts[10]); -#if DRM_DMA_HISTOGRAM - schedule_start = get_cycles(); -#endif again: if (dev->context_flag) { @@ -335,10 +320,6 @@ again: clear_bit(0, &dev->interrupt_flag); -#if DRM_DMA_HISTOGRAM - atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles() - - schedule_start)]); -#endif return retcode; } @@ -450,10 +431,6 @@ static int gamma_dma_priority(struct file *filp, } } -#if DRM_DMA_HISTOGRAM - buf->time_queued = get_cycles(); - buf->time_dispatched = buf->time_queued; -#endif gamma_dma_dispatch(dev, address, length); atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */ atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */ @@ -607,7 +584,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) memset( dev_priv, 0, sizeof(drm_gamma_private_t) ); list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; + drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if( r_list->map && r_list->map->type == _DRM_SHM && r_list->map->flags & _DRM_CONTAINS_LOCK ) { @@ -669,7 +646,8 @@ int gamma_do_cleanup_dma( drm_device_t *dev ) if ( dev->dev_private ) { drm_gamma_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), DRM_MEM_DRIVER ); @@ -811,7 +789,7 @@ int gamma_setsareactx(struct inode *inode, struct file *filp, down(&dev->struct_sem); r_list = NULL; list_for_each(list, &dev->maplist->head) { - r_list = (drm_map_list_t *)list; + r_list = list_entry(list, drm_map_list_t, head); if(r_list->map && r_list->map->handle == request.handle) break; } @@ -833,3 +811,35 @@ int gamma_setsareactx(struct inode *inode, struct file *filp, up(&dev->struct_sem); return 0; } + +void DRM(driver_irq_preinstall)( drm_device_t *dev ) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); +} + +void DRM(driver_irq_postinstall)( drm_device_t *dev ) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); +} + +void DRM(driver_irq_uninstall)( drm_device_t *dev ) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); +} diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index b41526bbc..f1b8b205f 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -39,16 +39,18 @@ #include "drm_auth.h" #include "drm_agpsupport.h" #include "drm_bufs.h" -#include "drm_context.h" +#include "gamma_context.h" /* NOTE! */ #include "drm_dma.h" +#include "gamma_old_dma.h" /* NOTE */ #include "drm_drawable.h" #include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" -#include "drm_lists.h" +#include "gamma_lists.h" /* NOTE */ #include "drm_lock.h" +#include "gamma_lock.h" /* NOTE */ #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h index 2f7d3588f..36affa68a 100644 --- a/linux/gamma_drv.h +++ b/linux/gamma_drv.h @@ -59,6 +59,29 @@ extern int gamma_dma(struct inode *inode, struct file *filp, extern int gamma_find_devices(void); extern int gamma_found(void); +/* Gamma-specific code pulled from drm_dma.h: + */ +extern void DRM(clear_next_buffer)(drm_device_t *dev); +extern int DRM(select_queue)(drm_device_t *dev, + void (*wrapper)(unsigned long)); +extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma); +extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma); + + +/* Gamma-specific code pulled from drm_lists.h (now renamed gamma_lists.h): + */ +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); +extern int DRM(freelist_create)(drm_freelist_t *bl, int count); +extern int DRM(freelist_destroy)(drm_freelist_t *bl); +extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, + drm_buf_t *buf); +extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); + + + #define GLINT_DRI_BUF_COUNT 256 #define GAMMA_OFF(reg) \ diff --git a/linux/i810.h b/linux/i810.h index f37cb2e87..72cbed325 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -93,7 +93,7 @@ */ #define __HAVE_DMA 1 #define __HAVE_DMA_QUEUE 1 -#define __HAVE_DMA_WAITLIST 1 +#define __HAVE_DMA_WAITLIST 0 #define __HAVE_DMA_RECLAIM 1 #define __HAVE_DMA_QUIESCENT 1 diff --git a/linux/i810_dma.c b/linux/i810_dma.c index de9345e3b..a37271643 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -122,9 +122,7 @@ static struct file_operations i810_buffer_fops = { .release = DRM(release), .ioctl = DRM(ioctl), .mmap = i810_mmap_buffers, - .read = DRM(read), .fasync = DRM(fasync), - .poll = DRM(poll), }; int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -263,7 +261,8 @@ static int i810_dma_cleanup(drm_device_t *dev) for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + if ( buf_priv->kernel_virtual && buf->total ) + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); } } return 0; @@ -347,7 +346,7 @@ static int i810_dma_initialize(drm_device_t *dev, memset(dev_priv, 0, sizeof(drm_i810_private_t)); list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; + drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if( r_list->map && r_list->map->type == _DRM_SHM && r_list->map->flags & _DRM_CONTAINS_LOCK ) { diff --git a/linux/i810_drv.c b/linux/i810_drv.c index 439d7887a..0bc793864 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -49,7 +49,6 @@ #include "drm_init.h" #include "drm_ioctl.h" #include "drm_lock.h" -#include "drm_lists.h" #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/linux/i830.h b/linux/i830.h index a351a4cff..432397a86 100644 --- a/linux/i830.h +++ b/linux/i830.h @@ -94,7 +94,7 @@ */ #define __HAVE_DMA 1 #define __HAVE_DMA_QUEUE 1 -#define __HAVE_DMA_WAITLIST 1 +#define __HAVE_DMA_WAITLIST 0 #define __HAVE_DMA_RECLAIM 1 #define __HAVE_DMA_QUIESCENT 1 diff --git a/linux/i830_dma.c b/linux/i830_dma.c index 47f10d56f..df58e9900 100644 --- a/linux/i830_dma.c +++ b/linux/i830_dma.c @@ -130,9 +130,7 @@ static struct file_operations i830_buffer_fops = { .release = DRM(release), .ioctl = DRM(ioctl), .mmap = i830_mmap_buffers, - .read = DRM(read), .fasync = DRM(fasync), - .poll = DRM(poll), }; int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) @@ -280,7 +278,8 @@ static int i830_dma_cleanup(drm_device_t *dev) for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + if ( buf_priv->kernel_virtual && buf->total ) + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); } } return 0; @@ -370,7 +369,7 @@ static int i830_dma_initialize(drm_device_t *dev, memset(dev_priv, 0, sizeof(drm_i830_private_t)); list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; + drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); if( r_list->map && r_list->map->type == _DRM_SHM && r_list->map->flags & _DRM_CONTAINS_LOCK ) { diff --git a/linux/i830_drv.c b/linux/i830_drv.c index d9a659a44..0735c94db 100644 --- a/linux/i830_drv.c +++ b/linux/i830_drv.c @@ -51,7 +51,6 @@ #include "drm_init.h" #include "drm_ioctl.h" #include "drm_lock.h" -#include "drm_lists.h" #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/linux/picker.c b/linux/picker.c deleted file mode 100644 index 6c228dfc3..000000000 --- a/linux/picker.c +++ /dev/null @@ -1,30 +0,0 @@ - -#include -#include - -#ifndef CONFIG_SMP -#define CONFIG_SMP 0 -#endif - -#ifndef CONFIG_MODULES -#define CONFIG_MODULES 0 -#endif - -#ifndef CONFIG_MODVERSIONS -#define CONFIG_MODVERSIONS 0 -#endif - -#ifndef CONFIG_AGP_MODULE -#define CONFIG_AGP_MODULE 0 -#endif - -#ifndef CONFIG_AGP -#define CONFIG_AGP 0 -#endif - -SMP = CONFIG_SMP -MODULES = CONFIG_MODULES -MODVERSIONS = CONFIG_MODVERSIONS -AGP = CONFIG_AGP -AGP_MODULE = CONFIG_AGP_MODULE -RELEASE = UTS_RELEASE diff --git a/linux/sis_drv.c b/linux/sis_drv.c index 0c917bd4e..3dd075d30 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -41,7 +41,6 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" -#include "drm_lists.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c index 5e95c9f9b..96fd97ff0 100644 --- a/shared-core/mga_dma.c +++ b/shared-core/mga_dma.c @@ -642,9 +642,12 @@ int mga_do_cleanup_dma( drm_device_t *dev ) if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->warp ); - DRM_IOREMAPFREE( dev_priv->primary ); - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->warp != NULL ) + DRM_IOREMAPFREE( dev_priv->warp ); + if ( dev_priv->primary != NULL ) + DRM_IOREMAPFREE( dev_priv->primary ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); if ( dev_priv->head != NULL ) { mga_freelist_cleanup( dev ); diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c index 7f0f43254..ad03f4f9d 100644 --- a/shared-core/r128_cce.c +++ b/shared-core/r128_cce.c @@ -619,9 +619,12 @@ int r128_do_cleanup_cce( drm_device_t *dev ) #if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { #endif - DRM_IOREMAPFREE( dev_priv->cce_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->cce_ring != NULL ) + DRM_IOREMAPFREE( dev_priv->cce_ring ); + if ( dev_priv->ring_rptr != NULL ) + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); #if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 3ec8dfd17..fce148a04 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -36,12 +36,6 @@ #define RADEON_FIFO_DEBUG 0 -#if defined(__alpha__) || defined(__powerpc__) -# define PCIGART_ENABLED -#else -# undef PCIGART_ENABLED -#endif - /* CP microcode (from ATI) */ static u32 R200_cp_microcode[][2] = { @@ -777,7 +771,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); - *dev_priv->ring.head = cur_read_ptr; + SET_RING_HEAD( dev_priv, cur_read_ptr ); dev_priv->ring.tail = cur_read_ptr; } @@ -889,13 +883,18 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, /* Initialize the ring buffer's read and write pointers */ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); - *dev_priv->ring.head = cur_read_ptr; + SET_RING_HEAD( dev_priv, cur_read_ptr ); dev_priv->ring.tail = cur_read_ptr; +#if __REALLY_HAVE_AGP if ( !dev_priv->is_pci ) { RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset ); - } else { + dev_priv->ring_rptr->offset + - dev->agp->base + + dev_priv->agp_vm_start); + } else +#endif + { drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; @@ -920,7 +919,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, + RADEON_SCRATCH_REG_OFFSET ); dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring.head + + dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); @@ -990,17 +989,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->is_pci = init->is_pci; -#if !defined(PCIGART_ENABLED) - /* PCI support is not 100% working, so we disable it here. - */ - if ( dev_priv->is_pci ) { - DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); - dev->dev_private = (void *)dev_priv; - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } -#endif - if ( dev_priv->is_pci && !dev->sg ) { DRM_ERROR( "PCI GART memory not allocated!\n" ); dev->dev_private = (void *)dev_priv; @@ -1097,6 +1085,13 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_ROUND_PREC_8TH_PIX); DRM_GETSAREA(); + + dev_priv->fb_offset = init->fb_offset; + dev_priv->mmio_offset = init->mmio_offset; + dev_priv->ring_offset = init->ring_offset; + dev_priv->ring_rptr_offset = init->ring_rptr_offset; + dev_priv->buffers_offset = init->buffers_offset; + dev_priv->agp_textures_offset = init->agp_textures_offset; if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); @@ -1204,9 +1199,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", dev_priv->agp_buffers_offset ); - dev_priv->ring.head = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle); - dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle + init->ring_size / sizeof(u32)); @@ -1217,7 +1209,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - dev_priv->ring.ring_rptr = dev_priv->ring_rptr; #if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { @@ -1279,9 +1270,12 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) drm_radeon_private_t *dev_priv = dev->dev_private; if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cp_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->cp_ring != NULL ) + DRM_IOREMAPFREE( dev_priv->cp_ring ); + if ( dev_priv->ring_rptr != NULL ) + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); } else { #if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, @@ -1592,10 +1586,10 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; - u32 last_head = GET_RING_HEAD(ring); + u32 last_head = GET_RING_HEAD( dev_priv ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - u32 head = GET_RING_HEAD(ring); + u32 head = GET_RING_HEAD( dev_priv ); ring->space = (head - ring->tail) * sizeof(u32); if ( ring->space <= 0 ) diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index b280eae59..7efb3c16e 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -526,6 +526,10 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_LAST_CLEAR 4 #define RADEON_PARAM_IRQ_NR 5 #define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */ +#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */ +#define RADEON_PARAM_STATUS_HANDLE 8 +#define RADEON_PARAM_SAREA_HANDLE 9 +#define RADEON_PARAM_AGP_TEX_HANDLE 10 typedef struct drm_radeon_getparam { int param; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 6d70576de..f79cc6daf 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -31,8 +31,8 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_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) DRM_READ32( (dev_priv)->ring_rptr, 0 ) +#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) typedef struct drm_radeon_freelist { unsigned int age; @@ -47,13 +47,11 @@ typedef struct drm_radeon_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_radeon_ring_buffer_t; typedef struct drm_radeon_depth_clear_t { @@ -126,6 +124,13 @@ typedef struct drm_radeon_private { u32 depth_pitch_offset; drm_radeon_depth_clear_t depth_clear; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; drm_local_map_t *sarea; drm_local_map_t *fb; @@ -776,7 +781,7 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \ - u32 head = GET_RING_HEAD(&dev_priv->ring); \ + u32 head = GET_RING_HEAD( dev_priv ); \ if (head == dev_priv->ring.tail) \ dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \ } \ @@ -848,8 +853,8 @@ do { \ #define COMMIT_RING() do { \ /* Flush writes to ring */ \ - DRM_READMEMORYBARRIER(dev_priv->mmio); \ - GET_RING_HEAD( &dev_priv->ring ); \ + DRM_READMEMORYBARRIER( dev_priv->mmio ); \ + GET_RING_HEAD( dev_priv ); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ /* read from PCI bus to ensure correct posting */ \ RADEON_READ( RADEON_CP_RB_RPTR ); \ diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 86cbead5d..8e9485a77 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -2191,6 +2191,19 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS ) case RADEON_PARAM_AGP_BASE: value = dev_priv->agp_vm_start; break; + case RADEON_PARAM_REGISTER_HANDLE: + value = dev_priv->mmio_offset; + break; + case RADEON_PARAM_STATUS_HANDLE: + value = dev_priv->ring_rptr_offset; + break; + case RADEON_PARAM_SAREA_HANDLE: + /* The lock is the first dword in the sarea. */ + value = (int)dev->lock.hw_lock; + break; + case RADEON_PARAM_AGP_TEX_HANDLE: + value = dev_priv->agp_textures_offset; + break; default: return DRM_ERR(EINVAL); } diff --git a/shared/mga_dma.c b/shared/mga_dma.c index 5e95c9f9b..96fd97ff0 100644 --- a/shared/mga_dma.c +++ b/shared/mga_dma.c @@ -642,9 +642,12 @@ int mga_do_cleanup_dma( drm_device_t *dev ) if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->warp ); - DRM_IOREMAPFREE( dev_priv->primary ); - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->warp != NULL ) + DRM_IOREMAPFREE( dev_priv->warp ); + if ( dev_priv->primary != NULL ) + DRM_IOREMAPFREE( dev_priv->primary ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); if ( dev_priv->head != NULL ) { mga_freelist_cleanup( dev ); diff --git a/shared/r128_cce.c b/shared/r128_cce.c index 7f0f43254..ad03f4f9d 100644 --- a/shared/r128_cce.c +++ b/shared/r128_cce.c @@ -619,9 +619,12 @@ int r128_do_cleanup_cce( drm_device_t *dev ) #if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { #endif - DRM_IOREMAPFREE( dev_priv->cce_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->cce_ring != NULL ) + DRM_IOREMAPFREE( dev_priv->cce_ring ); + if ( dev_priv->ring_rptr != NULL ) + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); #if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, diff --git a/shared/radeon.h b/shared/radeon.h index d465773e1..7e75e69d3 100644 --- a/shared/radeon.h +++ b/shared/radeon.h @@ -78,6 +78,7 @@ * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian) * 1.8 - Remove need to call cleanup ioctls on last client exit (keith) + * Add 'GET' queries for starting additional clients on different VT's. */ #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c index 3ec8dfd17..fce148a04 100644 --- a/shared/radeon_cp.c +++ b/shared/radeon_cp.c @@ -36,12 +36,6 @@ #define RADEON_FIFO_DEBUG 0 -#if defined(__alpha__) || defined(__powerpc__) -# define PCIGART_ENABLED -#else -# undef PCIGART_ENABLED -#endif - /* CP microcode (from ATI) */ static u32 R200_cp_microcode[][2] = { @@ -777,7 +771,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); - *dev_priv->ring.head = cur_read_ptr; + SET_RING_HEAD( dev_priv, cur_read_ptr ); dev_priv->ring.tail = cur_read_ptr; } @@ -889,13 +883,18 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, /* Initialize the ring buffer's read and write pointers */ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); - *dev_priv->ring.head = cur_read_ptr; + SET_RING_HEAD( dev_priv, cur_read_ptr ); dev_priv->ring.tail = cur_read_ptr; +#if __REALLY_HAVE_AGP if ( !dev_priv->is_pci ) { RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset ); - } else { + dev_priv->ring_rptr->offset + - dev->agp->base + + dev_priv->agp_vm_start); + } else +#endif + { drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; @@ -920,7 +919,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, + RADEON_SCRATCH_REG_OFFSET ); dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring.head + + dev_priv->ring_rptr->handle + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); @@ -990,17 +989,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) dev_priv->is_pci = init->is_pci; -#if !defined(PCIGART_ENABLED) - /* PCI support is not 100% working, so we disable it here. - */ - if ( dev_priv->is_pci ) { - DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); - dev->dev_private = (void *)dev_priv; - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } -#endif - if ( dev_priv->is_pci && !dev->sg ) { DRM_ERROR( "PCI GART memory not allocated!\n" ); dev->dev_private = (void *)dev_priv; @@ -1097,6 +1085,13 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_ROUND_PREC_8TH_PIX); DRM_GETSAREA(); + + dev_priv->fb_offset = init->fb_offset; + dev_priv->mmio_offset = init->mmio_offset; + dev_priv->ring_offset = init->ring_offset; + dev_priv->ring_rptr_offset = init->ring_rptr_offset; + dev_priv->buffers_offset = init->buffers_offset; + dev_priv->agp_textures_offset = init->agp_textures_offset; if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); @@ -1204,9 +1199,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", dev_priv->agp_buffers_offset ); - dev_priv->ring.head = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle); - dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle + init->ring_size / sizeof(u32)); @@ -1217,7 +1209,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - dev_priv->ring.ring_rptr = dev_priv->ring_rptr; #if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { @@ -1279,9 +1270,12 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) drm_radeon_private_t *dev_priv = dev->dev_private; if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cp_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + if ( dev_priv->cp_ring != NULL ) + DRM_IOREMAPFREE( dev_priv->cp_ring ); + if ( dev_priv->ring_rptr != NULL ) + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + if ( dev_priv->buffers != NULL ) + DRM_IOREMAPFREE( dev_priv->buffers ); } else { #if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, @@ -1592,10 +1586,10 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; - u32 last_head = GET_RING_HEAD(ring); + u32 last_head = GET_RING_HEAD( dev_priv ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - u32 head = GET_RING_HEAD(ring); + u32 head = GET_RING_HEAD( dev_priv ); ring->space = (head - ring->tail) * sizeof(u32); if ( ring->space <= 0 ) diff --git a/shared/radeon_drm.h b/shared/radeon_drm.h index b280eae59..7efb3c16e 100644 --- a/shared/radeon_drm.h +++ b/shared/radeon_drm.h @@ -526,6 +526,10 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_LAST_CLEAR 4 #define RADEON_PARAM_IRQ_NR 5 #define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */ +#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */ +#define RADEON_PARAM_STATUS_HANDLE 8 +#define RADEON_PARAM_SAREA_HANDLE 9 +#define RADEON_PARAM_AGP_TEX_HANDLE 10 typedef struct drm_radeon_getparam { int param; diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h index 6d70576de..f79cc6daf 100644 --- a/shared/radeon_drv.h +++ b/shared/radeon_drv.h @@ -31,8 +31,8 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_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) DRM_READ32( (dev_priv)->ring_rptr, 0 ) +#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) typedef struct drm_radeon_freelist { unsigned int age; @@ -47,13 +47,11 @@ typedef struct drm_radeon_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_radeon_ring_buffer_t; typedef struct drm_radeon_depth_clear_t { @@ -126,6 +124,13 @@ typedef struct drm_radeon_private { u32 depth_pitch_offset; drm_radeon_depth_clear_t depth_clear; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; drm_local_map_t *sarea; drm_local_map_t *fb; @@ -776,7 +781,7 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \ - u32 head = GET_RING_HEAD(&dev_priv->ring); \ + u32 head = GET_RING_HEAD( dev_priv ); \ if (head == dev_priv->ring.tail) \ dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \ } \ @@ -848,8 +853,8 @@ do { \ #define COMMIT_RING() do { \ /* Flush writes to ring */ \ - DRM_READMEMORYBARRIER(dev_priv->mmio); \ - GET_RING_HEAD( &dev_priv->ring ); \ + DRM_READMEMORYBARRIER( dev_priv->mmio ); \ + GET_RING_HEAD( dev_priv ); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ /* read from PCI bus to ensure correct posting */ \ RADEON_READ( RADEON_CP_RB_RPTR ); \ diff --git a/shared/radeon_state.c b/shared/radeon_state.c index 86cbead5d..8e9485a77 100644 --- a/shared/radeon_state.c +++ b/shared/radeon_state.c @@ -2191,6 +2191,19 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS ) case RADEON_PARAM_AGP_BASE: value = dev_priv->agp_vm_start; break; + case RADEON_PARAM_REGISTER_HANDLE: + value = dev_priv->mmio_offset; + break; + case RADEON_PARAM_STATUS_HANDLE: + value = dev_priv->ring_rptr_offset; + break; + case RADEON_PARAM_SAREA_HANDLE: + /* The lock is the first dword in the sarea. */ + value = (int)dev->lock.hw_lock; + break; + case RADEON_PARAM_AGP_TEX_HANDLE: + value = dev_priv->agp_textures_offset; + break; default: return DRM_ERR(EINVAL); } -- cgit v1.2.3