Bug 6242: [mach64] Use private DMA buffers, part #2.
authorGeorge Sapountzis <gsap7@yahoo.gr>
Mon, 28 Aug 2006 02:44:37 +0000 (05:44 +0300)
committerGeorge Sapountzis <gsap7@yahoo.gr>
Mon, 2 Oct 2006 19:47:19 +0000 (22:47 +0300)
Factor out from mach64_dma_dispatch_vertex() the code to reclaim an unsed
buffer, in preperation for using it in mach64_dma_dispatch_blit() also.

shared-core/mach64_dma.c
shared-core/mach64_drv.h
shared-core/mach64_state.c

index 3f4394c..7cba8ad 100644 (file)
@@ -1449,6 +1449,33 @@ drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv)
        return entry->buf;
 }
 
+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;
+}
+
 /*@}*/
 
 
index 2a5f2ff..e8dc71e 100644 (file)
@@ -123,6 +123,8 @@ extern void mach64_driver_lastclose(drm_device_t * dev);
 extern int mach64_init_freelist(drm_device_t * dev);
 extern void mach64_destroy_freelist(drm_device_t * dev);
 extern drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv);
+extern int mach64_freelist_put(drm_mach64_private_t * dev_priv,
+                              drm_buf_t * copy_buf);
 
 extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv,
                                   int entries);
index ce44f0d..31e3b56 100644 (file)
@@ -546,12 +546,15 @@ static __inline__ int copy_and_verify_from_user(u32 *to,
 }
 
 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;
+       void *buf = vertex->buf;
+       unsigned long used = vertex->used;
+       int ret = 0;
+       int i = 0;
        int done = 0;
        int verify_ret = 0;
        DMALOCALS;
@@ -559,87 +562,65 @@ static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev,
        DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n",
                  __FUNCTION__, buf, used, sarea_priv->nbox);
 
-       if (used) {
-               int ret = 0;
-               int i = 0;
+       if (!used)
+               goto _vertex_done;
 
-               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);
-               }
+       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_and_verify_from_user(GETBUFPTR(copy_buf), buf, used);
 
-               if ((verify_ret =
-                    copy_and_verify_from_user(GETBUFPTR(copy_buf), buf,
-                                              used)) == 0) {
+       if (verify_ret != 0) {
+               mach64_freelist_put(dev_priv, copy_buf);
+               goto _vertex_done;
+       }
 
-                       copy_buf->used = used;
+       copy_buf->used = used;
 
-                       DMASETPTR(copy_buf);
+       DMASETPTR(copy_buf);
 
-                       if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) {
-                               ret = mach64_emit_state(filp, dev_priv);
-                               if (ret < 0)
-                                       return ret;
-                       }
+       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);
-
-                       } while (++i < sarea_priv->nbox);
+       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);
+
+       } while (++i < sarea_priv->nbox);
 
-               if (copy_buf->pending && !done) {
+       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;
 
@@ -842,8 +823,7 @@ 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)