summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/drm/drmP.h16
-rw-r--r--drivers/char/drm/drm_bufs.c22
-rw-r--r--drivers/char/drm/drm_drv.c8
-rw-r--r--drivers/char/drm/drm_pci.c45
-rw-r--r--drivers/char/drm/drm_vm.c8
-rw-r--r--drivers/char/drm/i915_dma.c15
-rw-r--r--drivers/char/drm/i915_drv.h3
7 files changed, 78 insertions, 39 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 804e622436a9..7e633a9ce933 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -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;
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index eb3cf550626d..be54efbefe84 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -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);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index f4046c8c70b5..ab172ea8e98a 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -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);
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index 192e8762571c..3e452e8967fa 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -46,10 +46,10 @@
/**
* \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);
/*@}*/
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 644ec9dadc05..675d2397def9 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -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);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index acf9e52a9507..759f22943eb1 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -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);
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 9c37d2367dd5..93080868d18f 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -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;