aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-09-05 07:23:23 -0400
committerDave Airlie <airlied@linux.ie>2005-09-05 07:23:23 -0400
commit89625eb186b9b0b9454d44126f8b1bcc72ad93b7 (patch)
tree0e5bf395d8c53fcfaf0790b417666a8dabae8a8e /drivers/char
parentf505380ba7b98ec97bf25300c2a58aeae903530b (diff)
drm: fix issue with handle lookup for a 0 handle
On 32-bit PPC a 0 handle is valid for AGP space, the 32/64 lookup doesn't handle 0 correctly. From: Ben Herrenschmidt <benh@kernel.crashing.org> and Paul Mackerras <paulus@samba.org> Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/drm_bufs.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index e0743ebbe4bd..8eff0736a94d 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -48,8 +48,8 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
48} 48}
49EXPORT_SYMBOL(drm_get_resource_len); 49EXPORT_SYMBOL(drm_get_resource_len);
50 50
51static drm_local_map_t *drm_find_matching_map(drm_device_t *dev, 51static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
52 drm_local_map_t *map) 52 drm_local_map_t *map)
53{ 53{
54 struct list_head *list; 54 struct list_head *list;
55 55
@@ -57,7 +57,7 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
57 drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); 57 drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
58 if (entry->map && map->type == entry->map->type && 58 if (entry->map && map->type == entry->map->type &&
59 entry->map->offset == map->offset) { 59 entry->map->offset == map->offset) {
60 return entry->map; 60 return entry;
61 } 61 }
62 } 62 }
63 63
@@ -114,14 +114,13 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev
114 * 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
115 * applicable and if supported by the kernel. 115 * applicable and if supported by the kernel.
116 */ 116 */
117int drm_addmap(drm_device_t * dev, unsigned int offset, 117int drm_addmap_core(drm_device_t * dev, unsigned int offset,
118 unsigned int size, drm_map_type_t type, 118 unsigned int size, drm_map_type_t type,
119 drm_map_flags_t flags, drm_local_map_t ** map_ptr) 119 drm_map_flags_t flags, drm_map_list_t **maplist)
120{ 120{
121 drm_map_t *map; 121 drm_map_t *map;
122 drm_map_list_t *list; 122 drm_map_list_t *list;
123 drm_dma_handle_t *dmah; 123 drm_dma_handle_t *dmah;
124 drm_local_map_t *found_map;
125 124
126 map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); 125 map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
127 if ( !map ) 126 if ( !map )
@@ -166,17 +165,17 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
166 * needing to be aware of it. Therefore, we just return success 165 * needing to be aware of it. Therefore, we just return success
167 * when the server tries to create a duplicate map. 166 * when the server tries to create a duplicate map.
168 */ 167 */
169 found_map = drm_find_matching_map(dev, map); 168 list = drm_find_matching_map(dev, map);
170 if (found_map != NULL) { 169 if (list != NULL) {
171 if (found_map->size != map->size) { 170 if (list->map->size != map->size) {
172 DRM_DEBUG("Matching maps of type %d with " 171 DRM_DEBUG("Matching maps of type %d with "
173 "mismatched sizes, (%ld vs %ld)\n", 172 "mismatched sizes, (%ld vs %ld)\n",
174 map->type, map->size, found_map->size); 173 map->type, map->size, list->map->size);
175 found_map->size = map->size; 174 list->map->size = map->size;
176 } 175 }
177 176
178 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 177 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
179 *map_ptr = found_map; 178 *maplist = list;
180 return 0; 179 return 0;
181 } 180 }
182 181
@@ -264,9 +263,22 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
264 : map->offset, dev); 263 : map->offset, dev);
265 up(&dev->struct_sem); 264 up(&dev->struct_sem);
266 265
267 *map_ptr = map; 266 *maplist = list;
268 return 0; 267 return 0;
269} 268}
269
270int drm_addmap(drm_device_t *dev, unsigned int offset,
271 unsigned int size, drm_map_type_t type,
272 drm_map_flags_t flags, drm_local_map_t **map_ptr)
273{
274 drm_map_list_t *list;
275 int rc;
276
277 rc = drm_addmap_core(dev, offset, size, type, flags, &list);
278 if (!rc)
279 *map_ptr = list->map;
280 return rc;
281}
270EXPORT_SYMBOL(drm_addmap); 282EXPORT_SYMBOL(drm_addmap);
271 283
272int drm_addmap_ioctl(struct inode *inode, struct file *filp, 284int drm_addmap_ioctl(struct inode *inode, struct file *filp,
@@ -275,10 +287,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
275 drm_file_t *priv = filp->private_data; 287 drm_file_t *priv = filp->private_data;
276 drm_device_t *dev = priv->head->dev; 288 drm_device_t *dev = priv->head->dev;
277 drm_map_t map; 289 drm_map_t map;
278 drm_map_t *map_ptr; 290 drm_map_list_t *maplist;
279 drm_map_t __user *argp = (void __user *)arg; 291 drm_map_t __user *argp = (void __user *)arg;
280 int err; 292 int err;
281 unsigned long handle = 0;
282 293
283 if (!(filp->f_mode & 3)) 294 if (!(filp->f_mode & 3))
284 return -EACCES; /* Require read/write */ 295 return -EACCES; /* Require read/write */
@@ -287,26 +298,15 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
287 return -EFAULT; 298 return -EFAULT;
288 } 299 }
289 300
290 err = drm_addmap(dev, map.offset, map.size, map.type, map.flags, 301 err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
291 &map_ptr); 302 &maplist);
292 303
293 if (err) { 304 if (err)
294 return err; 305 return err;
295 }
296
297 {
298 drm_map_list_t *_entry;
299 list_for_each_entry(_entry, &dev->maplist->head, head) {
300 if (_entry->map == map_ptr)
301 handle = _entry->user_token;
302 }
303 if (!handle)
304 return -EFAULT;
305 }
306 306
307 if (copy_to_user(argp, map_ptr, sizeof(*map_ptr))) 307 if (copy_to_user(argp, maplist->map, sizeof(drm_map_t)))
308 return -EFAULT; 308 return -EFAULT;
309 if (put_user(handle, &argp->handle)) 309 if (put_user(maplist->user_token, &argp->handle))
310 return -EFAULT; 310 return -EFAULT;
311 return 0; 311 return 0;
312} 312}