Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 6488
b: refs/heads/master
c: d1f2b55
h: refs/heads/master
v: v3
  • Loading branch information
Dave Airlie authored and Dave Airlie committed Aug 5, 2005
1 parent 8f5f6b2 commit 9821d0c
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 55 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c73681e77b40697d16ada777adf2c6dc4db05917
refs/heads/master: d1f2b55ad2c11f46e30547a9f7754e99b478348e
14 changes: 6 additions & 8 deletions trunk/drivers/char/drm/drmP.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ typedef struct drm_dma_handle {
typedef struct drm_map_list {
struct list_head head; /**< list head */
drm_map_t *map; /**< mapping */
unsigned int user_token;
} drm_map_list_t;

typedef drm_map_t drm_local_map_t;
Expand Down Expand Up @@ -759,6 +760,7 @@ typedef struct drm_device {

struct drm_driver *driver;
drm_local_map_t *agp_buffer_map;
unsigned int agp_buffer_token;
drm_head_t primary; /**< primary screen head */
} drm_device_t;

Expand Down Expand Up @@ -1048,16 +1050,12 @@ static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_devi
drm_ioremapfree( map->handle, map->size, dev );
}

static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset)
static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token)
{
struct list_head *_list;
list_for_each( _list, &dev->maplist->head ) {
drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head );
if ( _entry->map &&
_entry->map->offset == offset ) {
drm_map_list_t *_entry;
list_for_each_entry(_entry, &dev->maplist->head, head)
if (_entry->user_token == token)
return _entry->map;
}
}
return NULL;
}

Expand Down
81 changes: 59 additions & 22 deletions trunk/drivers/char/drm/drm_bufs.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,41 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
return NULL;
}

#ifdef CONFIG_COMPAT
/*
* Used to allocate 32-bit handles for _DRM_SHM regions
* The 0x10000000 value is chosen to be out of the way of
* FB/register and GART physical addresses.
* Used to allocate 32-bit handles for mappings.
*/
static unsigned int map32_handle = 0x10000000;
#define START_RANGE 0x10000000
#define END_RANGE 0x40000000

#ifdef _LP64
static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev)
{
static unsigned int map32_handle = START_RANGE;
unsigned int hash;

if (lhandle & 0xffffffff00000000) {
hash = map32_handle;
map32_handle += PAGE_SIZE;
if (map32_handle > END_RANGE)
map32_handle = START_RANGE;
} else
hash = lhandle;

while (1) {
drm_map_list_t *_entry;
list_for_each_entry(_entry, &dev->maplist->head,head) {
if (_entry->user_token == hash)
break;
}
if (&_entry->head == &dev->maplist->head)
return hash;

hash += PAGE_SIZE;
map32_handle += PAGE_SIZE;
}
}
#else
# define HandleID(x,dev) (unsigned int)(x)
#endif

/**
Expand Down Expand Up @@ -198,7 +226,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
map->offset += dev->sg->handle;
map->offset += (unsigned long)dev->sg->virtual;
break;
case _DRM_CONSISTENT:
/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
Expand Down Expand Up @@ -229,12 +257,11 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,

down(&dev->struct_sem);
list_add(&list->head, &dev->maplist->head);
#ifdef CONFIG_COMPAT
/* Assign a 32-bit handle for _DRM_SHM mappings */
/* Assign a 32-bit handle */
/* We do it here so that dev->struct_sem protects the increment */
if (map->type == _DRM_SHM)
map->offset = map32_handle += PAGE_SIZE;
#endif
list->user_token = HandleID(map->type==_DRM_SHM
? (unsigned long)map->handle
: map->offset, dev);
up(&dev->struct_sem);

*map_ptr = map;
Expand All @@ -251,6 +278,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
drm_map_t *map_ptr;
drm_map_t __user *argp = (void __user *)arg;
int err;
unsigned long handle = 0;

if (!(filp->f_mode & 3))
return -EACCES; /* Require read/write */
Expand All @@ -259,22 +287,29 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
return -EFAULT;
}

err = drm_addmap( dev, map.offset, map.size, map.type, map.flags,
&map_ptr );
err = drm_addmap(dev, map.offset, map.size, map.type, map.flags,
&map_ptr);

if (err) {
return err;
}

if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
return -EFAULT;
if (map_ptr->type != _DRM_SHM) {
if (copy_to_user(&argp->handle, &map_ptr->offset,
sizeof(map_ptr->offset)))
{
drm_map_list_t *_entry;
list_for_each_entry(_entry, &dev->maplist->head, head) {
if (_entry->map == map_ptr)
handle = _entry->user_token;
}
if (!handle)
return -EFAULT;
}

if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
return -EFAULT;
if (put_user(handle, &argp->handle))
return -EFAULT;
return 0;
}
}


/**
Expand Down Expand Up @@ -388,7 +423,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);

if (r_list->map &&
r_list->map->handle == request.handle &&
r_list->user_token == (unsigned long) request.handle &&
r_list->map->flags & _DRM_REMOVABLE) {
map = r_list->map;
break;
Expand Down Expand Up @@ -939,7 +974,8 @@ static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)

buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
buf->address = (void *)(agp_offset + offset + dev->sg->handle);
buf->address = (void *)(agp_offset + offset
+ (unsigned long)dev->sg->virtual);
buf->next = NULL;
buf->waiting = 0;
buf->pending = 0;
Expand Down Expand Up @@ -1456,6 +1492,7 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
&& (dma->flags & _DRM_DMA_USE_FB))) {
drm_map_t *map = dev->agp_buffer_map;
unsigned long token = dev->agp_buffer_token;

if ( !map ) {
retcode = -EINVAL;
Expand All @@ -1470,7 +1507,7 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
virtual = do_mmap( filp, 0, map->size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
(unsigned long)map->offset );
token );
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
Expand Down
15 changes: 13 additions & 2 deletions trunk/drivers/char/drm/drm_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
drm_ctx_priv_map_t __user *argp = (void __user *)arg;
drm_ctx_priv_map_t request;
drm_map_t *map;
drm_map_list_t *_entry;

if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
Expand All @@ -225,7 +226,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
map = dev->context_sareas[request.ctx_id];
up(&dev->struct_sem);

request.handle = (void *) map->offset;
request.handle = 0;
list_for_each_entry(_entry, &dev->maplist->head,head) {
if (_entry->map == map) {
request.handle = (void *)(unsigned long)_entry->user_token;
break;
}
}
if (request.handle == 0)
return -EINVAL;


if (copy_to_user(argp, &request, sizeof(request)))
return -EFAULT;
return 0;
Expand Down Expand Up @@ -262,7 +273,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
if (r_list->map
&& r_list->map->offset == (unsigned long) request.handle)
&& r_list->user_token == (unsigned long) request.handle)
goto found;
}
bad:
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/char/drm/drm_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ int drm_getmap( struct inode *inode, struct file *filp,
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.handle = (void *)(unsigned long) r_list->user_token;
map.mtrr = r_list->map->mtrr;
up(&dev->struct_sem);

Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/char/drm/drm_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,13 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
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%08x ",
i,
map->offset,
map->size,
type,
map->flags,
(unsigned long)map->handle);
r_list->user_token);
if (map->mtrr < 0) {
DRM_PROC_PRINT("none\n");
} else {
Expand Down
11 changes: 9 additions & 2 deletions trunk/drivers/char/drm/drm_scatter.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
DRM_MEM_SGLISTS );
}

#ifdef _LP64
# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
#else
# define ScatterHandle(x) (unsigned int)(x)
#endif

int drm_sg_alloc( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
Expand Down Expand Up @@ -133,12 +139,13 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
*/
memset( entry->virtual, 0, pages << PAGE_SHIFT );

entry->handle = (unsigned long)entry->virtual;
entry->handle = ScatterHandle((unsigned long)entry->virtual);

DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );

for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
for (i = (unsigned long)entry->virtual, j = 0; j < pages;
i += PAGE_SIZE, j++) {
entry->pagelist[j] = vmalloc_to_page((void *)i);
if (!entry->pagelist[j])
goto failed;
Expand Down
20 changes: 10 additions & 10 deletions trunk/drivers/char/drm/drm_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
if (!map) continue;
if (map->offset == VM_OFFSET(vma)) break;
if (r_list->user_token == VM_OFFSET(vma))
break;
}

if (map && map->type == _DRM_AGP) {
unsigned long offset = address - vma->vm_start;
unsigned long baddr = VM_OFFSET(vma) + offset;
unsigned long baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;

Expand Down Expand Up @@ -304,7 +305,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,


offset = address - vma->vm_start;
map_offset = map->offset - dev->sg->handle;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
page = entry->pagelist[page_offset];
get_page(page);
Expand Down Expand Up @@ -568,13 +569,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
for performance, even if the list was a
bit longer. */
list_for_each(list, &dev->maplist->head) {
unsigned long off;

r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
if (!map) continue;
off = dev->driver->get_map_ofs(map);
if (off == VM_OFFSET(vma)) break;
if (r_list->user_token == VM_OFFSET(vma))
break;
}

if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
Expand Down Expand Up @@ -613,7 +613,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
/* fall through to _DRM_FRAME_BUFFER... */
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
if (map->offset >= __pa(high_memory)) {
#if defined(__i386__) || defined(__x86_64__)
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
Expand All @@ -636,20 +636,20 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
offset = dev->driver->get_reg_ofs(dev);
#ifdef __sparc__
if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
(VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
#else
if (io_remap_pfn_range(vma, vma->vm_start,
(VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
#endif
return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
" offset = 0x%lx\n",
map->type,
vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
vma->vm_start, vma->vm_end, map->offset + offset);
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
Expand Down
5 changes: 1 addition & 4 deletions trunk/drivers/char/drm/ffb_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,11 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
return NULL;

list_for_each(list, &dev->maplist->head) {
unsigned long uoff;

r_list = (drm_map_list_t *)list;
map = r_list->map;
if (!map)
continue;
uoff = (map->offset & 0xffffffff);
if (uoff == off)
if (r_list->user_token == off)
return map;
}

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/drm/i810_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ static int i810_dma_initialize(drm_device_t *dev,
DRM_ERROR("can not find mmio map!\n");
return -EINVAL;
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) {
dev->dev_private = (void *)dev_priv;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/drm/i830_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ static int i830_dma_initialize(drm_device_t *dev,
DRM_ERROR("can not find mmio map!\n");
return -EINVAL;
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
if(!dev->agp_buffer_map) {
dev->dev_private = (void *)dev_priv;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/drm/mga_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
DRM_ERROR("failed to find primary dma region!\n");
return DRM_ERR(EINVAL);
}
dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) {
DRM_ERROR("failed to find dma buffer region!\n");
Expand Down
Loading

0 comments on commit 9821d0c

Please sign in to comment.