drm: update support for drm pci buffers
Dave Airlie [Sun, 10 Jul 2005 05:38:56 +0000 (15:38 +1000)]
The DRM needs to change the drm_pci interface for FreeBSD compatiblity,
this patch introduces the drm_dma_handle_t and uses it in the Linux code.

From: Tonnerre Lombard, Eric Anholt, and Sergey Vlasov
Signed-off-by: David Airlie <airlied@linux.ie>

drivers/char/drm/drmP.h
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_drv.c
drivers/char/drm/drm_pci.c
drivers/char/drm/drm_vm.c
drivers/char/drm/i915_dma.c
drivers/char/drm/i915_drv.h

index 804e622..7e633a9 100644 (file)
@@ -527,6 +527,12 @@ typedef struct drm_sigdata {
        drm_hw_lock_t *lock;
 } drm_sigdata_t;
 
+typedef struct drm_dma_handle {
+       dma_addr_t busaddr;
+       void *vaddr;
+       size_t size;
+} drm_dma_handle_t;
+
 /**
  * Mappings list
  */
@@ -978,12 +984,10 @@ extern int            drm_ati_pcigart_cleanup(drm_device_t *dev,
                                               unsigned long addr,
                                               dma_addr_t bus_addr);
 
-extern void *drm_pci_alloc(drm_device_t * dev, size_t size,
-                          size_t align, dma_addr_t maxaddr,
-                          dma_addr_t * busaddr);
-
-extern void drm_pci_free(drm_device_t * dev, size_t size,
-                        void *vaddr, dma_addr_t busaddr);
+extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
+                                      size_t align, dma_addr_t maxaddr);
+extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
+extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
 
                               /* sysfs support (drm_sysfs.c) */
 struct drm_sysfs_class;
index eb3cf55..be54efb 100644 (file)
@@ -90,6 +90,7 @@ int drm_addmap( struct inode *inode, struct file *filp,
        drm_map_t *map;
        drm_map_t __user *argp = (void __user *)arg;
        drm_map_list_t *list;
+       drm_dma_handle_t *dmah;
 
        if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
 
@@ -181,21 +182,19 @@ int drm_addmap( struct inode *inode, struct file *filp,
                map->offset += dev->sg->handle;
                break;
        case _DRM_CONSISTENT: 
-       {
                /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
-                * As we're limit the address to 2^32-1 (or lses),
+                * As we're limiting the address to 2^32-1 (or less),
                 * casting it down to 32 bits is no problem, but we
                 * need to point to a 64bit variable first. */
-               dma_addr_t bus_addr;
-               map->handle = drm_pci_alloc(dev, map->size, map->size,
-                                           0xffffffffUL, &bus_addr);
-               map->offset = (unsigned long)bus_addr;
-               if (!map->handle) {
+               dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
+               if (!dmah) {
                        drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                        return -ENOMEM;
                }
+               map->handle = dmah->vaddr;
+               map->offset = (unsigned long)dmah->busaddr;
+               kfree(dmah);
                break;
-       }
        default:
                drm_free( map, sizeof(*map), DRM_MEM_MAPS );
                return -EINVAL;
@@ -286,6 +285,8 @@ int drm_rmmap(struct inode *inode, struct file *filp,
        }
 
        if(!found_maps) {
+               drm_dma_handle_t dmah;
+
                switch (map->type) {
                case _DRM_REGISTERS:
                case _DRM_FRAME_BUFFER:
@@ -307,7 +308,10 @@ int drm_rmmap(struct inode *inode, struct file *filp,
                case _DRM_SCATTER_GATHER:
                        break;
                case _DRM_CONSISTENT:
-                       drm_pci_free(dev, map->size, map->handle, map->offset);
+                       dmah.vaddr = map->handle;
+                       dmah.busaddr = map->offset;
+                       dmah.size = map->size;
+                       __drm_pci_free(dev, &dmah);
                        break;
                }
                drm_free(map, sizeof(*map), DRM_MEM_MAPS);
index f4046c8..ab172ea 100644 (file)
@@ -198,6 +198,8 @@ int drm_takedown( drm_device_t *dev )
                        r_list = (drm_map_list_t *)list;
 
                        if ( ( map = r_list->map ) ) {
+                               drm_dma_handle_t dmah;
+
                                switch ( map->type ) {
                                case _DRM_REGISTERS:
                                case _DRM_FRAME_BUFFER:
@@ -229,8 +231,10 @@ int drm_takedown( drm_device_t *dev )
                                        }
                                        break;
                                case _DRM_CONSISTENT:
-                                       drm_pci_free(dev, map->size,
-                                                    map->handle, map->offset);
+                                       dmah.vaddr = map->handle;
+                                       dmah.busaddr = map->offset;
+                                       dmah.size = map->size;
+                                       __drm_pci_free(dev, &dmah);
                                        break;
                                }
                                drm_free(map, sizeof(*map), DRM_MEM_MAPS);
index 192e876..3e452e8 100644 (file)
 /**
  * \brief Allocate a PCI consistent memory block, for DMA.
  */
-void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
-                   dma_addr_t maxaddr, dma_addr_t * busaddr)
+drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
+                               dma_addr_t maxaddr)
 {
-       void *address;
+       drm_dma_handle_t *dmah;
 #if DRM_DEBUG_MEMORY
        int area = DRM_MEM_DMA;
 
@@ -74,13 +74,19 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
                return NULL;
        }
 
-       address = pci_alloc_consistent(dev->pdev, size, busaddr);
+       dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
+       if (!dmah)
+               return NULL;
+       
+       dmah->size = size;
+       dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
 
 #if DRM_DEBUG_MEMORY
-       if (address == NULL) {
+       if (dmah->vaddr == NULL) {
                spin_lock(&drm_mem_lock);
                ++drm_mem_stats[area].fail_count;
                spin_unlock(&drm_mem_lock);
+               kfree(dmah);
                return NULL;
        }
 
@@ -90,21 +96,25 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
        drm_ram_used += size;
        spin_unlock(&drm_mem_lock);
 #else
-       if (address == NULL)
+       if (dmah->vaddr == NULL) {
+               kfree(dmah);
                return NULL;
+       }
 #endif
 
-       memset(address, 0, size);
+       memset(dmah->vaddr, 0, size);
 
-       return address;
+       return dmah;
 }
 EXPORT_SYMBOL(drm_pci_alloc);
 
 /**
- * \brief Free a PCI consistent memory block.
+ * \brief Free a PCI consistent memory block with freeing its descriptor.
+ *
+ * This function is for internal use in the Linux-specific DRM core code.
  */
 void
-drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
+__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
 {
 #if DRM_DEBUG_MEMORY
        int area = DRM_MEM_DMA;
@@ -112,12 +122,13 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
        int free_count;
 #endif
 
-       if (!vaddr) {
+       if (!dmah->vaddr) {
 #if DRM_DEBUG_MEMORY
                DRM_MEM_ERROR(area, "Attempt to free address 0\n");
 #endif
        } else {
-               pci_free_consistent(dev->pdev, size, vaddr, busaddr);
+               pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr,
+                                   dmah->busaddr);
        }
 
 #if DRM_DEBUG_MEMORY
@@ -135,6 +146,16 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
 #endif
 
 }
+
+/**
+ * \brief Free a PCI consistent memory block
+ */
+void
+drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
+{
+       __drm_pci_free(dev, dmah);
+       kfree(dmah);
+}
 EXPORT_SYMBOL(drm_pci_free);
 
 /*@}*/
index 644ec9d..675d239 100644 (file)
@@ -210,6 +210,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
                }
 
                if(!found_maps) {
+                       drm_dma_handle_t dmah;
+
                        switch (map->type) {
                        case _DRM_REGISTERS:
                        case _DRM_FRAME_BUFFER:
@@ -229,8 +231,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
                        case _DRM_SCATTER_GATHER:
                                break;
                        case _DRM_CONSISTENT:
-                               drm_pci_free(dev, map->size, map->handle,
-                                            map->offset);
+                               dmah.vaddr = map->handle;
+                               dmah.busaddr = map->offset;
+                               dmah.size = map->size;
+                               __drm_pci_free(dev, &dmah);
                                break;
                        }
                        drm_free(map, sizeof(*map), DRM_MEM_MAPS);
index acf9e52..759f229 100644 (file)
@@ -95,9 +95,8 @@ static int i915_dma_cleanup(drm_device_t * dev)
                        drm_core_ioremapfree( &dev_priv->ring.map, dev);
                }
 
-               if (dev_priv->hw_status_page) {
-                       drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page,
-                                    dev_priv->dma_status_page);
+               if (dev_priv->status_page_dmah) {
+                       drm_pci_free(dev, dev_priv->status_page_dmah);
                        /* Need to rewrite hardware status page */
                        I915_WRITE(0x02080, 0x1ffff000);
                }
@@ -174,16 +173,18 @@ static int i915_initialize(drm_device_t * dev,
        dev_priv->allow_batchbuffer = 1;
 
        /* Program Hardware Status Page */
-       dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
-                                                0xffffffff, 
-                                                &dev_priv->dma_status_page);
+       dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
+                                                  0xffffffff);
 
-       if (!dev_priv->hw_status_page) {
+       if (!dev_priv->status_page_dmah) {
                dev->dev_private = (void *)dev_priv;
                i915_dma_cleanup(dev);
                DRM_ERROR("Can not allocate hardware status page\n");
                return DRM_ERR(ENOMEM);
        }
+       dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+       dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
+
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
        DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
 
index 9c37d23..9308086 100644 (file)
@@ -79,9 +79,10 @@ typedef struct drm_i915_private {
        drm_i915_sarea_t *sarea_priv;
        drm_i915_ring_buffer_t ring;
 
+       drm_dma_handle_t *status_page_dmah;
        void *hw_status_page;
-       unsigned long counter;
        dma_addr_t dma_status_page;
+       unsigned long counter;
 
        int back_offset;
        int front_offset;