diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/drm_bufs.c drm-tst/linux-core/drm_bufs.c --- drm/linux-core/drm_bufs.c 2006-03-10 05:44:33.000000000 +0200 +++ drm-tst/linux-core/drm_bufs.c 2006-04-12 22:57:48.000000000 +0300 @@ -940,6 +940,9 @@ int drm_addbufs_pci(drm_device_t * dev, request->count = entry->buf_count; request->size = size; + if (request->flags & _DRM_PCI_READ_ONLY) + dma->flags = _DRM_DMA_USE_PCI_READ_ONLY; + atomic_dec(&dev->buf_alloc); return 0; @@ -1526,9 +1529,10 @@ int drm_freebufs(struct inode *inode, st * \param arg pointer to a drm_buf_map structure. * \return zero on success or a negative number on failure. * - * Maps the AGP or SG buffer region with do_mmap(), and copies information - * about each buffer into user space. The PCI buffers are already mapped on the - * addbufs_pci() call. + * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls do_mmap() with + * offset equal to 0, which drm_mmap interpretes as PCI buffers and calls + * drm_mmap_dma(). */ int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/drm.h drm-tst/linux-core/drm.h --- drm/linux-core/drm.h 2006-01-02 15:26:59.000000000 +0200 +++ drm-tst/linux-core/drm.h 2006-04-12 22:53:17.000000000 +0300 @@ -408,7 +408,8 @@ typedef struct drm_buf_desc { _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ - _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */ + _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ + _DRM_PCI_READ_ONLY = 0x10 /**< Map PCI DMA buffers read-only */ } flags; unsigned long agp_start; /**< * Start address of where the AGP buffers are diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/drmP.h drm-tst/linux-core/drmP.h --- drm/linux-core/drmP.h 2006-04-08 14:26:38.000000000 +0300 +++ drm-tst/linux-core/drmP.h 2006-04-12 23:00:32.000000000 +0300 @@ -441,7 +441,8 @@ typedef struct drm_device_dma { enum { _DRM_DMA_USE_AGP = 0x01, _DRM_DMA_USE_SG = 0x02, - _DRM_DMA_USE_FB = 0x04 + _DRM_DMA_USE_FB = 0x04, + _DRM_DMA_USE_PCI_READ_ONLY = 0x08 } flags; } drm_device_dma_t; diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/drm_vm.c drm-tst/linux-core/drm_vm.c --- drm/linux-core/drm_vm.c 2006-02-18 14:07:59.000000000 +0200 +++ drm-tst/linux-core/drm_vm.c 2006-04-12 23:01:41.000000000 +0300 @@ -517,6 +517,22 @@ static int drm_mmap_dma(struct file *fil vma->vm_flags |= VM_RESERVED; /* Don't swap */ #endif + if (!capable(CAP_SYS_ADMIN) && + (dma->flags & _DRM_DMA_USE_PCI_READ_ONLY)) { + vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); +#if defined(__i386__) || defined(__x86_64__) + pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; +#else + /* Ye gads this is ugly. With more thought + we could move this up higher and use + `protection_map' instead. */ + vma->vm_page_prot = + __pgprot(pte_val + (pte_wrprotect + (__pte(pgprot_val(vma->vm_page_prot))))); +#endif + } + vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open(vma); return 0; Common subdirectories: drm/linux-core/linux and drm-tst/linux-core/linux diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/mach64_dma.c drm-tst/linux-core/mach64_dma.c --- drm/linux-core/mach64_dma.c 2006-03-11 14:25:05.000000000 +0200 +++ drm-tst/linux-core/mach64_dma.c 2006-04-12 03:19:07.000000000 +0300 @@ -815,17 +815,18 @@ static int mach64_do_dma_init(drm_device return DRM_ERR(EINVAL); } + dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset); + if (!dev_priv->ring_map) { + DRM_ERROR("can not find ring map!\n"); + dev->dev_private = (void *)dev_priv; + mach64_do_cleanup_dma(dev); + return DRM_ERR(EINVAL); + } + dev_priv->sarea_priv = (drm_mach64_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); if (!dev_priv->is_pci) { - dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->ring_map) { - DRM_ERROR("can not find ring map!\n"); - dev->dev_private = (void *)dev_priv; - mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); - } drm_core_ioremap(dev_priv->ring_map, dev); if (!dev_priv->ring_map->handle) { DRM_ERROR("can not ioremap virtual address for" @@ -891,27 +892,9 @@ static int mach64_do_dma_init(drm_device } } - /* allocate descriptor memory from pci pool */ - DRM_DEBUG("Allocating dma descriptor ring\n"); dev_priv->ring.size = 0x4000; /* 16KB */ - - if (dev_priv->is_pci) { - dev_priv->ring.dmah = drm_pci_alloc(dev, dev_priv->ring.size, - dev_priv->ring.size, - 0xfffffffful); - - if (!dev_priv->ring.dmah) { - DRM_ERROR("Allocating dma descriptor ring failed\n"); - return DRM_ERR(ENOMEM); - } else { - dev_priv->ring.start = dev_priv->ring.dmah->vaddr; - dev_priv->ring.start_addr = - (u32) dev_priv->ring.dmah->busaddr; - } - } else { - dev_priv->ring.start = dev_priv->ring_map->handle; - dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset; - } + dev_priv->ring.start = dev_priv->ring_map->handle; + dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset; memset(dev_priv->ring.start, 0, dev_priv->ring.size); DRM_INFO("descriptor ring: cpu addr %p, bus addr: 0x%08x\n", @@ -1149,18 +1132,14 @@ int mach64_do_cleanup_dma(drm_device_t * if (dev->dev_private) { drm_mach64_private_t *dev_priv = dev->dev_private; - if (dev_priv->is_pci) { - if (dev_priv->ring.dmah) { - drm_pci_free(dev, dev_priv->ring.dmah); - } - } else { + if (!dev_priv->is_pci) { if (dev_priv->ring_map) drm_core_ioremapfree(dev_priv->ring_map, dev); - } - if (dev->agp_buffer_map) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; + if (dev->agp_buffer_map) { + drm_core_ioremapfree(dev->agp_buffer_map, dev); + dev->agp_buffer_map = NULL; + } } mach64_destroy_freelist(dev); @@ -1329,17 +1308,88 @@ int mach64_do_release_used_buffers(drm_m return 0; } +static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv) +{ + drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; + struct list_head *ptr; + struct list_head *tmp; + drm_mach64_freelist_t *entry; + u32 head, tail, ofs; + + mach64_ring_tick(dev_priv, ring); + head = ring->head; + tail = ring->tail; + + if (head == tail) { +#if MACH64_EXTRA_CHECKING + if (MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE) { + DRM_ERROR("Empty ring with non-idle engine!\n"); + mach64_dump_ring_info(dev_priv); + return -1; + } +#endif + /* last pass is complete, so release everything */ + mach64_do_release_used_buffers(dev_priv); + DRM_DEBUG("%s: idle engine, freed all buffers.\n", + __FUNCTION__); + if (list_empty(&dev_priv->free_list)) { + DRM_ERROR("Freelist empty with idle engine\n"); + return -1; + } + return 0; + } + /* Look for a completed buffer and bail out of the loop + * as soon as we find one -- don't waste time trying + * to free extra bufs here, leave that to do_release_used_buffers + */ + list_for_each_safe(ptr, tmp, &dev_priv->pending) { + entry = list_entry(ptr, drm_mach64_freelist_t, list); + ofs = entry->ring_ofs; + if (entry->discard && + ((head < tail && (ofs < head || ofs >= tail)) || + (head > tail && (ofs < head && ofs >= tail)))) { +#if MACH64_EXTRA_CHECKING + int i; + + for (i = head; i != tail; i = (i + 4) & ring->tail_mask) + { + u32 o1 = le32_to_cpu(((u32 *) ring-> + start)[i + 1]); + u32 o2 = GETBUFADDR(entry->buf); + + if (o1 == o2) { + DRM_ERROR + ("Attempting to free used buffer: " + "i=%d buf=0x%08x\n", + i, o1); + mach64_dump_ring_info(dev_priv); + return -1; + } + } +#endif + /* found a processed buffer */ + entry->buf->pending = 0; + list_del(ptr); + list_add_tail(ptr, &dev_priv->free_list); + DRM_DEBUG + ("%s: freed processed buffer (head=%d tail=%d " + "buf ring ofs=%d).\n", + __FUNCTION__, head, tail, ofs); + return 0; + } + } + + return 1; +} + drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv) { drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; drm_mach64_freelist_t *entry; struct list_head *ptr; - struct list_head *tmp; int t; if (list_empty(&dev_priv->free_list)) { - u32 head, tail, ofs; - if (list_empty(&dev_priv->pending)) { DRM_ERROR ("Couldn't get buffer - pending and free lists empty\n"); @@ -1351,81 +1401,15 @@ drm_buf_t *mach64_freelist_get(drm_mach6 return NULL; } - tail = ring->tail; for (t = 0; t < dev_priv->usec_timeout; t++) { - mach64_ring_tick(dev_priv, ring); - head = ring->head; + int ret; - if (head == tail) { -#if MACH64_EXTRA_CHECKING - if (MACH64_READ(MACH64_GUI_STAT) & - MACH64_GUI_ACTIVE) { - DRM_ERROR - ("Empty ring with non-idle engine!\n"); - mach64_dump_ring_info(dev_priv); - return NULL; - } -#endif - /* last pass is complete, so release everything */ - mach64_do_release_used_buffers(dev_priv); - DRM_DEBUG - ("%s: idle engine, freed all buffers.\n", - __FUNCTION__); - if (list_empty(&dev_priv->free_list)) { - DRM_ERROR - ("Freelist empty with idle engine\n"); - return NULL; - } + ret = mach64_do_reclaim_completed(dev_priv); + if (ret == 0) goto _freelist_entry_found; - } - /* Look for a completed buffer and bail out of the loop - * as soon as we find one -- don't waste time trying - * to free extra bufs here, leave that to do_release_used_buffers - */ - list_for_each_safe(ptr, tmp, &dev_priv->pending) { - entry = - list_entry(ptr, drm_mach64_freelist_t, - list); - ofs = entry->ring_ofs; - if (entry->discard && - ((head < tail - && (ofs < head || ofs >= tail)) - || (head > tail - && (ofs < head && ofs >= tail)))) { -#if MACH64_EXTRA_CHECKING - int i; + if (ret < 0) + return NULL; - for (i = head; i != tail; - i = (i + 4) & ring->tail_mask) { - u32 o1 = - le32_to_cpu(((u32 *) ring-> - start)[i + 1]); - u32 o2 = GETBUFADDR(entry->buf); - - if (o1 == o2) { - DRM_ERROR - ("Attempting to free used buffer: " - "i=%d buf=0x%08x\n", - i, o1); - mach64_dump_ring_info - (dev_priv); - return NULL; - } - } -#endif - /* found a processed buffer */ - entry->buf->pending = 0; - list_del(ptr); - entry->buf->used = 0; - list_add_tail(ptr, - &dev_priv->placeholders); - DRM_DEBUG - ("%s: freed processed buffer (head=%d tail=%d " - "buf ring ofs=%d).\n", - __FUNCTION__, head, tail, ofs); - return entry->buf; - } - } DRM_UDELAY(1); } mach64_dump_ring_info(dev_priv); diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/mach64_drm.h drm-tst/linux-core/mach64_drm.h --- drm/linux-core/mach64_drm.h 2005-11-29 02:32:00.000000000 +0200 +++ drm-tst/linux-core/mach64_drm.h 2006-04-11 18:54:47.000000000 +0300 @@ -237,7 +237,7 @@ typedef struct drm_mach64_vertex { } drm_mach64_vertex_t; typedef struct drm_mach64_blit { - int idx; + void *buf; int pitch; int offset; int format; diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/mach64_drv.h drm-tst/linux-core/mach64_drv.h --- drm/linux-core/mach64_drv.h 2005-11-29 02:32:00.000000000 +0200 +++ drm-tst/linux-core/mach64_drv.h 2006-04-12 23:06:09.000000000 +0300 @@ -61,7 +61,6 @@ typedef struct drm_mach64_freelist { } drm_mach64_freelist_t; typedef struct drm_mach64_descriptor_ring { - drm_dma_handle_t *dmah; /* Handle to pci dma memory */ void *start; /* write pointer (cpu address) to start of descriptor ring */ u32 start_addr; /* bus address of beginning of descriptor ring */ int size; /* size of ring in bytes */ diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/mach64_state.c drm-tst/linux-core/mach64_state.c --- drm/linux-core/mach64_state.c 2006-03-13 01:48:55.000000000 +0200 +++ drm-tst/linux-core/mach64_state.c 2006-04-12 19:45:38.000000000 +0300 @@ -452,7 +452,8 @@ static int mach64_do_get_frames_queued(d head = ring->head; start = (MACH64_MAX_QUEUED_FRAMES - - DRM_MIN(MACH64_MAX_QUEUED_FRAMES, sarea_priv->frames_queued)); + DRM_MIN(MACH64_MAX_QUEUED_FRAMES, + (int)sarea_priv->frames_queued)); if (head == tail) { sarea_priv->frames_queued = 0; @@ -480,9 +481,9 @@ static int mach64_do_get_frames_queued(d /* Copy and verify a client submited buffer. * FIXME: Make an assembly optimized version */ -static __inline__ int copy_and_verify_from_user(u32 *to, - const u32 __user *ufrom, - unsigned long bytes) +static __inline__ int copy_from_user_vertex(u32 *to, + const u32 __user *ufrom, + unsigned long bytes) { unsigned long n = bytes; /* dwords remaining in buffer */ u32 *from, *orig_from; @@ -545,114 +546,138 @@ static __inline__ int copy_and_verify_fr } } +/* FIXME: move to mach64_dma.c */ +static __inline__ int mach64_freelist_put(drm_mach64_private_t * dev_priv, + drm_buf_t * copy_buf) +{ + struct list_head *ptr; + drm_mach64_freelist_t *entry; + +#if MACH64_EXTRA_CHECKING + list_for_each(ptr, &dev_priv->pending) { + entry = list_entry(ptr, drm_mach64_freelist_t, list); + if (copy_buf == entry->buf) { + DRM_ERROR("%s: Trying to release a pending buf\n", + __FUNCTION__); + return DRM_ERR(EFAULT); + } + } +#endif + ptr = dev_priv->placeholders.next; + entry = list_entry(ptr, drm_mach64_freelist_t, list); + copy_buf->pending = 0; + copy_buf->used = 0; + entry->buf = copy_buf; + entry->discard = 1; + list_del(ptr); + list_add_tail(ptr, &dev_priv->free_list); + + return 0; +} + static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, - int prim, void *buf, unsigned long used, - int discard) + drm_mach64_vertex_t * vertex) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_buf_t *copy_buf; - int done = 0; + void *buf = vertex->buf; + unsigned long used = vertex->used; int verify_ret = 0; + int ret = 0; + int i = 0; + int done = 0; DMALOCALS; DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n", __FUNCTION__, buf, used, sarea_priv->nbox); - if (used) { - int ret = 0; - int i = 0; - - copy_buf = mach64_freelist_get(dev_priv); - if (copy_buf == NULL) { - DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", - __FUNCTION__); - return DRM_ERR(EAGAIN); - } + if (!used) + goto _vertex_done; - if ((verify_ret = - copy_and_verify_from_user(GETBUFPTR(copy_buf), buf, - used)) == 0) { - - copy_buf->used = used; - - DMASETPTR(copy_buf); - - if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) { - ret = mach64_emit_state(filp, dev_priv); - if (ret < 0) - return ret; - } + copy_buf = mach64_freelist_get(dev_priv); + if (copy_buf == NULL) { + DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__); + return DRM_ERR(EAGAIN); + } - do { - /* Emit the next cliprect */ - if (i < sarea_priv->nbox) { - ret = - mach64_emit_cliprect(filp, dev_priv, - &sarea_priv-> - boxes[i]); - if (ret < 0) { - /* failed to get buffer */ - return ret; - } else if (ret != 0) { - /* null intersection with scissor */ - continue; - } - } - if ((i >= sarea_priv->nbox - 1)) - done = 1; + verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used); - /* Add the buffer to the DMA queue */ - DMAADVANCE(dev_priv, done); + if (verify_ret != 0) { + mach64_freelist_put(dev_priv, copy_buf); + goto _vertex_done; + } + + copy_buf->used = used; - } while (++i < sarea_priv->nbox); + DMASETPTR(copy_buf); + + if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) { + ret = mach64_emit_state(filp, dev_priv); + if (ret < 0) + return ret; + } + + do { + /* Emit the next cliprect */ + if (i < sarea_priv->nbox) { + ret = mach64_emit_cliprect(filp, dev_priv, + &sarea_priv->boxes[i]); + if (ret < 0) { + /* failed to get buffer */ + return ret; + } else if (ret != 0) { + /* null intersection with scissor */ + continue; + } } + if ((i >= sarea_priv->nbox - 1)) + done = 1; + + /* Add the buffer to the DMA queue */ + DMAADVANCE(dev_priv, done); - if (copy_buf->pending && !done) { + } while (++i < sarea_priv->nbox); + + if (!done) { + if (copy_buf->pending) { DMADISCARDBUF(); - } else if (!done) { - /* This buffer wasn't used (no cliprects or verify failed), so place it back - * on the free list + } else { + /* This buffer wasn't used (no cliprects), so place it + * back on the free list */ - struct list_head *ptr; - drm_mach64_freelist_t *entry; -#if MACH64_EXTRA_CHECKING - list_for_each(ptr, &dev_priv->pending) { - entry = - list_entry(ptr, drm_mach64_freelist_t, - list); - if (copy_buf == entry->buf) { - DRM_ERROR - ("%s: Trying to release a pending buf\n", - __FUNCTION__); - return DRM_ERR(EFAULT); - } - } -#endif - ptr = dev_priv->placeholders.next; - entry = list_entry(ptr, drm_mach64_freelist_t, list); - copy_buf->pending = 0; - copy_buf->used = 0; - entry->buf = copy_buf; - entry->discard = 1; - list_del(ptr); - list_add_tail(ptr, &dev_priv->free_list); + mach64_freelist_put(dev_priv, copy_buf); } } +_vertex_done: sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; return verify_ret; } +static __inline__ int copy_from_user_blit(u32 *to, + const u32 __user *ufrom, + unsigned long bytes) +{ + to = (u32 *)((char *)to + MACH64_HOSTDATA_BLIT_OFFSET); + + if (DRM_COPY_FROM_USER(to, ufrom, bytes)) { + return DRM_ERR(EFAULT); + } + + return 0; +} + static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev, drm_mach64_blit_t * blit) { drm_mach64_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; + drm_buf_t *copy_buf; + unsigned long used; int dword_shift, dwords; - drm_buf_t *buf; + int verify_ret = 0; DMALOCALS; /* The compiler won't optimize away a division by a variable, @@ -679,34 +704,34 @@ static int mach64_dma_dispatch_blit(DRMF return DRM_ERR(EINVAL); } - /* Dispatch the blit buffer. - */ - buf = dma->buflist[blit->idx]; - - if (buf->filp != filp) { - DRM_ERROR("process %d (filp %p) using buffer with filp %p\n", - DRM_CURRENTPID, filp, buf->filp); - return DRM_ERR(EINVAL); - } - - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", blit->idx); - return DRM_ERR(EINVAL); - } - /* Set buf->used to the bytes of blit data based on the blit dimensions * and verify the size. When the setup is emitted to the buffer with * the DMA* macros below, buf->used is incremented to include the bytes * used for setup as well as the blit data. */ dwords = (blit->width * blit->height) >> dword_shift; - buf->used = dwords << 2; - if (buf->used <= 0 || - buf->used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) { - DRM_ERROR("Invalid blit size: %d bytes\n", buf->used); + used = dwords << 2; + if (used <= 0 || + used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) { + DRM_ERROR("Invalid blit size: %lu bytes\n", used); return DRM_ERR(EINVAL); } + copy_buf = mach64_freelist_get(dev_priv); + if (copy_buf == NULL) { + DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__); + return DRM_ERR(EAGAIN); + } + + verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used); + + if (verify_ret != 0) { + mach64_freelist_put(dev_priv, copy_buf); + goto _blit_done; + } + + copy_buf->used = used; + /* FIXME: Use a last buffer flag and reduce the state emitted for subsequent, * continuation buffers? */ @@ -715,7 +740,7 @@ static int mach64_dma_dispatch_blit(DRMF * a register command every 16 dwords. State setup is added at the start of the * buffer -- the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET */ - DMASETPTR(buf); + DMASETPTR(copy_buf); DMAOUTREG(MACH64_Z_CNTL, 0); DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); @@ -745,12 +770,13 @@ static int mach64_dma_dispatch_blit(DRMF DMAOUTREG(MACH64_DST_X_Y, (blit->y << 16) | blit->x); DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (blit->height << 16) | blit->width); - DRM_DEBUG("%s: %d bytes\n", __FUNCTION__, buf->used); + DRM_DEBUG("%s: %lu bytes\n", __FUNCTION__, used); /* Add the buffer to the queue */ DMAADVANCEHOSTDATA(dev_priv); - return 0; +_blit_done: + return verify_ret; } /* ================================================================ @@ -842,14 +868,12 @@ int mach64_dma_vertex(DRM_IOCTL_ARGS) if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - return mach64_dma_dispatch_vertex(filp, dev, vertex.prim, vertex.buf, - vertex.used, vertex.discard); + return mach64_dma_dispatch_vertex(filp, dev, &vertex); } int mach64_dma_blit(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_blit_t blit; @@ -860,15 +884,6 @@ int mach64_dma_blit(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(blit, (drm_mach64_blit_t *) data, sizeof(blit)); - DRM_DEBUG("%s: pid=%d index=%d\n", - __FUNCTION__, DRM_CURRENTPID, blit.idx); - - if (blit.idx < 0 || blit.idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - blit.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); - } - ret = mach64_dma_dispatch_blit(filp, dev, &blit); /* Make sure we restore the 3D state next time.