summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <idr@us.ibm.com>2003-04-23 02:20:25 +0000
committerIan Romanick <idr@us.ibm.com>2003-04-23 02:20:25 +0000
commit189ad4f724036aeb37ef4e7b5b7d25e3f3250bd8 (patch)
treee59c024f2cfc4d93630697065b9d2c4dcf070b35
parente9cced1b969aff998c5747f531f9cf7428f88bc7 (diff)
Merge from trunk.texmem-0-0-1
-rw-r--r--linux-core/Config.in19
-rw-r--r--linux-core/Makefile.kernel43
-rw-r--r--linux-core/drmP.h121
-rw-r--r--linux-core/drm_agpsupport.c8
-rw-r--r--linux-core/drm_bufs.c20
-rw-r--r--linux-core/drm_context.c396
-rw-r--r--linux-core/drm_dma.c341
-rw-r--r--linux-core/drm_drv.c55
-rw-r--r--linux-core/drm_fops.c95
-rw-r--r--linux-core/drm_init.c5
-rw-r--r--linux-core/drm_ioctl.c2
-rw-r--r--linux-core/drm_lock.c115
-rw-r--r--linux-core/drm_os_linux.h47
-rw-r--r--linux-core/drm_proc.c149
-rw-r--r--linux-core/drm_vm.c6
-rw-r--r--linux-core/i810_dma.c7
-rw-r--r--linux-core/i810_drv.c1
-rw-r--r--linux-core/i830_dma.c7
-rw-r--r--linux-core/i830_drv.c1
-rw-r--r--linux-core/sis_drv.c1
-rw-r--r--linux/Config.in19
-rw-r--r--linux/Makefile.kernel43
-rw-r--r--linux/Makefile.linux488
-rw-r--r--linux/drmP.h121
-rw-r--r--linux/drm_agpsupport.h8
-rw-r--r--linux/drm_bufs.h20
-rw-r--r--linux/drm_context.h396
-rw-r--r--linux/drm_dma.h341
-rw-r--r--linux/drm_drv.h55
-rw-r--r--linux/drm_fops.h95
-rw-r--r--linux/drm_init.h5
-rw-r--r--linux/drm_ioctl.h2
-rw-r--r--linux/drm_lists.h230
-rw-r--r--linux/drm_lock.h115
-rw-r--r--linux/drm_os_linux.h47
-rw-r--r--linux/drm_proc.h149
-rw-r--r--linux/drm_vm.h6
-rw-r--r--linux/gamma.h65
-rw-r--r--linux/gamma_dma.c70
-rw-r--r--linux/gamma_drv.c6
-rw-r--r--linux/gamma_drv.h23
-rw-r--r--linux/i810.h2
-rw-r--r--linux/i810_dma.c7
-rw-r--r--linux/i810_drv.c1
-rw-r--r--linux/i830.h2
-rw-r--r--linux/i830_dma.c7
-rw-r--r--linux/i830_drv.c1
-rw-r--r--linux/picker.c30
-rw-r--r--linux/sis_drv.c1
-rw-r--r--shared-core/mga_dma.c9
-rw-r--r--shared-core/r128_cce.c9
-rw-r--r--shared-core/radeon_cp.c56
-rw-r--r--shared-core/radeon_drm.h4
-rw-r--r--shared-core/radeon_drv.h19
-rw-r--r--shared-core/radeon_state.c13
-rw-r--r--shared/mga_dma.c9
-rw-r--r--shared/r128_cce.c9
-rw-r--r--shared/radeon.h1
-rw-r--r--shared/radeon_cp.c56
-rw-r--r--shared/radeon_drm.h4
-rw-r--r--shared/radeon_drv.h19
-rw-r--r--shared/radeon_state.c13
62 files changed, 776 insertions, 3239 deletions
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 <linux/types.h>
#include <linux/agp_backend.h>
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
+#define HAS_WORKQUEUE 0
+#else
+#define HAS_WORKQUEUE 1
+#endif
+#if !HAS_WORKQUEUE
#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
#include <linux/poll.h>
#include <asm/pgalloc.h>
#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 );
@@ -859,25 +832,7 @@ extern void DRM(vbl_send_signals)( drm_device_t *dev );
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;
@@ -1011,19 +1011,10 @@ int DRM(lock)( struct inode *inode, struct file *filp,
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 <linux/types.h>
#include <linux/agp_backend.h>
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
+#define HAS_WORKQUEUE 0
+#else
+#define HAS_WORKQUEUE 1
+#endif
+#if !HAS_WORKQUEUE
#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
#include <linux/poll.h>
#include <asm/pgalloc.h>
#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 );
@@ -859,25 +832,7 @@ extern void DRM(vbl_send_signals)( drm_device_t *dev );
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;
@@ -1011,19 +1011,10 @@ int DRM(lock)( struct inode *inode, struct file *filp,
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 <faith@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- */
-
-#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 <linux/config.h>
-#include <linux/version.h>
-
-#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);
}