Please apply this to the DRI codebase.  Also forwarding it to 
XFree86.


-- 
Mike A. Harris                  Shipping/mailing address:
OS Systems Engineer             190 Pittsburgh Ave., Sault Ste. Marie,
XFree86 maintainer              Ontario, Canada, P6C 5B3
Red Hat Inc.
http://www.redhat.com           ftp://people.redhat.com/mharris

---------- Forwarded message ----------
Date: Tue, 9 Jul 2002 09:02:48 -0400
From: Arjan van de Ven <[EMAIL PROTECTED]>
To: Mike A. Harris <[EMAIL PROTECTED]>
Content-Type: text/plain; charset=us-ascii
Subject: DRM patch for i810/i830 memory allocation

Hi,

The patch below makes the i810 and i830 drm kernel
module use the PCI DMA mapping API instead of an
ad-hoc allocator for allocating the page that is used
to communicate between driver and card. The ad-hoc allocator doesn't
actually work well in practice (I get quite a few bugreports about it) and
the PCI DMA API should be used regardless (it actually works cross-platform)

Greetings,
   Arjan van de Ven


diff -urN linux/drivers/char/drm.org/i810_dma.c linux/drivers/char/drm/i810_dma.c
--- linux/drivers/char/drm.org/i810_dma.c       Fri Jul  5 16:12:21 2002
+++ linux/drivers/char/drm/i810_dma.c   Fri Jul  5 17:15:08 2002
@@ -258,30 +258,6 @@
        return retcode;
 }
 
-static unsigned long i810_alloc_page(drm_device_t *dev)
-{
-       unsigned long address;
-
-       address = __get_free_page(GFP_KERNEL);
-       if(address == 0UL)
-               return 0;
-
-       get_page(virt_to_page(address));
-       LockPage(virt_to_page(address));
-
-       return address;
-}
-
-static void i810_free_page(drm_device_t *dev, unsigned long page)
-{
-       if (page) {
-               struct page *p = virt_to_page(page);
-               put_page(p);
-               UnlockPage(p);
-               free_page(page);
-       }
-}
-
 static int i810_dma_cleanup(drm_device_t *dev)
 {
        drm_device_dma_t *dma = dev->dma;
@@ -296,7 +272,8 @@
                                         dev_priv->ring.Size);
                }
                if(dev_priv->hw_status_page != 0UL) {
-                       i810_free_page(dev, dev_priv->hw_status_page);
+                       pci_free_consistent(dev->pdev, PAGE_SIZE, 
+dev_priv->hw_status_page,
+                               dev_priv->dma_status_page);
                        /* Need to rewrite hardware status page */
                        I810_WRITE(0x02080, 0x1ffff000);
                }
@@ -462,7 +439,8 @@
        dev_priv->zi1 = init->depth_offset | init->pitch_bits;
 
        /* Program Hardware Status Page */
-       dev_priv->hw_status_page = i810_alloc_page(dev);
+       dev_priv->hw_status_page = pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+                       &dev_priv->dma_status_page);
        if(dev_priv->hw_status_page == 0UL) {
                dev->dev_private = (void *)dev_priv;
                i810_dma_cleanup(dev);
@@ -472,7 +450,7 @@
        memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
        DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
 
-       I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+       I810_WRITE(0x02080, dev_priv->dma_status_page);
        DRM_DEBUG("Enabled hardware status page\n");
 
        /* Now we need to init our freelist */
diff -urN linux/drivers/char/drm.org/i810_drv.h linux/drivers/char/drm/i810_drv.h
--- linux/drivers/char/drm.org/i810_drv.h       Fri Jul  5 16:12:02 2002
+++ linux/drivers/char/drm/i810_drv.h   Fri Jul  5 17:10:41 2002
@@ -63,6 +63,7 @@
 
        unsigned long hw_status_page;
        unsigned long counter;
+       dma_addr_t dma_status_page;
 
        atomic_t flush_done;
        wait_queue_head_t flush_queue;  /* Processes waiting until flush    */
diff -u linux/drivers/char/drm.org/i830_dma.c linux/drivers/char/drm/i830_dma.c
--- linux/drivers/char/drm.org/i830_dma.c       Sat Jul  6 11:57:25 2002
+++ linux/drivers/char/drm/i830_dma.c   Sat Jul  6 15:18:14 2002
@@ -283,31 +283,6 @@
        return retcode;
 }
 
-static unsigned long i830_alloc_page(drm_device_t *dev)
-{
-       unsigned long address;
-   
-       address = __get_free_page(GFP_KERNEL);
-       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 i830_free_page(drm_device_t *dev, unsigned long addr)
-{
-       if (addr) {
-               struct page *page = virt_to_page(addr);
-
-               put_page(page);
-               UnlockPage(page);
-               free_page(addr);
-       }
-}
-
 static int i830_dma_cleanup(drm_device_t *dev)
 {
        drm_device_dma_t *dma = dev->dma;
@@ -322,7 +297,8 @@
                                         dev_priv->ring.Size);
                }
                if(dev_priv->hw_status_page != 0UL) {
-                       i830_free_page(dev, dev_priv->hw_status_page);
+                       pci_free_consistent(dev->pdev, PAGE_SIZE, 
+                           dev_priv->hw_status_page, dev_priv->dma_status_page);
                        /* Need to rewrite hardware status page */
                        I830_WRITE(0x02080, 0x1ffff000);
                }
@@ -496,7 +472,8 @@
        dev_priv->depth_pitch = init->depth_pitch;
 
        /* Program Hardware Status Page */
-       dev_priv->hw_status_page = i830_alloc_page(dev);
+       dev_priv->hw_status_page = pci_alloc_consistent(dev->pdev, PAGE_SIZE, 
+                                               &dev_priv->dma_status_page);
        if(dev_priv->hw_status_page == 0UL) {
                dev->dev_private = (void *)dev_priv;
                i830_dma_cleanup(dev);
@@ -506,7 +483,7 @@
        memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
        DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
    
-       I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+       I830_WRITE(0x02080, dev_priv->dma_status_page);
        DRM_DEBUG("Enabled hardware status page\n");
    
        /* Now we need to init our freelist */
diff -u linux/drivers/char/drm.org/i830_drv.h linux/drivers/char/drm/i830_drv.h
--- linux/drivers/char/drm.org/i830_drv.h       Sat Jul  6 11:57:17 2002
+++ linux/drivers/char/drm/i830_drv.h   Sat Jul  6 15:15:42 2002
@@ -63,6 +63,8 @@
 
        unsigned long hw_status_page;
        unsigned long counter;
+       
+       dma_addr_t dma_status_page;
 
        atomic_t flush_done;
        wait_queue_head_t flush_queue;  /* Processes waiting until flush    */



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Stuff, things, and much much more.
http://thinkgeek.com/sf
_______________________________________________
Dri-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to