drm: add _DRM_CONSISTENT map type

Added a new DRM map type _DRM_CONSISTENT for consistent PCI memory. It
uses drm_pci_alloc/free for allocating/freeing the memory.

From: Felix Kuhling <fxkuehl@gmx.de>
Signed-off-by: David Airlie <airlied@linux.ie>
This commit is contained in:
Dave Airlie 2005-07-10 14:34:13 +10:00 committed by Dave Airlie
parent f179bc77d0
commit 2d0f9eaff8
5 changed files with 40 additions and 7 deletions

View File

@ -209,7 +209,8 @@ typedef enum drm_map_type {
_DRM_REGISTERS = 1, /**< no caching, no core dump */ _DRM_REGISTERS = 1, /**< no caching, no core dump */
_DRM_SHM = 2, /**< shared, cached */ _DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */ _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; } drm_map_type_t;

View File

@ -180,7 +180,22 @@ int drm_addmap( struct inode *inode, struct file *filp,
} }
map->offset += dev->sg->handle; map->offset += dev->sg->handle;
break; 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),
* 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: default:
drm_free( map, sizeof(*map), DRM_MEM_MAPS ); drm_free( map, sizeof(*map), DRM_MEM_MAPS );
return -EINVAL; return -EINVAL;
@ -291,6 +306,9 @@ int drm_rmmap(struct inode *inode, struct file *filp,
case _DRM_AGP: case _DRM_AGP:
case _DRM_SCATTER_GATHER: case _DRM_SCATTER_GATHER:
break; break;
case _DRM_CONSISTENT:
drm_pci_free(dev, map->size, map->handle, map->offset);
break;
} }
drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(map, sizeof(*map), DRM_MEM_MAPS);
} }

View File

@ -228,6 +228,10 @@ int drm_takedown( drm_device_t *dev )
dev->sg = NULL; dev->sg = NULL;
} }
break; break;
case _DRM_CONSISTENT:
drm_pci_free(dev, map->size,
map->handle, map->offset);
break;
} }
drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(map, sizeof(*map), DRM_MEM_MAPS);
} }

View File

@ -210,8 +210,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
/* Hardcoded from _DRM_FRAME_BUFFER, /* Hardcoded from _DRM_FRAME_BUFFER,
_DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
_DRM_SCATTER_GATHER. */ _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" }; const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
const char *type; const char *type;
int i; int i;
@ -229,9 +229,12 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) { if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head); r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map; map = r_list->map;
if(!map) continue; if(!map)
if (map->type < 0 || map->type > 4) type = "??"; continue;
else type = types[map->type]; if (map->type < 0 || map->type > 5)
type = "??";
else
type = types[map->type];
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i, i,
map->offset, map->offset,

View File

@ -228,6 +228,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
case _DRM_AGP: case _DRM_AGP:
case _DRM_SCATTER_GATHER: case _DRM_SCATTER_GATHER:
break; break;
case _DRM_CONSISTENT:
drm_pci_free(dev, map->size, map->handle,
map->offset);
break;
} }
drm_free(map, sizeof(*map), DRM_MEM_MAPS); drm_free(map, sizeof(*map), DRM_MEM_MAPS);
} }
@ -645,6 +649,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_ops; vma->vm_ops = &drm_vm_ops;
break; break;
case _DRM_SHM: case _DRM_SHM:
case _DRM_CONSISTENT:
/* Consistent memory is really like shared memory. It's only
* allocate in a different way */
vma->vm_ops = &drm_vm_shm_ops; vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map; vma->vm_private_data = (void *)map;
/* Don't let this area swap. Change when /* Don't let this area swap. Change when