diff options
39 files changed, 1576 insertions, 1303 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index b9a4dab4..fcee4104 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -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,16 +23,22 @@ * 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> - * + * */ #ifndef _DRM_P_H_ #define _DRM_P_H_ #ifdef __KERNEL__ +#ifdef __alpha__ +/* add include of current.h so that "current" is defined + * before static inline funcs in wait.h. Doing this so we + * can build the DRM (part of PI DRI). 4/21/2000 S + B */ +#include <asm/current.h> +#endif /* __alpha__ */ #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> @@ -47,6 +53,9 @@ #include <linux/sched.h> #include <linux/smp_lock.h> /* For (un)lock_kernel */ #include <linux/mm.h> +#ifdef __alpha__ +#include <asm/pgtable.h> /* For pte_wrprotect */ +#endif #include <asm/io.h> #include <asm/mman.h> #include <asm/uaccess.h> @@ -61,6 +70,9 @@ #include <linux/tqueue.h> #include <linux/poll.h> #endif +#if LINUX_VERSION_CODE < 0x020400 +#include "compat-pre24.h" +#endif #include "drm.h" #define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then @@ -140,15 +152,75 @@ typedef struct wait_queue *wait_queue_head_t; #define module_exit(x) void cleanup_module(void) { x(); } #endif - /* virt_to_page added in 2.4.0-test6 */ -#if LINUX_VERSION_CODE < 0x020400 -#define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr)) -#endif - /* Generic cmpxchg added in 2.3.x */ #ifndef __HAVE_ARCH_CMPXCHG /* Include this here so that driver can be used with older kernels. */ +#if defined(__alpha__) +static __inline__ unsigned long +__cmpxchg_u32(volatile int *m, int old, int new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldl_l %0,%2\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stl_c %1,%2\n" + " beq %1,3f\n" + "2: mb\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m)); + + return prev; +} + +static __inline__ unsigned long +__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldq_l %0,%2\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stq_c %1,%2\n" + " beq %1,3f\n" + "2: mb\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m)); + + return prev; +} + +static __inline__ unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); + case 8: + return __cmpxchg_u64(ptr, old, new); + } + return old; +} +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + +#elif __i386__ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { @@ -179,6 +251,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, #define cmpxchg(ptr,o,n) \ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ (unsigned long)(n),sizeof(*(ptr)))) +#endif /* i386 & alpha */ #endif /* Macros to make printk easier */ @@ -231,7 +304,7 @@ typedef struct drm_ioctl_desc { typedef struct drm_devstate { pid_t owner; /* X server pid holding x_lock */ - + } drm_devstate_t; typedef struct drm_magic_entry { @@ -292,14 +365,14 @@ typedef struct drm_buf { #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]; @@ -323,7 +396,7 @@ typedef struct drm_freelist { int initialized; /* Freelist in use */ atomic_t count; /* Number of free buffers */ drm_buf_t *next; /* End pointer */ - + wait_queue_head_t waiting; /* Processes waiting on free bufs */ int low_mark; /* Low water mark */ int high_mark; /* High water mark */ @@ -388,7 +461,7 @@ typedef struct drm_device_dma { atomic_t total_prio; /* Total DRM_DMA_PRIORITY */ atomic_t total_bytes; /* Total bytes DMA'd */ atomic_t total_dmas; /* Total DMA buffers dispatched */ - + atomic_t total_missed_dma; /* Missed drm_do_dma */ atomic_t total_missed_lock; /* Missed lock in drm_do_dma */ atomic_t total_missed_free; /* Missed drm_free_this_buffer */ @@ -401,7 +474,7 @@ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; drm_buf_t **buflist; /* Vector of pointers info bufs */ - int seg_count; + int seg_count; int page_count; unsigned long *pagelist; unsigned long byte_count; @@ -462,7 +535,7 @@ typedef struct drm_device { int unique_len; /* Length of unique field */ dev_t device; /* Device number for mknod */ char *devname; /* For /proc/interrupts */ - + int blocked; /* Blocked due to VC switch? */ struct proc_dir_entry *root; /* Root for this device's entries */ @@ -483,7 +556,7 @@ typedef struct drm_device { atomic_t total_ioctl; atomic_t total_irq; /* Total interruptions */ atomic_t total_ctx; /* Total context switches */ - + atomic_t total_locks; atomic_t total_unlocks; atomic_t total_contends; @@ -524,7 +597,7 @@ typedef struct drm_device { #if DRM_DMA_HISTOGRAM drm_histogram_t histo; #endif - + /* Callback to X server for context switch and for heavy-handed reset. */ char buf[DRM_BSZ]; /* Output buffer */ @@ -534,7 +607,7 @@ typedef struct drm_device { struct fasync_struct *buf_async;/* Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ - + #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) drm_agp_head_t *agp; #endif diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 5792bf39..a9f860cd 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.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 @@ -107,14 +107,14 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev) drm_device_dma_t *dma = dev->dma; int i; int used; - + /* Linear search might not be the best solution */ 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; /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, + used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, I810_BUF_CLIENT); if(used == I810_BUF_FREE) { return buf; @@ -131,14 +131,14 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) { drm_i810_buf_priv_t *buf_priv = buf->dev_private; int used; - + /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); if(used != I810_BUF_CLIENT) { DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); return -EINVAL; } - + return 0; } @@ -166,10 +166,10 @@ int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) dev_priv = dev->dev_private; buf = dev_priv->mmap_buffer; buf_priv = buf->dev_private; - + vma->vm_flags |= (VM_IO | VM_DONTCOPY); vma->vm_file = filp; - + buf_priv->currently_mapped = I810_BUF_MAPPED; unlock_kernel(); @@ -196,9 +196,9 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) old_fops = filp->f_op; filp->f_op = &i810_buffer_fops; dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, PROT_READ|PROT_WRITE, - MAP_SHARED, + MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; @@ -222,15 +222,15 @@ static int i810_unmap_buffer(drm_buf_t *buf) int retcode = 0; if(VM_DONTCOPY != 0) { - if(buf_priv->currently_mapped != I810_BUF_MAPPED) + if(buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; down(¤t->mm->mmap_sem); #if LINUX_VERSION_CODE < 0x020399 - retcode = do_munmap((unsigned long)buf_priv->virtual, + retcode = do_munmap((unsigned long)buf_priv->virtual, (size_t) buf->total); #else - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, (size_t) buf->total); #endif up(¤t->mm->mmap_sem); @@ -241,7 +241,7 @@ static int i810_unmap_buffer(drm_buf_t *buf) return retcode; } -static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, +static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, struct file *filp) { drm_file_t *priv = filp->private_data; @@ -255,16 +255,16 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, DRM_DEBUG("%s retcode %d\n", __FUNCTION__, retcode); goto out_get_buf; } - + retcode = i810_map_buffer(buf, filp); if(retcode) { i810_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed in %s retcode %d\n", + DRM_DEBUG("mapbuf failed in %s retcode %d\n", __FUNCTION__, retcode); goto out_get_buf; } buf->pid = priv->pid; - buf_priv = buf->dev_private; + buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; d->request_size = buf->total; @@ -277,22 +277,22 @@ out_get_buf: static unsigned long i810_alloc_page(drm_device_t *dev) { unsigned long address; - + address = __get_free_page(GFP_KERNEL); - if(address == 0UL) + if(address == 0UL) return 0; - + atomic_inc(&virt_to_page(address)->count); set_bit(PG_locked, &virt_to_page(address)->flags); - + return address; } static void i810_free_page(drm_device_t *dev, unsigned long page) { - if(page == 0UL) + if(page == 0UL) return; - + atomic_dec(&virt_to_page(page)->count); clear_bit(PG_locked, &virt_to_page(page)->flags); wake_up(&virt_to_page(page)->wait); @@ -306,9 +306,9 @@ static int i810_dma_cleanup(drm_device_t *dev) if(dev->dev_private) { int i; - drm_i810_private_t *dev_priv = + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - + if(dev_priv->ring.virtual_start) { drm_ioremapfree((void *) dev_priv->ring.virtual_start, dev_priv->ring.Size); @@ -318,7 +318,7 @@ static int i810_dma_cleanup(drm_device_t *dev) /* Need to rewrite hardware status page */ I810_WRITE(0x02080, 0x1ffff000); } - drm_free(dev->dev_private, sizeof(drm_i810_private_t), + drm_free(dev->dev_private, sizeof(drm_i810_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -342,14 +342,14 @@ static int i810_wait_ring(drm_device_t *dev, int n) end = jiffies + (HZ*3); while (ring->space < n) { int i; - + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; - + if (ring->head != last_head) end = jiffies + (HZ*3); - + iters++; if((signed)(end - jiffies) <= 0) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); @@ -360,7 +360,7 @@ static int i810_wait_ring(drm_device_t *dev, int n) for (i = 0 ; i < 2000 ; i++) ; } -out_wait_ring: +out_wait_ring: return iters; } @@ -368,7 +368,7 @@ static void i810_kernel_lost_context(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->tail = I810_READ(LP_RING + RING_TAIL); ring->space = ring->head - (ring->tail+8); @@ -382,7 +382,7 @@ static int i810_freelist_init(drm_device_t *dev) int my_idx = 24; u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); int i; - + if(dma->buf_count > 1019) { /* Not enough space in the status page for the freelist */ return -EINVAL; @@ -391,20 +391,20 @@ static int i810_freelist_init(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; - + buf_priv->in_use = hw_status++; buf_priv->my_use_idx = my_idx; my_idx += 4; *buf_priv->in_use = I810_BUF_FREE; - buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, buf->total); } return 0; } -static int i810_dma_initialize(drm_device_t *dev, +static int i810_dma_initialize(drm_device_t *dev, drm_i810_private_t *dev_priv, drm_i810_init_t *init) { @@ -419,27 +419,27 @@ static int i810_dma_initialize(drm_device_t *dev, DRM_ERROR("ring_map or buffer_map are invalid\n"); return -EINVAL; } - + dev_priv->ring_map_idx = init->ring_map_idx; dev_priv->buffer_map_idx = init->buffer_map_idx; sarea_map = dev->maplist[0]; - dev_priv->sarea_priv = (drm_i810_sarea_t *) - ((u8 *)sarea_map->handle + + dev_priv->sarea_priv = (drm_i810_sarea_t *) + ((u8 *)sarea_map->handle + init->sarea_priv_offset); atomic_set(&dev_priv->flush_done, 0); init_waitqueue_head(&dev_priv->flush_queue); - + dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; - dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + - init->ring_start, + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, init->ring_size); dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - + if (dev_priv->ring.virtual_start == NULL) { i810_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" @@ -456,8 +456,8 @@ static int i810_dma_initialize(drm_device_t *dev, dev_priv->front_di1 = init->front_offset | init->pitch_bits; dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; - - + + /* Program Hardware Status Page */ dev_priv->hw_status_page = i810_alloc_page(dev); memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); @@ -467,10 +467,10 @@ static int i810_dma_initialize(drm_device_t *dev, return -ENOMEM; } DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - + I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); DRM_DEBUG("Enabled hardware status page\n"); - + /* Now we need to init our freelist */ if(i810_freelist_init(dev) != 0) { i810_dma_cleanup(dev); @@ -489,13 +489,13 @@ int i810_dma_init(struct inode *inode, struct file *filp, drm_i810_private_t *dev_priv; drm_i810_init_t init; int retcode = 0; - - copy_from_user_ret(&init, (drm_i810_init_t *)arg, - sizeof(init), -EFAULT); - + + if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init))) + return -EFAULT; + switch(init.func) { case I810_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i810_private_t), + dev_priv = drm_alloc(sizeof(drm_i810_private_t), DRM_MEM_DRIVER); if(dev_priv == NULL) return -ENOMEM; retcode = i810_dma_initialize(dev, dev_priv, &init); @@ -507,7 +507,7 @@ int i810_dma_init(struct inode *inode, struct file *filp, retcode = -EINVAL; break; } - + return retcode; } @@ -519,9 +519,9 @@ int i810_dma_init(struct inode *inode, struct file *filp, * Use 'volatile' & local var tmp to force the emitted values to be * identical to the verified ones. */ -static void i810EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) -{ +static void i810EmitContextVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; @@ -539,22 +539,22 @@ static void i810EmitContextVerified( drm_device_t *dev, tmp = code[i]; if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( tmp ); j++; - } + } } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING( 0 ); ADVANCE_LP_RING(); } -static void i810EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) -{ +static void i810EmitTexVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; @@ -571,15 +571,15 @@ static void i810EmitTexVerified( drm_device_t *dev, tmp = code[i]; if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( tmp ); j++; } - } - - if (j & 1) - OUT_RING( 0 ); + } + + if (j & 1) + OUT_RING( 0 ); ADVANCE_LP_RING(); } @@ -587,9 +587,9 @@ static void i810EmitTexVerified( drm_device_t *dev, /* Need to do some additional checking when setting the dest buffer. */ -static void i810EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) -{ +static void i810EmitDestVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ drm_i810_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; @@ -653,9 +653,9 @@ static void i810EmitState( drm_device_t *dev ) -/* need to verify +/* need to verify */ -static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, +static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, unsigned int clear_color, unsigned int clear_zval ) { @@ -686,10 +686,10 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, pbox->y2 > dev_priv->h) continue; - if ( flags & I810_FRONT ) { + if ( flags & I810_FRONT ) { DRM_DEBUG("clear front\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); OUT_RING( (height << 16) | width ); @@ -701,8 +701,8 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, if ( flags & I810_BACK ) { DRM_DEBUG("clear back\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); OUT_RING( (height << 16) | width ); @@ -714,8 +714,8 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, if ( flags & I810_DEPTH ) { DRM_DEBUG("clear depth\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); OUT_RING( (height << 16) | width ); @@ -746,7 +746,7 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - for (i = 0 ; i < nbox; i++, pbox++) + for (i = 0 ; i < nbox; i++, pbox++) { unsigned int w = pbox->x2 - pbox->x1; unsigned int h = pbox->y2 - pbox->y1; @@ -758,7 +758,7 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; - + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2); @@ -768,14 +768,14 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) OUT_RING( pitch | (0xCC << 16)); OUT_RING( (h << 16) | (w * cpp)); OUT_RING( dst ); - OUT_RING( pitch ); + OUT_RING( pitch ); OUT_RING( start ); ADVANCE_LP_RING(); } } -static void i810_dma_dispatch_vertex(drm_device_t *dev, +static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, int discard, int used) @@ -786,30 +786,30 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_clip_rect_t *box = sarea_priv->boxes; int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; + unsigned long start = address - dev->agp->base; int i = 0, u; RING_LOCALS; i810_kernel_lost_context(dev); - if (nbox > I810_NR_SAREA_CLIPRECTS) + if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; if (discard) { - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); if(u != I810_BUF_CLIENT) { DRM_DEBUG("xxxx 2\n"); } } - if (used > 4*1024) + if (used > 4*1024) used = 0; if (sarea_priv->dirty) i810EmitState( dev ); - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", address, used, nbox); dev_priv->counter++; @@ -823,7 +823,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | sarea_priv->vertex_prim | ((used/4)-2)); - + if (used & 4) { *(u32 *)((u32)buf_priv->virtual + used) = 0; used += 4; @@ -831,26 +831,26 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, i810_unmap_buffer(buf); } - + if (used) { do { if (i < nbox) { BEGIN_LP_RING(4); - OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | + OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | SC_ENABLE ); OUT_RING( GFX_OP_SCISSOR_INFO ); OUT_RING( box[i].x1 | (box[i].y1<<16) ); OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); ADVANCE_LP_RING(); } - + BEGIN_LP_RING(4); OUT_RING( CMD_OP_BATCH_BUFFER ); OUT_RING( start | BB1_PROTECTED ); OUT_RING( start + used - 4 ); OUT_RING( 0 ); ADVANCE_LP_RING(); - + } while (++i < nbox); } @@ -878,15 +878,15 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; u16 temp; - + atomic_inc(&dev->total_irq); temp = I810_READ16(I810REG_INT_IDENTITY_R); temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, temp); /* Clear all interrupts */ else return; - + queue_task(&dev->tq, &tq_immediate); mark_bh(IMMEDIATE_BH); } @@ -904,9 +904,9 @@ int i810_irq_install(drm_device_t *dev, int irq) { int retcode; u16 temp; - + if (!irq) return -EINVAL; - + down(&dev->struct_sem); if (dev->irq) { up(&dev->struct_sem); @@ -914,14 +914,14 @@ int i810_irq_install(drm_device_t *dev, int irq) } dev->irq = irq; up(&dev->struct_sem); - + DRM_DEBUG( "Interrupt Install : %d\n", irq); DRM_DEBUG("%d\n", irq); dev->context_flag = 0; dev->interrupt_flag = 0; dev->dma_flag = 0; - + dev->dma->next_buffer = NULL; dev->dma->next_queue = NULL; dev->dma->this_buffer = NULL; @@ -935,7 +935,7 @@ int i810_irq_install(drm_device_t *dev, int irq) temp = I810_READ16(I810REG_HWSTAM); temp = temp & 0x6000; I810_WRITE16(I810REG_HWSTAM, temp); - + temp = I810_READ16(I810REG_INT_MASK_R); temp = temp & 0x6000; I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */ @@ -957,7 +957,7 @@ int i810_irq_install(drm_device_t *dev, int irq) temp = I810_READ16(I810REG_INT_ENABLE_R); temp = temp & 0x6000; temp = temp | 0x0003; - I810_WRITE16(I810REG_INT_ENABLE_R, + I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Enable bp & user interrupts */ return 0; } @@ -974,20 +974,20 @@ int i810_irq_uninstall(drm_device_t *dev) irq = dev->irq; dev->irq = 0; up(&dev->struct_sem); - + if (!irq) return -EINVAL; - DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); + DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); DRM_DEBUG("%d\n", irq); - + temp = I810_READ16(I810REG_INT_IDENTITY_R); temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, temp); /* Clear all interrupts */ - + temp = I810_READ16(I810REG_INT_ENABLE_R); temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_ENABLE_R, + I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */ free_irq(irq, dev); @@ -1002,11 +1002,12 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_control_t ctl; int retcode; - + DRM_DEBUG( "i810_control\n"); - copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); - + if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) + return -EFAULT; + switch (ctl.func) { case DRM_INST_HANDLER: if ((retcode = i810_irq_install(dev, ctl.irq))) @@ -1062,7 +1063,7 @@ static void i810_dma_quiescent(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - unsigned long end; + unsigned long end; if(dev_priv == NULL) { return; @@ -1071,23 +1072,23 @@ static void i810_dma_quiescent(drm_device_t *dev) current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); end = jiffies + (HZ*3); - + for (;;) { i810_dma_quiescent_emit(dev); if (atomic_read(&dev_priv->flush_done) == 1) break; if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; - } + } schedule_timeout(HZ*3); if (signal_pending(current)) { break; } } - + current->state = TASK_RUNNING; remove_wait_queue(&dev_priv->flush_queue, &entry); - + return; } @@ -1097,7 +1098,7 @@ static int i810_flush_queue(drm_device_t *dev) drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; drm_device_dma_t *dma = dev->dma; unsigned long end; - int i, ret = 0; + int i, ret = 0; if(dev_priv == NULL) { return 0; @@ -1112,14 +1113,14 @@ static int i810_flush_queue(drm_device_t *dev) if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; - } + } schedule_timeout(HZ*3); if (signal_pending(current)) { ret = -EINTR; /* Can't restart */ break; } } - + current->state = TASK_RUNNING; remove_wait_queue(&dev_priv->flush_queue, &entry); @@ -1127,8 +1128,8 @@ static int i810_flush_queue(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; - - int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, + + int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, I810_BUF_FREE); if (used == I810_BUF_HARDWARE) @@ -1155,9 +1156,9 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) 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; - + if (buf->pid == pid && buf_priv) { - int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); if (used == I810_BUF_CLIENT) @@ -1178,14 +1179,15 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, int ret = 0; 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); return -EINVAL; } - + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", lock.context, current->pid, dev->lock.hw_lock->lock, lock.flags); @@ -1211,7 +1213,7 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -1225,9 +1227,8 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, current->state = TASK_RUNNING; remove_wait_queue(&dev->lock.lock_queue, &entry); } - + if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -1236,7 +1237,7 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_QUIESCENT) { DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); DRM_DEBUG("fred\n"); @@ -1247,12 +1248,12 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, return ret; } -int i810_flush_ioctl(struct inode *inode, struct file *filp, +int i810_flush_ioctl(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_DEBUG("i810_flush_ioctl\n"); if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_flush_ioctl called without lock held\n"); @@ -1272,12 +1273,12 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, drm_device_dma_t *dma = dev->dma; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; drm_i810_vertex_t vertex; - copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), - -EFAULT); + if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex))) + return -EFAULT; if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_dma_vertex called without lock held\n"); @@ -1287,15 +1288,15 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", vertex.idx, vertex.used, vertex.discard); - i810_dma_dispatch_vertex( dev, - dma->buflist[ vertex.idx ], + i810_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], vertex.discard, vertex.used ); atomic_add(vertex.used, &dma->total_bytes); atomic_inc(&dma->total_dmas); sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; - + return 0; } @@ -1308,16 +1309,16 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_i810_clear_t clear; - copy_from_user_ret(&clear, (drm_i810_clear_t *)arg, sizeof(clear), - -EFAULT); - + if (copy_from_user(&clear, (drm_i810_clear_t *)arg, sizeof(clear))) + return -EFAULT; + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_clear_bufs called without lock held\n"); return -EINVAL; } - i810_dma_dispatch_clear( dev, clear.flags, - clear.clear_color, + i810_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, clear.clear_depth ); return 0; } @@ -1327,7 +1328,7 @@ int i810_swap_bufs(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - + DRM_DEBUG("i810_swap_bufs\n"); if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { @@ -1346,8 +1347,8 @@ int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; sarea_priv->last_dispatch = (int) hw_status[5]; return 0; @@ -1362,17 +1363,18 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, drm_i810_dma_t d; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; DRM_DEBUG("getbuf\n"); - copy_from_user_ret(&d, (drm_i810_dma_t *)arg, sizeof(d), -EFAULT); - + if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d))) + return -EFAULT; + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_dma called without lock held\n"); return -EINVAL; } - + d.granted = 0; retcode = i810_dma_get_buffer(dev, &d, filp); @@ -1380,7 +1382,8 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", current->pid, retcode, d.granted); - copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); + if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) + return -EFAULT; sarea_priv->last_dispatch = (int) hw_status[5]; return retcode; @@ -1394,8 +1397,8 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, drm_i810_copy_t d; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; drm_device_dma_t *dma = dev->dma; @@ -1404,15 +1407,17 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("i810_dma called without lock held\n"); return -EINVAL; } - - copy_from_user_ret(&d, (drm_i810_copy_t *)arg, sizeof(d), -EFAULT); + + if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d))) + return -EFAULT; if(d.idx > dma->buf_count) return -EINVAL; buf = dma->buflist[ d.idx ]; buf_priv = buf->dev_private; if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM; - copy_from_user_ret(buf_priv->virtual, d.address, d.used, -EFAULT); + if (copy_from_user(buf_priv->virtual, d.address, d.used)) + return -EFAULT; sarea_priv->last_dispatch = (int) hw_status[5]; diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index 18168605..86d5e230 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -1,6 +1,6 @@ /* i810_drv.c -- I810 driver -*- linux-c -*- * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -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 @@ -35,7 +35,7 @@ #define I810_NAME "i810" #define I810_DESC "Intel I810" -#define I810_DATE "20000719" +#define I810_DATE "20000910" #define I810_MAJOR 1 #define I810_MINOR 1 #define I810_PATCHLEVEL 0 @@ -143,7 +143,7 @@ __setup("i810=", i810_options); static int i810_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -188,22 +188,22 @@ static int i810_setup(drm_device_t *dev) #endif 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; dev->buf_async = NULL; init_waitqueue_head(&dev->buf_readers); init_waitqueue_head(&dev->buf_writers); - + 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,15 +218,15 @@ static int i810_takedown(drm_device_t *dev) DRM_DEBUG("\n"); if (dev->irq) i810_irq_uninstall(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; @@ -244,7 +244,7 @@ static int i810_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - + /* Remove AGP resources, but leave dev->agp intact until r128_cleanup is called. */ for (entry = dev->agp->memory; entry; entry = nexte) { @@ -254,10 +254,10 @@ static int i810_takedown(drm_device_t *dev) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; - + if (dev->agp->acquired && drm_agp.release) (*drm_agp.release)(); - + dev->agp->acquired = 0; dev->agp->enabled = 0; } @@ -269,7 +269,7 @@ static int i810_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++) { @@ -305,7 +305,7 @@ static int i810_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->queuelist) { for (i = 0; i < dev->queue_count; i++) { drm_waitlist_destroy(&dev->queuelist[i]->waitlist); @@ -331,7 +331,7 @@ static int i810_takedown(drm_device_t *dev) wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -348,7 +348,7 @@ static int i810_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(i810); #endif @@ -402,7 +402,7 @@ static void i810_cleanup(void) drm_device_t *dev = &i810_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&i810_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -428,17 +428,18 @@ int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = I810_MAJOR; @@ -449,10 +450,10 @@ int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, I810_DATE); DRM_COPY(version.desc, I810_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -460,7 +461,7 @@ int i810_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &i810_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 @@ -497,7 +498,7 @@ int i810_release(struct inode *inode, struct file *filp) drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - + /* FIXME: may require heavy-handed reset of hardware at this point, possibly processed via a callback to the X @@ -518,7 +519,7 @@ int i810_release(struct inode *inode, struct file *filp) dev->lock.lock_time = jiffies; atomic_inc(&dev->total_locks); break; /* Got lock */ - } + } /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -544,7 +545,7 @@ int i810_release(struct inode *inode, struct file *filp) if (priv->next) priv->next->prev = priv->prev; else dev->file_last = priv->prev; up(&dev->struct_sem); - + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); #if LINUX_VERSION_CODE < 0x020333 MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ @@ -584,7 +585,7 @@ int i810_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); @@ -604,7 +605,7 @@ int i810_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -616,8 +617,9 @@ int i810_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); @@ -641,9 +643,7 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles() - dev->lck_start)]); #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); -#endif return 0; } diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index a4a8fe55..c551ba6e 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -1,6 +1,6 @@ /* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*- * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -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 @@ -35,9 +35,9 @@ #include "mga_drv.h" #define MGA_NAME "mga" -#define MGA_DESC "Matrox g200/g400" -#define MGA_DATE "20000719" -#define MGA_MAJOR 1 +#define MGA_DESC "Matrox G200/G400" +#define MGA_DATE "20000910" +#define MGA_MAJOR 2 #define MGA_MINOR 0 #define MGA_PATCHLEVEL 0 @@ -123,7 +123,7 @@ static char *mga = NULL; #endif MODULE_AUTHOR("VA Linux Systems, Inc."); -MODULE_DESCRIPTION("Matrox g200/g400"); +MODULE_DESCRIPTION("Matrox G200/G400"); MODULE_PARM(mga, "s"); #ifndef MODULE @@ -144,7 +144,7 @@ __setup("mga=", mga_options); static int mga_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -187,22 +187,22 @@ static int mga_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; dev->buf_async = NULL; init_waitqueue_head(&dev->buf_readers); init_waitqueue_head(&dev->buf_writers); - + 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; } @@ -217,15 +217,15 @@ static int mga_takedown(drm_device_t *dev) DRM_DEBUG("\n"); if (dev->irq) mga_irq_uninstall(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; @@ -243,7 +243,7 @@ static int mga_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - + /* Remove AGP resources, but leave dev->agp intact until cleanup is called. */ for (entry = dev->agp->memory; entry; entry = nexte) { @@ -253,10 +253,10 @@ static int mga_takedown(drm_device_t *dev) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; - + if (dev->agp->acquired && drm_agp.release) (*drm_agp.release)(); - + dev->agp->acquired = 0; dev->agp->enabled = 0; } @@ -268,7 +268,7 @@ static int mga_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++) { @@ -304,7 +304,7 @@ static int mga_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->queuelist) { for (i = 0; i < dev->queue_count; i++) { drm_waitlist_destroy(&dev->queuelist[i]->waitlist); @@ -330,7 +330,7 @@ static int mga_takedown(drm_device_t *dev) wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -347,7 +347,7 @@ static int mga_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(mga); #endif @@ -407,7 +407,7 @@ static void mga_cleanup(void) drm_device_t *dev = &mga_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&mga_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -419,7 +419,7 @@ static void mga_cleanup(void) #ifdef CONFIG_MTRR if(dev->agp && dev->agp->agp_mtrr) { int retval; - retval = mtrr_del(dev->agp->agp_mtrr, + retval = mtrr_del(dev->agp->agp_mtrr, dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size * 1024*1024); DRM_DEBUG("mtrr_del = %d\n", retval); @@ -444,17 +444,18 @@ int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = MGA_MAJOR; @@ -465,10 +466,10 @@ int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, MGA_DATE); DRM_COPY(version.desc, MGA_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -476,7 +477,7 @@ int mga_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &mga_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 @@ -513,7 +514,7 @@ int mga_release(struct inode *inode, struct file *filp) drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - + /* FIXME: may require heavy-handed reset of hardware at this point, possibly processed via a callback to the X @@ -534,7 +535,7 @@ int mga_release(struct inode *inode, struct file *filp) dev->lock.lock_time = jiffies; atomic_inc(&dev->total_locks); break; /* Got lock */ - } + } /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -560,7 +561,7 @@ int mga_release(struct inode *inode, struct file *filp) if (priv->next) priv->next->prev = priv->prev; else dev->file_last = priv->prev; up(&dev->struct_sem); - + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); #if LINUX_VERSION_CODE < 0x020333 MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ @@ -601,7 +602,7 @@ int mga_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); @@ -621,7 +622,7 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -633,8 +634,9 @@ int mga_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); @@ -655,8 +657,6 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ unblock_all_signals(); -#endif return 0; } diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index dd982ab4..b58dcf06 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -35,7 +35,7 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20000827" +#define R128_DATE "20000910" #define R128_MAJOR 1 #define R128_MINOR 0 #define R128_PATCHLEVEL 0 @@ -420,17 +420,18 @@ int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = R128_MAJOR; @@ -441,10 +442,10 @@ int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, R128_DATE); DRM_COPY(version.desc, R128_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -559,7 +560,8 @@ int r128_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", @@ -656,7 +658,6 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -665,7 +666,6 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -700,7 +700,8 @@ int r128_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", @@ -729,9 +730,6 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, current->priority = DEF_PRIORITY; } #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ unblock_all_signals(); -#endif return 0; } diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index 434a1ccd..d5fe8fc0 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -9,11 +9,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 @@ -100,7 +100,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 }, @@ -121,7 +121,7 @@ MODULE_PARM(sis, "s"); 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; @@ -163,7 +163,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; @@ -172,15 +172,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; } @@ -200,12 +200,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; @@ -224,7 +224,7 @@ static int sis_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - + /* Remove AGP resources, but leave dev->agp intact until cleanup is called. */ for (entry = dev->agp->memory; entry; entry = nexte) { @@ -234,13 +234,13 @@ static int sis_takedown(drm_device_t *dev) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; - + if (dev->agp->acquired && drm_agp.release) (*drm_agp.release)(); - + dev->agp->acquired = 0; dev->agp->enabled = 0; - } + } #endif /* Clear vma list (only built for debugging) */ @@ -251,7 +251,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++) { @@ -289,14 +289,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; } @@ -313,7 +313,7 @@ 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 @@ -356,7 +356,7 @@ int sis_init(void) SIS_PATCHLEVEL, SIS_DATE, sis_misc.minor); - + return 0; } @@ -367,7 +367,7 @@ 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"); @@ -378,7 +378,7 @@ void sis_cleanup(void) #ifdef CONFIG_MTRR if(dev->agp && dev->agp->agp_mtrr) { int retval; - retval = mtrr_del(dev->agp->agp_mtrr, + retval = mtrr_del(dev->agp->agp_mtrr, dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size * 1024*1024); DRM_DEBUG("mtrr_del = %d\n", retval); @@ -433,7 +433,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))) { @@ -492,7 +492,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); @@ -512,7 +512,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; } @@ -549,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) @@ -561,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; @@ -584,7 +584,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); current->state = TASK_INTERRUPTIBLE; @@ -626,7 +626,6 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -635,7 +634,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -652,7 +651,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; } @@ -665,7 +664,7 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, drm_lock_t lock; copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); - + if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", current->pid, lock.context); @@ -687,9 +686,7 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ unblock_all_signals(); -#endif return 0; } diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c index 07febea1..2026e9d0 100644 --- a/linux-core/tdfx_drv.c +++ b/linux-core/tdfx_drv.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. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Daryll Strauss <daryll@valinux.com> @@ -36,7 +36,7 @@ #define TDFX_NAME "tdfx" #define TDFX_DESC "3dfx Banshee/Voodoo3+" -#define TDFX_DATE "20000719" +#define TDFX_DATE "20000910" #define TDFX_MAJOR 1 #define TDFX_MINOR 0 #define TDFX_PATCHLEVEL 0 @@ -76,7 +76,7 @@ static drm_ioctl_desc_t tdfx_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)] = { tdfx_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { tdfx_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { tdfx_modctx, 1, 1 }, @@ -128,7 +128,7 @@ __setup("tdfx=", tdfx_options); static int tdfx_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -170,7 +170,7 @@ static int tdfx_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; @@ -179,15 +179,15 @@ static int tdfx_setup(drm_device_t *dev) init_waitqueue_head(&dev->buf_writers); tdfx_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; } @@ -203,12 +203,12 @@ static int tdfx_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; @@ -227,7 +227,7 @@ static int tdfx_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; @@ -246,7 +246,7 @@ static int tdfx_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++) { @@ -284,14 +284,14 @@ static int tdfx_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; } @@ -308,7 +308,7 @@ static int tdfx_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(tdfx); #endif @@ -340,7 +340,7 @@ static int tdfx_init(void) TDFX_PATCHLEVEL, TDFX_DATE, tdfx_misc.minor); - + return 0; } @@ -351,7 +351,7 @@ static void tdfx_cleanup(void) drm_device_t *dev = &tdfx_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&tdfx_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -379,17 +379,18 @@ int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = TDFX_MAJOR; @@ -400,10 +401,10 @@ int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, TDFX_DATE); DRM_COPY(version.desc, TDFX_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -411,7 +412,7 @@ int tdfx_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &tdfx_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 @@ -479,7 +480,7 @@ int tdfx_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); @@ -499,7 +500,7 @@ int tdfx_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -518,7 +519,8 @@ int tdfx_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", @@ -536,7 +538,7 @@ int tdfx_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) @@ -548,7 +550,7 @@ int tdfx_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; @@ -571,7 +573,7 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -615,7 +617,6 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -624,7 +625,7 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -647,7 +648,7 @@ int tdfx_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; } @@ -659,8 +660,9 @@ int tdfx_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); @@ -688,9 +690,7 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd, current->priority = DEF_PRIORITY; } #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); -#endif return 0; } diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 7dfb20b1..7fe57f8e 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -54,7 +54,7 @@ PROGS= drmstat DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o -DRMHEADERS= drm.h drmP.h +DRMHEADERS= drm.h drmP.h compat-pre24.h GAMMAOBJS= gamma_drv.o gamma_dma.o GAMMAHEADERS= gamma_drv.h $(DRMHEADERS) @@ -126,6 +126,7 @@ 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 \ | egrep -q '(band|int, int)'; then echo 3; else echo 2; fi) +MACHINE := $(shell echo `uname -m`) ifeq ($(AGP),0) AGP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \ | grep -s 'AGP_MODULE = ' | cut -d' ' -f3) @@ -134,7 +135,11 @@ endif ifeq ($(AGP),1) MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE DRMOBJS += agpsupport.o -MODS += mga.o i810.o +MODS += mga.o +ifeq ($(MACHINE),i386) +MODS += i810.o +endif + MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o MGAHEADERS= mga_drv.h $(DRMHEADERS) @@ -159,6 +164,7 @@ endif all::;@echo === KERNEL HEADERS IN $(TREE) all::;@echo === SMP=${SMP} MODVERSIONS=${MODVERSIONS} AGP=${AGP} SIS=${SIS} all::;@echo === kill_fasync has $(PARAMS) parameters +all::;@echo === Compiling for machine $(MACHINE) all:: $(LIBS) $(MODS) $(PROGS) endif diff --git a/linux/agpsupport.c b/linux/agpsupport.c index 42a1bc2f..24fd59cd 100644 --- a/linux/agpsupport.c +++ b/linux/agpsupport.c @@ -95,7 +95,8 @@ int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd, info.id_vendor = kern->device->vendor; info.id_device = kern->device->device; - copy_to_user_ret((drm_agp_info_t *)arg, &info, sizeof(info), -EFAULT); + if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info))) + return -EFAULT; return 0; } @@ -134,8 +135,8 @@ int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd, if (!dev->agp->acquired || !drm_agp.enable) return -EINVAL; - copy_from_user_ret(&mode, (drm_agp_mode_t *)arg, sizeof(mode), - -EFAULT); + if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode))) + return -EFAULT; dev->agp->mode = mode.mode; (*drm_agp.enable)(mode.mode); @@ -155,8 +156,8 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long pages; u32 type; if (!dev->agp->acquired) return -EINVAL; - copy_from_user_ret(&request, (drm_agp_buffer_t *)arg, sizeof(request), - -EFAULT); + if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request))) + return -EFAULT; if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; @@ -212,8 +213,8 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd, drm_agp_mem_t *entry; if (!dev->agp->acquired) return -EINVAL; - copy_from_user_ret(&request, (drm_agp_binding_t *)arg, sizeof(request), - -EFAULT); + if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) + return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; @@ -231,8 +232,8 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, int page; if (!dev->agp->acquired || !drm_agp.bind_memory) return -EINVAL; - copy_from_user_ret(&request, (drm_agp_binding_t *)arg, sizeof(request), - -EFAULT); + if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) + return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) return -EINVAL; @@ -253,8 +254,8 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, drm_agp_mem_t *entry; if (!dev->agp->acquired) return -EINVAL; - copy_from_user_ret(&request, (drm_agp_buffer_t *)arg, sizeof(request), - -EFAULT); + 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); diff --git a/linux/auth.c b/linux/auth.c index 4556bd96..80bb4b65 100644 --- a/linux/auth.c +++ b/linux/auth.c @@ -137,7 +137,8 @@ int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd, } DRM_DEBUG("%u\n", auth.magic); - copy_to_user_ret((drm_auth_t *)arg, &auth, sizeof(auth), -EFAULT); + if (copy_to_user((drm_auth_t *)arg, &auth, sizeof(auth))) + return -EFAULT; return 0; } @@ -149,7 +150,8 @@ int drm_authmagic(struct inode *inode, struct file *filp, unsigned int cmd, drm_auth_t auth; drm_file_t *file; - copy_from_user_ret(&auth, (drm_auth_t *)arg, sizeof(auth), -EFAULT); + if (copy_from_user(&auth, (drm_auth_t *)arg, sizeof(auth))) + return -EFAULT; DRM_DEBUG("%u\n", auth.magic); if ((file = drm_find_file(dev, auth.magic))) { file->authenticated = 1; diff --git a/linux/bufs.c b/linux/bufs.c index c00f051a..28e0eb5f 100644 --- a/linux/bufs.c +++ b/linux/bufs.c @@ -133,12 +133,13 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, dev->maplist[dev->map_count-1] = map; up(&dev->struct_sem); - copy_to_user_ret((drm_map_t *)arg, map, sizeof(*map), -EFAULT); + if (copy_to_user((drm_map_t *)arg, map, sizeof(*map))) + return -EFAULT; if (map->type != _DRM_SHM) { - copy_to_user_ret(&((drm_map_t *)arg)->handle, + if (copy_to_user(&((drm_map_t *)arg)->handle, &map->offset, - sizeof(map->offset), - -EFAULT); + sizeof(map->offset))) + return -EFAULT; } return 0; } @@ -166,10 +167,10 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; count = request.count; order = drm_order(request.size); @@ -295,10 +296,10 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, request.count = entry->buf_count; request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, + if (copy_to_user((drm_buf_desc_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; atomic_dec(&dev->buf_alloc); return 0; @@ -324,10 +325,10 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_info_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) { if (dma->bufs[i].buf_count) ++count; @@ -338,28 +339,26 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, if (request.count >= count) { for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) { if (dma->bufs[i].buf_count) { - copy_to_user_ret(&request.list[count].count, + if (copy_to_user(&request.list[count].count, &dma->bufs[i].buf_count, sizeof(dma->bufs[0] - .buf_count), - -EFAULT); - copy_to_user_ret(&request.list[count].size, + .buf_count)) || + copy_to_user(&request.list[count].size, &dma->bufs[i].buf_size, - sizeof(dma->bufs[0].buf_size), - -EFAULT); - copy_to_user_ret(&request.list[count].low_mark, + sizeof(dma->bufs[0].buf_size)) || + copy_to_user(&request.list[count].low_mark, &dma->bufs[i] .freelist.low_mark, sizeof(dma->bufs[0] - .freelist.low_mark), - -EFAULT); - copy_to_user_ret(&request.list[count] + .freelist.low_mark)) || + copy_to_user(&request.list[count] .high_mark, &dma->bufs[i] .freelist.high_mark, sizeof(dma->bufs[0] - .freelist.high_mark), - -EFAULT); + .freelist.high_mark))) + return -EFAULT; + DRM_DEBUG("%d %d %d %d %d\n", i, dma->bufs[i].buf_count, @@ -372,10 +371,10 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, } request.count = count; - copy_to_user_ret((drm_buf_info_t *)arg, + if (copy_to_user((drm_buf_info_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; return 0; } @@ -392,10 +391,10 @@ int drm_markbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("%d, %d, %d\n", request.size, request.low_mark, request.high_mark); @@ -427,17 +426,17 @@ int drm_freebufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_free_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("%d\n", request.count); for (i = 0; i < request.count; i++) { - copy_from_user_ret(&idx, + if (copy_from_user(&idx, &request.list[i], - sizeof(idx), - -EFAULT); + sizeof(idx))) + return -EFAULT; if (idx < 0 || idx >= dma->buf_count) { DRM_ERROR("Index %d (of %d max)\n", idx, dma->buf_count - 1); @@ -480,10 +479,10 @@ int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_map_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; if (request.count >= dma->buf_count) { down(¤t->mm->mmap_sem); @@ -529,10 +528,10 @@ done: request.count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - copy_to_user_ret((drm_buf_map_t *)arg, + if (copy_to_user((drm_buf_map_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; return retcode; } diff --git a/linux/compat-pre24.h b/linux/compat-pre24.h new file mode 100644 index 00000000..257baca1 --- /dev/null +++ b/linux/compat-pre24.h @@ -0,0 +1,41 @@ +/* compat-pre24.h -- Linux pre-2.4.0 compatibility + * Created: Mon Aug 28 15:31:43 2000 by faith@acm.org + * 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 + * 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. + * + * Authors: + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#ifndef _COMPAT_PRE24_H_ +#define _COMPAT_PRE24_H_ + + /* virt_to_page added in 2.4.0-test6 */ +#if LINUX_VERSION_CODE < 0x020400 +#define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr)) +#endif + +#define block_all_signals(a,b,c) +#define unblock_all_signals() + +#endif diff --git a/linux/context.c b/linux/context.c index ca491094..933fd0cd 100644 --- a/linux/context.c +++ b/linux/context.c @@ -129,19 +129,21 @@ int drm_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], + if (copy_to_user(&res.contexts[i], &i, - sizeof(i), - -EFAULT); + 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; } @@ -153,7 +155,8 @@ int drm_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 = 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); @@ -161,7 +164,8 @@ int drm_addctx(struct inode *inode, struct file *filp, unsigned int cmd, } drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); DRM_DEBUG("%d\n", 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; } @@ -173,7 +177,8 @@ int drm_modctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_ctx_t ctx; drm_queue_t *q; - 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); @@ -206,7 +211,8 @@ int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_ctx_t ctx; drm_queue_t *q; - 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); @@ -223,7 +229,8 @@ int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd, ctx.flags = q->flags; atomic_dec(&q->use_count); - 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; } @@ -235,7 +242,8 @@ int drm_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 drm_context_switch(dev, dev->last_context, ctx.handle); } @@ -247,7 +255,8 @@ int drm_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); drm_context_switch_complete(dev, ctx.handle); @@ -263,7 +272,8 @@ int drm_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, drm_queue_t *q; drm_buf_t *buf; - 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); if (ctx.handle >= dev->queue_count) return -EINVAL; diff --git a/linux/dma.c b/linux/dma.c index ac2d1bc5..62340170 100644 --- a/linux/dma.c +++ b/linux/dma.c @@ -486,14 +486,16 @@ static int drm_dma_get_buffers_of_order(drm_device_t *dev, drm_dma_t *d, buf->pending); } buf->pid = current->pid; - copy_to_user_ret(&d->request_indices[i], + if (copy_to_user(&d->request_indices[i], &buf->idx, - sizeof(buf->idx), - -EFAULT); - copy_to_user_ret(&d->request_sizes[i], + sizeof(buf->idx))) + return -EFAULT; + + if (copy_to_user(&d->request_sizes[i], &buf->total, - sizeof(buf->total), - -EFAULT); + sizeof(buf->total))) + return -EFAULT; + ++d->granted_count; } return 0; diff --git a/linux/drawable.c b/linux/drawable.c index 03839f5b..1328054e 100644 --- a/linux/drawable.c +++ b/linux/drawable.c @@ -39,7 +39,8 @@ int drm_adddraw(struct inode *inode, struct file *filp, unsigned int cmd, draw.handle = 0; /* NOOP */ DRM_DEBUG("%d\n", draw.handle); - copy_to_user_ret((drm_draw_t *)arg, &draw, sizeof(draw), -EFAULT); + if (copy_to_user((drm_draw_t *)arg, &draw, sizeof(draw))) + return -EFAULT; return 0; } diff --git a/linux/drmP.h b/linux/drmP.h index b9a4dab4..fcee4104 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -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,16 +23,22 @@ * 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> - * + * */ #ifndef _DRM_P_H_ #define _DRM_P_H_ #ifdef __KERNEL__ +#ifdef __alpha__ +/* add include of current.h so that "current" is defined + * before static inline funcs in wait.h. Doing this so we + * can build the DRM (part of PI DRI). 4/21/2000 S + B */ +#include <asm/current.h> +#endif /* __alpha__ */ #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> @@ -47,6 +53,9 @@ #include <linux/sched.h> #include <linux/smp_lock.h> /* For (un)lock_kernel */ #include <linux/mm.h> +#ifdef __alpha__ +#include <asm/pgtable.h> /* For pte_wrprotect */ +#endif #include <asm/io.h> #include <asm/mman.h> #include <asm/uaccess.h> @@ -61,6 +70,9 @@ #include <linux/tqueue.h> #include <linux/poll.h> #endif +#if LINUX_VERSION_CODE < 0x020400 +#include "compat-pre24.h" +#endif #include "drm.h" #define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then @@ -140,15 +152,75 @@ typedef struct wait_queue *wait_queue_head_t; #define module_exit(x) void cleanup_module(void) { x(); } #endif - /* virt_to_page added in 2.4.0-test6 */ -#if LINUX_VERSION_CODE < 0x020400 -#define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr)) -#endif - /* Generic cmpxchg added in 2.3.x */ #ifndef __HAVE_ARCH_CMPXCHG /* Include this here so that driver can be used with older kernels. */ +#if defined(__alpha__) +static __inline__ unsigned long +__cmpxchg_u32(volatile int *m, int old, int new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldl_l %0,%2\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stl_c %1,%2\n" + " beq %1,3f\n" + "2: mb\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m)); + + return prev; +} + +static __inline__ unsigned long +__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldq_l %0,%2\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stq_c %1,%2\n" + " beq %1,3f\n" + "2: mb\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m)); + + return prev; +} + +static __inline__ unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); + case 8: + return __cmpxchg_u64(ptr, old, new); + } + return old; +} +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + +#elif __i386__ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { @@ -179,6 +251,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, #define cmpxchg(ptr,o,n) \ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ (unsigned long)(n),sizeof(*(ptr)))) +#endif /* i386 & alpha */ #endif /* Macros to make printk easier */ @@ -231,7 +304,7 @@ typedef struct drm_ioctl_desc { typedef struct drm_devstate { pid_t owner; /* X server pid holding x_lock */ - + } drm_devstate_t; typedef struct drm_magic_entry { @@ -292,14 +365,14 @@ typedef struct drm_buf { #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]; @@ -323,7 +396,7 @@ typedef struct drm_freelist { int initialized; /* Freelist in use */ atomic_t count; /* Number of free buffers */ drm_buf_t *next; /* End pointer */ - + wait_queue_head_t waiting; /* Processes waiting on free bufs */ int low_mark; /* Low water mark */ int high_mark; /* High water mark */ @@ -388,7 +461,7 @@ typedef struct drm_device_dma { atomic_t total_prio; /* Total DRM_DMA_PRIORITY */ atomic_t total_bytes; /* Total bytes DMA'd */ atomic_t total_dmas; /* Total DMA buffers dispatched */ - + atomic_t total_missed_dma; /* Missed drm_do_dma */ atomic_t total_missed_lock; /* Missed lock in drm_do_dma */ atomic_t total_missed_free; /* Missed drm_free_this_buffer */ @@ -401,7 +474,7 @@ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; drm_buf_t **buflist; /* Vector of pointers info bufs */ - int seg_count; + int seg_count; int page_count; unsigned long *pagelist; unsigned long byte_count; @@ -462,7 +535,7 @@ typedef struct drm_device { int unique_len; /* Length of unique field */ dev_t device; /* Device number for mknod */ char *devname; /* For /proc/interrupts */ - + int blocked; /* Blocked due to VC switch? */ struct proc_dir_entry *root; /* Root for this device's entries */ @@ -483,7 +556,7 @@ typedef struct drm_device { atomic_t total_ioctl; atomic_t total_irq; /* Total interruptions */ atomic_t total_ctx; /* Total context switches */ - + atomic_t total_locks; atomic_t total_unlocks; atomic_t total_contends; @@ -524,7 +597,7 @@ typedef struct drm_device { #if DRM_DMA_HISTOGRAM drm_histogram_t histo; #endif - + /* Callback to X server for context switch and for heavy-handed reset. */ char buf[DRM_BSZ]; /* Output buffer */ @@ -534,7 +607,7 @@ typedef struct drm_device { struct fasync_struct *buf_async;/* Processes waiting for SIGIO */ wait_queue_head_t buf_readers; /* Processes waiting to read */ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */ - + #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) drm_agp_head_t *agp; #endif diff --git a/linux/fops.c b/linux/fops.c index f3966d96..8e373e5a 100644 --- a/linux/fops.c +++ b/linux/fops.c @@ -176,7 +176,8 @@ ssize_t drm_read(struct file *filp, char *buf, size_t count, loff_t *off) } else { cur = DRM_MIN(send, dev->buf_end - dev->buf_rp); } - copy_to_user_ret(buf, dev->buf_rp, cur, -EINVAL); + 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; diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index 4a2acfb3..ad981bdd 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.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. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * @@ -97,7 +97,7 @@ static inline void gamma_dma_quiescent_single(drm_device_t *dev) GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - + do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) ; @@ -115,13 +115,13 @@ static inline void gamma_dma_quiescent_dual(drm_device_t *dev) GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - + /* Read from first MX */ do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) ; } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - + /* Read from second MX */ do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) @@ -144,7 +144,7 @@ static void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; drm_device_dma_t *dma = dev->dma; - + atomic_inc(&dev->total_irq); GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); @@ -183,7 +183,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) atomic_inc(&dma->total_missed_dma); return -EBUSY; } - + #if DRM_DMA_HISTOGRAM dma_start = get_cycles(); #endif @@ -215,7 +215,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) clear_bit(0, &dev->dma_flag); return 0; } - + if (!gamma_dma_is_ready(dev)) { clear_bit(0, &dev->dma_flag); return -EBUSY; @@ -246,7 +246,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) } retcode = -EBUSY; goto cleanup; - + /* POST: we will wait for the context switch and will dispatch on a later call when dev->last_context == buf->context. @@ -371,9 +371,9 @@ again: goto again; } } - + clear_bit(0, &dev->interrupt_flag); - + #if DRM_DMA_HISTOGRAM atomic_inc(&dev->histo.schedule[drm_histogram_slot(get_cycles() - schedule_start)]); @@ -461,7 +461,7 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) goto cleanup; } buf->pending = 1; - + if (dev->last_context != buf->context && !(dev->queuelist[buf->context]->flags & _DRM_CONTEXT_PRESERVED)) { @@ -496,7 +496,7 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) gamma_dma_dispatch(dev, address, length); atomic_add(length, &dma->total_bytes); atomic_inc(&dma->total_dmas); - + if (last_buf) { drm_free_buffer(dev, last_buf); } @@ -509,7 +509,7 @@ cleanup: gamma_dma_ready(dev); drm_free_buffer(dev, last_buf); } - + if (must_free && !dev->context_flag) { if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { @@ -531,15 +531,15 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) last_buf = dma->buflist[d->send_indices[d->send_count-1]]; add_wait_queue(&last_buf->dma_wait, &entry); } - + if ((retcode = drm_dma_enqueue(dev, d))) { if (d->flags & _DRM_DMA_BLOCK) remove_wait_queue(&last_buf->dma_wait, &entry); return retcode; } - + gamma_dma_schedule(dev, 0); - + if (d->flags & _DRM_DMA_BLOCK) { DRM_DEBUG("%d waiting\n", current->pid); current->state = TASK_INTERRUPTIBLE; @@ -586,7 +586,8 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, int retcode = 0; drm_dma_t d; - copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); + if (copy_from_user(&d, (drm_dma_t *)arg, sizeof(d))) + return -EFAULT; DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); @@ -609,7 +610,7 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, if (d.send_count) { if (d.flags & _DRM_DMA_PRIORITY) retcode = gamma_dma_priority(dev, &d); - else + else retcode = gamma_dma_send_buffers(dev, &d); } @@ -621,7 +622,8 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("%d returning, granted = %d\n", current->pid, d.granted_count); - copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); + if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) + return -EFAULT; return retcode; } @@ -631,7 +633,7 @@ int gamma_irq_install(drm_device_t *dev, int irq) int retcode; if (!irq) return -EINVAL; - + down(&dev->struct_sem); if (dev->irq) { up(&dev->struct_sem); @@ -639,13 +641,13 @@ int gamma_irq_install(drm_device_t *dev, int irq) } dev->irq = irq; up(&dev->struct_sem); - + DRM_DEBUG("%d\n", irq); dev->context_flag = 0; dev->interrupt_flag = 0; dev->dma_flag = 0; - + dev->dma->next_buffer = NULL; dev->dma->next_queue = NULL; dev->dma->this_buffer = NULL; @@ -659,7 +661,7 @@ int gamma_irq_install(drm_device_t *dev, int irq) /* Before installing handler */ GAMMA_WRITE(GAMMA_GCOMMANDMODE, 0); GAMMA_WRITE(GAMMA_GDMACONTROL, 0); - + /* Install handler */ if ((retcode = request_irq(dev->irq, gamma_dma_service, @@ -676,7 +678,7 @@ int gamma_irq_install(drm_device_t *dev, int irq) GAMMA_WRITE(GAMMA_GINTENABLE, 0x2001); GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0x0008); GAMMA_WRITE(GAMMA_GDELAYTIMER, 0x39090); - + return 0; } @@ -688,11 +690,11 @@ int gamma_irq_uninstall(drm_device_t *dev) irq = dev->irq; dev->irq = 0; up(&dev->struct_sem); - + if (!irq) return -EINVAL; - + DRM_DEBUG("%d\n", irq); - + GAMMA_WRITE(GAMMA_GDELAYTIMER, 0); GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0); GAMMA_WRITE(GAMMA_GINTENABLE, 0); @@ -709,9 +711,10 @@ int gamma_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_control_t ctl; int retcode; - - copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); - + + if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) + return -EFAULT; + switch (ctl.func) { case DRM_INST_HANDLER: if ((retcode = gamma_irq_install(dev, ctl.irq))) @@ -742,7 +745,8 @@ int gamma_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", @@ -757,7 +761,7 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd, if (lock.context < 0 || lock.context >= dev->queue_count) return -EINVAL; q = dev->queuelist[lock.context]; - + ret = drm_flush_block_and_flush(dev, lock.context, lock.flags); if (!ret) { @@ -787,7 +791,7 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&q->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -802,9 +806,8 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd, } drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */ - + if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -813,7 +816,7 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_READY) gamma_dma_ready(dev); if (lock.flags & _DRM_LOCK_QUIESCENT) { @@ -829,6 +832,6 @@ int gamma_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; } diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index 1fcd1933..dba974c2 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.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. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * @@ -42,7 +42,7 @@ #define GAMMA_NAME "gamma" #define GAMMA_DESC "3dlabs GMX 2000" -#define GAMMA_DATE "20000719" +#define GAMMA_DATE "20000910" #define GAMMA_MAJOR 1 #define GAMMA_MINOR 0 #define GAMMA_PATCHLEVEL 0 @@ -87,7 +87,7 @@ static drm_ioctl_desc_t gamma_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 }, - + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 }, @@ -120,7 +120,7 @@ MODULE_PARM_DESC(devices, * passed via the boot-loader (e.g., LILO). It calls the insmod option * routine, drm_parse_options. */ - + static int __init gamma_options(char *str) { @@ -134,7 +134,7 @@ __setup("gamma=", gamma_options); static int gamma_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -179,22 +179,22 @@ static int gamma_setup(drm_device_t *dev) #endif 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; dev->buf_async = NULL; init_waitqueue_head(&dev->buf_readers); init_waitqueue_head(&dev->buf_writers); - + 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; } @@ -209,15 +209,15 @@ static int gamma_takedown(drm_device_t *dev) DRM_DEBUG("\n"); if (dev->irq) gamma_irq_uninstall(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; @@ -231,7 +231,7 @@ static int gamma_takedown(drm_device_t *dev) } dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } - + /* Clear vma list (only built for debugging) */ if (dev->vmalist) { for (vma = dev->vmalist; vma; vma = vma_next) { @@ -240,7 +240,7 @@ static int gamma_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++) { @@ -278,7 +278,7 @@ static int gamma_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->queuelist) { for (i = 0; i < dev->queue_count; i++) { drm_waitlist_destroy(&dev->queuelist[i]->waitlist); @@ -304,7 +304,7 @@ static int gamma_takedown(drm_device_t *dev) wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -349,7 +349,7 @@ static int gamma_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(gamma); #endif @@ -374,7 +374,7 @@ static int gamma_init(void) GAMMA_DATE, gamma_misc.minor, devices); - + return 0; } @@ -385,7 +385,7 @@ static void gamma_cleanup(void) drm_device_t *dev = &gamma_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&gamma_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -405,17 +405,18 @@ int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = GAMMA_MAJOR; @@ -426,10 +427,10 @@ int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, GAMMA_DATE); DRM_COPY(version.desc, GAMMA_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -437,7 +438,7 @@ int gamma_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &gamma_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 @@ -504,7 +505,7 @@ int gamma_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); @@ -524,7 +525,7 @@ int gamma_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -537,8 +538,9 @@ int gamma_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); @@ -563,9 +565,7 @@ int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles() - dev->lck_start)]); #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); -#endif return 0; } diff --git a/linux/i810_bufs.c b/linux/i810_bufs.c index fa1f84dc..a999e96b 100644 --- a/linux/i810_bufs.c +++ b/linux/i810_bufs.c @@ -56,10 +56,10 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; count = request.count; order = drm_order(request.size); @@ -155,10 +155,10 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, request.count = entry->buf_count; request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, + if (copy_to_user((drm_buf_desc_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; atomic_dec(&dev->buf_alloc); dma->flags = _DRM_DMA_USE_AGP; @@ -170,10 +170,10 @@ int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, { drm_buf_desc_t request; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; if(request.flags & _DRM_AGP_BUFFER) return i810_addbufs_agp(inode, filp, cmd, arg); @@ -201,10 +201,10 @@ int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_info_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) { if (dma->bufs[i].buf_count) ++count; @@ -215,28 +215,26 @@ int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, if (request.count >= count) { for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) { if (dma->bufs[i].buf_count) { - copy_to_user_ret(&request.list[count].count, + if (copy_to_user(&request.list[count].count, &dma->bufs[i].buf_count, sizeof(dma->bufs[0] - .buf_count), - -EFAULT); - copy_to_user_ret(&request.list[count].size, + .buf_count)) || + copy_to_user(&request.list[count].size, &dma->bufs[i].buf_size, - sizeof(dma->bufs[0].buf_size), - -EFAULT); - copy_to_user_ret(&request.list[count].low_mark, + sizeof(dma->bufs[0].buf_size)) || + copy_to_user(&request.list[count].low_mark, &dma->bufs[i] .freelist.low_mark, sizeof(dma->bufs[0] - .freelist.low_mark), - -EFAULT); - copy_to_user_ret(&request.list[count] + .freelist.low_mark)) || + copy_to_user(&request.list[count] .high_mark, &dma->bufs[i] .freelist.high_mark, sizeof(dma->bufs[0] - .freelist.high_mark), - -EFAULT); + .freelist.high_mark))) + return -EFAULT; + DRM_DEBUG("%d %d %d %d %d\n", i, dma->bufs[i].buf_count, @@ -249,10 +247,10 @@ int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, } request.count = count; - copy_to_user_ret((drm_buf_info_t *)arg, + if (copy_to_user((drm_buf_info_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; return 0; } @@ -269,10 +267,10 @@ int i810_markbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("%d, %d, %d\n", request.size, request.low_mark, request.high_mark); @@ -304,17 +302,17 @@ int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_free_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("%d\n", request.count); for (i = 0; i < request.count; i++) { - copy_from_user_ret(&idx, + if (copy_from_user(&idx, &request.list[i], - sizeof(idx), - -EFAULT); + sizeof(idx))) + return -EFAULT; if (idx < 0 || idx >= dma->buf_count) { DRM_ERROR("Index %d (of %d max)\n", idx, dma->buf_count - 1); diff --git a/linux/i810_context.c b/linux/i810_context.c index 85c0877b..c331beed 100644 --- a/linux/i810_context.c +++ b/linux/i810_context.c @@ -103,19 +103,21 @@ int i810_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], + if (copy_to_user(&res.contexts[i], &i, - sizeof(i), - -EFAULT); + 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; } @@ -126,7 +128,8 @@ int i810_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 = i810_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ ctx.handle = i810_alloc_queue(dev); @@ -137,7 +140,8 @@ int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd, return -ENOMEM; } DRM_DEBUG("%d\n", 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; } @@ -153,10 +157,12 @@ int i810_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; } @@ -167,7 +173,8 @@ int i810_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 i810_context_switch(dev, dev->last_context, ctx.handle); } @@ -179,7 +186,8 @@ int i810_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); i810_context_switch_complete(dev, ctx.handle); @@ -193,7 +201,8 @@ int i810_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); if(ctx.handle != DRM_KERNEL_CONTEXT) { drm_ctxbitmap_free(dev, ctx.handle); diff --git a/linux/i810_dma.c b/linux/i810_dma.c index 5792bf39..a9f860cd 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.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 @@ -107,14 +107,14 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev) drm_device_dma_t *dma = dev->dma; int i; int used; - + /* Linear search might not be the best solution */ 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; /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, + used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, I810_BUF_CLIENT); if(used == I810_BUF_FREE) { return buf; @@ -131,14 +131,14 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) { drm_i810_buf_priv_t *buf_priv = buf->dev_private; int used; - + /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); if(used != I810_BUF_CLIENT) { DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); return -EINVAL; } - + return 0; } @@ -166,10 +166,10 @@ int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) dev_priv = dev->dev_private; buf = dev_priv->mmap_buffer; buf_priv = buf->dev_private; - + vma->vm_flags |= (VM_IO | VM_DONTCOPY); vma->vm_file = filp; - + buf_priv->currently_mapped = I810_BUF_MAPPED; unlock_kernel(); @@ -196,9 +196,9 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) old_fops = filp->f_op; filp->f_op = &i810_buffer_fops; dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, PROT_READ|PROT_WRITE, - MAP_SHARED, + MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; @@ -222,15 +222,15 @@ static int i810_unmap_buffer(drm_buf_t *buf) int retcode = 0; if(VM_DONTCOPY != 0) { - if(buf_priv->currently_mapped != I810_BUF_MAPPED) + if(buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; down(¤t->mm->mmap_sem); #if LINUX_VERSION_CODE < 0x020399 - retcode = do_munmap((unsigned long)buf_priv->virtual, + retcode = do_munmap((unsigned long)buf_priv->virtual, (size_t) buf->total); #else - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, (size_t) buf->total); #endif up(¤t->mm->mmap_sem); @@ -241,7 +241,7 @@ static int i810_unmap_buffer(drm_buf_t *buf) return retcode; } -static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, +static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, struct file *filp) { drm_file_t *priv = filp->private_data; @@ -255,16 +255,16 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, DRM_DEBUG("%s retcode %d\n", __FUNCTION__, retcode); goto out_get_buf; } - + retcode = i810_map_buffer(buf, filp); if(retcode) { i810_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed in %s retcode %d\n", + DRM_DEBUG("mapbuf failed in %s retcode %d\n", __FUNCTION__, retcode); goto out_get_buf; } buf->pid = priv->pid; - buf_priv = buf->dev_private; + buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; d->request_size = buf->total; @@ -277,22 +277,22 @@ out_get_buf: static unsigned long i810_alloc_page(drm_device_t *dev) { unsigned long address; - + address = __get_free_page(GFP_KERNEL); - if(address == 0UL) + if(address == 0UL) return 0; - + atomic_inc(&virt_to_page(address)->count); set_bit(PG_locked, &virt_to_page(address)->flags); - + return address; } static void i810_free_page(drm_device_t *dev, unsigned long page) { - if(page == 0UL) + if(page == 0UL) return; - + atomic_dec(&virt_to_page(page)->count); clear_bit(PG_locked, &virt_to_page(page)->flags); wake_up(&virt_to_page(page)->wait); @@ -306,9 +306,9 @@ static int i810_dma_cleanup(drm_device_t *dev) if(dev->dev_private) { int i; - drm_i810_private_t *dev_priv = + drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - + if(dev_priv->ring.virtual_start) { drm_ioremapfree((void *) dev_priv->ring.virtual_start, dev_priv->ring.Size); @@ -318,7 +318,7 @@ static int i810_dma_cleanup(drm_device_t *dev) /* Need to rewrite hardware status page */ I810_WRITE(0x02080, 0x1ffff000); } - drm_free(dev->dev_private, sizeof(drm_i810_private_t), + drm_free(dev->dev_private, sizeof(drm_i810_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -342,14 +342,14 @@ static int i810_wait_ring(drm_device_t *dev, int n) end = jiffies + (HZ*3); while (ring->space < n) { int i; - + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; - + if (ring->head != last_head) end = jiffies + (HZ*3); - + iters++; if((signed)(end - jiffies) <= 0) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); @@ -360,7 +360,7 @@ static int i810_wait_ring(drm_device_t *dev, int n) for (i = 0 ; i < 2000 ; i++) ; } -out_wait_ring: +out_wait_ring: return iters; } @@ -368,7 +368,7 @@ static void i810_kernel_lost_context(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; ring->tail = I810_READ(LP_RING + RING_TAIL); ring->space = ring->head - (ring->tail+8); @@ -382,7 +382,7 @@ static int i810_freelist_init(drm_device_t *dev) int my_idx = 24; u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); int i; - + if(dma->buf_count > 1019) { /* Not enough space in the status page for the freelist */ return -EINVAL; @@ -391,20 +391,20 @@ static int i810_freelist_init(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; - + buf_priv->in_use = hw_status++; buf_priv->my_use_idx = my_idx; my_idx += 4; *buf_priv->in_use = I810_BUF_FREE; - buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, buf->total); } return 0; } -static int i810_dma_initialize(drm_device_t *dev, +static int i810_dma_initialize(drm_device_t *dev, drm_i810_private_t *dev_priv, drm_i810_init_t *init) { @@ -419,27 +419,27 @@ static int i810_dma_initialize(drm_device_t *dev, DRM_ERROR("ring_map or buffer_map are invalid\n"); return -EINVAL; } - + dev_priv->ring_map_idx = init->ring_map_idx; dev_priv->buffer_map_idx = init->buffer_map_idx; sarea_map = dev->maplist[0]; - dev_priv->sarea_priv = (drm_i810_sarea_t *) - ((u8 *)sarea_map->handle + + dev_priv->sarea_priv = (drm_i810_sarea_t *) + ((u8 *)sarea_map->handle + init->sarea_priv_offset); atomic_set(&dev_priv->flush_done, 0); init_waitqueue_head(&dev_priv->flush_queue); - + dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; - dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + - init->ring_start, + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + + init->ring_start, init->ring_size); dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - + if (dev_priv->ring.virtual_start == NULL) { i810_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" @@ -456,8 +456,8 @@ static int i810_dma_initialize(drm_device_t *dev, dev_priv->front_di1 = init->front_offset | init->pitch_bits; dev_priv->back_di1 = init->back_offset | init->pitch_bits; dev_priv->zi1 = init->depth_offset | init->pitch_bits; - - + + /* Program Hardware Status Page */ dev_priv->hw_status_page = i810_alloc_page(dev); memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); @@ -467,10 +467,10 @@ static int i810_dma_initialize(drm_device_t *dev, return -ENOMEM; } DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - + I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); DRM_DEBUG("Enabled hardware status page\n"); - + /* Now we need to init our freelist */ if(i810_freelist_init(dev) != 0) { i810_dma_cleanup(dev); @@ -489,13 +489,13 @@ int i810_dma_init(struct inode *inode, struct file *filp, drm_i810_private_t *dev_priv; drm_i810_init_t init; int retcode = 0; - - copy_from_user_ret(&init, (drm_i810_init_t *)arg, - sizeof(init), -EFAULT); - + + if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init))) + return -EFAULT; + switch(init.func) { case I810_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i810_private_t), + dev_priv = drm_alloc(sizeof(drm_i810_private_t), DRM_MEM_DRIVER); if(dev_priv == NULL) return -ENOMEM; retcode = i810_dma_initialize(dev, dev_priv, &init); @@ -507,7 +507,7 @@ int i810_dma_init(struct inode *inode, struct file *filp, retcode = -EINVAL; break; } - + return retcode; } @@ -519,9 +519,9 @@ int i810_dma_init(struct inode *inode, struct file *filp, * Use 'volatile' & local var tmp to force the emitted values to be * identical to the verified ones. */ -static void i810EmitContextVerified( drm_device_t *dev, - volatile unsigned int *code ) -{ +static void i810EmitContextVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; @@ -539,22 +539,22 @@ static void i810EmitContextVerified( drm_device_t *dev, tmp = code[i]; if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( tmp ); j++; - } + } } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING( 0 ); ADVANCE_LP_RING(); } -static void i810EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) -{ +static void i810EmitTexVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; @@ -571,15 +571,15 @@ static void i810EmitTexVerified( drm_device_t *dev, tmp = code[i]; if ((tmp & (7<<29)) == (3<<29) && - (tmp & (0x1f<<24)) < (0x1d<<24)) + (tmp & (0x1f<<24)) < (0x1d<<24)) { - OUT_RING( tmp ); + OUT_RING( tmp ); j++; } - } - - if (j & 1) - OUT_RING( 0 ); + } + + if (j & 1) + OUT_RING( 0 ); ADVANCE_LP_RING(); } @@ -587,9 +587,9 @@ static void i810EmitTexVerified( drm_device_t *dev, /* Need to do some additional checking when setting the dest buffer. */ -static void i810EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) -{ +static void i810EmitDestVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ drm_i810_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; @@ -653,9 +653,9 @@ static void i810EmitState( drm_device_t *dev ) -/* need to verify +/* need to verify */ -static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, +static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, unsigned int clear_color, unsigned int clear_zval ) { @@ -686,10 +686,10 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, pbox->y2 > dev_priv->h) continue; - if ( flags & I810_FRONT ) { + if ( flags & I810_FRONT ) { DRM_DEBUG("clear front\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); OUT_RING( (height << 16) | width ); @@ -701,8 +701,8 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, if ( flags & I810_BACK ) { DRM_DEBUG("clear back\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); OUT_RING( (height << 16) | width ); @@ -714,8 +714,8 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, if ( flags & I810_DEPTH ) { DRM_DEBUG("clear depth\n"); - BEGIN_LP_RING( 6 ); - OUT_RING( BR00_BITBLT_CLIENT | + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); OUT_RING( (height << 16) | width ); @@ -746,7 +746,7 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - for (i = 0 ; i < nbox; i++, pbox++) + for (i = 0 ; i < nbox; i++, pbox++) { unsigned int w = pbox->x2 - pbox->x1; unsigned int h = pbox->y2 - pbox->y1; @@ -758,7 +758,7 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; - + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2); @@ -768,14 +768,14 @@ static void i810_dma_dispatch_swap( drm_device_t *dev ) OUT_RING( pitch | (0xCC << 16)); OUT_RING( (h << 16) | (w * cpp)); OUT_RING( dst ); - OUT_RING( pitch ); + OUT_RING( pitch ); OUT_RING( start ); ADVANCE_LP_RING(); } } -static void i810_dma_dispatch_vertex(drm_device_t *dev, +static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, int discard, int used) @@ -786,30 +786,30 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_clip_rect_t *box = sarea_priv->boxes; int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; + unsigned long start = address - dev->agp->base; int i = 0, u; RING_LOCALS; i810_kernel_lost_context(dev); - if (nbox > I810_NR_SAREA_CLIPRECTS) + if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; if (discard) { - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); if(u != I810_BUF_CLIENT) { DRM_DEBUG("xxxx 2\n"); } } - if (used > 4*1024) + if (used > 4*1024) used = 0; if (sarea_priv->dirty) i810EmitState( dev ); - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", address, used, nbox); dev_priv->counter++; @@ -823,7 +823,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | sarea_priv->vertex_prim | ((used/4)-2)); - + if (used & 4) { *(u32 *)((u32)buf_priv->virtual + used) = 0; used += 4; @@ -831,26 +831,26 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, i810_unmap_buffer(buf); } - + if (used) { do { if (i < nbox) { BEGIN_LP_RING(4); - OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | + OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | SC_ENABLE ); OUT_RING( GFX_OP_SCISSOR_INFO ); OUT_RING( box[i].x1 | (box[i].y1<<16) ); OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); ADVANCE_LP_RING(); } - + BEGIN_LP_RING(4); OUT_RING( CMD_OP_BATCH_BUFFER ); OUT_RING( start | BB1_PROTECTED ); OUT_RING( start + used - 4 ); OUT_RING( 0 ); ADVANCE_LP_RING(); - + } while (++i < nbox); } @@ -878,15 +878,15 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; u16 temp; - + atomic_inc(&dev->total_irq); temp = I810_READ16(I810REG_INT_IDENTITY_R); temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, temp); /* Clear all interrupts */ else return; - + queue_task(&dev->tq, &tq_immediate); mark_bh(IMMEDIATE_BH); } @@ -904,9 +904,9 @@ int i810_irq_install(drm_device_t *dev, int irq) { int retcode; u16 temp; - + if (!irq) return -EINVAL; - + down(&dev->struct_sem); if (dev->irq) { up(&dev->struct_sem); @@ -914,14 +914,14 @@ int i810_irq_install(drm_device_t *dev, int irq) } dev->irq = irq; up(&dev->struct_sem); - + DRM_DEBUG( "Interrupt Install : %d\n", irq); DRM_DEBUG("%d\n", irq); dev->context_flag = 0; dev->interrupt_flag = 0; dev->dma_flag = 0; - + dev->dma->next_buffer = NULL; dev->dma->next_queue = NULL; dev->dma->this_buffer = NULL; @@ -935,7 +935,7 @@ int i810_irq_install(drm_device_t *dev, int irq) temp = I810_READ16(I810REG_HWSTAM); temp = temp & 0x6000; I810_WRITE16(I810REG_HWSTAM, temp); - + temp = I810_READ16(I810REG_INT_MASK_R); temp = temp & 0x6000; I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */ @@ -957,7 +957,7 @@ int i810_irq_install(drm_device_t *dev, int irq) temp = I810_READ16(I810REG_INT_ENABLE_R); temp = temp & 0x6000; temp = temp | 0x0003; - I810_WRITE16(I810REG_INT_ENABLE_R, + I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Enable bp & user interrupts */ return 0; } @@ -974,20 +974,20 @@ int i810_irq_uninstall(drm_device_t *dev) irq = dev->irq; dev->irq = 0; up(&dev->struct_sem); - + if (!irq) return -EINVAL; - DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); + DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); DRM_DEBUG("%d\n", irq); - + temp = I810_READ16(I810REG_INT_IDENTITY_R); temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, temp); /* Clear all interrupts */ - + temp = I810_READ16(I810REG_INT_ENABLE_R); temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_ENABLE_R, + I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */ free_irq(irq, dev); @@ -1002,11 +1002,12 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_control_t ctl; int retcode; - + DRM_DEBUG( "i810_control\n"); - copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); - + if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) + return -EFAULT; + switch (ctl.func) { case DRM_INST_HANDLER: if ((retcode = i810_irq_install(dev, ctl.irq))) @@ -1062,7 +1063,7 @@ static void i810_dma_quiescent(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - unsigned long end; + unsigned long end; if(dev_priv == NULL) { return; @@ -1071,23 +1072,23 @@ static void i810_dma_quiescent(drm_device_t *dev) current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); end = jiffies + (HZ*3); - + for (;;) { i810_dma_quiescent_emit(dev); if (atomic_read(&dev_priv->flush_done) == 1) break; if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; - } + } schedule_timeout(HZ*3); if (signal_pending(current)) { break; } } - + current->state = TASK_RUNNING; remove_wait_queue(&dev_priv->flush_queue, &entry); - + return; } @@ -1097,7 +1098,7 @@ static int i810_flush_queue(drm_device_t *dev) drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; drm_device_dma_t *dma = dev->dma; unsigned long end; - int i, ret = 0; + int i, ret = 0; if(dev_priv == NULL) { return 0; @@ -1112,14 +1113,14 @@ static int i810_flush_queue(drm_device_t *dev) if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; - } + } schedule_timeout(HZ*3); if (signal_pending(current)) { ret = -EINTR; /* Can't restart */ break; } } - + current->state = TASK_RUNNING; remove_wait_queue(&dev_priv->flush_queue, &entry); @@ -1127,8 +1128,8 @@ static int i810_flush_queue(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; - - int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, + + int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, I810_BUF_FREE); if (used == I810_BUF_HARDWARE) @@ -1155,9 +1156,9 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) 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; - + if (buf->pid == pid && buf_priv) { - int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); if (used == I810_BUF_CLIENT) @@ -1178,14 +1179,15 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, int ret = 0; 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); return -EINVAL; } - + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", lock.context, current->pid, dev->lock.hw_lock->lock, lock.flags); @@ -1211,7 +1213,7 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -1225,9 +1227,8 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, current->state = TASK_RUNNING; remove_wait_queue(&dev->lock.lock_queue, &entry); } - + if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -1236,7 +1237,7 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_QUIESCENT) { DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); DRM_DEBUG("fred\n"); @@ -1247,12 +1248,12 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd, return ret; } -int i810_flush_ioctl(struct inode *inode, struct file *filp, +int i810_flush_ioctl(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_DEBUG("i810_flush_ioctl\n"); if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_flush_ioctl called without lock held\n"); @@ -1272,12 +1273,12 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, drm_device_dma_t *dma = dev->dma; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; drm_i810_vertex_t vertex; - copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), - -EFAULT); + if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex))) + return -EFAULT; if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_dma_vertex called without lock held\n"); @@ -1287,15 +1288,15 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", vertex.idx, vertex.used, vertex.discard); - i810_dma_dispatch_vertex( dev, - dma->buflist[ vertex.idx ], + i810_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], vertex.discard, vertex.used ); atomic_add(vertex.used, &dma->total_bytes); atomic_inc(&dma->total_dmas); sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; - + return 0; } @@ -1308,16 +1309,16 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_i810_clear_t clear; - copy_from_user_ret(&clear, (drm_i810_clear_t *)arg, sizeof(clear), - -EFAULT); - + if (copy_from_user(&clear, (drm_i810_clear_t *)arg, sizeof(clear))) + return -EFAULT; + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_clear_bufs called without lock held\n"); return -EINVAL; } - i810_dma_dispatch_clear( dev, clear.flags, - clear.clear_color, + i810_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, clear.clear_depth ); return 0; } @@ -1327,7 +1328,7 @@ int i810_swap_bufs(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - + DRM_DEBUG("i810_swap_bufs\n"); if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { @@ -1346,8 +1347,8 @@ int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; sarea_priv->last_dispatch = (int) hw_status[5]; return 0; @@ -1362,17 +1363,18 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, drm_i810_dma_t d; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; DRM_DEBUG("getbuf\n"); - copy_from_user_ret(&d, (drm_i810_dma_t *)arg, sizeof(d), -EFAULT); - + if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d))) + return -EFAULT; + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("i810_dma called without lock held\n"); return -EINVAL; } - + d.granted = 0; retcode = i810_dma_get_buffer(dev, &d, filp); @@ -1380,7 +1382,8 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", current->pid, retcode, d.granted); - copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); + if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) + return -EFAULT; sarea_priv->last_dispatch = (int) hw_status[5]; return retcode; @@ -1394,8 +1397,8 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, drm_i810_copy_t d; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u32 *hw_status = (u32 *)dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; drm_device_dma_t *dma = dev->dma; @@ -1404,15 +1407,17 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("i810_dma called without lock held\n"); return -EINVAL; } - - copy_from_user_ret(&d, (drm_i810_copy_t *)arg, sizeof(d), -EFAULT); + + if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d))) + return -EFAULT; if(d.idx > dma->buf_count) return -EINVAL; buf = dma->buflist[ d.idx ]; buf_priv = buf->dev_private; if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM; - copy_from_user_ret(buf_priv->virtual, d.address, d.used, -EFAULT); + if (copy_from_user(buf_priv->virtual, d.address, d.used)) + return -EFAULT; sarea_priv->last_dispatch = (int) hw_status[5]; diff --git a/linux/i810_drv.c b/linux/i810_drv.c index 18168605..86d5e230 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -1,6 +1,6 @@ /* i810_drv.c -- I810 driver -*- linux-c -*- * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -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 @@ -35,7 +35,7 @@ #define I810_NAME "i810" #define I810_DESC "Intel I810" -#define I810_DATE "20000719" +#define I810_DATE "20000910" #define I810_MAJOR 1 #define I810_MINOR 1 #define I810_PATCHLEVEL 0 @@ -143,7 +143,7 @@ __setup("i810=", i810_options); static int i810_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -188,22 +188,22 @@ static int i810_setup(drm_device_t *dev) #endif 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; dev->buf_async = NULL; init_waitqueue_head(&dev->buf_readers); init_waitqueue_head(&dev->buf_writers); - + 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,15 +218,15 @@ static int i810_takedown(drm_device_t *dev) DRM_DEBUG("\n"); if (dev->irq) i810_irq_uninstall(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; @@ -244,7 +244,7 @@ static int i810_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - + /* Remove AGP resources, but leave dev->agp intact until r128_cleanup is called. */ for (entry = dev->agp->memory; entry; entry = nexte) { @@ -254,10 +254,10 @@ static int i810_takedown(drm_device_t *dev) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; - + if (dev->agp->acquired && drm_agp.release) (*drm_agp.release)(); - + dev->agp->acquired = 0; dev->agp->enabled = 0; } @@ -269,7 +269,7 @@ static int i810_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++) { @@ -305,7 +305,7 @@ static int i810_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->queuelist) { for (i = 0; i < dev->queue_count; i++) { drm_waitlist_destroy(&dev->queuelist[i]->waitlist); @@ -331,7 +331,7 @@ static int i810_takedown(drm_device_t *dev) wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -348,7 +348,7 @@ static int i810_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(i810); #endif @@ -402,7 +402,7 @@ static void i810_cleanup(void) drm_device_t *dev = &i810_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&i810_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -428,17 +428,18 @@ int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = I810_MAJOR; @@ -449,10 +450,10 @@ int i810_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, I810_DATE); DRM_COPY(version.desc, I810_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -460,7 +461,7 @@ int i810_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &i810_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 @@ -497,7 +498,7 @@ int i810_release(struct inode *inode, struct file *filp) drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - + /* FIXME: may require heavy-handed reset of hardware at this point, possibly processed via a callback to the X @@ -518,7 +519,7 @@ int i810_release(struct inode *inode, struct file *filp) dev->lock.lock_time = jiffies; atomic_inc(&dev->total_locks); break; /* Got lock */ - } + } /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -544,7 +545,7 @@ int i810_release(struct inode *inode, struct file *filp) if (priv->next) priv->next->prev = priv->prev; else dev->file_last = priv->prev; up(&dev->struct_sem); - + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); #if LINUX_VERSION_CODE < 0x020333 MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ @@ -584,7 +585,7 @@ int i810_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); @@ -604,7 +605,7 @@ int i810_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -616,8 +617,9 @@ int i810_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); @@ -641,9 +643,7 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles() - dev->lck_start)]); #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); -#endif return 0; } diff --git a/linux/ioctl.c b/linux/ioctl.c index b246f76e..2f4286b1 100644 --- a/linux/ioctl.c +++ b/linux/ioctl.c @@ -38,13 +38,15 @@ int drm_irq_busid(struct inode *inode, struct file *filp, unsigned int cmd, drm_irq_busid_t p; struct pci_dev *dev; - copy_from_user_ret(&p, (drm_irq_busid_t *)arg, sizeof(p), -EFAULT); + if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) + return -EFAULT; dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); if (dev) p.irq = dev->irq; else p.irq = 0; DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq); - copy_to_user_ret((drm_irq_busid_t *)arg, &p, sizeof(p), -EFAULT); + if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p))) + return -EFAULT; return 0; } @@ -55,13 +57,15 @@ int drm_getunique(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_unique_t u; - copy_from_user_ret(&u, (drm_unique_t *)arg, sizeof(u), -EFAULT); + if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u))) + return -EFAULT; if (u.unique_len >= dev->unique_len) { - copy_to_user_ret(u.unique, dev->unique, dev->unique_len, - -EFAULT); + if (copy_to_user(u.unique, dev->unique, dev->unique_len)) + return -EFAULT; } u.unique_len = dev->unique_len; - copy_to_user_ret((drm_unique_t *)arg, &u, sizeof(u), -EFAULT); + if (copy_to_user((drm_unique_t *)arg, &u, sizeof(u))) + return -EFAULT; return 0; } @@ -72,15 +76,19 @@ int drm_setunique(struct inode *inode, struct file *filp, unsigned int cmd, drm_device_t *dev = priv->dev; drm_unique_t u; - if (dev->unique_len || dev->unique) return -EBUSY; + if (dev->unique_len || dev->unique) + return -EBUSY; - copy_from_user_ret(&u, (drm_unique_t *)arg, sizeof(u), -EFAULT); - if (!u.unique_len) return -EINVAL; + if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u))) + return -EFAULT; + + if (!u.unique_len) + return -EINVAL; dev->unique_len = u.unique_len; dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER); - copy_from_user_ret(dev->unique, u.unique, dev->unique_len, - -EFAULT); + if (copy_from_user(dev->unique, u.unique, dev->unique_len)) + return -EFAULT; dev->unique[dev->unique_len] = '\0'; dev->devname = drm_alloc(strlen(dev->name) + strlen(dev->unique) + 2, diff --git a/linux/lock.c b/linux/lock.c index 33b2cc03..e5fd435f 100644 --- a/linux/lock.c +++ b/linux/lock.c @@ -218,7 +218,8 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("\n"); - 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; ret = drm_flush_block_and_flush(dev, lock.context, lock.flags); drm_flush_unblock(dev, lock.context, lock.flags); return ret; diff --git a/linux/mga_bufs.c b/linux/mga_bufs.c index b97eb495..3ec28a76 100644 --- a/linux/mga_bufs.c +++ b/linux/mga_bufs.c @@ -57,10 +57,10 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; count = request.count; order = drm_order(request.size); @@ -173,10 +173,10 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, request.count = entry->buf_count; request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, + if (copy_to_user((drm_buf_desc_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; atomic_dec(&dev->buf_alloc); @@ -219,10 +219,10 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; count = request.count; order = drm_order(request.size); @@ -348,10 +348,10 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, request.count = entry->buf_count; request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, + if (copy_to_user((drm_buf_desc_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; atomic_dec(&dev->buf_alloc); return 0; @@ -362,10 +362,10 @@ int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, { drm_buf_desc_t request; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; if(request.flags & _DRM_AGP_BUFFER) return mga_addbufs_agp(inode, filp, cmd, arg); @@ -393,10 +393,10 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_info_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) { if (dma->bufs[i].buf_count) ++count; @@ -407,28 +407,26 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, if (request.count >= count) { for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) { if (dma->bufs[i].buf_count) { - copy_to_user_ret(&request.list[count].count, + if (copy_to_user(&request.list[count].count, &dma->bufs[i].buf_count, sizeof(dma->bufs[0] - .buf_count), - -EFAULT); - copy_to_user_ret(&request.list[count].size, + .buf_count)) || + copy_to_user(&request.list[count].size, &dma->bufs[i].buf_size, - sizeof(dma->bufs[0].buf_size), - -EFAULT); - copy_to_user_ret(&request.list[count].low_mark, + sizeof(dma->bufs[0].buf_size)) || + copy_to_user(&request.list[count].low_mark, &dma->bufs[i] .freelist.low_mark, sizeof(dma->bufs[0] - .freelist.low_mark), - -EFAULT); - copy_to_user_ret(&request.list[count] + .freelist.low_mark)) || + copy_to_user(&request.list[count] .high_mark, &dma->bufs[i] .freelist.high_mark, sizeof(dma->bufs[0] - .freelist.high_mark), - -EFAULT); + .freelist.high_mark))) + return -EFAULT; + DRM_DEBUG("%d %d %d %d %d\n", i, dma->bufs[i].buf_count, @@ -441,10 +439,10 @@ int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, } request.count = count; - copy_to_user_ret((drm_buf_info_t *)arg, + if (copy_to_user((drm_buf_info_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; return 0; } @@ -461,10 +459,10 @@ int mga_markbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("%d, %d, %d\n", request.size, request.low_mark, request.high_mark); @@ -496,17 +494,17 @@ int mga_freebufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_free_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("%d\n", request.count); for (i = 0; i < request.count; i++) { - copy_from_user_ret(&idx, + if (copy_from_user(&idx, &request.list[i], - sizeof(idx), - -EFAULT); + sizeof(idx))) + return -EFAULT; if (idx < 0 || idx >= dma->buf_count) { DRM_ERROR("Index %d (of %d max)\n", idx, dma->buf_count - 1); @@ -550,10 +548,10 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_map_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("mga_mapbufs\n"); DRM_DEBUG("dma->flags : %x\n", dma->flags); @@ -628,10 +626,10 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, request.count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - copy_to_user_ret((drm_buf_map_t *)arg, + if (copy_to_user((drm_buf_map_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; DRM_DEBUG("retcode : %d\n", retcode); diff --git a/linux/mga_context.c b/linux/mga_context.c index 9a73e6c1..43733c14 100644 --- a/linux/mga_context.c +++ b/linux/mga_context.c @@ -103,19 +103,21 @@ int mga_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], + if (copy_to_user(&res.contexts[i], &i, - sizeof(i), - -EFAULT); + 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; } @@ -126,7 +128,8 @@ int mga_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 = mga_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ ctx.handle = mga_alloc_queue(dev); @@ -137,7 +140,8 @@ int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd, return -ENOMEM; } DRM_DEBUG("%d\n", 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; } @@ -153,10 +157,12 @@ int mga_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; } @@ -167,7 +173,8 @@ int mga_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 mga_context_switch(dev, dev->last_context, ctx.handle); } @@ -179,7 +186,8 @@ int mga_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); mga_context_switch_complete(dev, ctx.handle); @@ -193,7 +201,8 @@ int mga_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); if(ctx.handle != DRM_KERNEL_CONTEXT) { drm_ctxbitmap_free(dev, ctx.handle); diff --git a/linux/mga_dma.c b/linux/mga_dma.c index d315954d..f80fb489 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.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 @@ -51,7 +51,7 @@ static int mga_flush_queue(drm_device_t *dev); static unsigned long mga_alloc_page(drm_device_t *dev) { unsigned long address; - + DRM_DEBUG("%s\n", __FUNCTION__); address = __get_free_page(GFP_KERNEL); if(address == 0UL) { @@ -59,7 +59,7 @@ static unsigned long mga_alloc_page(drm_device_t *dev) } atomic_inc(&virt_to_page(address)->count); set_bit(PG_locked, &virt_to_page(address)->flags); - + return address; } @@ -82,19 +82,6 @@ static void mga_delay(void) return; } -#ifdef __i386__ -void mga_flush_write_combine(void) -{ - int xchangeDummy; - DRM_DEBUG("%s\n", __FUNCTION__); - - __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); - __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" - " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" - " pop %%eax" : /* no outputs */ : /* no inputs */ ); -} -#endif - /* These are two age tags that will never be sent to * the hardware */ #define MGA_BUF_USED 0xffffffff @@ -115,7 +102,7 @@ static int mga_freelist_init(drm_device_t *dev) if(dev_priv->head == NULL) return -ENOMEM; memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); dev_priv->head->age = MGA_BUF_USED; - + for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[ i ]; buf_priv = buf->dev_private; @@ -135,7 +122,7 @@ static int mga_freelist_init(drm_device_t *dev) buf_priv->dispatched = 0; dev_priv->head->next = item; } - + return 0; } @@ -153,7 +140,7 @@ static void mga_freelist_cleanup(drm_device_t *dev) item = item->next; drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); } - + dev_priv->head = dev_priv->tail = NULL; } @@ -169,15 +156,15 @@ static inline void mga_dma_quiescent(drm_device_t *dev) DRM_DEBUG("%s\n", __FUNCTION__); end = jiffies + (HZ*3); while(1) { - if(!test_and_set_bit(MGA_IN_DISPATCH, + if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) { break; } if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), atomic_read(&dma->total_lost)); - DRM_ERROR("lockup\n"); + DRM_ERROR("lockup\n"); goto out_nolock; } for (i = 0 ; i < 2000 ; i++) mga_delay(); @@ -186,13 +173,13 @@ static inline void mga_dma_quiescent(drm_device_t *dev) DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS)); while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), atomic_read(&dma->total_lost)); - DRM_ERROR("lockup\n"); + DRM_ERROR("lockup\n"); goto out_status; } - for (i = 0 ; i < 2000 ; i++) mga_delay(); + for (i = 0 ; i < 2000 ; i++) mga_delay(); } sarea_priv->dirty |= MGA_DMA_FLUSH; @@ -216,13 +203,13 @@ static void mga_reset_freelist(drm_device_t *dev) } /* Least recently used : - * These operations are not atomic b/c they are protected by the + * These operations are not atomic b/c they are protected by the * hardware lock */ drm_buf_t *mga_freelist_get(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); - drm_mga_private_t *dev_priv = + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; drm_mga_freelist_t *prev; drm_mga_freelist_t *next; @@ -230,17 +217,17 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev) DRM_DEBUG("%s : tail->age : %d last_prim_age : %d\n", __FUNCTION__, dev_priv->tail->age, dev_priv->last_prim_age); - + if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) { - DRM_DEBUG("I'm waiting on the freelist!!! %d\n", + DRM_DEBUG("I'm waiting on the freelist!!! %d\n", dev_priv->last_prim_age); set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->buf_queue, &entry); for (;;) { mga_dma_schedule(dev, 0); - if(!test_bit(MGA_IN_GETBUF, - &dev_priv->dispatch_status)) + if(!test_bit(MGA_IN_GETBUF, + &dev_priv->dispatch_status)) break; atomic_inc(&dev->total_sleeps); schedule(); @@ -253,7 +240,7 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev) current->state = TASK_RUNNING; remove_wait_queue(&dev_priv->buf_queue, &entry); } - + if(dev_priv->tail->age < dev_priv->last_prim_age) { prev = dev_priv->tail->prev; next = dev_priv->tail; @@ -272,7 +259,7 @@ failed_getbuf: int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf) { - drm_mga_private_t *dev_priv = + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_freelist_t *prev; @@ -303,7 +290,7 @@ int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf) next->prev = head; next->next = prev; } - + return 0; } @@ -315,41 +302,41 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) int offset = init->reserved_map_agpstart; DRM_DEBUG("%s\n", __FUNCTION__); - dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / + dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS; dev_priv->warp_ucode_size = init->warp_ucode_size; - dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) * - (MGA_NUM_PRIM_BUFS + 1), + dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) * + (MGA_NUM_PRIM_BUFS + 1), DRM_MEM_DRIVER); if(dev_priv->prim_bufs == NULL) { DRM_ERROR("Unable to allocate memory for prim_buf\n"); return -ENOMEM; } - memset(dev_priv->prim_bufs, + memset(dev_priv->prim_bufs, 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1)); - + temp = init->warp_ucode_size + dev_priv->primary_size; temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; - - dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, + + dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, temp); if(dev_priv->ioremap == NULL) { DRM_DEBUG("Ioremap failed\n"); return -ENOMEM; } init_waitqueue_head(&dev_priv->wait_queue); - + for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { - prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), + prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), DRM_MEM_DRIVER); if(prim_buffer == NULL) return -ENOMEM; memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t)); prim_buffer->phys_head = offset + dev->agp->base; - prim_buffer->current_dma_ptr = - prim_buffer->head = - (u32 *) (dev_priv->ioremap + - offset - + prim_buffer->current_dma_ptr = + prim_buffer->head = + (u32 *) (dev_priv->ioremap + + offset - init->reserved_map_agpstart); prim_buffer->num_dwords = 0; prim_buffer->max_dwords = size_of_buf / sizeof(u32); @@ -361,11 +348,11 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) dev_priv->prim_bufs[i] = prim_buffer; } dev_priv->current_prim_idx = 0; - dev_priv->next_prim = - dev_priv->last_prim = + dev_priv->next_prim = + dev_priv->last_prim = dev_priv->current_prim = dev_priv->prim_bufs[0]; - dev_priv->next_prim_age = 2; + dev_priv->next_prim_age = 2; dev_priv->last_prim_age = 1; set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status); return 0; @@ -384,11 +371,11 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) DRM_DEBUG("%s\n", __FUNCTION__); dev_priv->last_prim = prim; - + /* We never check for overflow, b/c there is always room */ PRIMPTR(prim); if(num_dwords <= 0) { - DRM_DEBUG("num_dwords == 0 when dispatched\n"); + DRM_ERROR("num_dwords == 0 when dispatched\n"); goto out_prim_wait; } PRIMOUTREG( MGAREG_DMAPAD, 0); @@ -399,17 +386,17 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) end = jiffies + (HZ*3); if(sarea_priv->dirty & MGA_DMA_FLUSH) { - DRM_DEBUG("Dma top flush\n"); + DRM_DEBUG("Dma top flush\n"); while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), atomic_read(&dma->total_lost)); DRM_ERROR("lockup in fire primary " "(Dma Top Flush)\n"); goto out_prim_wait; } - + for (i = 0 ; i < 4096 ; i++) mga_delay(); } sarea_priv->dirty &= ~(MGA_DMA_FLUSH); @@ -417,29 +404,27 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) DRM_DEBUG("Status wait\n"); while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) { if((signed)(end - jiffies) <= 0) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), atomic_read(&dma->total_lost)); DRM_ERROR("lockup in fire primary " "(Status Wait)\n"); goto out_prim_wait; } - + for (i = 0 ; i < 4096 ; i++) mga_delay(); } } -#ifdef __i386__ mga_flush_write_combine(); -#endif atomic_inc(&dev_priv->pending_bufs); MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); prim->num_dwords = 0; sarea_priv->last_enqueue = prim->prim_age; - + next_idx = prim->idx + 1; - if(next_idx >= MGA_NUM_PRIM_BUFS) + if(next_idx >= MGA_NUM_PRIM_BUFS) next_idx = 0; dev_priv->next_prim = dev_priv->prim_bufs[next_idx]; @@ -462,28 +447,28 @@ int mga_advance_primary(drm_device_t *dev) drm_device_dma_t *dma = dev->dma; int next_prim_idx; int ret = 0; - + /* This needs to reset the primary buffer if available, * we should collect stats on how many times it bites * it's tail */ DRM_DEBUG("%s\n", __FUNCTION__); - + next_prim_idx = dev_priv->current_prim_idx + 1; if(next_prim_idx >= MGA_NUM_PRIM_BUFS) next_prim_idx = 0; prim_buffer = dev_priv->prim_bufs[next_prim_idx]; set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status); - + /* In use is cleared in interrupt handler */ - + if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) { add_wait_queue(&dev_priv->wait_queue, &entry); current->state = TASK_INTERRUPTIBLE; for (;;) { mga_dma_schedule(dev, 0); - if(!test_and_set_bit(MGA_BUF_IN_USE, - &prim_buffer->buffer_status)) + if(!test_and_set_bit(MGA_BUF_IN_USE, + &prim_buffer->buffer_status)) break; atomic_inc(&dev->total_sleeps); atomic_inc(&dma->total_missed_sched); @@ -545,9 +530,9 @@ static inline int mga_decide_to_fire(drm_device_t *dev) atomic_inc(&dma->total_prio); return 1; } - + if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) { - if(test_bit(MGA_BUF_SWAP_PENDING, + if(test_bit(MGA_BUF_SWAP_PENDING, &dev_priv->next_prim->buffer_status)) { atomic_inc(&dma->total_dmas); return 1; @@ -583,16 +568,16 @@ int mga_dma_schedule(drm_device_t *dev, int locked) retval = -EBUSY; goto sch_out_wakeup; } - + DRM_DEBUG("%s\n", __FUNCTION__); - if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) || + if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) || test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) || test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) { locked = 1; } - - if (!locked && + + if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { atomic_inc(&dma->total_missed_lock); clear_bit(0, &dev->dma_flag); @@ -606,7 +591,7 @@ int mga_dma_schedule(drm_device_t *dev, int locked) /* Fire dma buffer */ if(mga_decide_to_fire(dev)) { DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx); - clear_bit(MGA_BUF_FORCE_FIRE, + clear_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status); if(dev_priv->current_prim == dev_priv->next_prim) { /* Schedule overflow for a later time */ @@ -620,7 +605,7 @@ int mga_dma_schedule(drm_device_t *dev, int locked) } else { DRM_DEBUG("I can't get the dispatch lock\n"); } - + if (!locked) { if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { @@ -642,8 +627,8 @@ sch_out_wakeup: DRM_DEBUG("Waking up buf queue\n"); wake_up_interruptible(&dev_priv->buf_queue); } else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) { - DRM_DEBUG("Not waking buf_queue on %d %d\n", - atomic_read(&dev->total_irq), + DRM_DEBUG("Not waking buf_queue on %d %d\n", + atomic_read(&dev->total_irq), dev_priv->last_prim_age); } @@ -664,7 +649,7 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs) last_prim_buffer = dev_priv->last_prim; last_prim_buffer->num_dwords = 0; last_prim_buffer->sec_used = 0; - dev_priv->sarea_priv->last_dispatch = + dev_priv->sarea_priv->last_dispatch = dev_priv->last_prim_age = last_prim_buffer->prim_age; clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status); wake_up_interruptible(&dev_priv->wait_queue); @@ -686,12 +671,12 @@ int mga_dma_cleanup(drm_device_t *dev) DRM_DEBUG("%s\n", __FUNCTION__); if(dev->dev_private) { - drm_mga_private_t *dev_priv = + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - + if(dev_priv->ioremap) { - int temp = (dev_priv->warp_ucode_size + - dev_priv->primary_size + + int temp = (dev_priv->warp_ucode_size + + dev_priv->primary_size + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; drm_ioremapfree((void *) dev_priv->ioremap, temp); @@ -712,7 +697,7 @@ int mga_dma_cleanup(drm_device_t *dev) } } drm_free(dev_priv->prim_bufs, sizeof(void *) * - (MGA_NUM_PRIM_BUFS + 1), + (MGA_NUM_PRIM_BUFS + 1), DRM_MEM_DRIVER); } if(dev_priv->head != NULL) { @@ -720,7 +705,7 @@ int mga_dma_cleanup(drm_device_t *dev) } - drm_free(dev->dev_private, sizeof(drm_mga_private_t), + drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; } @@ -747,12 +732,12 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { DRM_DEBUG("reserved_map or buffer_map are invalid\n"); return -EINVAL; } - + dev_priv->reserved_map_idx = init->reserved_map_idx; dev_priv->buffer_map_idx = init->buffer_map_idx; sarea_map = dev->maplist[0]; - dev_priv->sarea_priv = (drm_mga_sarea_t *) - ((u8 *)sarea_map->handle + + dev_priv->sarea_priv = (drm_mga_sarea_t *) + ((u8 *)sarea_map->handle + init->sarea_priv_offset); /* Scale primary size to the next page */ @@ -770,20 +755,21 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { init_waitqueue_head(&dev_priv->flush_queue); init_waitqueue_head(&dev_priv->buf_queue); dev_priv->WarpPipe = 0xff000000; + dev_priv->vertexsize = 0; DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n", - dev_priv->chipset, dev_priv->warp_ucode_size, + dev_priv->chipset, dev_priv->warp_ucode_size, dev_priv->backOffset, dev_priv->depthOffset); DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n", - dev_priv->cpp, dev_priv->sgram, dev_priv->stride, + dev_priv->cpp, dev_priv->sgram, dev_priv->stride, dev_priv->mAccess); - - memcpy(&dev_priv->WarpIndex, &init->WarpIndex, + + memcpy(&dev_priv->WarpIndex, &init->WarpIndex, sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES); - for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) + for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n", - i, + i, dev_priv->WarpIndex[i].installed, dev_priv->WarpIndex[i].phys_addr, dev_priv->WarpIndex[i].size); @@ -800,7 +786,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { return -ENOMEM; } - dev_priv->status_page = + dev_priv->status_page = ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page), PAGE_SIZE); @@ -811,15 +797,15 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { } /* Write status page when secend or softrap occurs */ - MGA_WRITE(MGAREG_PRIMPTR, + MGA_WRITE(MGAREG_PRIMPTR, virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); - + /* Private is now filled in, initialize the hardware */ { PRIMLOCALS; PRIMGETPTR( dev_priv ); - + PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DWGSYNC, 0x0100); @@ -827,15 +813,13 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { /* Poll for the first buffer to insure that * the status register will be correct */ - -#ifdef __i386__ + mga_flush_write_combine(); -#endif MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); - MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | + MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) | PDEA_pagpxfer_enable)); - + while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ; } @@ -853,11 +837,12 @@ int mga_dma_init(struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_mga_init_t init; - + DRM_DEBUG("%s\n", __FUNCTION__); - copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT); - + if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init))) + return -EFAULT; + switch(init.func) { case MGA_INIT_DMA: return mga_dma_initialize(dev, &init); @@ -873,7 +858,7 @@ int mga_irq_install(drm_device_t *dev, int irq) int retcode; if (!irq) return -EINVAL; - + down(&dev->struct_sem); if (dev->irq) { up(&dev->struct_sem); @@ -881,7 +866,7 @@ int mga_irq_install(drm_device_t *dev, int irq) } dev->irq = irq; up(&dev->struct_sem); - + DRM_DEBUG("install irq handler %d\n", irq); dev->context_flag = 0; @@ -922,7 +907,7 @@ int mga_irq_uninstall(drm_device_t *dev) irq = dev->irq; dev->irq = 0; up(&dev->struct_sem); - + if (!irq) return -EINVAL; DRM_DEBUG("remove irq handler %d\n", irq); MGA_WRITE(MGAREG_ICLEAR, 0x00000001); @@ -937,8 +922,9 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_control_t ctl; - - copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); + + if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) + return -EFAULT; DRM_DEBUG("%s\n", __FUNCTION__); @@ -963,21 +949,21 @@ static int mga_flush_queue(drm_device_t *dev) if(dev_priv == NULL) { return 0; } - + if(dev_priv->next_prim->num_dwords != 0) { current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status); mga_dma_schedule(dev, 0); for (;;) { - if (!test_bit(MGA_IN_FLUSH, - &dev_priv->dispatch_status)) + if (!test_bit(MGA_IN_FLUSH, + &dev_priv->dispatch_status)) break; atomic_inc(&dev->total_sleeps); schedule(); if (signal_pending(current)) { ret = -EINTR; /* Can't restart */ - clear_bit(MGA_IN_FLUSH, + clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status); break; } @@ -1005,11 +991,11 @@ void mga_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_mga_buf_priv_t *buf_priv = buf->dev_private; - /* Only buffers that need to get reclaimed ever - * get set to free + /* Only buffers that need to get reclaimed ever + * get set to free */ if (buf->pid == pid && buf_priv) { - if(buf_priv->my_freelist->age == MGA_BUF_USED) + if(buf_priv->my_freelist->age == MGA_BUF_USED) buf_priv->my_freelist->age = MGA_BUF_FREE; } } @@ -1025,14 +1011,15 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, drm_lock_t lock; DRM_DEBUG("%s\n", __FUNCTION__); - 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); return -EINVAL; } - + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", lock.context, current->pid, dev->lock.hw_lock->lock, lock.flags); @@ -1040,7 +1027,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, if (lock.context < 0) { return -EINVAL; } - + /* Only one queue: */ @@ -1059,7 +1046,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -1072,9 +1059,8 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, current->state = TASK_RUNNING; remove_wait_queue(&dev->lock.lock_queue, &entry); } - + if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -1083,19 +1069,19 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_QUIESCENT) { DRM_DEBUG("_DRM_LOCK_QUIESCENT\n"); mga_flush_queue(dev); mga_dma_quiescent(dev); } } - + DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); return ret; } - -int mga_flush_ioctl(struct inode *inode, struct file *filp, + +int mga_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; @@ -1104,7 +1090,8 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp, drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); - 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(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("mga_flush_ioctl called without lock held\n"); diff --git a/linux/mga_drm.h b/linux/mga_drm.h index e75e91a4..52cf7766 100644 --- a/linux/mga_drm.h +++ b/linux/mga_drm.h @@ -73,17 +73,19 @@ /* 3d state excluding texture units: */ -#define MGA_CTXREG_DSTORG 0 /* validated */ -#define MGA_CTXREG_MACCESS 1 -#define MGA_CTXREG_PLNWT 2 -#define MGA_CTXREG_DWGCTL 3 -#define MGA_CTXREG_ALPHACTRL 4 -#define MGA_CTXREG_FOGCOLOR 5 -#define MGA_CTXREG_WFLAG 6 -#define MGA_CTXREG_TDUAL0 7 -#define MGA_CTXREG_TDUAL1 8 -#define MGA_CTXREG_FCOL 9 -#define MGA_CTX_SETUP_SIZE 10 +#define MGA_CTXREG_DSTORG 0 /* validated */ +#define MGA_CTXREG_MACCESS 1 +#define MGA_CTXREG_PLNWT 2 +#define MGA_CTXREG_DWGCTL 3 +#define MGA_CTXREG_ALPHACTRL 4 +#define MGA_CTXREG_FOGCOLOR 5 +#define MGA_CTXREG_WFLAG 6 +#define MGA_CTXREG_TDUAL0 7 +#define MGA_CTXREG_TDUAL1 8 +#define MGA_CTXREG_FCOL 9 +#define MGA_CTXREG_STENCIL 10 +#define MGA_CTXREG_STENCILCTL 11 +#define MGA_CTX_SETUP_SIZE 12 /* 2d state */ @@ -233,6 +235,7 @@ typedef struct _drm_mga_sarea { /* Mechanism to validate card state. */ int ctxOwner; + int vertexsize; } drm_mga_sarea_t; /* Device specific ioctls: @@ -241,6 +244,8 @@ typedef struct _drm_mga_clear { unsigned int clear_color; unsigned int clear_depth; unsigned int flags; + unsigned int clear_depth_mask; + unsigned int clear_color_mask; } drm_mga_clear_t; typedef struct _drm_mga_swap { diff --git a/linux/mga_drv.c b/linux/mga_drv.c index a4a8fe55..c551ba6e 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -1,6 +1,6 @@ /* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*- * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * + * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. @@ -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 @@ -35,9 +35,9 @@ #include "mga_drv.h" #define MGA_NAME "mga" -#define MGA_DESC "Matrox g200/g400" -#define MGA_DATE "20000719" -#define MGA_MAJOR 1 +#define MGA_DESC "Matrox G200/G400" +#define MGA_DATE "20000910" +#define MGA_MAJOR 2 #define MGA_MINOR 0 #define MGA_PATCHLEVEL 0 @@ -123,7 +123,7 @@ static char *mga = NULL; #endif MODULE_AUTHOR("VA Linux Systems, Inc."); -MODULE_DESCRIPTION("Matrox g200/g400"); +MODULE_DESCRIPTION("Matrox G200/G400"); MODULE_PARM(mga, "s"); #ifndef MODULE @@ -144,7 +144,7 @@ __setup("mga=", mga_options); static int mga_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -187,22 +187,22 @@ static int mga_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; dev->buf_async = NULL; init_waitqueue_head(&dev->buf_readers); init_waitqueue_head(&dev->buf_writers); - + 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; } @@ -217,15 +217,15 @@ static int mga_takedown(drm_device_t *dev) DRM_DEBUG("\n"); if (dev->irq) mga_irq_uninstall(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; @@ -243,7 +243,7 @@ static int mga_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - + /* Remove AGP resources, but leave dev->agp intact until cleanup is called. */ for (entry = dev->agp->memory; entry; entry = nexte) { @@ -253,10 +253,10 @@ static int mga_takedown(drm_device_t *dev) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; - + if (dev->agp->acquired && drm_agp.release) (*drm_agp.release)(); - + dev->agp->acquired = 0; dev->agp->enabled = 0; } @@ -268,7 +268,7 @@ static int mga_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++) { @@ -304,7 +304,7 @@ static int mga_takedown(drm_device_t *dev) dev->maplist = NULL; dev->map_count = 0; } - + if (dev->queuelist) { for (i = 0; i < dev->queue_count; i++) { drm_waitlist_destroy(&dev->queuelist[i]->waitlist); @@ -330,7 +330,7 @@ static int mga_takedown(drm_device_t *dev) wake_up_interruptible(&dev->lock.lock_queue); } up(&dev->struct_sem); - + return 0; } @@ -347,7 +347,7 @@ static int mga_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(mga); #endif @@ -407,7 +407,7 @@ static void mga_cleanup(void) drm_device_t *dev = &mga_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&mga_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -419,7 +419,7 @@ static void mga_cleanup(void) #ifdef CONFIG_MTRR if(dev->agp && dev->agp->agp_mtrr) { int retval; - retval = mtrr_del(dev->agp->agp_mtrr, + retval = mtrr_del(dev->agp->agp_mtrr, dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size * 1024*1024); DRM_DEBUG("mtrr_del = %d\n", retval); @@ -444,17 +444,18 @@ int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = MGA_MAJOR; @@ -465,10 +466,10 @@ int mga_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, MGA_DATE); DRM_COPY(version.desc, MGA_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -476,7 +477,7 @@ int mga_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &mga_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 @@ -513,7 +514,7 @@ int mga_release(struct inode *inode, struct file *filp) drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - + /* FIXME: may require heavy-handed reset of hardware at this point, possibly processed via a callback to the X @@ -534,7 +535,7 @@ int mga_release(struct inode *inode, struct file *filp) dev->lock.lock_time = jiffies; atomic_inc(&dev->total_locks); break; /* Got lock */ - } + } /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -560,7 +561,7 @@ int mga_release(struct inode *inode, struct file *filp) if (priv->next) priv->next->prev = priv->prev; else dev->file_last = priv->prev; up(&dev->struct_sem); - + drm_free(priv, sizeof(*priv), DRM_MEM_FILES); #if LINUX_VERSION_CODE < 0x020333 MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ @@ -601,7 +602,7 @@ int mga_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); @@ -621,7 +622,7 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -633,8 +634,9 @@ int mga_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); @@ -655,8 +657,6 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd, DRM_ERROR("\n"); } -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ unblock_all_signals(); -#endif return 0; } diff --git a/linux/mga_drv.h b/linux/mga_drv.h index f49bd0f6..6feba09a 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -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 @@ -82,6 +82,7 @@ typedef struct _drm_mga_private { int use_agp; drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES]; unsigned int WarpPipe; + unsigned int vertexsize; atomic_t pending_bufs; void *status_page; unsigned long real_status_page; @@ -97,7 +98,7 @@ typedef struct _drm_mga_private { wait_queue_head_t wait_queue; /* Processes waiting until interrupt */ wait_queue_head_t buf_queue; /* Processes waiting for a free buf */ /* Some validated register values: - */ + */ u32 mAccess; } drm_mga_private_t; @@ -128,7 +129,6 @@ extern int mga_dma_init(struct inode *inode, struct file *filp, extern int mga_dma_cleanup(drm_device_t *dev); extern int mga_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void mga_flush_write_combine(void); extern unsigned int mga_create_sync_tag(drm_device_t *dev); extern drm_buf_t *mga_freelist_get(drm_device_t *dev); extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf); @@ -137,9 +137,9 @@ extern void mga_reclaim_buffers(drm_device_t *dev, pid_t pid); /* mga_bufs.c */ -extern int mga_addbufs(struct inode *inode, struct file *filp, +extern int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int mga_infobufs(struct inode *inode, struct file *filp, +extern int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int mga_markbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -179,6 +179,7 @@ extern int mga_rmctx(struct inode *inode, struct file *filp, extern int mga_context_switch(drm_device_t *dev, int old, int new); extern int mga_context_switch_complete(drm_device_t *dev, int new); +#define mga_flush_write_combine() mb() typedef enum { TT_GENERAL, @@ -201,7 +202,7 @@ typedef struct { #define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) #define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2) #define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) -#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) +#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) #define MGA_VERBOSE 0 #define MGA_NUM_PRIM_BUFS 8 @@ -212,13 +213,12 @@ typedef struct { #define PRIM_OVERFLOW(dev, dev_priv, length) do { \ drm_mga_prim_buf_t *tmp_buf = \ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - if( test_bit(MGA_BUF_NEEDS_OVERFLOW, \ - &tmp_buf->buffer_status)) { \ + if( test_bit(MGA_BUF_NEEDS_OVERFLOW, &tmp_buf->buffer_status)) { \ mga_advance_primary(dev); \ mga_dma_schedule(dev, 1); \ tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \ - tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \ + tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \ set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \ mga_advance_primary(dev); \ mga_dma_schedule(dev, 1); \ @@ -295,7 +295,7 @@ drm_mga_prim_buf_t *tmp_buf = \ num_dwords + 1 + outcount, ADRINDEX(reg), val); \ if( ++outcount == 4) { \ outcount = 0; \ - dma_ptr[0] = *(u32 *)tempIndex; \ + dma_ptr[0] = *(unsigned long *)tempIndex; \ dma_ptr+=5; \ num_dwords += 5; \ } \ @@ -396,8 +396,8 @@ drm_mga_prim_buf_t *tmp_buf = \ #define DC_atype_zi 0x30 #define DC_atype_blk 0x40 #define DC_atype_i 0x70 -#define DC_linear_xy 0x0 -#define DC_linear_linear 0x80 +#define DC_linear_xy 0x0 +#define DC_linear_linear 0x80 #define DC_zmode_nozcmp 0x0 #define DC_zmode_ze 0x200 #define DC_zmode_zne 0x300 @@ -405,16 +405,16 @@ drm_mga_prim_buf_t *tmp_buf = \ #define DC_zmode_zlte 0x500 #define DC_zmode_zgt 0x600 #define DC_zmode_zgte 0x700 -#define DC_solid_disable 0x0 -#define DC_solid_enable 0x800 -#define DC_arzero_disable 0x0 -#define DC_arzero_enable 0x1000 -#define DC_sgnzero_disable 0x0 -#define DC_sgnzero_enable 0x2000 -#define DC_shftzero_disable 0x0 -#define DC_shftzero_enable 0x4000 -#define DC_bop_SHIFT 16 -#define DC_trans_SHIFT 20 +#define DC_solid_disable 0x0 +#define DC_solid_enable 0x800 +#define DC_arzero_disable 0x0 +#define DC_arzero_enable 0x1000 +#define DC_sgnzero_disable 0x0 +#define DC_sgnzero_enable 0x2000 +#define DC_shftzero_disable 0x0 +#define DC_shftzero_enable 0x4000 +#define DC_bop_SHIFT 16 +#define DC_trans_SHIFT 20 #define DC_bltmod_bmonolef 0x0 #define DC_bltmod_bmonowf 0x8000000 #define DC_bltmod_bplan 0x2000000 @@ -423,21 +423,21 @@ drm_mga_prim_buf_t *tmp_buf = \ #define DC_bltmod_bu32rgb 0xe000000 #define DC_bltmod_bu24bgr 0x16000000 #define DC_bltmod_bu24rgb 0x1e000000 -#define DC_pattern_disable 0x0 -#define DC_pattern_enable 0x20000000 -#define DC_transc_disable 0x0 -#define DC_transc_enable 0x40000000 -#define DC_clipdis_disable 0x0 -#define DC_clipdis_enable 0x80000000 +#define DC_pattern_disable 0x0 +#define DC_pattern_enable 0x20000000 +#define DC_transc_disable 0x0 +#define DC_transc_enable 0x40000000 +#define DC_clipdis_disable 0x0 +#define DC_clipdis_enable 0x80000000 -#define SETADD_mode_vertlist 0x0 +#define SETADD_mode_vertlist 0x0 #define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ DC_sgnzero_enable | DC_shftzero_enable | \ (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ DC_solid_enable | DC_transc_enable) - + #define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ DC_solid_disable | DC_arzero_disable | \ diff --git a/linux/mga_state.c b/linux/mga_state.c index 5a9c7632..0c2f5729 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.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 @@ -38,13 +38,13 @@ * change these values */ -#define MGAEMITCLIP_SIZE 10 -#define MGAEMITCTX_SIZE 15 -#define MGAG200EMITTEX_SIZE 20 -#define MGAG400EMITTEX0_SIZE 30 -#define MGAG400EMITTEX1_SIZE 25 -#define MGAG400EMITPIPE_SIZE 50 -#define MGAG200EMITPIPE_SIZE 15 +#define MGAEMITCLIP_SIZE 10 +#define MGAEMITCTX_SIZE 20 +#define MGAG200EMITTEX_SIZE 20 +#define MGAG400EMITTEX0_SIZE 30 +#define MGAG400EMITTEX1_SIZE 25 +#define MGAG400EMITPIPE_SIZE 55 +#define MGAG200EMITPIPE_SIZE 15 #define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \ MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \ @@ -89,7 +89,7 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv) PRIMLOCALS; DRM_DEBUG("%s\n", __FUNCTION__); - /* This takes a max of 15 dwords */ + /* This takes a max of 20 dwords */ PRIMGETPTR(dev_priv); PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]); @@ -107,6 +107,11 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv) PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]); PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]); PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]); + + PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]); + PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); } else { PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -151,11 +156,13 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv) PRIMADVANCE(dev_priv); } +#define TMC_dualtex_enable 0x80 + static void mgaG400EmitTex0(drm_mga_private_t * dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->TexState[0]; - int multitex = sarea_priv->WarpPipe & MGA_T2; + int multitex = regs[MGA_TEXREG_CTL2] & TMC_dualtex_enable; PRIMLOCALS; DRM_DEBUG("%s\n", __FUNCTION__); @@ -183,7 +190,7 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv) PRIMOUTREG(0x2d00 + 61 * 4, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); - if (!multitex) { + if (!multitex || 1) { PRIMOUTREG(0x2d00 + 52 * 4, 0x40); PRIMOUTREG(0x2d00 + 60 * 4, 0x40); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -200,10 +207,10 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv) #define TMC_map1_enable 0x80000000 -static void mgaG400EmitTex1(drm_mga_private_t * dev_priv) +static void mgaG400EmitTex1(drm_mga_private_t * dev_priv, int source ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->TexState[1]; + unsigned int *regs = sarea_priv->TexState[source]; PRIMLOCALS; DRM_DEBUG("%s\n", __FUNCTION__); @@ -245,6 +252,8 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->WarpPipe; float fParam = 12800.0f; + int multitex = (sarea_priv->TexState[0][MGA_TEXREG_CTL2] & + TMC_dualtex_enable); PRIMLOCALS; DRM_DEBUG("%s\n", __FUNCTION__); @@ -252,14 +261,36 @@ 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); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); - if (pipe & MGA_T2) { + if (sarea_priv->vertexsize == 10) { + PRIMOUTREG(MGAREG_YDST, 0); + PRIMOUTREG(MGAREG_FXLEFT, 0); + PRIMOUTREG(MGAREG_FXRIGHT, 1); + PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD); + + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); + PRIMOUTREG(MGAREG_DMAPAD, 0); + + if (multitex) { + PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); + PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); + } else { + PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); + PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); + } + PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -270,23 +301,21 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000); } else { - if (dev_priv->WarpPipe & MGA_T2) { - /* Flush the WARP pipe */ - PRIMOUTREG(MGAREG_YDST, 0); - PRIMOUTREG(MGAREG_FXLEFT, 0); - PRIMOUTREG(MGAREG_FXRIGHT, 1); - PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD); - - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); - PRIMOUTREG(MGAREG_DMAPAD, 0); + /* Flush the WARP pipe */ + PRIMOUTREG(MGAREG_YDST, 0); + PRIMOUTREG(MGAREG_FXLEFT, 0); + PRIMOUTREG(MGAREG_FXRIGHT, 1); + PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD); - PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); - PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); - } + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); + PRIMOUTREG(MGAREG_DMAPAD, 0); + + PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); + PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000); + PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -314,13 +343,16 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) PRIMOUTREG(0x2d00 + 52 * 4, 0x40); /* Tex stage 1 : w */ PRIMOUTREG(0x2d00 + 60 * 4, 0x40); /* Tex stage 1 : h */ - /* Dma pading required due to hw bug */ - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR2, - (u32) (dev_priv->WarpIndex[pipe]. - phys_addr | WIA_wmode_start | WIA_wagp_agp)); + if (dev_priv->WarpPipe != pipe || 1) { + /* Dma pading required due to hw bug */ + PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); + PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); + PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); + PRIMOUTREG(MGAREG_WIADDR2, + (u32) (dev_priv->WarpIndex[pipe].phys_addr | + WIA_wmode_start | WIA_wagp_agp)); + } + PRIMADVANCE(dev_priv); } @@ -363,11 +395,20 @@ static void mgaEmitState(drm_mga_private_t * dev_priv) DRM_DEBUG("%s\n", __FUNCTION__); if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - int multitex = sarea_priv->WarpPipe & MGA_T2; + int multitex = (sarea_priv->TexState[0][MGA_TEXREG_CTL2] & + TMC_dualtex_enable); - if (sarea_priv->WarpPipe != dev_priv->WarpPipe) { + dirty = ~0; + + if (dirty & MGA_UPLOAD_PIPE +/* && (sarea_priv->WarpPipe != dev_priv->WarpPipe || */ +/* sarea_priv->vertexsize != dev_priv->vertexsize) */ + ) + { mgaG400EmitPipe(dev_priv); dev_priv->WarpPipe = sarea_priv->WarpPipe; + dev_priv->vertexsize = sarea_priv->vertexsize; + sarea_priv->dirty &= ~MGA_UPLOAD_PIPE; } if (dirty & MGA_UPLOAD_CTX) { @@ -380,8 +421,11 @@ static void mgaEmitState(drm_mga_private_t * dev_priv) sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; } - if ((dirty & MGA_UPLOAD_TEX1) && multitex) { - mgaG400EmitTex1(dev_priv); + if (dirty & MGA_UPLOAD_TEX1) { + if (multitex) + mgaG400EmitTex1(dev_priv, 1); + else + mgaG400EmitTex1(dev_priv, 0); sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; } } else { @@ -552,12 +596,15 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) if (buf->used) { /* WARNING: if you change any of the state functions verify - * these numbers (Overestimating this doesn't hurt). + * these numbers (Overestimating this doesn't hurt). */ buf_priv->dispatched = 1; PRIM_OVERFLOW(dev, dev_priv, (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS))); mgaEmitState(dev_priv); + +/* length = dev_priv->vertexsize * 3 * 4; */ + do { if (i < sarea_priv->nbox) { DRM_DEBUG("idx %d Emit box %d/%d:" @@ -614,7 +661,7 @@ static void mga_dma_dispatch_indices(drm_device_t * dev, if (start != end) { /* WARNING: if you change any of the state functions verify - * these numbers (Overestimating this doesn't hurt). + * these numbers (Overestimating this doesn't hurt). */ buf_priv->dispatched = 1; PRIM_OVERFLOW(dev, dev_priv, @@ -644,6 +691,7 @@ static void mga_dma_dispatch_indices(drm_device_t * dev, SETADD_mode_vertlist)); PRIMOUTREG(MGAREG_SETUPEND, ((address + end) | use_agp)); +/* ((address + start + 12) | use_agp)); */ PRIMADVANCE(dev_priv); } while (++i < sarea_priv->nbox); } @@ -658,7 +706,9 @@ static void mga_dma_dispatch_indices(drm_device_t * dev, static void mga_dma_dispatch_clear(drm_device_t * dev, int flags, unsigned int clear_color, - unsigned int clear_zval) + unsigned int clear_zval, + unsigned int clear_colormask, + unsigned int clear_depthmask) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -687,7 +737,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags, if (flags & MGA_FRONT) { DRM_DEBUG("clear front\n"); PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_PLNWT, clear_colormask); PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1 << 16) | height); PRIMOUTREG(MGAREG_FXBNDRY, @@ -702,7 +752,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags, if (flags & MGA_BACK) { DRM_DEBUG("clear back\n"); PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_PLNWT, clear_colormask); PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1 << 16) | height); PRIMOUTREG(MGAREG_FXBNDRY, @@ -717,7 +767,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags, if (flags & MGA_DEPTH) { DRM_DEBUG("clear depth\n"); PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_PLNWT, clear_depthmask); PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1 << 16) | height); PRIMOUTREG(MGAREG_FXBNDRY, @@ -802,8 +852,8 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; - copy_from_user_ret(&clear, (drm_mga_clear_t *) arg, sizeof(clear), - -EFAULT); + if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear))) + return -EFAULT; DRM_DEBUG("%s\n", __FUNCTION__); if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { @@ -818,11 +868,12 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, */ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; mga_dma_dispatch_clear(dev, clear.flags, - clear.clear_color, clear.clear_depth); + clear.clear_color, + clear.clear_depth, + clear.clear_color_mask, + clear.clear_depth_mask); PRIMUPDATE(dev_priv); -#ifdef __i386__ mga_flush_write_combine(); -#endif mga_dma_schedule(dev, 1); return 0; } @@ -852,9 +903,7 @@ int mga_swap_bufs(struct inode *inode, struct file *filp, PRIMUPDATE(dev_priv); set_bit(MGA_BUF_SWAP_PENDING, &dev_priv->current_prim->buffer_status); -#ifdef __i386__ mga_flush_write_combine(); -#endif mga_dma_schedule(dev, 1); return 0; } @@ -875,8 +924,8 @@ int mga_iload(struct inode *inode, struct file *filp, DRM_DEBUG("%s\n", __FUNCTION__); DRM_DEBUG("Starting Iload\n"); - copy_from_user_ret(&iload, (drm_mga_iload_t *) arg, sizeof(iload), - -EFAULT); + if (copy_from_user(&iload, (drm_mga_iload_t *) arg, sizeof(iload))) + return -EFAULT; if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("mga_iload called without lock held\n"); @@ -902,9 +951,7 @@ int mga_iload(struct inode *inode, struct file *filp, AGEBUF(dev_priv, buf_priv); buf_priv->discard = 1; mga_freelist_put(dev, buf); -#ifdef __i386__ mga_flush_write_combine(); -#endif mga_dma_schedule(dev, 1); return 0; } @@ -922,8 +969,8 @@ int mga_vertex(struct inode *inode, struct file *filp, drm_mga_vertex_t vertex; DRM_DEBUG("%s\n", __FUNCTION__); - copy_from_user_ret(&vertex, (drm_mga_vertex_t *) arg, - sizeof(vertex), -EFAULT); + if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex))) + return -EFAULT; if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("mga_vertex called without lock held\n"); @@ -952,9 +999,7 @@ int mga_vertex(struct inode *inode, struct file *filp, mga_dma_dispatch_vertex(dev, buf); PRIMUPDATE(dev_priv); -#ifdef __i386__ mga_flush_write_combine(); -#endif mga_dma_schedule(dev, 1); return 0; } @@ -973,8 +1018,8 @@ int mga_indices(struct inode *inode, struct file *filp, drm_mga_indices_t indices; DRM_DEBUG("%s\n", __FUNCTION__); - copy_from_user_ret(&indices, (drm_mga_indices_t *) arg, - sizeof(indices), -EFAULT); + if (copy_from_user(&indices, (drm_mga_indices_t *) arg, sizeof(indices))) + return -EFAULT; if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("mga_indices called without lock held\n"); @@ -1001,9 +1046,7 @@ int mga_indices(struct inode *inode, struct file *filp, mga_dma_dispatch_indices(dev, buf, indices.start, indices.end); PRIMUPDATE(dev_priv); -#ifdef __i386__ mga_flush_write_combine(); -#endif mga_dma_schedule(dev, 1); return 0; } @@ -1021,10 +1064,12 @@ static int mga_dma_get_buffers(drm_device_t * dev, drm_dma_t * d) if (!buf) break; buf->pid = current->pid; - copy_to_user_ret(&d->request_indices[i], - &buf->idx, sizeof(buf->idx), -EFAULT); - copy_to_user_ret(&d->request_sizes[i], - &buf->total, sizeof(buf->total), -EFAULT); + 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; @@ -1040,7 +1085,8 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, drm_dma_t d; DRM_DEBUG("%s\n", __FUNCTION__); - copy_from_user_ret(&d, (drm_dma_t *) arg, sizeof(d), -EFAULT); + if (copy_from_user(&d, (drm_dma_t *) arg, sizeof(d))) + return -EFAULT; DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); @@ -1075,6 +1121,7 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("%d returning, granted = %d\n", current->pid, d.granted_count); - copy_to_user_ret((drm_dma_t *) arg, &d, sizeof(d), -EFAULT); + if (copy_to_user((drm_dma_t *) arg, &d, sizeof(d))) + return -EFAULT; return retcode; } diff --git a/linux/r128_bufs.c b/linux/r128_bufs.c index bd81dcdc..7e76441e 100644 --- a/linux/r128_bufs.c +++ b/linux/r128_bufs.c @@ -60,10 +60,10 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, if (!dma) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; count = request.count; order = drm_order(request.size); @@ -173,10 +173,10 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, request.count = entry->buf_count; request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, + if (copy_to_user((drm_buf_desc_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; dma->flags = _DRM_DMA_USE_AGP; @@ -195,10 +195,10 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (!dev_priv || dev_priv->is_pci) return -EINVAL; - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) if (request.flags & _DRM_AGP_BUFFER) @@ -234,10 +234,10 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, ++dev->buf_use; /* Can't allocate more after this call */ spin_unlock(&dev->count_lock); - copy_from_user_ret(&request, + if (copy_from_user(&request, (drm_buf_map_t *)arg, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; if (request.count >= dma->buf_count) { if (dma->flags & _DRM_DMA_USE_AGP) { @@ -300,10 +300,10 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, request.count = dma->buf_count; DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - copy_to_user_ret((drm_buf_map_t *)arg, + if (copy_to_user((drm_buf_map_t *)arg, &request, - sizeof(request), - -EFAULT); + sizeof(request))) + return -EFAULT; return retcode; } diff --git a/linux/r128_context.c b/linux/r128_context.c index 2dd716d4..9cadadba 100644 --- a/linux/r128_context.c +++ b/linux/r128_context.c @@ -103,19 +103,21 @@ int r128_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], + if (copy_to_user(&res.contexts[i], &i, - sizeof(i), - -EFAULT); + 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; } @@ -127,7 +129,8 @@ int r128_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 = r128_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ ctx.handle = r128_alloc_queue(dev); @@ -139,7 +142,8 @@ int r128_addctx(struct inode *inode, struct file *filp, unsigned int cmd, return -ENOMEM; } - 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; } @@ -148,7 +152,8 @@ int r128_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) r128_res_ctx.handle=ctx.handle; return 0; @@ -159,10 +164,12 @@ int r128_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; } @@ -173,7 +180,8 @@ int r128_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 r128_context_switch(dev, dev->last_context, ctx.handle); } @@ -185,7 +193,8 @@ int r128_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); r128_context_switch_complete(dev, ctx.handle); @@ -199,7 +208,8 @@ int r128_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/r128_dma.c b/linux/r128_dma.c index d4b75bed..bcba6782 100644 --- a/linux/r128_dma.c +++ b/linux/r128_dma.c @@ -68,26 +68,8 @@ int R128_READ_PLL(drm_device_t *dev, int addr) return R128_READ(R128_CLOCK_CNTL_DATA); } -#ifdef __i386__ -static void r128_flush_write_combine(void) -{ - int xchangeDummy; - - __asm__ volatile("push %%eax ;" - "xchg %%eax, %0 ;" - "pop %%eax" : : "m" (xchangeDummy)); - __asm__ volatile("push %%eax ;" - "push %%ebx ;" - "push %%ecx ;" - "push %%edx ;" - "movl $0,%%eax ;" - "cpuid ;" - "pop %%edx ;" - "pop %%ecx ;" - "pop %%ebx ;" - "pop %%eax" : /* no outputs */ : /* no inputs */ ); -} -#endif +#define r128_flush_write_combine() mb() + static void r128_status(drm_device_t *dev) { @@ -213,8 +195,8 @@ int r128_init_cce(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_r128_init_t init; - copy_from_user_ret(&init, (drm_r128_init_t *)arg, sizeof(init), - -EFAULT); + if (copy_from_user(&init, (drm_r128_init_t *)arg, sizeof(init))) + return -EFAULT; switch (init.func) { case R128_INIT_CCE: @@ -498,10 +480,8 @@ static int r128_submit_packets_ring_secure(drm_device_t *dev, dev_priv->ring_start, write * sizeof(u32)); -#ifdef __i386__ /* Make sure WC cache has been flushed */ r128_flush_write_combine(); -#endif dev_priv->sarea_priv->ring_write = write; R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write); @@ -603,10 +583,8 @@ static int r128_submit_packets_ring(drm_device_t *dev, dev_priv->ring_start, write * sizeof(u32)); -#ifdef __i386__ /* Make sure WC cache has been flushed */ r128_flush_write_combine(); -#endif dev_priv->sarea_priv->ring_write = write; R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write); @@ -686,8 +664,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp, return -EINVAL; } - copy_from_user_ret(&packet, (drm_r128_packet_t *)arg, sizeof(packet), - -EFAULT); + if (copy_from_user(&packet, (drm_r128_packet_t *)arg, sizeof(packet))) + return -EFAULT; c = packet.count; size = c * sizeof(*buffer); @@ -702,7 +680,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp, } if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM; - copy_from_user_ret(buffer, packet.buffer, size, -EFAULT); + if (copy_from_user(buffer, packet.buffer, size)) + return -EFAULT; if (dev_priv->cce_secure) ret = r128_submit_packets_ring_secure(dev, buffer, &c); @@ -712,7 +691,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp, c += left; } else { if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM; - copy_from_user_ret(buffer, packet.buffer, size, -EFAULT); + if (copy_from_user(buffer, packet.buffer, size)) + return -EFAULT; if (dev_priv->cce_secure) ret = r128_submit_packets_pio_secure(dev, buffer, &c); @@ -723,8 +703,8 @@ int r128_submit_pkt(struct inode *inode, struct file *filp, kfree(buffer); packet.count = c; - copy_to_user_ret((drm_r128_packet_t *)arg, &packet, sizeof(packet), - -EFAULT); + if (copy_to_user((drm_r128_packet_t *)arg, &packet, sizeof(packet))) + return -EFAULT; if (ret) return ret; else if (c > 0) return -EAGAIN; @@ -772,10 +752,8 @@ static int r128_send_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v) r128_mark_vertbufs_done(dev); } -#ifdef __i386__ /* Make sure WC cache has been flushed (if in PIO mode) */ if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine(); -#endif /* FIXME: Add support for sending vertex buffer to the CCE here instead of in client code. The v->prim holds the primitive @@ -863,14 +841,13 @@ static int r128_get_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v) buf = r128_freelist_get(dev); if (!buf) break; buf->pid = current->pid; - copy_to_user_ret(&v->request_indices[i], + if (copy_to_user(&v->request_indices[i], &buf->idx, - sizeof(buf->idx), - -EFAULT); - copy_to_user_ret(&v->request_sizes[i], + sizeof(buf->idx)) || + copy_to_user(&v->request_sizes[i], &buf->total, - sizeof(buf->total), - -EFAULT); + sizeof(buf->total))) + return -EFAULT; ++v->granted_count; } return 0; @@ -897,7 +874,8 @@ int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd, return -EINVAL; } - copy_from_user_ret(&v, (drm_r128_vertex_t *)arg, sizeof(v), -EFAULT); + if (copy_from_user(&v, (drm_r128_vertex_t *)arg, sizeof(v))) + return -EFAULT; DRM_DEBUG("%d: %d send, %d req\n", current->pid, v.send_count, v.request_count); @@ -924,7 +902,8 @@ int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("%d returning, granted = %d\n", current->pid, v.granted_count); - copy_to_user_ret((drm_r128_vertex_t *)arg, &v, sizeof(v), -EFAULT); + if (copy_to_user((drm_r128_vertex_t *)arg, &v, sizeof(v))) + return -EFAULT; return retcode; } diff --git a/linux/r128_drv.c b/linux/r128_drv.c index dd982ab4..b58dcf06 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -35,7 +35,7 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20000827" +#define R128_DATE "20000910" #define R128_MAJOR 1 #define R128_MINOR 0 #define R128_PATCHLEVEL 0 @@ -420,17 +420,18 @@ int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = R128_MAJOR; @@ -441,10 +442,10 @@ int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, R128_DATE); DRM_COPY(version.desc, R128_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -559,7 +560,8 @@ int r128_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", @@ -656,7 +658,6 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -665,7 +666,6 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -700,7 +700,8 @@ int r128_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", @@ -729,9 +730,6 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, current->priority = DEF_PRIORITY; } #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ unblock_all_signals(); -#endif return 0; } diff --git a/linux/sis_drv.c b/linux/sis_drv.c index 434a1ccd..d5fe8fc0 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -9,11 +9,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 @@ -100,7 +100,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 }, @@ -121,7 +121,7 @@ MODULE_PARM(sis, "s"); 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; @@ -163,7 +163,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; @@ -172,15 +172,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; } @@ -200,12 +200,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; @@ -224,7 +224,7 @@ static int sis_takedown(drm_device_t *dev) if (dev->agp) { drm_agp_mem_t *entry; drm_agp_mem_t *nexte; - + /* Remove AGP resources, but leave dev->agp intact until cleanup is called. */ for (entry = dev->agp->memory; entry; entry = nexte) { @@ -234,13 +234,13 @@ static int sis_takedown(drm_device_t *dev) drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); } dev->agp->memory = NULL; - + if (dev->agp->acquired && drm_agp.release) (*drm_agp.release)(); - + dev->agp->acquired = 0; dev->agp->enabled = 0; - } + } #endif /* Clear vma list (only built for debugging) */ @@ -251,7 +251,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++) { @@ -289,14 +289,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; } @@ -313,7 +313,7 @@ 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 @@ -356,7 +356,7 @@ int sis_init(void) SIS_PATCHLEVEL, SIS_DATE, sis_misc.minor); - + return 0; } @@ -367,7 +367,7 @@ 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"); @@ -378,7 +378,7 @@ void sis_cleanup(void) #ifdef CONFIG_MTRR if(dev->agp && dev->agp->agp_mtrr) { int retval; - retval = mtrr_del(dev->agp->agp_mtrr, + retval = mtrr_del(dev->agp->agp_mtrr, dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size * 1024*1024); DRM_DEBUG("mtrr_del = %d\n", retval); @@ -433,7 +433,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))) { @@ -492,7 +492,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); @@ -512,7 +512,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; } @@ -549,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) @@ -561,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; @@ -584,7 +584,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); current->state = TASK_INTERRUPTIBLE; @@ -626,7 +626,6 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -635,7 +634,7 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -652,7 +651,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; } @@ -665,7 +664,7 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, drm_lock_t lock; copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); - + if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", current->pid, lock.context); @@ -687,9 +686,7 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd, } } -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ unblock_all_signals(); -#endif return 0; } diff --git a/linux/tdfx_context.c b/linux/tdfx_context.c index d6903c0a..1fd73310 100644 --- a/linux/tdfx_context.c +++ b/linux/tdfx_context.c @@ -105,19 +105,21 @@ int tdfx_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], + if (copy_to_user(&res.contexts[i], &i, - sizeof(i), - -EFAULT); + 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; } @@ -129,7 +131,8 @@ int tdfx_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 = tdfx_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ ctx.handle = tdfx_alloc_queue(dev); @@ -141,7 +144,8 @@ int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd, return -ENOMEM; } - 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; } @@ -150,7 +154,8 @@ int tdfx_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) tdfx_res_ctx.handle=ctx.handle; return 0; @@ -161,10 +166,12 @@ int tdfx_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); - /* This is 0, because we don't hanlde any context flags */ + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; + /* This is 0, because we don't handle 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; } @@ -175,7 +182,8 @@ int tdfx_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 tdfx_context_switch(dev, dev->last_context, ctx.handle); } @@ -187,7 +195,8 @@ int tdfx_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); tdfx_context_switch_complete(dev, ctx.handle); @@ -201,7 +210,8 @@ int tdfx_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/tdfx_drv.c b/linux/tdfx_drv.c index 07febea1..2026e9d0 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.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. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Daryll Strauss <daryll@valinux.com> @@ -36,7 +36,7 @@ #define TDFX_NAME "tdfx" #define TDFX_DESC "3dfx Banshee/Voodoo3+" -#define TDFX_DATE "20000719" +#define TDFX_DATE "20000910" #define TDFX_MAJOR 1 #define TDFX_MINOR 0 #define TDFX_PATCHLEVEL 0 @@ -76,7 +76,7 @@ static drm_ioctl_desc_t tdfx_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)] = { tdfx_addctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { tdfx_rmctx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { tdfx_modctx, 1, 1 }, @@ -128,7 +128,7 @@ __setup("tdfx=", tdfx_options); static int tdfx_setup(drm_device_t *dev) { int i; - + atomic_set(&dev->ioctl_count, 0); atomic_set(&dev->vma_count, 0); dev->buf_use = 0; @@ -170,7 +170,7 @@ static int tdfx_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; @@ -179,15 +179,15 @@ static int tdfx_setup(drm_device_t *dev) init_waitqueue_head(&dev->buf_writers); tdfx_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; } @@ -203,12 +203,12 @@ static int tdfx_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; @@ -227,7 +227,7 @@ static int tdfx_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; @@ -246,7 +246,7 @@ static int tdfx_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++) { @@ -284,14 +284,14 @@ static int tdfx_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; } @@ -308,7 +308,7 @@ static int tdfx_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(tdfx); #endif @@ -340,7 +340,7 @@ static int tdfx_init(void) TDFX_PATCHLEVEL, TDFX_DATE, tdfx_misc.minor); - + return 0; } @@ -351,7 +351,7 @@ static void tdfx_cleanup(void) drm_device_t *dev = &tdfx_device; DRM_DEBUG("\n"); - + drm_proc_cleanup(); if (misc_deregister(&tdfx_misc)) { DRM_ERROR("Cannot unload module\n"); @@ -379,17 +379,18 @@ int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, drm_version_t version; int len; - copy_from_user_ret(&version, + if (copy_from_user(&version, (drm_version_t *)arg, - sizeof(version), - -EFAULT); + 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 = TDFX_MAJOR; @@ -400,10 +401,10 @@ int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, DRM_COPY(version.date, TDFX_DATE); DRM_COPY(version.desc, TDFX_DESC); - copy_to_user_ret((drm_version_t *)arg, + if (copy_to_user((drm_version_t *)arg, &version, - sizeof(version), - -EFAULT); + sizeof(version))) + return -EFAULT; return 0; } @@ -411,7 +412,7 @@ int tdfx_open(struct inode *inode, struct file *filp) { drm_device_t *dev = &tdfx_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 @@ -479,7 +480,7 @@ int tdfx_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); @@ -499,7 +500,7 @@ int tdfx_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, retcode = (func)(inode, filp, cmd, arg); } } - + atomic_dec(&dev->ioctl_count); return retcode; } @@ -518,7 +519,8 @@ int tdfx_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", @@ -536,7 +538,7 @@ int tdfx_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) @@ -548,7 +550,7 @@ int tdfx_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; @@ -571,7 +573,7 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, atomic_inc(&dev->total_locks); break; /* Got lock */ } - + /* Contention */ atomic_inc(&dev->total_sleeps); current->state = TASK_INTERRUPTIBLE; @@ -615,7 +617,6 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, #endif if (!ret) { -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); @@ -624,7 +625,7 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); -#endif + if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } @@ -647,7 +648,7 @@ int tdfx_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; } @@ -659,8 +660,9 @@ int tdfx_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); @@ -688,9 +690,7 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd, current->priority = DEF_PRIORITY; } #endif - -#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */ + unblock_all_signals(); -#endif return 0; } |