aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Kuehling <fxkuehl@gmx.de>2005-01-01 20:03:15 +0000
committerFelix Kuehling <fxkuehl@gmx.de>2005-01-01 20:03:15 +0000
commited165a25292740d5d3ef7e78dc04a6a3402562aa (patch)
tree28545324112665f06e11a8f1ae5d786b1672595e
parentfe4ade81bb7a1242b18b84e012c1a293eea0420b (diff)
Added a new DRM map type _DRM_CONSISTENT for consistent PCI memory. It uses
drm_pci_alloc/free for allocating/freeing the memory. Only implemented in the Linux DRM so far.
-rw-r--r--libdrm/xf86drm.h3
-rw-r--r--linux-core/drm_bufs.c19
-rw-r--r--linux-core/drm_drv.c5
-rw-r--r--linux-core/drm_pci.c1
-rw-r--r--linux-core/drm_proc.c8
-rw-r--r--linux-core/drm_vm.c7
-rw-r--r--shared-core/drm.h3
7 files changed, 38 insertions, 8 deletions
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index b44e4281..b33d525e 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -104,7 +104,8 @@ typedef enum {
DRM_REGISTERS = 1, /**< no caching, no core dump */
DRM_SHM = 2, /**< shared, cached */
DRM_AGP = 3, /**< AGP/GART */
- DRM_SCATTER_GATHER = 4 /**< PCI scatter/gather */
+ DRM_SCATTER_GATHER = 4, /**< PCI scatter/gather */
+ DRM_CONSISTENT = 5 /**< PCI consistent */
} drmMapType;
typedef enum {
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index 947042bf..ce51397a 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -244,7 +244,21 @@ 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 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) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -ENOMEM;
+ }
+ break;
+ }
default:
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
@@ -348,6 +362,9 @@ int drm_rmmap(struct inode *inode, struct file *filp,
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->size, map->handle, map->offset);
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index fbebe23c..c720f94b 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -227,6 +227,10 @@ int drm_takedown(drm_device_t * dev)
dev->sg = NULL;
}
break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->size,
+ map->handle, map->offset);
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
@@ -396,6 +400,7 @@ static void __exit drm_cleanup(drm_device_t * dev)
case _DRM_SHM:
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
+ case _DRM_CONSISTENT:
DRM_DEBUG("Extra maplist item\n");
break;
}
diff --git a/linux-core/drm_pci.c b/linux-core/drm_pci.c
index 1ed0783a..30e1ba8d 100644
--- a/linux-core/drm_pci.c
+++ b/linux-core/drm_pci.c
@@ -6,7 +6,6 @@
* \warning These interfaces aren't stable yet.
*
* \todo Implement the remaining ioctl's for the PCI pools.
- * \todo Add support to map these buffers.
* \todo The wrappers here are so thin that they would be better off inlined..
*
* \author Jose Fonseca <jrfonseca@tungstengraphics.com>
diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c
index 5a92fb30..b385df5f 100644
--- a/linux-core/drm_proc.c
+++ b/linux-core/drm_proc.c
@@ -211,9 +211,9 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
struct list_head *list;
/* Hardcoded from _DRM_FRAME_BUFFER,
- _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
- _DRM_SCATTER_GATHER. */
- const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+ _DRM_REGISTERS, _DRM_SHM, _DRM_AGP,
+ _DRM_SCATTER_GATHER, and _DRM_CONSISTENT. */
+ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
const char *type;
int i;
@@ -234,7 +234,7 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
map = r_list->map;
if (!map)
continue;
- if (map->type < 0 || map->type > 4)
+ if (map->type < 0 || map->type > 5)
type = "??";
else
type = types[map->type];
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index 9b49efdc..3372498b 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -232,6 +232,10 @@ void drm_vm_shm_close(struct vm_area_struct *vma)
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->size, map->handle,
+ map->offset);
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
@@ -658,6 +662,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
+ case _DRM_CONSISTENT:
+ /* Consistent memory is really like shared memory. It's only
+ * allocated in a different way. */
vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map;
/* Don't let this area swap. Change when
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 0d907629..f223542e 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -246,7 +246,8 @@ typedef enum drm_map_type {
_DRM_REGISTERS = 1, /**< no caching, no core dump */
_DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */
- _DRM_SCATTER_GATHER = 4 /**< Scatter/gather memory for PCI DMA */
+ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
+ _DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */
} drm_map_type_t;
/**