diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-02-02 00:55:47 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 00:23:57 -0400 |
commit | 41c2e75e60200a860a74b7c84a6375c105e7437f (patch) | |
tree | 18e97662d6859eead4de816e121d001b34a7352a /drivers/gpu/drm/drm_vm.c | |
parent | f77d390c9779c496aa5b99ec832996fb76bb1d13 (diff) |
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 0d8bbd72ec55..22f76567ac7d 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) | |||
115 | * Using vm_pgoff as a selector forces us to use this unusual | 115 | * Using vm_pgoff as a selector forces us to use this unusual |
116 | * addressing scheme. | 116 | * addressing scheme. |
117 | */ | 117 | */ |
118 | unsigned long offset = (unsigned long)vmf->virtual_address - | 118 | resource_size_t offset = (unsigned long)vmf->virtual_address - |
119 | vma->vm_start; | 119 | vma->vm_start; |
120 | unsigned long baddr = map->offset + offset; | 120 | resource_size_t baddr = map->offset + offset; |
121 | struct drm_agp_mem *agpmem; | 121 | struct drm_agp_mem *agpmem; |
122 | struct page *page; | 122 | struct page *page; |
123 | 123 | ||
@@ -149,8 +149,10 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
149 | vmf->page = page; | 149 | vmf->page = page; |
150 | 150 | ||
151 | DRM_DEBUG | 151 | DRM_DEBUG |
152 | ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", | 152 | ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", |
153 | baddr, __va(agpmem->memory->memory[offset]), offset, | 153 | (unsigned long long)baddr, |
154 | __va(agpmem->memory->memory[offset]), | ||
155 | (unsigned long long)offset, | ||
154 | page_count(page)); | 156 | page_count(page)); |
155 | return 0; | 157 | return 0; |
156 | } | 158 | } |
@@ -512,14 +514,14 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
512 | return 0; | 514 | return 0; |
513 | } | 515 | } |
514 | 516 | ||
515 | unsigned long drm_core_get_map_ofs(struct drm_local_map * map) | 517 | resource_size_t drm_core_get_map_ofs(struct drm_local_map * map) |
516 | { | 518 | { |
517 | return map->offset; | 519 | return map->offset; |
518 | } | 520 | } |
519 | 521 | ||
520 | EXPORT_SYMBOL(drm_core_get_map_ofs); | 522 | EXPORT_SYMBOL(drm_core_get_map_ofs); |
521 | 523 | ||
522 | unsigned long drm_core_get_reg_ofs(struct drm_device *dev) | 524 | resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) |
523 | { | 525 | { |
524 | #ifdef __alpha__ | 526 | #ifdef __alpha__ |
525 | return dev->hose->dense_mem_base - dev->hose->mem_space->start; | 527 | 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) | |||
548 | struct drm_file *priv = filp->private_data; | 550 | struct drm_file *priv = filp->private_data; |
549 | struct drm_device *dev = priv->minor->dev; | 551 | struct drm_device *dev = priv->minor->dev; |
550 | struct drm_local_map *map = NULL; | 552 | struct drm_local_map *map = NULL; |
551 | unsigned long offset = 0; | 553 | resource_size_t offset = 0; |
552 | struct drm_hash_item *hash; | 554 | struct drm_hash_item *hash; |
553 | 555 | ||
554 | DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", | 556 | 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) | |||
623 | vma->vm_page_prot)) | 625 | vma->vm_page_prot)) |
624 | return -EAGAIN; | 626 | return -EAGAIN; |
625 | DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," | 627 | DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," |
626 | " offset = 0x%lx\n", | 628 | " offset = 0x%llx\n", |
627 | map->type, | 629 | map->type, |
628 | vma->vm_start, vma->vm_end, map->offset + offset); | 630 | vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); |
629 | vma->vm_ops = &drm_vm_ops; | 631 | vma->vm_ops = &drm_vm_ops; |
630 | break; | 632 | break; |
631 | case _DRM_CONSISTENT: | 633 | case _DRM_CONSISTENT: |