summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2005-04-26 05:19:11 +0000
committerEric Anholt <anholt@freebsd.org>2005-04-26 05:19:11 +0000
commitec111d70fee0647c4c68a02c723d4a3729c93b56 (patch)
tree114a3257310a979d3dea484af62322ba007bf1e0 /linux-core
parent31a06d0baca9e378a773ca8bd350860546dd8a79 (diff)
Convert BSD code to mostly use bus_dma, the dma abstraction for dealing
with IOMMUs and such. There is one usage of the forbidden vtophys() left in drm_scatter.c which will be fixed up soon. This required a KPI change for drm_pci_alloc/free() to return/use a drm_dma_handle_t that keeps track of os-specific bits, rather than just passing around the vaddr/busaddr/size. Submitted by: Tonnerre Lombard (partially) Tested on: FreeBSD: Rage128 AGP/PCI Linux: Savage4 AGP/PCI
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drmP.h14
-rw-r--r--linux-core/drm_bufs.c17
-rw-r--r--linux-core/drm_drv.c8
-rw-r--r--linux-core/drm_pci.c34
-rw-r--r--linux-core/drm_vm.c8
5 files changed, 53 insertions, 28 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index cdf7e76f..b7f4640f 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -482,6 +482,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
*/
@@ -959,11 +965,9 @@ extern int drm_ati_pcigart_init(drm_device_t * dev,
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);
/* sysfs support (drm_sysfs.c) */
struct drm_sysfs_class;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index 6339ac21..5f1336ff 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -130,6 +130,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 */
@@ -261,14 +262,13 @@ int drm_addmap(struct inode *inode, struct file *filp,
* 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;
break;
}
default:
@@ -364,6 +364,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:
@@ -375,7 +377,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/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 42ca3c3b..069ecd3e 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -207,6 +207,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:
@@ -230,8 +232,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/linux-core/drm_pci.c b/linux-core/drm_pci.c
index 30e1ba8d..f8f221cd 100644
--- a/linux-core/drm_pci.c
+++ b/linux-core/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 0
unsigned long addr;
size_t sz;
@@ -78,13 +78,18 @@ 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->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;
}
@@ -94,22 +99,24 @@ 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);
#if 0
/* XXX - Is virt_to_page() legal for consistent mem? */
/* Reserve */
- for (addr = (unsigned long)address, sz = size;
+ for (addr = (unsigned long)dmah->vaddr, sz = size;
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
SetPageReserved(virt_to_page(addr));
}
#endif
- return address;
+ return dmah;
}
EXPORT_SYMBOL(drm_pci_alloc);
@@ -117,7 +124,7 @@ EXPORT_SYMBOL(drm_pci_alloc);
* \brief Free a PCI consistent memory block.
*/
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 0
unsigned long addr;
@@ -129,7 +136,7 @@ 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
@@ -137,12 +144,13 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
#if 0
/* XXX - Is virt_to_page() legal for consistent mem? */
/* Unreserve */
- for (addr = (unsigned long)vaddr, sz = size;
+ for (addr = (unsigned long)dmah->vaddr, sz = size;
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
}
#endif
- pci_free_consistent(dev->pdev, size, vaddr, busaddr);
+ pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr,
+ dmah->busaddr);
}
#if DRM_DEBUG_MEMORY
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index 02520c76..bb982b80 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -218,6 +218,8 @@ 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:
@@ -237,8 +239,10 @@ 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);