diff options
Diffstat (limited to 'linux-core/i810_dma.c')
-rw-r--r-- | linux-core/i810_dma.c | 325 |
1 files changed, 165 insertions, 160 deletions
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]; |