summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drmP.h41
-rw-r--r--linux-core/drm_agpsupport.c6
-rw-r--r--linux-core/drm_context.c29
-rw-r--r--linux-core/drm_drv.c26
-rw-r--r--linux-core/drm_memory_debug.h1
-rw-r--r--linux/drmP.h41
-rw-r--r--linux/drm_agpsupport.h6
-rw-r--r--linux/drm_context.h29
-rw-r--r--linux/drm_drv.h26
-rw-r--r--linux/drm_memory_debug.h1
-rw-r--r--shared-core/sis_mm.c4
-rw-r--r--shared/sis_mm.c4
12 files changed, 178 insertions, 36 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index b7b346d4..c2c14dbd 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -158,6 +158,7 @@
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
#define DRM_MEM_SGLISTS 20
+#define DRM_MEM_CTXLIST 21
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
@@ -201,6 +202,14 @@
prefetch(pos->member.next))
#endif
+#ifndef list_for_each_entry_safe
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
static inline struct page * vmalloc_to_page(void * vmalloc_addr)
{
@@ -309,19 +318,6 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr)
DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \
} while (0)
-#ifndef VMAP_4_ARGS
-
-#define DRM_IOREMAPAGP(map, dev) \
- (map)->handle = DRM(ioremap_agp)( (map)->offset, (map)->size, (dev) )
-
-#define DRM_IOREMAPAGPFREE(map) \
- do { \
- if ( (map)->handle && (map)->size ) \
- DRM(ioremap_agp_free)( (map)->handle, (map)->size ); \
- } while (0)
-
-#endif
-
/**
* Find mapping.
*
@@ -651,6 +647,15 @@ typedef struct drm_map_list {
typedef drm_map_t drm_local_map_t;
+/**
+ * Context handle list
+ */
+typedef struct drm_ctx_list {
+ struct list_head head; /**< list head */
+ drm_context_t handle; /**< context handle */
+ drm_file_t *tag; /**< associated fd private data */
+} drm_ctx_list_t;
+
#if __HAVE_VBL_IRQ
typedef struct drm_vbl_sig {
@@ -711,6 +716,12 @@ typedef struct drm_device {
drm_map_list_t *maplist; /**< Linked list of regions */
int map_count; /**< Number of mappable regions */
+ /** \name Context handle management */
+ /*@{*/
+ drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
+ int ctx_count; /**< Number of context handles */
+ struct semaphore ctxlist_sem; /**< For ctxlist */
+
drm_map_t **context_sareas; /**< per-context SAREA's */
int max_context;
@@ -846,10 +857,6 @@ extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
#if __REALLY_HAVE_AGP
-#ifndef VMAP_4_ARGS
-extern void *DRM(ioremap_agp)(unsigned long offset, unsigned long size, drm_device_t *dev);
-extern void DRM(ioremap_agp_free)(void *pt, unsigned long size);
-#endif
extern DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type);
extern int DRM(free_agp)(DRM_AGP_MEM *handle, int pages);
extern int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start);
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c
index 0f281b57..f83651af 100644
--- a/linux-core/drm_agpsupport.c
+++ b/linux-core/drm_agpsupport.c
@@ -104,7 +104,11 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
int retcode;
- if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
+ if (!dev->agp)
+ return -ENODEV;
+ if (dev->agp->acquired)
+ return -EBUSY;
+ if (!drm_agp->acquire)
return -EINVAL;
#ifndef VMAP_4_ARGS
if ( dev->agp->cant_use_aperture )
diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c
index 82e90bcc..474b5ba0 100644
--- a/linux-core/drm_context.c
+++ b/linux-core/drm_context.c
@@ -402,6 +402,7 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+ drm_ctx_list_t * ctx_entry;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
@@ -422,6 +423,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
if ( ctx.handle != DRM_KERNEL_CONTEXT )
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
#endif
+ ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
+ if ( !ctx_entry ) {
+ DRM_DEBUG("out of memory\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD( &ctx_entry->head );
+ ctx_entry->handle = ctx.handle;
+ ctx_entry->tag = priv;
+
+ down( &dev->ctxlist_sem );
+ list_add( &ctx_entry->head, &dev->ctxlist->head );
+ ++dev->ctx_count;
+ up( &dev->ctxlist_sem );
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
return -EFAULT;
@@ -544,6 +559,20 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
DRM(ctxbitmap_free)( dev, ctx.handle );
}
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
+
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->handle == ctx.handle ) {
+ list_del( &pos->head );
+ DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ --dev->ctx_count;
+ }
+ }
+ }
+ up( &dev->ctxlist_sem );
+
return 0;
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index d0dceaab..3eec29a0 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -329,6 +329,12 @@ static int DRM(setup)( drm_device_t *dev )
memset(dev->maplist, 0, sizeof(*dev->maplist));
INIT_LIST_HEAD(&dev->maplist->head);
+ dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
+ DRM_MEM_CTXLIST);
+ if(dev->ctxlist == NULL) return -ENOMEM;
+ memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+ INIT_LIST_HEAD(&dev->ctxlist->head);
+
dev->vmalist = NULL;
dev->sigdata.lock = dev->lock.hw_lock = NULL;
init_waitqueue_head( &dev->lock.lock_queue );
@@ -567,6 +573,7 @@ static int DRM(probe)(struct pci_dev *pdev)
dev->count_lock = SPIN_LOCK_UNLOCKED;
init_timer( &dev->timer );
sema_init( &dev->struct_sem, 1 );
+ sema_init( &dev->ctxlist_sem, 1 );
if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
return -EPERM;
@@ -896,6 +903,25 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM(fasync)( -1, filp, 0 );
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
+
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->tag == priv &&
+ pos->handle != DRM_KERNEL_CONTEXT ) {
+#ifdef DRIVER_CTX_DTOR
+ DRIVER_CTX_DTOR(pos->handle);
+#endif
+ DRM(ctxbitmap_free)( dev, pos->handle );
+
+ list_del( &pos->head );
+ DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ }
+ }
+ }
+ up( &dev->ctxlist_sem );
+
down( &dev->struct_sem );
if ( priv->remove_auth_on_close == 1 ) {
drm_file_t *temp = dev->file_first;
diff --git a/linux-core/drm_memory_debug.h b/linux-core/drm_memory_debug.h
index fae419ec..2a2e7d79 100644
--- a/linux-core/drm_memory_debug.h
+++ b/linux-core/drm_memory_debug.h
@@ -68,6 +68,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
[DRM_MEM_TOTALAGP] = { "totalagp" },
[DRM_MEM_BOUNDAGP] = { "boundagp" },
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+ [DRM_MEM_CTXLIST] = { "ctxlist" },
[DRM_MEM_STUB] = { "stub" },
{ NULL, 0, } /* Last entry must be null */
};
diff --git a/linux/drmP.h b/linux/drmP.h
index b7b346d4..c2c14dbd 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -158,6 +158,7 @@
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
#define DRM_MEM_SGLISTS 20
+#define DRM_MEM_CTXLIST 21
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
@@ -201,6 +202,14 @@
prefetch(pos->member.next))
#endif
+#ifndef list_for_each_entry_safe
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
static inline struct page * vmalloc_to_page(void * vmalloc_addr)
{
@@ -309,19 +318,6 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr)
DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \
} while (0)
-#ifndef VMAP_4_ARGS
-
-#define DRM_IOREMAPAGP(map, dev) \
- (map)->handle = DRM(ioremap_agp)( (map)->offset, (map)->size, (dev) )
-
-#define DRM_IOREMAPAGPFREE(map) \
- do { \
- if ( (map)->handle && (map)->size ) \
- DRM(ioremap_agp_free)( (map)->handle, (map)->size ); \
- } while (0)
-
-#endif
-
/**
* Find mapping.
*
@@ -651,6 +647,15 @@ typedef struct drm_map_list {
typedef drm_map_t drm_local_map_t;
+/**
+ * Context handle list
+ */
+typedef struct drm_ctx_list {
+ struct list_head head; /**< list head */
+ drm_context_t handle; /**< context handle */
+ drm_file_t *tag; /**< associated fd private data */
+} drm_ctx_list_t;
+
#if __HAVE_VBL_IRQ
typedef struct drm_vbl_sig {
@@ -711,6 +716,12 @@ typedef struct drm_device {
drm_map_list_t *maplist; /**< Linked list of regions */
int map_count; /**< Number of mappable regions */
+ /** \name Context handle management */
+ /*@{*/
+ drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
+ int ctx_count; /**< Number of context handles */
+ struct semaphore ctxlist_sem; /**< For ctxlist */
+
drm_map_t **context_sareas; /**< per-context SAREA's */
int max_context;
@@ -846,10 +857,6 @@ extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
#if __REALLY_HAVE_AGP
-#ifndef VMAP_4_ARGS
-extern void *DRM(ioremap_agp)(unsigned long offset, unsigned long size, drm_device_t *dev);
-extern void DRM(ioremap_agp_free)(void *pt, unsigned long size);
-#endif
extern DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type);
extern int DRM(free_agp)(DRM_AGP_MEM *handle, int pages);
extern int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start);
diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h
index 0f281b57..f83651af 100644
--- a/linux/drm_agpsupport.h
+++ b/linux/drm_agpsupport.h
@@ -104,7 +104,11 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
int retcode;
- if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
+ if (!dev->agp)
+ return -ENODEV;
+ if (dev->agp->acquired)
+ return -EBUSY;
+ if (!drm_agp->acquire)
return -EINVAL;
#ifndef VMAP_4_ARGS
if ( dev->agp->cant_use_aperture )
diff --git a/linux/drm_context.h b/linux/drm_context.h
index 82e90bcc..474b5ba0 100644
--- a/linux/drm_context.h
+++ b/linux/drm_context.h
@@ -402,6 +402,7 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+ drm_ctx_list_t * ctx_entry;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
@@ -422,6 +423,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
if ( ctx.handle != DRM_KERNEL_CONTEXT )
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
#endif
+ ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
+ if ( !ctx_entry ) {
+ DRM_DEBUG("out of memory\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD( &ctx_entry->head );
+ ctx_entry->handle = ctx.handle;
+ ctx_entry->tag = priv;
+
+ down( &dev->ctxlist_sem );
+ list_add( &ctx_entry->head, &dev->ctxlist->head );
+ ++dev->ctx_count;
+ up( &dev->ctxlist_sem );
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
return -EFAULT;
@@ -544,6 +559,20 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
DRM(ctxbitmap_free)( dev, ctx.handle );
}
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
+
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->handle == ctx.handle ) {
+ list_del( &pos->head );
+ DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ --dev->ctx_count;
+ }
+ }
+ }
+ up( &dev->ctxlist_sem );
+
return 0;
}
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index d0dceaab..3eec29a0 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -329,6 +329,12 @@ static int DRM(setup)( drm_device_t *dev )
memset(dev->maplist, 0, sizeof(*dev->maplist));
INIT_LIST_HEAD(&dev->maplist->head);
+ dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
+ DRM_MEM_CTXLIST);
+ if(dev->ctxlist == NULL) return -ENOMEM;
+ memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+ INIT_LIST_HEAD(&dev->ctxlist->head);
+
dev->vmalist = NULL;
dev->sigdata.lock = dev->lock.hw_lock = NULL;
init_waitqueue_head( &dev->lock.lock_queue );
@@ -567,6 +573,7 @@ static int DRM(probe)(struct pci_dev *pdev)
dev->count_lock = SPIN_LOCK_UNLOCKED;
init_timer( &dev->timer );
sema_init( &dev->struct_sem, 1 );
+ sema_init( &dev->ctxlist_sem, 1 );
if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
return -EPERM;
@@ -896,6 +903,25 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM(fasync)( -1, filp, 0 );
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
+
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->tag == priv &&
+ pos->handle != DRM_KERNEL_CONTEXT ) {
+#ifdef DRIVER_CTX_DTOR
+ DRIVER_CTX_DTOR(pos->handle);
+#endif
+ DRM(ctxbitmap_free)( dev, pos->handle );
+
+ list_del( &pos->head );
+ DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ }
+ }
+ }
+ up( &dev->ctxlist_sem );
+
down( &dev->struct_sem );
if ( priv->remove_auth_on_close == 1 ) {
drm_file_t *temp = dev->file_first;
diff --git a/linux/drm_memory_debug.h b/linux/drm_memory_debug.h
index fae419ec..2a2e7d79 100644
--- a/linux/drm_memory_debug.h
+++ b/linux/drm_memory_debug.h
@@ -68,6 +68,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
[DRM_MEM_TOTALAGP] = { "totalagp" },
[DRM_MEM_BOUNDAGP] = { "boundagp" },
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+ [DRM_MEM_CTXLIST] = { "ctxlist" },
[DRM_MEM_STUB] = { "stub" },
{ NULL, 0, } /* Last entry must be null */
};
diff --git a/shared-core/sis_mm.c b/shared-core/sis_mm.c
index b6ff069d..092096c4 100644
--- a/shared-core/sis_mm.c
+++ b/shared-core/sis_mm.c
@@ -34,8 +34,12 @@
#include "sis_drv.h"
#include "sis_ds.h"
#if defined(__linux__) && defined(CONFIG_FB_SIS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#include <video/sisfb.h>
+#else
#include <linux/sisfb.h>
#endif
+#endif
#define MAX_CONTEXT 100
#define VIDEO_TYPE 0
diff --git a/shared/sis_mm.c b/shared/sis_mm.c
index b6ff069d..092096c4 100644
--- a/shared/sis_mm.c
+++ b/shared/sis_mm.c
@@ -34,8 +34,12 @@
#include "sis_drv.h"
#include "sis_ds.h"
#if defined(__linux__) && defined(CONFIG_FB_SIS)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#include <video/sisfb.h>
+#else
#include <linux/sisfb.h>
#endif
+#endif
#define MAX_CONTEXT 100
#define VIDEO_TYPE 0