aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_bufs.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-02-02 00:55:47 -0500
committerDave Airlie <airlied@redhat.com>2009-03-13 00:23:57 -0400
commit41c2e75e60200a860a74b7c84a6375c105e7437f (patch)
tree18e97662d6859eead4de816e121d001b34a7352a /drivers/gpu/drm/drm_bufs.c
parentf77d390c9779c496aa5b99ec832996fb76bb1d13 (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_bufs.c')
-rw-r--r--drivers/gpu/drm/drm_bufs.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 1b8dbd5961bc..cddea1a2472c 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -54,11 +54,29 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
54{ 54{
55 struct drm_map_list *entry; 55 struct drm_map_list *entry;
56 list_for_each_entry(entry, &dev->maplist, head) { 56 list_for_each_entry(entry, &dev->maplist, head) {
57 if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) && 57 /*
58 ((entry->map->offset == map->offset) || 58 * Because the kernel-userspace ABI is fixed at a 32-bit offset
59 ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) { 59 * while PCI resources may live above that, we ignore the map
60 * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS.
61 * It is assumed that each driver will have only one resource of
62 * each type.
63 */
64 if (!entry->map ||
65 map->type != entry->map->type ||
66 entry->master != dev->primary->master)
67 continue;
68 switch (map->type) {
69 case _DRM_SHM:
70 if (map->flags != _DRM_CONTAINS_LOCK)
71 break;
72 case _DRM_REGISTERS:
73 case _DRM_FRAME_BUFFER:
60 return entry; 74 return entry;
75 default: /* Make gcc happy */
76 ;
61 } 77 }
78 if (entry->map->offset == map->offset)
79 return entry;
62 } 80 }
63 81
64 return NULL; 82 return NULL;
@@ -96,7 +114,7 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
96 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where 114 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
97 * applicable and if supported by the kernel. 115 * applicable and if supported by the kernel.
98 */ 116 */
99static int drm_addmap_core(struct drm_device * dev, unsigned int offset, 117static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
100 unsigned int size, enum drm_map_type type, 118 unsigned int size, enum drm_map_type type,
101 enum drm_map_flags flags, 119 enum drm_map_flags flags,
102 struct drm_map_list ** maplist) 120 struct drm_map_list ** maplist)
@@ -124,9 +142,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
124 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 142 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
125 return -EINVAL; 143 return -EINVAL;
126 } 144 }
127 DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", 145 DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
128 map->offset, map->size, map->type); 146 (unsigned long long)map->offset, map->size, map->type);
129 if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) { 147 if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
130 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 148 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
131 return -EINVAL; 149 return -EINVAL;
132 } 150 }
@@ -254,7 +272,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
254 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 272 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
255 return -EPERM; 273 return -EPERM;
256 } 274 }
257 DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); 275 DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
276 (unsigned long long)map->offset, map->size);
258 277
259 break; 278 break;
260 case _DRM_GEM: 279 case _DRM_GEM:
@@ -322,7 +341,7 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
322 return 0; 341 return 0;
323 } 342 }
324 343
325int drm_addmap(struct drm_device * dev, unsigned int offset, 344int drm_addmap(struct drm_device * dev, resource_size_t offset,
326 unsigned int size, enum drm_map_type type, 345 unsigned int size, enum drm_map_type type,
327 enum drm_map_flags flags, struct drm_local_map ** map_ptr) 346 enum drm_map_flags flags, struct drm_local_map ** map_ptr)
328{ 347{