mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-25 01:20:11 +01:00
Initial merge with Gareth's templated drm code of big sareas and per client
sareas, untested and only mga/r128/radeon compile
This commit is contained in:
parent
f2f5bf6f5f
commit
68dc58a187
21 changed files with 707 additions and 254 deletions
|
|
@ -515,6 +515,16 @@ int drmAddMap(int fd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drmRmMap(int fd, drmHandle handle)
|
||||
{
|
||||
drm_map_t map;
|
||||
|
||||
map.handle = handle;
|
||||
|
||||
if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
|
||||
int agp_offset)
|
||||
{
|
||||
|
|
@ -1090,6 +1100,29 @@ void *drmGetContextTag(int fd, drmContext context)
|
|||
return value;
|
||||
}
|
||||
|
||||
int drmAddContextPrivateMapping(int fd, drmContext ctx_id, drmHandle handle)
|
||||
{
|
||||
drm_ctx_priv_map_t map;
|
||||
|
||||
map.ctx_id = ctx_id;
|
||||
map.handle = handle;
|
||||
|
||||
if(ioctl(fd, DRM_IOCTL_CTX_SAREA, &map)) return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle)
|
||||
{
|
||||
drm_ctx_priv_map_t map;
|
||||
|
||||
map.ctx_id = ctx_id;
|
||||
|
||||
if(ioctl(fd, DRM_IOCTL_GET_CTX_SAREA, &map)) return -errno;
|
||||
if(handle) *handle = map.handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(XFree86Server) || defined(DRM_USE_MALLOC)
|
||||
static void drmSIGIOHandler(int interrupt, void *closure)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -321,16 +321,19 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
DRM(ioremapfree)( (map)->handle, (map)->size ); \
|
||||
} while (0)
|
||||
|
||||
#define DRM_FIND_MAP(map, o) \
|
||||
do { \
|
||||
int i; \
|
||||
for ( i = 0 ; i < dev->map_count ; i++ ) { \
|
||||
if ( dev->maplist[i]->offset == o ) { \
|
||||
map = dev->maplist[i]; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define DRM_FIND_MAP(_map, _o) \
|
||||
do { \
|
||||
struct list_head *_list; \
|
||||
list_for_each(_list, &dev->maplist->head) { \
|
||||
drm_map_list_t *_r_list; \
|
||||
_r_list = (drm_map_list_t *)_list; \
|
||||
if(_r_list->map && \
|
||||
_r_list->map->offset == (_o)) { \
|
||||
(_map) = _r_list->map; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Internal types and structures */
|
||||
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
|
@ -341,6 +344,10 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
|
||||
#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
|
||||
|
||||
#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
|
||||
(_map) = (_dev)->context_sareas[_ctx]; \
|
||||
} while(0)
|
||||
|
||||
typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
|
|
@ -569,6 +576,11 @@ typedef struct drm_sigdata {
|
|||
drm_hw_lock_t *lock;
|
||||
} drm_sigdata_t;
|
||||
|
||||
typedef struct drm_map_list {
|
||||
struct list_head head;
|
||||
drm_map_t *map;
|
||||
} drm_map_list_t;
|
||||
|
||||
typedef struct drm_device {
|
||||
const char *name; /* Simple driver name */
|
||||
char *unique; /* Unique identifier: e.g., busid */
|
||||
|
|
@ -601,9 +613,12 @@ typedef struct drm_device {
|
|||
drm_magic_head_t magiclist[DRM_HASH_SIZE];
|
||||
|
||||
/* Memory management */
|
||||
drm_map_t **maplist; /* Vector of pointers to regions */
|
||||
drm_map_list_t *maplist; /* Linked list of regions */
|
||||
int map_count; /* Number of mappable regions */
|
||||
|
||||
drm_map_t **context_sareas;
|
||||
int max_context;
|
||||
|
||||
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
|
||||
drm_lock_data_t lock; /* Information on hardware lock */
|
||||
|
||||
|
|
@ -690,9 +705,6 @@ extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
|
|||
extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
|
@ -704,9 +716,6 @@ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
|
|||
extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
|
@ -824,14 +833,17 @@ extern int DRM(notifier)(void *priv);
|
|||
/* Context Bitmap support (ctxbitmap.c) */
|
||||
extern int DRM(ctxbitmap_init)( drm_device_t *dev );
|
||||
extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
|
||||
|
||||
|
||||
|
||||
extern int DRM(add_ctx_map)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(get_ctx_map)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
/* Buffer management support (bufs.c) */
|
||||
extern int DRM(order)( unsigned long size );
|
||||
extern int DRM(addmap)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(rmmap)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(addbufs)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(infobufs)( struct inode *inode, struct file *filp,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *list;
|
||||
|
||||
if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_MTRR
|
||||
#ifdef __REALLY_HAVE_MTRR
|
||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||
map->mtrr = mtrr_add( map->offset, map->size,
|
||||
|
|
@ -111,9 +112,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
break;
|
||||
|
||||
case _DRM_SHM:
|
||||
map->handle = (void *)DRM(alloc_pages)( DRM(order)( map->size )
|
||||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA );
|
||||
map->handle = vmalloc_32(map->size);
|
||||
DRM_DEBUG( "%ld %d %p\n",
|
||||
map->size, DRM(order)( map->size ), map->handle );
|
||||
if ( !map->handle ) {
|
||||
|
|
@ -135,22 +134,17 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
down( &dev->struct_sem );
|
||||
if ( dev->maplist ) {
|
||||
++dev->map_count;
|
||||
dev->maplist = DRM(realloc)( dev->maplist,
|
||||
(dev->map_count-1)
|
||||
* sizeof(*dev->maplist),
|
||||
dev->map_count
|
||||
* sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS );
|
||||
} else {
|
||||
dev->map_count = 1;
|
||||
dev->maplist = DRM(alloc)( dev->map_count*sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS );
|
||||
list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
|
||||
if(!list) {
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev->maplist[dev->map_count-1] = map;
|
||||
up( &dev->struct_sem );
|
||||
memset(list, 0, sizeof(*list));
|
||||
list->map = map;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list_add(&list->head, &dev->maplist->head);
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if ( copy_to_user( (drm_map_t *)arg, map, sizeof(*map) ) )
|
||||
return -EFAULT;
|
||||
|
|
@ -163,6 +157,70 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Remove a map private from list and deallocate resources */
|
||||
int DRM(rmmap)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
struct list_head *list;
|
||||
drm_map_list_t *r_list;
|
||||
|
||||
drm_map_t *map;
|
||||
drm_map_t request;
|
||||
|
||||
if (copy_from_user(&request, (drm_map_t *)arg,
|
||||
sizeof(request))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list = &dev->maplist->head;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *) list;
|
||||
|
||||
if(r_list->map &&
|
||||
r_list->map->handle == request.handle &&
|
||||
r_list->map->flags & _DRM_REMOVABLE) break;
|
||||
}
|
||||
|
||||
/* List has wrapped around to the head pointer, or its empty we didn't
|
||||
* find anything.
|
||||
*/
|
||||
if(list == (&dev->maplist->head)) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
map = r_list->map;
|
||||
list_del(list);
|
||||
up(&dev->struct_sem);
|
||||
|
||||
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
#ifdef __REALLY_HAVE_MTRR
|
||||
if (map->mtrr >= 0) {
|
||||
int retcode;
|
||||
retcode = mtrr_del(map->mtrr,
|
||||
map->offset,
|
||||
map->size);
|
||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
||||
}
|
||||
#endif
|
||||
DRM(ioremapfree)(map->handle, map->size);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
vfree(map->handle);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __HAVE_DMA
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
|
|
|
|||
|
|
@ -36,9 +36,13 @@
|
|||
void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
|
||||
{
|
||||
if ( ctx_handle < 0 ) goto failed;
|
||||
if ( !dev->ctx_bitmap ) goto failed;
|
||||
|
||||
if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
|
||||
down(&dev->struct_sem);
|
||||
clear_bit( ctx_handle, dev->ctx_bitmap );
|
||||
dev->context_sareas[ctx_handle] = NULL;
|
||||
up(&dev->struct_sem);
|
||||
return;
|
||||
}
|
||||
failed:
|
||||
|
|
@ -51,12 +55,37 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
|
|||
{
|
||||
int bit;
|
||||
|
||||
if(!dev->ctx_bitmap) return -1;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
|
||||
if ( bit < DRM_MAX_CTXBITMAP ) {
|
||||
set_bit( bit, dev->ctx_bitmap );
|
||||
DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
|
||||
if((bit+1) > dev->max_context) {
|
||||
dev->max_context = (bit+1);
|
||||
if(dev->context_sareas) {
|
||||
dev->context_sareas = DRM(realloc)(
|
||||
dev->context_sareas,
|
||||
(dev->max_context - 1) *
|
||||
sizeof(*dev->context_sareas),
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
} else {
|
||||
/* max_context == 1 at this point */
|
||||
dev->context_sareas = DRM(alloc)(
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
}
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
return bit;
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -65,12 +94,18 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
|
|||
int i;
|
||||
int temp;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
|
||||
DRM_MEM_CTXBITMAP );
|
||||
if ( dev->ctx_bitmap == NULL ) {
|
||||
up(&dev->struct_sem);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
|
||||
dev->context_sareas = NULL;
|
||||
dev->max_context = -1;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
|
||||
temp = DRM(ctxbitmap_next)( dev );
|
||||
DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
|
||||
|
|
@ -81,9 +116,86 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
|
|||
|
||||
void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
|
||||
{
|
||||
down(&dev->struct_sem);
|
||||
if( dev->context_sareas ) DRM(free)( dev->context_sareas,
|
||||
sizeof(*dev->context_sareas) *
|
||||
dev->max_context,
|
||||
DRM_MEM_MAPS );
|
||||
DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
|
||||
up(&dev->struct_sem);
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* Per Context SAREA Support
|
||||
*/
|
||||
|
||||
int DRM(get_ctx_map)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map;
|
||||
|
||||
if(copy_from_user(&request,
|
||||
(drm_ctx_priv_map_t *)arg,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if((int)request.ctx_id >= dev->max_context) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map = dev->context_sareas[request.ctx_id];
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.handle = map->handle;
|
||||
if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRM(add_ctx_map)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
if(copy_from_user(&request,
|
||||
(drm_ctx_priv_map_t *)arg,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
if(r_list->map &&
|
||||
r_list->map->handle == request.handle) break;
|
||||
}
|
||||
if(list == &(dev->maplist->head)) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
map = r_list->map;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if(!map) return -EINVAL;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if((int)request.ctx_id >= dev->max_context) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev->context_sareas[request.ctx_id] = map;
|
||||
up(&dev->struct_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* The actual DRM context handling routines
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { DRM(rmmap), 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CTX_SAREA)] = { DRM(add_ctx_map), 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX_SAREA)] = { DRM(get_ctx_map), 1, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
|
||||
|
|
@ -262,8 +266,14 @@ static int DRM(setup)( drm_device_t *dev )
|
|||
dev->magiclist[i].head = NULL;
|
||||
dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
dev->maplist = NULL;
|
||||
|
||||
dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS);
|
||||
if(dev->maplist == NULL) return -ENOMEM;
|
||||
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
||||
INIT_LIST_HEAD(&dev->maplist->head);
|
||||
dev->map_count = 0;
|
||||
|
||||
dev->vmalist = NULL;
|
||||
dev->lock.hw_lock = NULL;
|
||||
init_waitqueue_head( &dev->lock.lock_queue );
|
||||
|
|
@ -307,6 +317,8 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
{
|
||||
drm_magic_entry_t *pt, *next;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
drm_vma_entry_t *vma, *vma_next;
|
||||
int i;
|
||||
|
||||
|
|
@ -373,10 +385,13 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
dev->vmalist = NULL;
|
||||
}
|
||||
|
||||
/* Clear map area and mtrr information */
|
||||
if ( dev->maplist ) {
|
||||
for ( i = 0 ; i < dev->map_count ; i++ ) {
|
||||
map = dev->maplist[i];
|
||||
if( dev->maplist ) {
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
|
||||
if(!map) continue;
|
||||
|
||||
switch ( map->type ) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
|
|
@ -392,25 +407,20 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
DRM(ioremapfree)( map->handle, map->size );
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
DRM(free_pages)( (unsigned long)map->handle,
|
||||
DRM(order)( map->size )
|
||||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA );
|
||||
vfree(map->handle);
|
||||
break;
|
||||
|
||||
case _DRM_AGP:
|
||||
/* Do nothing here, because this is all
|
||||
* handled in the AGP/GART driver.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||
}
|
||||
DRM(free)( dev->maplist,
|
||||
dev->map_count * sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS );
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
|
||||
dev->maplist = NULL;
|
||||
dev->map_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES
|
||||
if ( dev->queuelist ) {
|
||||
|
|
|
|||
|
|
@ -105,22 +105,40 @@ int DRM(getmap)( struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t map;
|
||||
drm_map_list_t *r_list = NULL;
|
||||
struct list_head *list;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&map, (drm_map_t *)arg, sizeof(map)))
|
||||
return -EFAULT;
|
||||
idx = map.offset;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (idx < 0 || idx >= dev->map_count) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
map.offset = dev->maplist[idx]->offset;
|
||||
map.size = dev->maplist[idx]->size;
|
||||
map.type = dev->maplist[idx]->type;
|
||||
map.flags = dev->maplist[idx]->flags;
|
||||
map.handle = dev->maplist[idx]->handle;
|
||||
map.mtrr = dev->maplist[idx]->mtrr;
|
||||
|
||||
i = 0;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
if(i == idx) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(!r_list || !r_list->map) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map.offset = r_list->map->offset;
|
||||
map.size = r_list->map->size;
|
||||
map.type = r_list->map->type;
|
||||
map.flags = r_list->map->flags;
|
||||
map.handle = r_list->map->handle;
|
||||
map.mtrr = r_list->map->mtrr;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user((drm_map_t *)arg, &map, sizeof(map))) return -EFAULT;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
|
|||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
/* Hardcoded from _DRM_FRAME_BUFFER,
|
||||
_DRM_REGISTERS, _DRM_SHM, and
|
||||
_DRM_AGP. */
|
||||
|
|
@ -182,8 +185,11 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
|
|||
|
||||
DRM_PROC_PRINT("slot offset size type flags "
|
||||
"address mtrr\n\n");
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
i = 0;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
if(!map) continue;
|
||||
if (map->type < 0 || map->type > 3) type = "??";
|
||||
else type = types[map->type];
|
||||
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
|
||||
|
|
@ -198,6 +204,7 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
|
|||
} else {
|
||||
DRM_PROC_PRINT("%4d\n", map->mtrr);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
|
|
|
|||
|
|
@ -44,12 +44,6 @@ struct vm_operations_struct drm_vm_shm_ops = {
|
|||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_shm_lock_ops = {
|
||||
nopage: DRM(vm_shm_nopage_lock),
|
||||
open: DRM(vm_open),
|
||||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_dma_ops = {
|
||||
nopage: DRM(vm_dma_nopage),
|
||||
open: DRM(vm_open),
|
||||
|
|
@ -88,12 +82,26 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
#endif
|
||||
unsigned long physical;
|
||||
unsigned long offset;
|
||||
unsigned long i;
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!map) return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
physical = (unsigned long)map->handle + offset;
|
||||
i = (unsigned long)map->handle + offset;
|
||||
/* We have to walk page tables here because we need large SAREA's, and
|
||||
* they need to be virtually contigious in kernel space.
|
||||
*/
|
||||
pgd = pgd_offset_k( i );
|
||||
if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
|
||||
pmd = pmd_offset( pgd, i );
|
||||
if( !pmd_present( *pmd ) ) return NOPAGE_OOM;
|
||||
pte = pte_offset( pmd, i );
|
||||
if( !pte_present( *pte ) ) return NOPAGE_OOM;
|
||||
physical = (unsigned long)pte_page( *pte )->virtual;
|
||||
atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
|
||||
|
||||
DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
|
||||
|
|
@ -104,39 +112,6 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#endif
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
unsigned long physical;
|
||||
unsigned long offset;
|
||||
unsigned long page;
|
||||
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
page = offset >> PAGE_SHIFT;
|
||||
physical = (unsigned long)dev->lock.hw_lock + offset;
|
||||
atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
|
||||
|
||||
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
return physical;
|
||||
#else
|
||||
return virt_to_page(physical);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
|
|
@ -272,7 +247,8 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
int i;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
|
@ -286,12 +262,13 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
once, so it doesn't have to be optimized
|
||||
for performance, even if the list was a
|
||||
bit longer. */
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
if (!map) continue;
|
||||
if (map->offset == VM_OFFSET(vma)) break;
|
||||
}
|
||||
|
||||
if (i >= dev->map_count) return -EINVAL;
|
||||
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
|
||||
return -EPERM;
|
||||
|
||||
|
|
@ -339,17 +316,12 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
if (map->flags & _DRM_CONTAINS_LOCK)
|
||||
vma->vm_ops = &drm_vm_shm_lock_ops;
|
||||
else {
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
vma->vm_private_data = (void *)map;
|
||||
vma->vm_private_data = (void *)map;
|
||||
#else
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Don't let this area swap. Change when
|
||||
DRM_KERNEL advisory is supported. */
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
|
|
|
|||
13
linux/drm.h
13
linux/drm.h
|
|
@ -141,9 +141,15 @@ typedef enum drm_map_flags {
|
|||
_DRM_LOCKED = 0x04, /* shared, cached, locked */
|
||||
_DRM_KERNEL = 0x08, /* kernel requires access */
|
||||
_DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
|
||||
_DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
|
||||
_DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */
|
||||
_DRM_REMOVABLE = 0x40 /* Removable mapping */
|
||||
} drm_map_flags_t;
|
||||
|
||||
typedef struct drm_ctx_priv_map {
|
||||
unsigned int ctx_id; /* Context requesting private mapping */
|
||||
void *handle; /* Handle of map */
|
||||
} drm_ctx_priv_map_t;
|
||||
|
||||
typedef struct drm_map {
|
||||
unsigned long offset; /* Requested physical address (0 for SAREA)*/
|
||||
unsigned long size; /* Requested physical size (bytes) */
|
||||
|
|
@ -368,6 +374,11 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
|
||||
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
|
||||
|
||||
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
|
||||
|
||||
#define DRM_IOCTL_CTX_SAREA DRM_IOW( 0x1c, drm_ctx_priv_map_t)
|
||||
#define DRM_IOCTL_GET_CTX_SAREA DRM_IOWR(0x1d, drm_ctx_priv_map_t)
|
||||
|
||||
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
|
||||
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
|
||||
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
|
||||
|
|
|
|||
52
linux/drmP.h
52
linux/drmP.h
|
|
@ -321,16 +321,19 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
DRM(ioremapfree)( (map)->handle, (map)->size ); \
|
||||
} while (0)
|
||||
|
||||
#define DRM_FIND_MAP(map, o) \
|
||||
do { \
|
||||
int i; \
|
||||
for ( i = 0 ; i < dev->map_count ; i++ ) { \
|
||||
if ( dev->maplist[i]->offset == o ) { \
|
||||
map = dev->maplist[i]; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define DRM_FIND_MAP(_map, _o) \
|
||||
do { \
|
||||
struct list_head *_list; \
|
||||
list_for_each(_list, &dev->maplist->head) { \
|
||||
drm_map_list_t *_r_list; \
|
||||
_r_list = (drm_map_list_t *)_list; \
|
||||
if(_r_list->map && \
|
||||
_r_list->map->offset == (_o)) { \
|
||||
(_map) = _r_list->map; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Internal types and structures */
|
||||
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
|
@ -341,6 +344,10 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
|
||||
#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
|
||||
|
||||
#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
|
||||
(_map) = (_dev)->context_sareas[_ctx]; \
|
||||
} while(0)
|
||||
|
||||
typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
|
|
@ -569,6 +576,11 @@ typedef struct drm_sigdata {
|
|||
drm_hw_lock_t *lock;
|
||||
} drm_sigdata_t;
|
||||
|
||||
typedef struct drm_map_list {
|
||||
struct list_head head;
|
||||
drm_map_t *map;
|
||||
} drm_map_list_t;
|
||||
|
||||
typedef struct drm_device {
|
||||
const char *name; /* Simple driver name */
|
||||
char *unique; /* Unique identifier: e.g., busid */
|
||||
|
|
@ -601,9 +613,12 @@ typedef struct drm_device {
|
|||
drm_magic_head_t magiclist[DRM_HASH_SIZE];
|
||||
|
||||
/* Memory management */
|
||||
drm_map_t **maplist; /* Vector of pointers to regions */
|
||||
drm_map_list_t *maplist; /* Linked list of regions */
|
||||
int map_count; /* Number of mappable regions */
|
||||
|
||||
drm_map_t **context_sareas;
|
||||
int max_context;
|
||||
|
||||
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
|
||||
drm_lock_data_t lock; /* Information on hardware lock */
|
||||
|
||||
|
|
@ -690,9 +705,6 @@ extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
|
|||
extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
|
@ -704,9 +716,6 @@ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
|
|||
extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
|
|
@ -824,14 +833,17 @@ extern int DRM(notifier)(void *priv);
|
|||
/* Context Bitmap support (ctxbitmap.c) */
|
||||
extern int DRM(ctxbitmap_init)( drm_device_t *dev );
|
||||
extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
|
||||
|
||||
|
||||
|
||||
extern int DRM(add_ctx_map)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(get_ctx_map)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
/* Buffer management support (bufs.c) */
|
||||
extern int DRM(order)( unsigned long size );
|
||||
extern int DRM(addmap)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(rmmap)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(addbufs)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int DRM(infobufs)( struct inode *inode, struct file *filp,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *list;
|
||||
|
||||
if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_MTRR
|
||||
#ifdef __REALLY_HAVE_MTRR
|
||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||
map->mtrr = mtrr_add( map->offset, map->size,
|
||||
|
|
@ -111,9 +112,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
break;
|
||||
|
||||
case _DRM_SHM:
|
||||
map->handle = (void *)DRM(alloc_pages)( DRM(order)( map->size )
|
||||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA );
|
||||
map->handle = vmalloc_32(map->size);
|
||||
DRM_DEBUG( "%ld %d %p\n",
|
||||
map->size, DRM(order)( map->size ), map->handle );
|
||||
if ( !map->handle ) {
|
||||
|
|
@ -135,22 +134,17 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
down( &dev->struct_sem );
|
||||
if ( dev->maplist ) {
|
||||
++dev->map_count;
|
||||
dev->maplist = DRM(realloc)( dev->maplist,
|
||||
(dev->map_count-1)
|
||||
* sizeof(*dev->maplist),
|
||||
dev->map_count
|
||||
* sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS );
|
||||
} else {
|
||||
dev->map_count = 1;
|
||||
dev->maplist = DRM(alloc)( dev->map_count*sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS );
|
||||
list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
|
||||
if(!list) {
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev->maplist[dev->map_count-1] = map;
|
||||
up( &dev->struct_sem );
|
||||
memset(list, 0, sizeof(*list));
|
||||
list->map = map;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list_add(&list->head, &dev->maplist->head);
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if ( copy_to_user( (drm_map_t *)arg, map, sizeof(*map) ) )
|
||||
return -EFAULT;
|
||||
|
|
@ -163,6 +157,70 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Remove a map private from list and deallocate resources */
|
||||
int DRM(rmmap)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
struct list_head *list;
|
||||
drm_map_list_t *r_list;
|
||||
|
||||
drm_map_t *map;
|
||||
drm_map_t request;
|
||||
|
||||
if (copy_from_user(&request, (drm_map_t *)arg,
|
||||
sizeof(request))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list = &dev->maplist->head;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *) list;
|
||||
|
||||
if(r_list->map &&
|
||||
r_list->map->handle == request.handle &&
|
||||
r_list->map->flags & _DRM_REMOVABLE) break;
|
||||
}
|
||||
|
||||
/* List has wrapped around to the head pointer, or its empty we didn't
|
||||
* find anything.
|
||||
*/
|
||||
if(list == (&dev->maplist->head)) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
map = r_list->map;
|
||||
list_del(list);
|
||||
up(&dev->struct_sem);
|
||||
|
||||
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
#ifdef __REALLY_HAVE_MTRR
|
||||
if (map->mtrr >= 0) {
|
||||
int retcode;
|
||||
retcode = mtrr_del(map->mtrr,
|
||||
map->offset,
|
||||
map->size);
|
||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
||||
}
|
||||
#endif
|
||||
DRM(ioremapfree)(map->handle, map->size);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
vfree(map->handle);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __HAVE_DMA
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
|
|
|
|||
|
|
@ -36,9 +36,13 @@
|
|||
void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
|
||||
{
|
||||
if ( ctx_handle < 0 ) goto failed;
|
||||
if ( !dev->ctx_bitmap ) goto failed;
|
||||
|
||||
if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
|
||||
down(&dev->struct_sem);
|
||||
clear_bit( ctx_handle, dev->ctx_bitmap );
|
||||
dev->context_sareas[ctx_handle] = NULL;
|
||||
up(&dev->struct_sem);
|
||||
return;
|
||||
}
|
||||
failed:
|
||||
|
|
@ -51,12 +55,37 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
|
|||
{
|
||||
int bit;
|
||||
|
||||
if(!dev->ctx_bitmap) return -1;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
|
||||
if ( bit < DRM_MAX_CTXBITMAP ) {
|
||||
set_bit( bit, dev->ctx_bitmap );
|
||||
DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
|
||||
if((bit+1) > dev->max_context) {
|
||||
dev->max_context = (bit+1);
|
||||
if(dev->context_sareas) {
|
||||
dev->context_sareas = DRM(realloc)(
|
||||
dev->context_sareas,
|
||||
(dev->max_context - 1) *
|
||||
sizeof(*dev->context_sareas),
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
} else {
|
||||
/* max_context == 1 at this point */
|
||||
dev->context_sareas = DRM(alloc)(
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
}
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
return bit;
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -65,12 +94,18 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
|
|||
int i;
|
||||
int temp;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
|
||||
DRM_MEM_CTXBITMAP );
|
||||
if ( dev->ctx_bitmap == NULL ) {
|
||||
up(&dev->struct_sem);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
|
||||
dev->context_sareas = NULL;
|
||||
dev->max_context = -1;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
|
||||
temp = DRM(ctxbitmap_next)( dev );
|
||||
DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
|
||||
|
|
@ -81,9 +116,86 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
|
|||
|
||||
void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
|
||||
{
|
||||
down(&dev->struct_sem);
|
||||
if( dev->context_sareas ) DRM(free)( dev->context_sareas,
|
||||
sizeof(*dev->context_sareas) *
|
||||
dev->max_context,
|
||||
DRM_MEM_MAPS );
|
||||
DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
|
||||
up(&dev->struct_sem);
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* Per Context SAREA Support
|
||||
*/
|
||||
|
||||
int DRM(get_ctx_map)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map;
|
||||
|
||||
if(copy_from_user(&request,
|
||||
(drm_ctx_priv_map_t *)arg,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if((int)request.ctx_id >= dev->max_context) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map = dev->context_sareas[request.ctx_id];
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.handle = map->handle;
|
||||
if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRM(add_ctx_map)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
if(copy_from_user(&request,
|
||||
(drm_ctx_priv_map_t *)arg,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
if(r_list->map &&
|
||||
r_list->map->handle == request.handle) break;
|
||||
}
|
||||
if(list == &(dev->maplist->head)) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
map = r_list->map;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if(!map) return -EINVAL;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if((int)request.ctx_id >= dev->max_context) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev->context_sareas[request.ctx_id] = map;
|
||||
up(&dev->struct_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* The actual DRM context handling routines
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { DRM(rmmap), 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CTX_SAREA)] = { DRM(add_ctx_map), 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX_SAREA)] = { DRM(get_ctx_map), 1, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
|
||||
|
|
@ -262,8 +266,14 @@ static int DRM(setup)( drm_device_t *dev )
|
|||
dev->magiclist[i].head = NULL;
|
||||
dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
dev->maplist = NULL;
|
||||
|
||||
dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS);
|
||||
if(dev->maplist == NULL) return -ENOMEM;
|
||||
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
||||
INIT_LIST_HEAD(&dev->maplist->head);
|
||||
dev->map_count = 0;
|
||||
|
||||
dev->vmalist = NULL;
|
||||
dev->lock.hw_lock = NULL;
|
||||
init_waitqueue_head( &dev->lock.lock_queue );
|
||||
|
|
@ -307,6 +317,8 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
{
|
||||
drm_magic_entry_t *pt, *next;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
drm_vma_entry_t *vma, *vma_next;
|
||||
int i;
|
||||
|
||||
|
|
@ -373,10 +385,13 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
dev->vmalist = NULL;
|
||||
}
|
||||
|
||||
/* Clear map area and mtrr information */
|
||||
if ( dev->maplist ) {
|
||||
for ( i = 0 ; i < dev->map_count ; i++ ) {
|
||||
map = dev->maplist[i];
|
||||
if( dev->maplist ) {
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
|
||||
if(!map) continue;
|
||||
|
||||
switch ( map->type ) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
|
|
@ -392,25 +407,20 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
DRM(ioremapfree)( map->handle, map->size );
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
DRM(free_pages)( (unsigned long)map->handle,
|
||||
DRM(order)( map->size )
|
||||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA );
|
||||
vfree(map->handle);
|
||||
break;
|
||||
|
||||
case _DRM_AGP:
|
||||
/* Do nothing here, because this is all
|
||||
* handled in the AGP/GART driver.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||
}
|
||||
DRM(free)( dev->maplist,
|
||||
dev->map_count * sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS );
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
|
||||
dev->maplist = NULL;
|
||||
dev->map_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES
|
||||
if ( dev->queuelist ) {
|
||||
|
|
|
|||
|
|
@ -105,22 +105,40 @@ int DRM(getmap)( struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t map;
|
||||
drm_map_list_t *r_list = NULL;
|
||||
struct list_head *list;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&map, (drm_map_t *)arg, sizeof(map)))
|
||||
return -EFAULT;
|
||||
idx = map.offset;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (idx < 0 || idx >= dev->map_count) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
map.offset = dev->maplist[idx]->offset;
|
||||
map.size = dev->maplist[idx]->size;
|
||||
map.type = dev->maplist[idx]->type;
|
||||
map.flags = dev->maplist[idx]->flags;
|
||||
map.handle = dev->maplist[idx]->handle;
|
||||
map.mtrr = dev->maplist[idx]->mtrr;
|
||||
|
||||
i = 0;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
if(i == idx) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(!r_list || !r_list->map) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map.offset = r_list->map->offset;
|
||||
map.size = r_list->map->size;
|
||||
map.type = r_list->map->type;
|
||||
map.flags = r_list->map->flags;
|
||||
map.handle = r_list->map->handle;
|
||||
map.mtrr = r_list->map->mtrr;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user((drm_map_t *)arg, &map, sizeof(map))) return -EFAULT;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
|
|||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
/* Hardcoded from _DRM_FRAME_BUFFER,
|
||||
_DRM_REGISTERS, _DRM_SHM, and
|
||||
_DRM_AGP. */
|
||||
|
|
@ -182,8 +185,11 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
|
|||
|
||||
DRM_PROC_PRINT("slot offset size type flags "
|
||||
"address mtrr\n\n");
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
i = 0;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
if(!map) continue;
|
||||
if (map->type < 0 || map->type > 3) type = "??";
|
||||
else type = types[map->type];
|
||||
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
|
||||
|
|
@ -198,6 +204,7 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
|
|||
} else {
|
||||
DRM_PROC_PRINT("%4d\n", map->mtrr);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
|
|
|
|||
|
|
@ -44,12 +44,6 @@ struct vm_operations_struct drm_vm_shm_ops = {
|
|||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_shm_lock_ops = {
|
||||
nopage: DRM(vm_shm_nopage_lock),
|
||||
open: DRM(vm_open),
|
||||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_dma_ops = {
|
||||
nopage: DRM(vm_dma_nopage),
|
||||
open: DRM(vm_open),
|
||||
|
|
@ -88,12 +82,26 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
#endif
|
||||
unsigned long physical;
|
||||
unsigned long offset;
|
||||
unsigned long i;
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!map) return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
physical = (unsigned long)map->handle + offset;
|
||||
i = (unsigned long)map->handle + offset;
|
||||
/* We have to walk page tables here because we need large SAREA's, and
|
||||
* they need to be virtually contigious in kernel space.
|
||||
*/
|
||||
pgd = pgd_offset_k( i );
|
||||
if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
|
||||
pmd = pmd_offset( pgd, i );
|
||||
if( !pmd_present( *pmd ) ) return NOPAGE_OOM;
|
||||
pte = pte_offset( pmd, i );
|
||||
if( !pte_present( *pte ) ) return NOPAGE_OOM;
|
||||
physical = (unsigned long)pte_page( *pte )->virtual;
|
||||
atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
|
||||
|
||||
DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
|
||||
|
|
@ -104,39 +112,6 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#endif
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
unsigned long physical;
|
||||
unsigned long offset;
|
||||
unsigned long page;
|
||||
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
page = offset >> PAGE_SHIFT;
|
||||
physical = (unsigned long)dev->lock.hw_lock + offset;
|
||||
atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
|
||||
|
||||
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
return physical;
|
||||
#else
|
||||
return virt_to_page(physical);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
|
|
@ -272,7 +247,8 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
int i;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
|
@ -286,12 +262,13 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
once, so it doesn't have to be optimized
|
||||
for performance, even if the list was a
|
||||
bit longer. */
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
if (!map) continue;
|
||||
if (map->offset == VM_OFFSET(vma)) break;
|
||||
}
|
||||
|
||||
if (i >= dev->map_count) return -EINVAL;
|
||||
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
|
||||
return -EPERM;
|
||||
|
||||
|
|
@ -339,17 +316,12 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
if (map->flags & _DRM_CONTAINS_LOCK)
|
||||
vma->vm_ops = &drm_vm_shm_lock_ops;
|
||||
else {
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
vma->vm_private_data = (void *)map;
|
||||
vma->vm_private_data = (void *)map;
|
||||
#else
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Don't let this area swap. Change when
|
||||
DRM_KERNEL advisory is supported. */
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
|
|
|
|||
|
|
@ -433,6 +433,7 @@ static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
|
|||
static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
||||
{
|
||||
drm_mga_private_t *dev_priv;
|
||||
struct list_head *list;
|
||||
int ret;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
|
|
@ -464,7 +465,15 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
|||
dev_priv->depth_offset = init->depth_offset;
|
||||
dev_priv->depth_pitch = init->depth_pitch;
|
||||
|
||||
dev_priv->sarea = dev->maplist[0];
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
drm_map_list_t *r_list = (drm_map_list_t *)list;
|
||||
if( r_list->map &&
|
||||
r_list->map->type == _DRM_SHM &&
|
||||
r_list->map->flags & _DRM_CONTAINS_LOCK ) {
|
||||
dev_priv->sarea = r_list->map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
|
||||
DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
|
|||
static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
||||
{
|
||||
drm_r128_private_t *dev_priv;
|
||||
int i;
|
||||
struct list_head *list;
|
||||
|
||||
dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
|
||||
if ( dev_priv == NULL )
|
||||
|
|
@ -451,15 +451,15 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
|
||||
(dev_priv->span_offset >> 5));
|
||||
|
||||
/* FIXME: We want multiple shared areas, including one shared
|
||||
* only by the X Server and kernel module.
|
||||
*/
|
||||
for ( i = 0 ; i < dev->map_count ; i++ ) {
|
||||
if ( dev->maplist[i]->type == _DRM_SHM ) {
|
||||
dev_priv->sarea = dev->maplist[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
drm_map_list_t *r_list = (drm_map_list_t *)list;
|
||||
if( r_list->map &&
|
||||
r_list->map->type == _DRM_SHM &&
|
||||
r_list->map->flags & _DRM_CONTAINS_LOCK ) {
|
||||
dev_priv->sarea = r_list->map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
|
||||
DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
|
|||
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv;
|
||||
int i;
|
||||
struct list_head *list;
|
||||
|
||||
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
|
||||
if ( dev_priv == NULL )
|
||||
|
|
@ -711,15 +711,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
RADEON_ROUND_MODE_TRUNC |
|
||||
RADEON_ROUND_PREC_8TH_PIX);
|
||||
|
||||
/* FIXME: We want multiple shared areas, including one shared
|
||||
* only by the X Server and kernel module.
|
||||
*/
|
||||
for ( i = 0 ; i < dev->map_count ; i++ ) {
|
||||
if ( dev->maplist[i]->type == _DRM_SHM ) {
|
||||
dev_priv->sarea = dev->maplist[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
drm_map_list_t *r_list = (drm_map_list_t *)list;
|
||||
if( r_list->map &&
|
||||
r_list->map->type == _DRM_SHM &&
|
||||
r_list->map->flags & _DRM_CONTAINS_LOCK ) {
|
||||
dev_priv->sarea = r_list->map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
|
||||
DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
|
||||
|
|
|
|||
|
|
@ -141,9 +141,15 @@ typedef enum drm_map_flags {
|
|||
_DRM_LOCKED = 0x04, /* shared, cached, locked */
|
||||
_DRM_KERNEL = 0x08, /* kernel requires access */
|
||||
_DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
|
||||
_DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
|
||||
_DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */
|
||||
_DRM_REMOVABLE = 0x40 /* Removable mapping */
|
||||
} drm_map_flags_t;
|
||||
|
||||
typedef struct drm_ctx_priv_map {
|
||||
unsigned int ctx_id; /* Context requesting private mapping */
|
||||
void *handle; /* Handle of map */
|
||||
} drm_ctx_priv_map_t;
|
||||
|
||||
typedef struct drm_map {
|
||||
unsigned long offset; /* Requested physical address (0 for SAREA)*/
|
||||
unsigned long size; /* Requested physical size (bytes) */
|
||||
|
|
@ -368,6 +374,11 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
|
||||
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
|
||||
|
||||
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
|
||||
|
||||
#define DRM_IOCTL_CTX_SAREA DRM_IOW( 0x1c, drm_ctx_priv_map_t)
|
||||
#define DRM_IOCTL_GET_CTX_SAREA DRM_IOWR(0x1d, drm_ctx_priv_map_t)
|
||||
|
||||
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
|
||||
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
|
||||
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
|
||||
|
|
|
|||
13
shared/drm.h
13
shared/drm.h
|
|
@ -141,9 +141,15 @@ typedef enum drm_map_flags {
|
|||
_DRM_LOCKED = 0x04, /* shared, cached, locked */
|
||||
_DRM_KERNEL = 0x08, /* kernel requires access */
|
||||
_DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
|
||||
_DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
|
||||
_DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */
|
||||
_DRM_REMOVABLE = 0x40 /* Removable mapping */
|
||||
} drm_map_flags_t;
|
||||
|
||||
typedef struct drm_ctx_priv_map {
|
||||
unsigned int ctx_id; /* Context requesting private mapping */
|
||||
void *handle; /* Handle of map */
|
||||
} drm_ctx_priv_map_t;
|
||||
|
||||
typedef struct drm_map {
|
||||
unsigned long offset; /* Requested physical address (0 for SAREA)*/
|
||||
unsigned long size; /* Requested physical size (bytes) */
|
||||
|
|
@ -368,6 +374,11 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
|
||||
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
|
||||
|
||||
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
|
||||
|
||||
#define DRM_IOCTL_CTX_SAREA DRM_IOW( 0x1c, drm_ctx_priv_map_t)
|
||||
#define DRM_IOCTL_GET_CTX_SAREA DRM_IOWR(0x1d, drm_ctx_priv_map_t)
|
||||
|
||||
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
|
||||
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
|
||||
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue