Common subdirectories: drm/linux-core/linux and drm-vtx/linux-core/linux diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/mach64_drm.h drm-vtx/linux-core/mach64_drm.h --- drm/linux-core/mach64_drm.h 2005-11-29 02:32:00.000000000 +0200 +++ drm-vtx/linux-core/mach64_drm.h 2006-03-13 01:37:19.000000000 +0200 @@ -231,7 +231,7 @@ typedef struct drm_mach64_clear { typedef struct drm_mach64_vertex { int prim; - void *buf; /* Address of vertex buffer */ + int idx; /* Index of vertex buffer */ unsigned long used; /* Number of bytes in buffer */ int discard; /* Client finished with buffer? */ } drm_mach64_vertex_t; diff -aup -x '.*' -x CVS -x '*.mod.c' -x '*.o' -x '*.ko' drm/linux-core/mach64_state.c drm-vtx/linux-core/mach64_state.c --- drm/linux-core/mach64_state.c 2006-03-13 01:48:55.000000000 +0200 +++ drm-vtx/linux-core/mach64_state.c 2006-03-13 02:55:01.000000000 +0200 @@ -546,37 +546,23 @@ static __inline__ int copy_and_verify_fr } static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, - int prim, void *buf, unsigned long used, - int discard) + drm_buf_t * buf, int prim, int discard) { 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; - int verify_ret = 0; + int dispatched = 0; DMALOCALS; - DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n", - __FUNCTION__, buf, used, sarea_priv->nbox); + DRM_DEBUG("%s: buf=%p used=%d nbox=%d\n", + __FUNCTION__, GETBUFPTR(buf), buf->used, sarea_priv->nbox); - if (used) { + if (buf->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 ((verify_ret = - copy_and_verify_from_user(GETBUFPTR(copy_buf), buf, - used)) == 0) { - - copy_buf->used = used; - - DMASETPTR(copy_buf); + /* FIXME: I dropped copy_and_verify_from_user() test. + * FIXME: Do we need to keep it to check register values ? + */ if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) { ret = mach64_emit_state(filp, dev_priv); @@ -584,6 +570,10 @@ static int mach64_dma_dispatch_vertex(DR return ret; } + /* nbox is either 0 or 1, the following block is executed + * exactly one time. It submits a cliprect only if nbox is 1. + * dri should always set discard to 1 because nbox <= 1. + */ do { /* Emit the next cliprect */ if (i < sarea_priv->nbox) { @@ -599,18 +589,28 @@ static int mach64_dma_dispatch_vertex(DR continue; } } - if ((i >= sarea_priv->nbox - 1)) - done = 1; + +#if 0 + DRM_INFO("idx=%3d used=%5d discard=%d nbox=%d i=%d\n", + buf->idx, buf->used, discard, sarea_priv->nbox, i); +#endif + DMASETPTR(buf); + /* Add the buffer to the DMA queue */ - DMAADVANCE(dev_priv, done); - + DMAADVANCE(dev_priv, discard); + + dispatched = 1; + } while (++i < sarea_priv->nbox); - } + } + + if (!dispatched && discard) { + if (buf->pending) { + DMASETPTR(buf); - if (copy_buf->pending && !done) { DMADISCARDBUF(); - } else if (!done) { + } else { /* This buffer wasn't used (no cliprects or verify failed), so place it back * on the free list */ @@ -631,9 +631,9 @@ static int mach64_dma_dispatch_vertex(DR #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; + buf->pending = 0; + buf->used = 0; + entry->buf = buf; entry->discard = 1; list_del(ptr); list_add_tail(ptr, &dev_priv->free_list); @@ -643,7 +643,7 @@ static int mach64_dma_dispatch_vertex(DR sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; - return verify_ret; + return 0; } static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev, @@ -811,6 +811,8 @@ int mach64_dma_vertex(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_vertex_t vertex; @@ -824,10 +826,15 @@ int mach64_dma_vertex(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(vertex, (drm_mach64_vertex_t *) data, sizeof(vertex)); - DRM_DEBUG("%s: pid=%d buf=%p used=%lu discard=%d\n", + DRM_DEBUG("%s: pid=%d index=%d used=%lu discard=%d\n", __FUNCTION__, DRM_CURRENTPID, - vertex.buf, vertex.used, vertex.discard); + vertex.idx, vertex.used, vertex.discard); + if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + DRM_ERROR("buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1); + return DRM_ERR(EINVAL); + } if (vertex.prim < 0 || vertex.prim > MACH64_PRIM_POLYGON) { DRM_ERROR("buffer prim %d\n", vertex.prim); return DRM_ERR(EINVAL); @@ -839,11 +846,29 @@ int mach64_dma_vertex(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } + buf = dma->buflist[vertex.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 0 + /* FIXME: vertex buffers can be reused, are they ? */ + if (buf->pending) { + DRM_ERROR("sending pending buffer %d\n", buf->idx); + return DRM_ERR(EINVAL); + } +#endif + 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); + buf->used = vertex.used; + + return mach64_dma_dispatch_vertex(filp, dev, buf, vertex.prim, + vertex.discard); } int mach64_dma_blit(DRM_IOCTL_ARGS)