diff options
-rw-r--r-- | linux-core/drmP.h | 18 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 7 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 9 | ||||
-rw-r--r-- | linux-core/sis_drv.c | 75 | ||||
-rw-r--r-- | linux-core/tdfx_drv.c | 6 | ||||
-rw-r--r-- | linux/Makefile.linux | 8 | ||||
-rw-r--r-- | linux/agpsupport.c | 146 | ||||
-rw-r--r-- | linux/compat-pre24.h | 4 | ||||
-rw-r--r-- | linux/drm.h | 11 | ||||
-rw-r--r-- | linux/drmP.h | 18 | ||||
-rw-r--r-- | linux/gamma_drv.c | 4 | ||||
-rw-r--r-- | linux/i810_drv.c | 7 | ||||
-rw-r--r-- | linux/memory.c | 64 | ||||
-rw-r--r-- | linux/mga_drv.c | 9 | ||||
-rw-r--r-- | linux/mga_state.c | 4 | ||||
-rw-r--r-- | linux/picker.c | 1 | ||||
-rw-r--r-- | linux/sis_context.c | 58 | ||||
-rw-r--r-- | linux/sis_drv.c | 75 | ||||
-rw-r--r-- | linux/sis_mm.c | 24 | ||||
-rw-r--r-- | linux/tdfx_drv.c | 6 | ||||
-rw-r--r-- | shared-core/drm.h | 11 | ||||
-rw-r--r-- | shared/drm.h | 11 |
22 files changed, 284 insertions, 292 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 21da1fda..abf67725 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -510,19 +510,6 @@ typedef struct drm_agp_head { unsigned long base; int agp_mtrr; } drm_agp_head_t; - -typedef struct { - void (*free_memory)(agp_memory *); - agp_memory *(*allocate_memory)(size_t, u32); - int (*bind_memory)(agp_memory *, off_t); - int (*unbind_memory)(agp_memory *); - void (*enable)(u32); - int (*acquire)(void); - void (*release)(void); - void (*copy_info)(agp_kern_info *); -} drm_agp_func_t; - -extern drm_agp_func_t drm_agp; #endif typedef struct drm_sigdata { @@ -824,6 +811,7 @@ extern drm_agp_head_t *drm_agp_init(void); extern void drm_agp_uninit(void); extern int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern void _drm_agp_release(void); extern int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_enable(struct inode *inode, struct file *filp, @@ -838,6 +826,10 @@ extern int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern agp_memory *drm_agp_allocate_memory(size_t pages, u32 type); +extern int drm_agp_free_memory(agp_memory *handle); +extern int drm_agp_bind_memory(agp_memory *handle, off_t start); +extern int drm_agp_unbind_memory(agp_memory *handle); #endif #endif #endif diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index ed880c41..7152eac3 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -255,8 +255,7 @@ static int i810_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -338,7 +337,7 @@ static int i810_takedown(drm_device_t *dev) /* i810_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int i810_init(void) +static int __init i810_init(void) { int retcode; drm_device_t *dev = &i810_device; @@ -397,7 +396,7 @@ static int i810_init(void) /* i810_cleanup is called via cleanup_module at module unload time. */ -static void i810_cleanup(void) +static void __exit i810_cleanup(void) { drm_device_t *dev = &i810_device; diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index 4aaac625..a6d2e570 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -255,8 +255,7 @@ static int mga_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -338,7 +337,7 @@ static int mga_takedown(drm_device_t *dev) /* mga_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int mga_init(void) +static int __init mga_init(void) { int retcode; drm_device_t *dev = &mga_device; @@ -398,7 +397,7 @@ static int mga_init(void) /* mga_cleanup is called via cleanup_module at module unload time. */ -static void mga_cleanup(void) +static void __exit mga_cleanup(void) { drm_device_t *dev = &mga_device; @@ -514,7 +513,7 @@ int mga_release(struct inode *inode, struct file *filp) if (dev->dev_private) ((drm_mga_private_t *)dev->dev_private) ->dispatch_status &= MGA_IN_DISPATCH; - + drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index 2f98e322..f7fe1cd1 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -10,11 +10,11 @@ * 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 @@ -72,7 +72,7 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, - + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { sis_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { sis_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { sis_modctx, 1, 1 }, @@ -103,7 +103,7 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sis_agp_init, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sis_agp_alloc, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sis_agp_free, 1, 1 }, - + #if defined(SIS_STEREO) [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, @@ -139,7 +139,7 @@ __setup("sis=", sis_options); static int sis_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -181,7 +181,7 @@ static int sis_setup(drm_device_t *dev) dev->ctx_start = 0; dev->lck_start = 0; - + dev->buf_rp = dev->buf; dev->buf_wp = dev->buf; dev->buf_end = dev->buf + DRM_BSZ; @@ -190,15 +190,15 @@ static int sis_setup(drm_device_t *dev) init_waitqueue_head(&dev->buf_writers); sis_res_ctx.handle=-1; - + DRM_DEBUG("\n"); - + /* The kernel's context could be created here, but is now created in drm_dma_enqueue. This is more resource-efficient for hardware that does not do DMA, but may mean that drm_select_queue fails between the time the interrupt is initialized and the time the queues are initialized. */ - + return 0; } @@ -218,12 +218,12 @@ static int sis_takedown(drm_device_t *dev) down(&dev->struct_sem); del_timer(&dev->timer); - + if (dev->devname) { drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER); dev->devname = NULL; } - + if (dev->unique) { drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER); dev->unique = NULL; @@ -242,7 +242,7 @@ static int sis_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *temp; drm_agp_mem_t *temp_next; - + temp = dev->agp->memory; while(temp != NULL) { temp_next = temp->next; @@ -250,7 +250,7 @@ static int sis_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if (dev->agp->acquired) (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); } #endif /* Clear vma list (only built for debugging) */ @@ -261,7 +261,7 @@ static int sis_takedown(drm_device_t *dev) } dev->vmalist = NULL; } - + /* Clear map area and mtrr information */ if (dev->maplist) { for (i = 0; i < dev->map_count; i++) { @@ -299,14 +299,14 @@ static int sis_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->lock.hw_lock) { dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.pid = 0; wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -323,7 +323,7 @@ static int sis_init(void) memset((void *)dev, 0, sizeof(*dev)); dev->count_lock = SPIN_LOCK_UNLOCKED; sema_init(&dev->struct_sem, 1); - + #ifdef MODULE drm_parse_options(sis); #endif @@ -355,7 +355,7 @@ static int sis_init(void) SIS_PATCHLEVEL, SIS_DATE, sis_misc.minor); - + return 0; } @@ -366,7 +366,7 @@ static void sis_cleanup(void) drm_device_t *dev = &sis_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&sis_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -394,17 +394,16 @@ int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, - (drm_version_t *)arg, - sizeof(version), - -EFAULT); + if (copy_from_user(&version, (drm_version_t *)arg, sizeof(version))) + return -EFAULT; #define DRM_COPY(name,value) \ len = strlen(value); \ if (len > name##_len) len = name##_len; \ name##_len = strlen(value); \ if (len && name) { \ - copy_to_user_ret(name, value, len, -EFAULT); \ + if (copy_to_user(name, value, len)) \ + return -EFAULT; \ } version.version_major = SIS_MAJOR; @@ -415,10 +414,8 @@ int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, SIS_DATE); DRM_COPY(version.desc, SIS_DESC); - copy_to_user_ret((drm_version_t *)arg, - &version, - sizeof(version), - -EFAULT); + if (copy_to_user((drm_version_t *)arg, &version, sizeof(version))) + return -EFAULT; return 0; } @@ -426,7 +423,7 @@ int sis_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &sis_device; int retcode = 0; - + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { #if LINUX_VERSION_CODE < 0x020333 @@ -494,7 +491,7 @@ int sis_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->ioctl_count); atomic_inc(&dev->total_ioctl); ++priv->ioctl_count; - + DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n", current->pid, cmd, nr, dev->device, priv->authenticated); @@ -514,7 +511,7 @@ int sis_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -533,7 +530,8 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->lck_start = start = get_cycles(); #endif - copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", @@ -551,7 +549,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, if (lock.context < 0 || lock.context >= dev->queue_count) return -EINVAL; #endif - + if (!ret) { #if 0 if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) @@ -563,7 +561,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, /* Can't take lock if we just had it and there is contention. */ DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n", - lock.context, current->pid, j, + lock.context, current->pid, j, dev->lock.lock_time, jiffies); current->state = TASK_INTERRUPTIBLE; current->policy |= SCHED_YIELD; @@ -587,7 +585,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); #if 1 @@ -655,7 +653,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, #if DRM_DMA_HISTOGRAM atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]); #endif - + return ret; } @@ -667,8 +665,9 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_lock_t lock; - copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); - + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; + if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", current->pid, lock.context); diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c index 5f2c804a..7d79a013 100644 --- a/linux-core/tdfx_drv.c +++ b/linux-core/tdfx_drv.c @@ -235,7 +235,7 @@ static int tdfx_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if (dev->agp->acquired) (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); } #endif /* Clear vma list (only built for debugging) */ @@ -298,7 +298,7 @@ static int tdfx_takedown(drm_device_t *dev) /* tdfx_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int tdfx_init(void) +static int __init tdfx_init(void) { int retcode; drm_device_t *dev = &tdfx_device; @@ -346,7 +346,7 @@ static int tdfx_init(void) /* tdfx_cleanup is called via cleanup_module at module unload time. */ -static void tdfx_cleanup(void) +static void __exit tdfx_cleanup(void) { drm_device_t *dev = &tdfx_device; diff --git a/linux/Makefile.linux b/linux/Makefile.linux index ca8a4564..9779922c 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -23,7 +23,7 @@ # 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. -# +# # # ***** NOTE NOTE NOTE NOTE NOTE ***** # To override the automatic Linux source tree determination, pass the @@ -113,15 +113,15 @@ all:; @echo Error: Could not locate kernel tree in $A $B $C 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 \ +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 \ +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) SIS := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ | grep -s 'SIS = ' | cut -d' ' -f3) -PARAMS := $(shell if fgrep kill_fasync $(TREE)/linux/fs.h \ +PARAMS := $(shell if fgrep kill_fasync $(TREE)/linux/fs.h 2>/dev/null \ | egrep -q '(band|int, int)'; then echo 3; else echo 2; fi) MACHINE := $(shell echo `uname -m`) ifeq ($(AGP),0) diff --git a/linux/agpsupport.c b/linux/agpsupport.c index 24fd59cd..bc383041 100644 --- a/linux/agpsupport.c +++ b/linux/agpsupport.c @@ -11,11 +11,11 @@ * 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 @@ -23,7 +23,7 @@ * 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. - * + * * Author: Rickard E. (Rik) Faith <faith@valinux.com> * */ @@ -31,48 +31,14 @@ #define __NO_VERSION__ #include "drmP.h" #include <linux/module.h> +#if LINUX_VERSION_CODE < 0x020400 +#include "agpsupport-pre24.h" +#else +#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp") +#define DRM_AGP_PUT inter_module_put("drm_agp") +#endif -drm_agp_func_t drm_agp = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - -/* The C standard says that 'void *' is not guaranteed to hold a function - pointer, so we use this union to define a generic pointer that is - guaranteed to hold any of the function pointers we care about. */ -typedef union { - void (*free_memory)(agp_memory *); - agp_memory *(*allocate_memory)(size_t, u32); - int (*bind_memory)(agp_memory *, off_t); - int (*unbind_memory)(agp_memory *); - void (*enable)(u32); - int (*acquire)(void); - void (*release)(void); - void (*copy_info)(agp_kern_info *); - unsigned long address; -} drm_agp_func_u; - -typedef struct drm_agp_fill { - const char *name; - drm_agp_func_u *f; -} drm_agp_fill_t; - -static drm_agp_fill_t drm_agp_fill[] = { - { __MODULE_STRING(agp_free_memory), - (drm_agp_func_u *)&drm_agp.free_memory }, - { __MODULE_STRING(agp_allocate_memory), - (drm_agp_func_u *)&drm_agp.allocate_memory }, - { __MODULE_STRING(agp_bind_memory), - (drm_agp_func_u *)&drm_agp.bind_memory }, - { __MODULE_STRING(agp_unbind_memory), - (drm_agp_func_u *)&drm_agp.unbind_memory }, - { __MODULE_STRING(agp_enable), - (drm_agp_func_u *)&drm_agp.enable }, - { __MODULE_STRING(agp_backend_acquire), - (drm_agp_func_u *)&drm_agp.acquire }, - { __MODULE_STRING(agp_backend_release), - (drm_agp_func_u *)&drm_agp.release }, - { __MODULE_STRING(agp_copy_info), - (drm_agp_func_u *)&drm_agp.copy_info }, - { NULL, NULL } -}; +static const drm_agp_t *drm_agp = NULL; int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -82,7 +48,7 @@ int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd, agp_kern_info *kern; drm_agp_info_t info; - if (!dev->agp->acquired || !drm_agp.copy_info) return -EINVAL; + if (!dev->agp->acquired || !drm_agp->copy_info) return -EINVAL; kern = &dev->agp->agp_info; info.agp_version_major = kern->version.major; @@ -107,8 +73,8 @@ int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; int retcode; - if (dev->agp->acquired || !drm_agp.acquire) return -EINVAL; - if ((retcode = (*drm_agp.acquire)())) return retcode; + if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL; + if ((retcode = drm_agp->acquire())) return retcode; dev->agp->acquired = 1; return 0; } @@ -119,11 +85,16 @@ int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - if (!dev->agp->acquired || !drm_agp.release) return -EINVAL; - (*drm_agp.release)(); + if (!dev->agp->acquired || !drm_agp->release) return -EINVAL; + drm_agp->release(); dev->agp->acquired = 0; return 0; - + +} + +void _drm_agp_release(void) +{ + if (drm_agp->release) drm_agp->release(); } int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd, @@ -133,13 +104,13 @@ int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_agp_mode_t mode; - if (!dev->agp->acquired || !drm_agp.enable) return -EINVAL; + if (!dev->agp->acquired || !drm_agp->enable) return -EINVAL; if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode))) return -EFAULT; - + dev->agp->mode = mode.mode; - (*drm_agp.enable)(mode.mode); + drm_agp->enable(mode.mode); dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->enabled = 1; return 0; @@ -160,7 +131,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, return -EFAULT; if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; - + memset(entry, 0, sizeof(*entry)); pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; @@ -170,7 +141,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -ENOMEM; } - + entry->handle = (unsigned long)memory->memory; entry->memory = memory; entry->bound = 0; @@ -230,8 +201,8 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, drm_agp_mem_t *entry; int retcode; int page; - - if (!dev->agp->acquired || !drm_agp.bind_memory) return -EINVAL; + + if (!dev->agp->acquired || !drm_agp->bind_memory) return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) @@ -240,7 +211,7 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; if ((retcode = drm_bind_agp(entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); - DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", + DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", dev->agp->base, entry->bound); return 0; } @@ -252,14 +223,14 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_agp_buffer_t request; drm_agp_mem_t *entry; - + if (!dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) drm_unbind_agp(entry->memory); - + if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; @@ -270,24 +241,14 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, drm_agp_head_t *drm_agp_init(void) { - drm_agp_fill_t *fill; drm_agp_head_t *head = NULL; - int agp_available = 1; - - for (fill = &drm_agp_fill[0]; fill->name; fill++) { - char *n = (char *)fill->name; - *fill->f = (drm_agp_func_u)get_module_symbol(NULL, n); - DRM_DEBUG("%s resolves to 0x%08lx\n", n, (*fill->f).address); - if (!(*fill->f).address) agp_available = 0; - } - - DRM_DEBUG("agp_available = %d\n", agp_available); - if (agp_available) { + drm_agp = DRM_AGP_GET; + if (drm_agp) { if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) return NULL; memset((void *)head, 0, sizeof(*head)); - (*drm_agp.copy_info)(&head->agp_info); + drm_agp->copy_info(&head->agp_info); if (head->agp_info.chipset == NOT_SUPPORTED) { drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); return NULL; @@ -310,9 +271,9 @@ drm_agp_head_t *drm_agp_init(void) #if LINUX_VERSION_CODE >= 0x020400 case VIA_MVP4: head->chipset = "VIA MVP4"; break; - case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133"; + case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133"; break; - case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; + case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133"; break; #endif @@ -337,12 +298,31 @@ drm_agp_head_t *drm_agp_init(void) void drm_agp_uninit(void) { - drm_agp_fill_t *fill; - - for (fill = &drm_agp_fill[0]; fill->name; fill++) { -#if LINUX_VERSION_CODE >= 0x020400 - if ((*fill->f).address) put_module_symbol((*fill->f).address); -#endif - (*fill->f).address = 0; - } + DRM_AGP_PUT; + drm_agp = NULL; +} + +agp_memory *drm_agp_allocate_memory(size_t pages, u32 type) +{ + if (!drm_agp->allocate_memory) return NULL; + return drm_agp->allocate_memory(pages, type); +} + +int drm_agp_free_memory(agp_memory *handle) +{ + if (!handle || !drm_agp->free_memory) return 0; + drm_agp->free_memory(handle); + return 1; +} + +int drm_agp_bind_memory(agp_memory *handle, off_t start) +{ + if (!handle || !drm_agp->bind_memory) return -EINVAL; + return drm_agp->bind_memory(handle, start); +} + +int drm_agp_unbind_memory(agp_memory *handle) +{ + if (!handle || !drm_agp->unbind_memory) return -EINVAL; + return drm_agp->unbind_memory(handle); } diff --git a/linux/compat-pre24.h b/linux/compat-pre24.h index 257baca1..77a2bee1 100644 --- a/linux/compat-pre24.h +++ b/linux/compat-pre24.h @@ -38,4 +38,8 @@ #define block_all_signals(a,b,c) #define unblock_all_signals() +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +#define __exit +#endif + #endif diff --git a/linux/drm.h b/linux/drm.h index 6a4099bd..5d383427 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -82,6 +82,7 @@ typedef struct drm_clip_rect { #include "mga_drm.h" #include "i810_drm.h" #include "r128_drm.h" +#include "sis_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -375,4 +376,14 @@ typedef struct drm_agp_info { #define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) #define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) +/* SiS specific ioctls */ +#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) + #endif diff --git a/linux/drmP.h b/linux/drmP.h index 21da1fda..abf67725 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -510,19 +510,6 @@ typedef struct drm_agp_head { unsigned long base; int agp_mtrr; } drm_agp_head_t; - -typedef struct { - void (*free_memory)(agp_memory *); - agp_memory *(*allocate_memory)(size_t, u32); - int (*bind_memory)(agp_memory *, off_t); - int (*unbind_memory)(agp_memory *); - void (*enable)(u32); - int (*acquire)(void); - void (*release)(void); - void (*copy_info)(agp_kern_info *); -} drm_agp_func_t; - -extern drm_agp_func_t drm_agp; #endif typedef struct drm_sigdata { @@ -824,6 +811,7 @@ extern drm_agp_head_t *drm_agp_init(void); extern void drm_agp_uninit(void); extern int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern void _drm_agp_release(void); extern int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_enable(struct inode *inode, struct file *filp, @@ -838,6 +826,10 @@ extern int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern agp_memory *drm_agp_allocate_memory(size_t pages, u32 type); +extern int drm_agp_free_memory(agp_memory *handle); +extern int drm_agp_bind_memory(agp_memory *handle, off_t start); +extern int drm_agp_unbind_memory(agp_memory *handle); #endif #endif #endif diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index dba974c2..a17bc1a9 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -339,7 +339,7 @@ int gamma_find_devices(void) /* gamma_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int gamma_init(void) +static int __init gamma_init(void) { int retcode; drm_device_t *dev = &gamma_device; @@ -380,7 +380,7 @@ static int gamma_init(void) /* gamma_cleanup is called via cleanup_module at module unload time. */ -static void gamma_cleanup(void) +static void __exit gamma_cleanup(void) { drm_device_t *dev = &gamma_device; diff --git a/linux/i810_drv.c b/linux/i810_drv.c index ed880c41..7152eac3 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -255,8 +255,7 @@ static int i810_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -338,7 +337,7 @@ static int i810_takedown(drm_device_t *dev) /* i810_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int i810_init(void) +static int __init i810_init(void) { int retcode; drm_device_t *dev = &i810_device; @@ -397,7 +396,7 @@ static int i810_init(void) /* i810_cleanup is called via cleanup_module at module unload time. */ -static void i810_cleanup(void) +static void __exit i810_cleanup(void) { drm_device_t *dev = &i810_device; diff --git a/linux/memory.c b/linux/memory.c index 34d19b20..261fb34a 100644 --- a/linux/memory.c +++ b/linux/memory.c @@ -352,16 +352,13 @@ agp_memory *drm_alloc_agp(int pages, u32 type) return NULL; } - if (drm_agp.allocate_memory) { - if ((handle = (*drm_agp.allocate_memory)(pages, - type))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; - drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated - += pages << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - return handle; - } + if ((handle = drm_agp_allocate_memory(pages, type))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; + drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated + += pages << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + return handle; } spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; @@ -381,8 +378,7 @@ int drm_free_agp(agp_memory *handle, int pages) return retval;; } - if (drm_agp.free_memory) { - (*drm_agp.free_memory)(handle); + if (drm_agp_free_memory(handle)) { spin_lock(&drm_mem_lock); free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; @@ -403,24 +399,19 @@ int drm_bind_agp(agp_memory *handle, unsigned int start) { int retcode = -EINVAL; - DRM_DEBUG("drm_bind_agp called\n"); if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to bind NULL AGP handle\n"); return retcode; } - DRM_DEBUG("drm_agp.bind_memory : %p\n", drm_agp.bind_memory); - if (drm_agp.bind_memory) { - if (!(retcode = (*drm_agp.bind_memory)(handle, start))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated - += handle->page_count << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - DRM_DEBUG("drm_agp.bind_memory: retcode %d\n", retcode); - return retcode; - } + if (!(retcode = drm_agp_bind_memory(handle, start))) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; + drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated + += handle->page_count << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + return retcode; } spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; @@ -440,20 +431,17 @@ int drm_unbind_agp(agp_memory *handle) return retcode; } - if (drm_agp.unbind_memory) { - int c = handle->page_count; - if ((retcode = (*drm_agp.unbind_memory)(handle))) - return retcode; - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; - alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed += c << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - if (free_count > alloc_count) { - DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } + if ((retcode = drm_agp_unbind_memory(handle))) return retcode; + spin_lock(&drm_mem_lock); + free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; + alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; + drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed + += handle->page_count << PAGE_SHIFT; + spin_unlock(&drm_mem_lock); + if (free_count > alloc_count) { + DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, + "Excess frees: %d frees, %d allocs\n", + free_count, alloc_count); } return retcode; } diff --git a/linux/mga_drv.c b/linux/mga_drv.c index 4aaac625..a6d2e570 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -255,8 +255,7 @@ static int mga_takedown(drm_device_t *dev) } dev->agp->memory = NULL; - if (dev->agp->acquired && drm_agp.release) - (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); dev->agp->acquired = 0; dev->agp->enabled = 0; @@ -338,7 +337,7 @@ static int mga_takedown(drm_device_t *dev) /* mga_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int mga_init(void) +static int __init mga_init(void) { int retcode; drm_device_t *dev = &mga_device; @@ -398,7 +397,7 @@ static int mga_init(void) /* mga_cleanup is called via cleanup_module at module unload time. */ -static void mga_cleanup(void) +static void __exit mga_cleanup(void) { drm_device_t *dev = &mga_device; @@ -514,7 +513,7 @@ int mga_release(struct inode *inode, struct file *filp) if (dev->dev_private) ((drm_mga_private_t *)dev->dev_private) ->dispatch_status &= MGA_IN_DISPATCH; - + drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); diff --git a/linux/mga_state.c b/linux/mga_state.c index 9bbd254c..e983dfea 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -255,7 +255,7 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) /* This takes 50 dwords */ - /* Establish vertex size. + /* Establish vertex size. */ PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -287,7 +287,7 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000); PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000); PRIMOUTREG(MGAREG_DMAPAD, 0); } diff --git a/linux/picker.c b/linux/picker.c index 77519a56..4b4fbe90 100644 --- a/linux/picker.c +++ b/linux/picker.c @@ -1,4 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/picker.c,v 1.3 2000/09/01 02:31:40 tsi Exp $ */ #include <linux/config.h> #include <linux/version.h> diff --git a/linux/sis_context.c b/linux/sis_context.c index f2fdf6dd..ca847ed7 100644 --- a/linux/sis_context.c +++ b/linux/sis_context.c @@ -11,11 +11,11 @@ * 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 @@ -23,12 +23,12 @@ * 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> * Daryll Strauss <daryll@valinux.com> * Sung-Ching Lin <sclin@sis.com.tw> - * + * */ #define __NO_VERSION__ @@ -56,21 +56,21 @@ int sis_context_switch(drm_device_t *dev, int old, int new) #if DRM_DMA_HISTOGRAM dev->ctx_start = get_cycles(); #endif - + DRM_DEBUG("Context switch from %d to %d\n", old, new); if (new == dev->last_context) { clear_bit(0, &dev->context_flag); return 0; } - + if (drm_flags & DRM_FLAG_NOCTX) { sis_context_switch_complete(dev, new); } else { sprintf(buf, "C %d %d\n", old, new); drm_write_string(dev, buf); } - + return 0; } @@ -78,7 +78,7 @@ int sis_context_switch_complete(drm_device_t *dev, int new) { 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"); } @@ -89,11 +89,11 @@ int sis_context_switch_complete(drm_device_t *dev, int new) #if DRM_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); - + return 0; } @@ -106,19 +106,19 @@ int sis_resctx(struct inode *inode, struct file *filp, unsigned int cmd, int i; DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT); + 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; - copy_to_user_ret(&res.contexts[i], - &i, - sizeof(i), - -EFAULT); + if (copy_to_user(&res.contexts[i], &i, sizeof(i))) + return -EFAULT; } } res.count = DRM_RESERVED_CONTEXTS; - copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT); + if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) + return -EFAULT; return 0; } @@ -130,7 +130,8 @@ int sis_addctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; if ((ctx.handle = sis_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ ctx.handle = sis_alloc_queue(dev); @@ -141,11 +142,12 @@ int sis_addctx(struct inode *inode, struct file *filp, unsigned int cmd, /* Should this return -EBUSY instead? */ return -ENOMEM; } - + /* new added */ sis_init_context(ctx.handle); - copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT); + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; return 0; } @@ -154,7 +156,8 @@ int sis_modctx(struct inode *inode, struct file *filp, unsigned int cmd, { drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; if (ctx.flags==_DRM_CONTEXT_PRESERVED) sis_res_ctx.handle=ctx.handle; return 0; @@ -165,10 +168,12 @@ int sis_getctx(struct inode *inode, struct file *filp, unsigned int cmd, { drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; /* This is 0, because we don't hanlde any context flags */ ctx.flags = 0; - copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT); + if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx))) + return -EFAULT; return 0; } @@ -179,7 +184,8 @@ int sis_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); return sis_context_switch(dev, dev->last_context, ctx.handle); } @@ -191,7 +197,8 @@ int sis_newctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); sis_context_switch_complete(dev, ctx.handle); @@ -205,7 +212,8 @@ int sis_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_ctx_t ctx; - copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT); + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; DRM_DEBUG("%d\n", ctx.handle); drm_ctxbitmap_free(dev, ctx.handle); diff --git a/linux/sis_drv.c b/linux/sis_drv.c index 2f98e322..f7fe1cd1 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -10,11 +10,11 @@ * 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 @@ -72,7 +72,7 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, - + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { sis_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { sis_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { sis_modctx, 1, 1 }, @@ -103,7 +103,7 @@ static drm_ioctl_desc_t sis_ioctls[] = { [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sis_agp_init, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sis_agp_alloc, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sis_agp_free, 1, 1 }, - + #if defined(SIS_STEREO) [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, @@ -139,7 +139,7 @@ __setup("sis=", sis_options); static int sis_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -181,7 +181,7 @@ static int sis_setup(drm_device_t *dev) dev->ctx_start = 0; dev->lck_start = 0; - + dev->buf_rp = dev->buf; dev->buf_wp = dev->buf; dev->buf_end = dev->buf + DRM_BSZ; @@ -190,15 +190,15 @@ static int sis_setup(drm_device_t *dev) init_waitqueue_head(&dev->buf_writers); sis_res_ctx.handle=-1; - + DRM_DEBUG("\n"); - + /* The kernel's context could be created here, but is now created in drm_dma_enqueue. This is more resource-efficient for hardware that does not do DMA, but may mean that drm_select_queue fails between the time the interrupt is initialized and the time the queues are initialized. */ - + return 0; } @@ -218,12 +218,12 @@ static int sis_takedown(drm_device_t *dev) down(&dev->struct_sem); del_timer(&dev->timer); - + if (dev->devname) { drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER); dev->devname = NULL; } - + if (dev->unique) { drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER); dev->unique = NULL; @@ -242,7 +242,7 @@ static int sis_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *temp; drm_agp_mem_t *temp_next; - + temp = dev->agp->memory; while(temp != NULL) { temp_next = temp->next; @@ -250,7 +250,7 @@ static int sis_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if (dev->agp->acquired) (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); } #endif /* Clear vma list (only built for debugging) */ @@ -261,7 +261,7 @@ static int sis_takedown(drm_device_t *dev) } dev->vmalist = NULL; } - + /* Clear map area and mtrr information */ if (dev->maplist) { for (i = 0; i < dev->map_count; i++) { @@ -299,14 +299,14 @@ static int sis_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->lock.hw_lock) { dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.pid = 0; wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -323,7 +323,7 @@ static int sis_init(void) memset((void *)dev, 0, sizeof(*dev)); dev->count_lock = SPIN_LOCK_UNLOCKED; sema_init(&dev->struct_sem, 1); - + #ifdef MODULE drm_parse_options(sis); #endif @@ -355,7 +355,7 @@ static int sis_init(void) SIS_PATCHLEVEL, SIS_DATE, sis_misc.minor); - + return 0; } @@ -366,7 +366,7 @@ static void sis_cleanup(void) drm_device_t *dev = &sis_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&sis_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -394,17 +394,16 @@ int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, - (drm_version_t *)arg, - sizeof(version), - -EFAULT); + if (copy_from_user(&version, (drm_version_t *)arg, sizeof(version))) + return -EFAULT; #define DRM_COPY(name,value) \ len = strlen(value); \ if (len > name##_len) len = name##_len; \ name##_len = strlen(value); \ if (len && name) { \ - copy_to_user_ret(name, value, len, -EFAULT); \ + if (copy_to_user(name, value, len)) \ + return -EFAULT; \ } version.version_major = SIS_MAJOR; @@ -415,10 +414,8 @@ int sis_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, SIS_DATE); DRM_COPY(version.desc, SIS_DESC); - copy_to_user_ret((drm_version_t *)arg, - &version, - sizeof(version), - -EFAULT); + if (copy_to_user((drm_version_t *)arg, &version, sizeof(version))) + return -EFAULT; return 0; } @@ -426,7 +423,7 @@ int sis_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &sis_device; int retcode = 0; - + DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { #if LINUX_VERSION_CODE < 0x020333 @@ -494,7 +491,7 @@ int sis_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->ioctl_count); atomic_inc(&dev->total_ioctl); ++priv->ioctl_count; - + DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n", current->pid, cmd, nr, dev->device, priv->authenticated); @@ -514,7 +511,7 @@ int sis_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -533,7 +530,8 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->lck_start = start = get_cycles(); #endif - copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", @@ -551,7 +549,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, if (lock.context < 0 || lock.context >= dev->queue_count) return -EINVAL; #endif - + if (!ret) { #if 0 if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) @@ -563,7 +561,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, /* Can't take lock if we just had it and there is contention. */ DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n", - lock.context, current->pid, j, + lock.context, current->pid, j, dev->lock.lock_time, jiffies); current->state = TASK_INTERRUPTIBLE; current->policy |= SCHED_YIELD; @@ -587,7 +585,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); #if 1 @@ -655,7 +653,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, #if DRM_DMA_HISTOGRAM atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]); #endif - + return ret; } @@ -667,8 +665,9 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_lock_t lock; - copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); - + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; + if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", current->pid, lock.context); diff --git a/linux/sis_mm.c b/linux/sis_mm.c index e6e8ed7d..4c2b5a6c 100644 --- a/linux/sis_mm.c +++ b/linux/sis_mm.c @@ -33,9 +33,6 @@ #include "sis_drm.h" #include "sis_ds.h" #include "sis_drv.h" -#include <linux/fb.h> -#include <linux/sisfb.h> -#include <linux/interrupt.h> #define MAX_CONTEXT 100 #define VIDEO_TYPE 0 @@ -73,7 +70,7 @@ static int del_alloc_set(int context, int type, unsigned int val) } /* fb management via fb device */ -#if 1 +#if 0 int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -81,7 +78,8 @@ int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd, struct sis_memreq req; int retval = 0; - copy_from_user_ret(&fb, (drm_sis_mem_t *)arg, sizeof(fb), -EFAULT); + if (copy_from_user(&fb, (drm_sis_mem_t *)arg, sizeof(fb))) + return -EFAULT; req.size = fb.size; sis_malloc(&req); @@ -101,7 +99,7 @@ int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd, fb.free = 0; } - copy_to_user_ret((drm_sis_mem_t *)arg, &fb, sizeof(fb), -EFAULT); + if (copy_to_user((drm_sis_mem_t *)arg, &fb, sizeof(fb))) return -EFAULT; DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); @@ -114,7 +112,8 @@ int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd, drm_sis_mem_t fb; int retval = 0; - copy_from_user_ret(&fb, (drm_sis_mem_t *)arg, sizeof(fb), -EFAULT); + if (copy_from_user(&fb, (drm_sis_mem_t *)arg, sizeof(fb))) + return -EFAULT; if(!fb.free){ return -1; @@ -155,7 +154,8 @@ int sis_agp_init(struct inode *inode, struct file *filp, unsigned int cmd, { drm_sis_agp_t agp; - copy_from_user_ret(&agp, (drm_sis_agp_t *)arg, sizeof(agp), -EFAULT); + if (copy_from_user(&agp, (drm_sis_agp_t *)arg, sizeof(agp))) + return -EFAULT; AgpHeap = mmInit(agp.offset, agp.size); @@ -174,7 +174,8 @@ int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, if(!AgpHeap) return -1; - copy_from_user_ret(&agp, (drm_sis_mem_t *)arg, sizeof(agp), -EFAULT); + if (copy_from_user(&agp, (drm_sis_mem_t *)arg, sizeof(agp))) + return -EFAULT; block = mmAllocMem(AgpHeap, agp.size, 0, 0); if(block){ @@ -193,7 +194,7 @@ int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, agp.free = 0; } - copy_to_user_ret((drm_sis_mem_t *)arg, &agp, sizeof(agp), -EFAULT); + if (copy_to_user((drm_sis_mem_t *)arg, &agp, sizeof(agp))) return -EFAULT; DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset); @@ -209,7 +210,8 @@ int sis_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, if(!AgpHeap) return -1; - copy_from_user_ret(&agp, (drm_sis_mem_t *)arg, sizeof(agp), -EFAULT); + if (copy_from_user(&agp, (drm_sis_mem_t *)arg, sizeof(agp))) + return -EFAULT; if(!agp.free){ return -1; diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index 5f2c804a..7d79a013 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -235,7 +235,7 @@ static int tdfx_takedown(drm_device_t *dev) drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS); temp = temp_next; } - if (dev->agp->acquired) (*drm_agp.release)(); + if (dev->agp->acquired) _drm_agp_release(); } #endif /* Clear vma list (only built for debugging) */ @@ -298,7 +298,7 @@ static int tdfx_takedown(drm_device_t *dev) /* tdfx_init is called via init_module at module load time, or via * linux/init/main.c (this is not currently supported). */ -static int tdfx_init(void) +static int __init tdfx_init(void) { int retcode; drm_device_t *dev = &tdfx_device; @@ -346,7 +346,7 @@ static int tdfx_init(void) /* tdfx_cleanup is called via cleanup_module at module unload time. */ -static void tdfx_cleanup(void) +static void __exit tdfx_cleanup(void) { drm_device_t *dev = &tdfx_device; diff --git a/shared-core/drm.h b/shared-core/drm.h index 6a4099bd..5d383427 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -82,6 +82,7 @@ typedef struct drm_clip_rect { #include "mga_drm.h" #include "i810_drm.h" #include "r128_drm.h" +#include "sis_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -375,4 +376,14 @@ typedef struct drm_agp_info { #define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) #define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) +/* SiS specific ioctls */ +#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) + #endif diff --git a/shared/drm.h b/shared/drm.h index 6a4099bd..5d383427 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -82,6 +82,7 @@ typedef struct drm_clip_rect { #include "mga_drm.h" #include "i810_drm.h" #include "r128_drm.h" +#include "sis_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -375,4 +376,14 @@ typedef struct drm_agp_info { #define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) #define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) +/* SiS specific ioctls */ +#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) + #endif |