diff options
| author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-02-02 16:55:47 +1100 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 14:23:57 +1000 | 
| commit | 41c2e75e60200a860a74b7c84a6375c105e7437f (patch) | |
| tree | 18e97662d6859eead4de816e121d001b34a7352a /drivers/gpu/drm/drm_vm.c | |
| parent | f77d390c9779c496aa5b99ec832996fb76bb1d13 (diff) | |
| download | olio-linux-3.10-41c2e75e60200a860a74b7c84a6375c105e7437f.tar.xz olio-linux-3.10-41c2e75e60200a860a74b7c84a6375c105e7437f.zip  | |
drm: Make drm_local_map use a resource_size_t offset
This changes drm_local_map to use a resource_size for its "offset"
member instead of an unsigned long, thus allowing 32-bit machines
with a >32-bit physical address space to be able to store there
their register or framebuffer addresses when those are above 4G,
such as when using a PCI video card on a recent AMCC 440 SoC.
This patch isn't as "trivial" as it sounds: A few functions needed
to have some unsigned long/int changed to resource_size_t and a few
printk's had to be adjusted.
But also, because userspace isn't capable of passing such offsets,
I had to modify drm_find_matching_map() to ignore the offset passed
in for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS.
If we ever support multiple _DRM_FRAMEBUFFER or _DRM_REGISTERS maps
for a given device, we might have to change that trick, but I don't
think that happens on any current driver.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/gpu/drm/drm_vm.c')
| -rw-r--r-- | drivers/gpu/drm/drm_vm.c | 22 | 
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 0d8bbd72ec5..22f76567ac7 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -115,9 +115,9 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  		 * Using vm_pgoff as a selector forces us to use this unusual  		 * addressing scheme.  		 */ -		unsigned long offset = (unsigned long)vmf->virtual_address - -								vma->vm_start; -		unsigned long baddr = map->offset + offset; +		resource_size_t offset = (unsigned long)vmf->virtual_address - +			vma->vm_start; +		resource_size_t baddr = map->offset + offset;  		struct drm_agp_mem *agpmem;  		struct page *page; @@ -149,8 +149,10 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  		vmf->page = page;  		DRM_DEBUG -		    ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", -		     baddr, __va(agpmem->memory->memory[offset]), offset, +		    ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", +		     (unsigned long long)baddr, +		     __va(agpmem->memory->memory[offset]), +		     (unsigned long long)offset,  		     page_count(page));  		return 0;  	} @@ -512,14 +514,14 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)  	return 0;  } -unsigned long drm_core_get_map_ofs(struct drm_local_map * map) +resource_size_t drm_core_get_map_ofs(struct drm_local_map * map)  {  	return map->offset;  }  EXPORT_SYMBOL(drm_core_get_map_ofs); -unsigned long drm_core_get_reg_ofs(struct drm_device *dev) +resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)  {  #ifdef __alpha__  	return dev->hose->dense_mem_base - dev->hose->mem_space->start; @@ -548,7 +550,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)  	struct drm_file *priv = filp->private_data;  	struct drm_device *dev = priv->minor->dev;  	struct drm_local_map *map = NULL; -	unsigned long offset = 0; +	resource_size_t offset = 0;  	struct drm_hash_item *hash;  	DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", @@ -623,9 +625,9 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)  				       vma->vm_page_prot))  			return -EAGAIN;  		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx," -			  " offset = 0x%lx\n", +			  " offset = 0x%llx\n",  			  map->type, -			  vma->vm_start, vma->vm_end, map->offset + offset); +			  vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset));  		vma->vm_ops = &drm_vm_ops;  		break;  	case _DRM_CONSISTENT:  |