Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 1069 lines 32 kB view raw
1/** 2 * \file drm_ioc32.c 3 * 4 * 32-bit ioctl compatibility routines for the DRM. 5 * 6 * \author Paul Mackerras <paulus@samba.org> 7 * 8 * Copyright (C) Paul Mackerras 2005. 9 * All Rights Reserved. 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice (including the next 19 * paragraph) shall be included in all copies or substantial portions of the 20 * Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 28 * IN THE SOFTWARE. 29 */ 30#include <linux/compat.h> 31#include <linux/ioctl32.h> 32 33#include "drmP.h" 34#include "drm_core.h" 35 36#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t) 37#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t) 38#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t) 39#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t) 40#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t) 41 42#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t) 43#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t) 44#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t) 45#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t) 46#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t) 47#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t) 48#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t) 49 50#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t) 51 52#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t) 53#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t) 54 55#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t) 56#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t) 57 58#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t) 59#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t) 60#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t) 61#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t) 62#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t) 63#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t) 64 65#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t) 66#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t) 67 68#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) 69 70typedef struct drm_version_32 { 71 int version_major; /**< Major version */ 72 int version_minor; /**< Minor version */ 73 int version_patchlevel;/**< Patch level */ 74 u32 name_len; /**< Length of name buffer */ 75 u32 name; /**< Name of driver */ 76 u32 date_len; /**< Length of date buffer */ 77 u32 date; /**< User-space buffer to hold date */ 78 u32 desc_len; /**< Length of desc buffer */ 79 u32 desc; /**< User-space buffer to hold desc */ 80} drm_version32_t; 81 82static int compat_drm_version(struct file *file, unsigned int cmd, 83 unsigned long arg) 84{ 85 drm_version32_t v32; 86 drm_version_t __user *version; 87 int err; 88 89 if (copy_from_user(&v32, (void __user *) arg, sizeof(v32))) 90 return -EFAULT; 91 92 version = compat_alloc_user_space(sizeof(*version)); 93 if (!access_ok(VERIFY_WRITE, version, sizeof(*version))) 94 return -EFAULT; 95 if (__put_user(v32.name_len, &version->name_len) 96 || __put_user((void __user *)(unsigned long)v32.name, 97 &version->name) 98 || __put_user(v32.date_len, &version->date_len) 99 || __put_user((void __user *)(unsigned long)v32.date, 100 &version->date) 101 || __put_user(v32.desc_len, &version->desc_len) 102 || __put_user((void __user *)(unsigned long)v32.desc, 103 &version->desc)) 104 return -EFAULT; 105 106 err = drm_ioctl(file->f_dentry->d_inode, file, 107 DRM_IOCTL_VERSION, (unsigned long) version); 108 if (err) 109 return err; 110 111 if (__get_user(v32.version_major, &version->version_major) 112 || __get_user(v32.version_minor, &version->version_minor) 113 || __get_user(v32.version_patchlevel, &version->version_patchlevel) 114 || __get_user(v32.name_len, &version->name_len) 115 || __get_user(v32.date_len, &version->date_len) 116 || __get_user(v32.desc_len, &version->desc_len)) 117 return -EFAULT; 118 119 if (copy_to_user((void __user *) arg, &v32, sizeof(v32))) 120 return -EFAULT; 121 return 0; 122} 123 124typedef struct drm_unique32 { 125 u32 unique_len; /**< Length of unique */ 126 u32 unique; /**< Unique name for driver instantiation */ 127} drm_unique32_t; 128 129static int compat_drm_getunique(struct file *file, unsigned int cmd, 130 unsigned long arg) 131{ 132 drm_unique32_t uq32; 133 drm_unique_t __user *u; 134 int err; 135 136 if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32))) 137 return -EFAULT; 138 139 u = compat_alloc_user_space(sizeof(*u)); 140 if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) 141 return -EFAULT; 142 if (__put_user(uq32.unique_len, &u->unique_len) 143 || __put_user((void __user *)(unsigned long) uq32.unique, 144 &u->unique)) 145 return -EFAULT; 146 147 err = drm_ioctl(file->f_dentry->d_inode, file, 148 DRM_IOCTL_GET_UNIQUE, (unsigned long) u); 149 if (err) 150 return err; 151 152 if (__get_user(uq32.unique_len, &u->unique_len)) 153 return -EFAULT; 154 if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32))) 155 return -EFAULT; 156 return 0; 157} 158 159static int compat_drm_setunique(struct file *file, unsigned int cmd, 160 unsigned long arg) 161{ 162 drm_unique32_t uq32; 163 drm_unique_t __user *u; 164 165 if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32))) 166 return -EFAULT; 167 168 u = compat_alloc_user_space(sizeof(*u)); 169 if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) 170 return -EFAULT; 171 if (__put_user(uq32.unique_len, &u->unique_len) 172 || __put_user((void __user *)(unsigned long) uq32.unique, 173 &u->unique)) 174 return -EFAULT; 175 176 return drm_ioctl(file->f_dentry->d_inode, file, 177 DRM_IOCTL_SET_UNIQUE, (unsigned long) u); 178} 179 180typedef struct drm_map32 { 181 u32 offset; /**< Requested physical address (0 for SAREA)*/ 182 u32 size; /**< Requested physical size (bytes) */ 183 drm_map_type_t type; /**< Type of memory to map */ 184 drm_map_flags_t flags; /**< Flags */ 185 u32 handle; /**< User-space: "Handle" to pass to mmap() */ 186 int mtrr; /**< MTRR slot used */ 187} drm_map32_t; 188 189static int compat_drm_getmap(struct file *file, unsigned int cmd, 190 unsigned long arg) 191{ 192 drm_map32_t __user *argp = (void __user *)arg; 193 drm_map32_t m32; 194 drm_map_t __user *map; 195 int idx, err; 196 void *handle; 197 198 if (get_user(idx, &argp->offset)) 199 return -EFAULT; 200 201 map = compat_alloc_user_space(sizeof(*map)); 202 if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) 203 return -EFAULT; 204 if (__put_user(idx, &map->offset)) 205 return -EFAULT; 206 207 err = drm_ioctl(file->f_dentry->d_inode, file, 208 DRM_IOCTL_GET_MAP, (unsigned long) map); 209 if (err) 210 return err; 211 212 if (__get_user(m32.offset, &map->offset) 213 || __get_user(m32.size, &map->size) 214 || __get_user(m32.type, &map->type) 215 || __get_user(m32.flags, &map->flags) 216 || __get_user(handle, &map->handle) 217 || __get_user(m32.mtrr, &map->mtrr)) 218 return -EFAULT; 219 220 m32.handle = (unsigned long) handle; 221 if (copy_to_user(argp, &m32, sizeof(m32))) 222 return -EFAULT; 223 return 0; 224 225} 226 227static int compat_drm_addmap(struct file *file, unsigned int cmd, 228 unsigned long arg) 229{ 230 drm_map32_t __user *argp = (void __user *)arg; 231 drm_map32_t m32; 232 drm_map_t __user *map; 233 int err; 234 void *handle; 235 236 if (copy_from_user(&m32, argp, sizeof(m32))) 237 return -EFAULT; 238 239 map = compat_alloc_user_space(sizeof(*map)); 240 if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) 241 return -EFAULT; 242 if (__put_user(m32.offset, &map->offset) 243 || __put_user(m32.size, &map->size) 244 || __put_user(m32.type, &map->type) 245 || __put_user(m32.flags, &map->flags)) 246 return -EFAULT; 247 248 err = drm_ioctl(file->f_dentry->d_inode, file, 249 DRM_IOCTL_ADD_MAP, (unsigned long) map); 250 if (err) 251 return err; 252 253 if (__get_user(m32.offset, &map->offset) 254 || __get_user(m32.mtrr, &map->mtrr) 255 || __get_user(handle, &map->handle)) 256 return -EFAULT; 257 258 m32.handle = (unsigned long) handle; 259 if (m32.handle != (unsigned long) handle && printk_ratelimit()) 260 printk(KERN_ERR "compat_drm_addmap truncated handle" 261 " %p for type %d offset %x\n", 262 handle, m32.type, m32.offset); 263 264 if (copy_to_user(argp, &m32, sizeof(m32))) 265 return -EFAULT; 266 267 return 0; 268} 269 270static int compat_drm_rmmap(struct file *file, unsigned int cmd, 271 unsigned long arg) 272{ 273 drm_map32_t __user *argp = (void __user *)arg; 274 drm_map_t __user *map; 275 u32 handle; 276 277 if (get_user(handle, &argp->handle)) 278 return -EFAULT; 279 280 map = compat_alloc_user_space(sizeof(*map)); 281 if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) 282 return -EFAULT; 283 if (__put_user((void *)(unsigned long) handle, &map->handle)) 284 return -EFAULT; 285 286 return drm_ioctl(file->f_dentry->d_inode, file, 287 DRM_IOCTL_RM_MAP, (unsigned long) map); 288} 289 290typedef struct drm_client32 { 291 int idx; /**< Which client desired? */ 292 int auth; /**< Is client authenticated? */ 293 u32 pid; /**< Process ID */ 294 u32 uid; /**< User ID */ 295 u32 magic; /**< Magic */ 296 u32 iocs; /**< Ioctl count */ 297} drm_client32_t; 298 299static int compat_drm_getclient(struct file *file, unsigned int cmd, 300 unsigned long arg) 301{ 302 drm_client32_t c32; 303 drm_client32_t __user *argp = (void __user *)arg; 304 drm_client_t __user *client; 305 int idx, err; 306 307 if (get_user(idx, &argp->idx)) 308 return -EFAULT; 309 310 client = compat_alloc_user_space(sizeof(*client)); 311 if (!access_ok(VERIFY_WRITE, client, sizeof(*client))) 312 return -EFAULT; 313 if (__put_user(idx, &client->idx)) 314 return -EFAULT; 315 316 err = drm_ioctl(file->f_dentry->d_inode, file, 317 DRM_IOCTL_GET_CLIENT, (unsigned long) client); 318 if (err) 319 return err; 320 321 if (__get_user(c32.auth, &client->auth) 322 || __get_user(c32.pid, &client->pid) 323 || __get_user(c32.uid, &client->uid) 324 || __get_user(c32.magic, &client->magic) 325 || __get_user(c32.iocs, &client->iocs)) 326 return -EFAULT; 327 328 if (copy_to_user(argp, &c32, sizeof(c32))) 329 return -EFAULT; 330 return 0; 331} 332 333typedef struct drm_stats32 { 334 u32 count; 335 struct { 336 u32 value; 337 drm_stat_type_t type; 338 } data[15]; 339} drm_stats32_t; 340 341static int compat_drm_getstats(struct file *file, unsigned int cmd, 342 unsigned long arg) 343{ 344 drm_stats32_t s32; 345 drm_stats32_t __user *argp = (void __user *)arg; 346 drm_stats_t __user *stats; 347 int i, err; 348 349 stats = compat_alloc_user_space(sizeof(*stats)); 350 if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) 351 return -EFAULT; 352 353 err = drm_ioctl(file->f_dentry->d_inode, file, 354 DRM_IOCTL_GET_STATS, (unsigned long) stats); 355 if (err) 356 return err; 357 358 if (__get_user(s32.count, &stats->count)) 359 return -EFAULT; 360 for (i = 0; i < 15; ++i) 361 if (__get_user(s32.data[i].value, &stats->data[i].value) 362 || __get_user(s32.data[i].type, &stats->data[i].type)) 363 return -EFAULT; 364 365 if (copy_to_user(argp, &s32, sizeof(s32))) 366 return -EFAULT; 367 return 0; 368} 369 370typedef struct drm_buf_desc32 { 371 int count; /**< Number of buffers of this size */ 372 int size; /**< Size in bytes */ 373 int low_mark; /**< Low water mark */ 374 int high_mark; /**< High water mark */ 375 int flags; 376 u32 agp_start; /**< Start address in the AGP aperture */ 377} drm_buf_desc32_t; 378 379static int compat_drm_addbufs(struct file *file, unsigned int cmd, 380 unsigned long arg) 381{ 382 drm_buf_desc32_t __user *argp = (void __user *)arg; 383 drm_buf_desc_t __user *buf; 384 int err; 385 unsigned long agp_start; 386 387 buf = compat_alloc_user_space(sizeof(*buf)); 388 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)) 389 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))) 390 return -EFAULT; 391 392 if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start)) 393 || __get_user(agp_start, &argp->agp_start) 394 || __put_user(agp_start, &buf->agp_start)) 395 return -EFAULT; 396 397 err = drm_ioctl(file->f_dentry->d_inode, file, 398 DRM_IOCTL_ADD_BUFS, (unsigned long) buf); 399 if (err) 400 return err; 401 402 if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start)) 403 || __get_user(agp_start, &buf->agp_start) 404 || __put_user(agp_start, &argp->agp_start)) 405 return -EFAULT; 406 407 return 0; 408} 409 410static int compat_drm_markbufs(struct file *file, unsigned int cmd, 411 unsigned long arg) 412{ 413 drm_buf_desc32_t b32; 414 drm_buf_desc32_t __user *argp = (void __user *)arg; 415 drm_buf_desc_t __user *buf; 416 417 if (copy_from_user(&b32, argp, sizeof(b32))) 418 return -EFAULT; 419 420 buf = compat_alloc_user_space(sizeof(*buf)); 421 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))) 422 return -EFAULT; 423 424 if (__put_user(b32.size, &buf->size) 425 || __put_user(b32.low_mark, &buf->low_mark) 426 || __put_user(b32.high_mark, &buf->high_mark)) 427 return -EFAULT; 428 429 return drm_ioctl(file->f_dentry->d_inode, file, 430 DRM_IOCTL_MARK_BUFS, (unsigned long) buf); 431} 432 433typedef struct drm_buf_info32 { 434 int count; /**< Entries in list */ 435 u32 list; 436} drm_buf_info32_t; 437 438static int compat_drm_infobufs(struct file *file, unsigned int cmd, 439 unsigned long arg) 440{ 441 drm_buf_info32_t req32; 442 drm_buf_info32_t __user *argp = (void __user *)arg; 443 drm_buf_desc32_t __user *to; 444 drm_buf_info_t __user *request; 445 drm_buf_desc_t __user *list; 446 size_t nbytes; 447 int i, err; 448 int count, actual; 449 450 if (copy_from_user(&req32, argp, sizeof(req32))) 451 return -EFAULT; 452 453 count = req32.count; 454 to = (drm_buf_desc32_t __user *)(unsigned long) req32.list; 455 if (count < 0) 456 count = 0; 457 if (count > 0 458 && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t))) 459 return -EFAULT; 460 461 nbytes = sizeof(*request) + count * sizeof(drm_buf_desc_t); 462 request = compat_alloc_user_space(nbytes); 463 if (!access_ok(VERIFY_WRITE, request, nbytes)) 464 return -EFAULT; 465 list = (drm_buf_desc_t *) (request + 1); 466 467 if (__put_user(count, &request->count) 468 || __put_user(list, &request->list)) 469 return -EFAULT; 470 471 err = drm_ioctl(file->f_dentry->d_inode, file, 472 DRM_IOCTL_INFO_BUFS, (unsigned long) request); 473 if (err) 474 return err; 475 476 if (__get_user(actual, &request->count)) 477 return -EFAULT; 478 if (count >= actual) 479 for (i = 0; i < actual; ++i) 480 if (__copy_in_user(&to[i], &list[i], 481 offsetof(drm_buf_desc_t, flags))) 482 return -EFAULT; 483 484 if (__put_user(actual, &argp->count)) 485 return -EFAULT; 486 487 return 0; 488} 489 490typedef struct drm_buf_pub32 { 491 int idx; /**< Index into the master buffer list */ 492 int total; /**< Buffer size */ 493 int used; /**< Amount of buffer in use (for DMA) */ 494 u32 address; /**< Address of buffer */ 495} drm_buf_pub32_t; 496 497typedef struct drm_buf_map32 { 498 int count; /**< Length of the buffer list */ 499 u32 virtual; /**< Mmap'd area in user-virtual */ 500 u32 list; /**< Buffer information */ 501} drm_buf_map32_t; 502 503static int compat_drm_mapbufs(struct file *file, unsigned int cmd, 504 unsigned long arg) 505{ 506 drm_buf_map32_t __user *argp = (void __user *)arg; 507 drm_buf_map32_t req32; 508 drm_buf_pub32_t __user *list32; 509 drm_buf_map_t __user *request; 510 drm_buf_pub_t __user *list; 511 int i, err; 512 int count, actual; 513 size_t nbytes; 514 void __user *addr; 515 516 if (copy_from_user(&req32, argp, sizeof(req32))) 517 return -EFAULT; 518 count = req32.count; 519 list32 = (void __user *)(unsigned long)req32.list; 520 521 if (count < 0) 522 return -EINVAL; 523 nbytes = sizeof(*request) + count * sizeof(drm_buf_pub_t); 524 request = compat_alloc_user_space(nbytes); 525 if (!access_ok(VERIFY_WRITE, request, nbytes)) 526 return -EFAULT; 527 list = (drm_buf_pub_t *) (request + 1); 528 529 if (__put_user(count, &request->count) 530 || __put_user(list, &request->list)) 531 return -EFAULT; 532 533 err = drm_ioctl(file->f_dentry->d_inode, file, 534 DRM_IOCTL_MAP_BUFS, (unsigned long) request); 535 if (err) 536 return err; 537 538 if (__get_user(actual, &request->count)) 539 return -EFAULT; 540 if (count >= actual) 541 for (i = 0; i < actual; ++i) 542 if (__copy_in_user(&list32[i], &list[i], 543 offsetof(drm_buf_pub_t, address)) 544 || __get_user(addr, &list[i].address) 545 || __put_user((unsigned long) addr, 546 &list32[i].address)) 547 return -EFAULT; 548 549 if (__put_user(actual, &argp->count) 550 || __get_user(addr, &request->virtual) 551 || __put_user((unsigned long) addr, &argp->virtual)) 552 return -EFAULT; 553 554 return 0; 555} 556 557typedef struct drm_buf_free32 { 558 int count; 559 u32 list; 560} drm_buf_free32_t; 561 562static int compat_drm_freebufs(struct file *file, unsigned int cmd, 563 unsigned long arg) 564{ 565 drm_buf_free32_t req32; 566 drm_buf_free_t __user *request; 567 drm_buf_free32_t __user *argp = (void __user *)arg; 568 569 if (copy_from_user(&req32, argp, sizeof(req32))) 570 return -EFAULT; 571 572 request = compat_alloc_user_space(sizeof(*request)); 573 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) 574 return -EFAULT; 575 if (__put_user(req32.count, &request->count) 576 || __put_user((int __user *)(unsigned long) req32.list, 577 &request->list)) 578 return -EFAULT; 579 580 return drm_ioctl(file->f_dentry->d_inode, file, 581 DRM_IOCTL_FREE_BUFS, (unsigned long) request); 582} 583 584typedef struct drm_ctx_priv_map32 { 585 unsigned int ctx_id; /**< Context requesting private mapping */ 586 u32 handle; /**< Handle of map */ 587} drm_ctx_priv_map32_t; 588 589static int compat_drm_setsareactx(struct file *file, unsigned int cmd, 590 unsigned long arg) 591{ 592 drm_ctx_priv_map32_t req32; 593 drm_ctx_priv_map_t __user *request; 594 drm_ctx_priv_map32_t __user *argp = (void __user *)arg; 595 596 if (copy_from_user(&req32, argp, sizeof(req32))) 597 return -EFAULT; 598 599 request = compat_alloc_user_space(sizeof(*request)); 600 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) 601 return -EFAULT; 602 if (__put_user(req32.ctx_id, &request->ctx_id) 603 || __put_user((void *)(unsigned long) req32.handle, 604 &request->handle)) 605 return -EFAULT; 606 607 return drm_ioctl(file->f_dentry->d_inode, file, 608 DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request); 609} 610 611static int compat_drm_getsareactx(struct file *file, unsigned int cmd, 612 unsigned long arg) 613{ 614 drm_ctx_priv_map_t __user *request; 615 drm_ctx_priv_map32_t __user *argp = (void __user *)arg; 616 int err; 617 unsigned int ctx_id; 618 void *handle; 619 620 if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp)) 621 || __get_user(ctx_id, &argp->ctx_id)) 622 return -EFAULT; 623 624 request = compat_alloc_user_space(sizeof(*request)); 625 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) 626 return -EFAULT; 627 if (__put_user(ctx_id, &request->ctx_id)) 628 return -EFAULT; 629 630 err = drm_ioctl(file->f_dentry->d_inode, file, 631 DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request); 632 if (err) 633 return err; 634 635 if (__get_user(handle, &request->handle) 636 || __put_user((unsigned long) handle, &argp->handle)) 637 return -EFAULT; 638 639 return 0; 640} 641 642typedef struct drm_ctx_res32 { 643 int count; 644 u32 contexts; 645} drm_ctx_res32_t; 646 647static int compat_drm_resctx(struct file *file, unsigned int cmd, 648 unsigned long arg) 649{ 650 drm_ctx_res32_t __user *argp = (void __user *)arg; 651 drm_ctx_res32_t res32; 652 drm_ctx_res_t __user *res; 653 int err; 654 655 if (copy_from_user(&res32, argp, sizeof(res32))) 656 return -EFAULT; 657 658 res = compat_alloc_user_space(sizeof(*res)); 659 if (!access_ok(VERIFY_WRITE, res, sizeof(*res))) 660 return -EFAULT; 661 if (__put_user(res32.count, &res->count) 662 || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts, 663 &res->contexts)) 664 return -EFAULT; 665 666 err = drm_ioctl(file->f_dentry->d_inode, file, 667 DRM_IOCTL_RES_CTX, (unsigned long) res); 668 if (err) 669 return err; 670 671 if (__get_user(res32.count, &res->count) 672 || __put_user(res32.count, &argp->count)) 673 return -EFAULT; 674 675 return 0; 676} 677 678typedef struct drm_dma32 { 679 int context; /**< Context handle */ 680 int send_count; /**< Number of buffers to send */ 681 u32 send_indices; /**< List of handles to buffers */ 682 u32 send_sizes; /**< Lengths of data to send */ 683 drm_dma_flags_t flags; /**< Flags */ 684 int request_count; /**< Number of buffers requested */ 685 int request_size; /**< Desired size for buffers */ 686 u32 request_indices; /**< Buffer information */ 687 u32 request_sizes; 688 int granted_count; /**< Number of buffers granted */ 689} drm_dma32_t; 690 691static int compat_drm_dma(struct file *file, unsigned int cmd, 692 unsigned long arg) 693{ 694 drm_dma32_t d32; 695 drm_dma32_t __user *argp = (void __user *) arg; 696 drm_dma_t __user *d; 697 int err; 698 699 if (copy_from_user(&d32, argp, sizeof(d32))) 700 return -EFAULT; 701 702 d = compat_alloc_user_space(sizeof(*d)); 703 if (!access_ok(VERIFY_WRITE, d, sizeof(*d))) 704 return -EFAULT; 705 706 if (__put_user(d32.context, &d->context) 707 || __put_user(d32.send_count, &d->send_count) 708 || __put_user((int __user *)(unsigned long) d32.send_indices, 709 &d->send_indices) 710 || __put_user((int __user *)(unsigned long) d32.send_sizes, 711 &d->send_sizes) 712 || __put_user(d32.flags, &d->flags) 713 || __put_user(d32.request_count, &d->request_count) 714 || __put_user((int __user *)(unsigned long) d32.request_indices, 715 &d->request_indices) 716 || __put_user((int __user *)(unsigned long) d32.request_sizes, 717 &d->request_sizes)) 718 return -EFAULT; 719 720 err = drm_ioctl(file->f_dentry->d_inode, file, 721 DRM_IOCTL_DMA, (unsigned long) d); 722 if (err) 723 return err; 724 725 if (__get_user(d32.request_size, &d->request_size) 726 || __get_user(d32.granted_count, &d->granted_count) 727 || __put_user(d32.request_size, &argp->request_size) 728 || __put_user(d32.granted_count, &argp->granted_count)) 729 return -EFAULT; 730 731 return 0; 732} 733 734#if __OS_HAS_AGP 735typedef struct drm_agp_mode32 { 736 u32 mode; /**< AGP mode */ 737} drm_agp_mode32_t; 738 739static int compat_drm_agp_enable(struct file *file, unsigned int cmd, 740 unsigned long arg) 741{ 742 drm_agp_mode32_t __user *argp = (void __user *)arg; 743 drm_agp_mode32_t m32; 744 drm_agp_mode_t __user *mode; 745 746 if (get_user(m32.mode, &argp->mode)) 747 return -EFAULT; 748 749 mode = compat_alloc_user_space(sizeof(*mode)); 750 if (put_user(m32.mode, &mode->mode)) 751 return -EFAULT; 752 753 return drm_ioctl(file->f_dentry->d_inode, file, 754 DRM_IOCTL_AGP_ENABLE, (unsigned long) mode); 755} 756 757typedef struct drm_agp_info32 { 758 int agp_version_major; 759 int agp_version_minor; 760 u32 mode; 761 u32 aperture_base; /* physical address */ 762 u32 aperture_size; /* bytes */ 763 u32 memory_allowed; /* bytes */ 764 u32 memory_used; 765 766 /* PCI information */ 767 unsigned short id_vendor; 768 unsigned short id_device; 769} drm_agp_info32_t; 770 771static int compat_drm_agp_info(struct file *file, unsigned int cmd, 772 unsigned long arg) 773{ 774 drm_agp_info32_t __user *argp = (void __user *)arg; 775 drm_agp_info32_t i32; 776 drm_agp_info_t __user *info; 777 int err; 778 779 info = compat_alloc_user_space(sizeof(*info)); 780 if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) 781 return -EFAULT; 782 783 err = drm_ioctl(file->f_dentry->d_inode, file, 784 DRM_IOCTL_AGP_INFO, (unsigned long) info); 785 if (err) 786 return err; 787 788 if (__get_user(i32.agp_version_major, &info->agp_version_major) 789 || __get_user(i32.agp_version_minor, &info->agp_version_minor) 790 || __get_user(i32.mode, &info->mode) 791 || __get_user(i32.aperture_base, &info->aperture_base) 792 || __get_user(i32.aperture_size, &info->aperture_size) 793 || __get_user(i32.memory_allowed, &info->memory_allowed) 794 || __get_user(i32.memory_used, &info->memory_used) 795 || __get_user(i32.id_vendor, &info->id_vendor) 796 || __get_user(i32.id_device, &info->id_device)) 797 return -EFAULT; 798 799 if (copy_to_user(argp, &i32, sizeof(i32))) 800 return -EFAULT; 801 802 return 0; 803} 804 805typedef struct drm_agp_buffer32 { 806 u32 size; /**< In bytes -- will round to page boundary */ 807 u32 handle; /**< Used for binding / unbinding */ 808 u32 type; /**< Type of memory to allocate */ 809 u32 physical; /**< Physical used by i810 */ 810} drm_agp_buffer32_t; 811 812static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, 813 unsigned long arg) 814{ 815 drm_agp_buffer32_t __user *argp = (void __user *)arg; 816 drm_agp_buffer32_t req32; 817 drm_agp_buffer_t __user *request; 818 int err; 819 820 if (copy_from_user(&req32, argp, sizeof(req32))) 821 return -EFAULT; 822 823 request = compat_alloc_user_space(sizeof(*request)); 824 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 825 || __put_user(req32.size, &request->size) 826 || __put_user(req32.type, &request->type)) 827 return -EFAULT; 828 829 err = drm_ioctl(file->f_dentry->d_inode, file, 830 DRM_IOCTL_AGP_ALLOC, (unsigned long) request); 831 if (err) 832 return err; 833 834 if (__get_user(req32.handle, &request->handle) 835 || __get_user(req32.physical, &request->physical) 836 || copy_to_user(argp, &req32, sizeof(req32))) { 837 drm_ioctl(file->f_dentry->d_inode, file, 838 DRM_IOCTL_AGP_FREE, (unsigned long) request); 839 return -EFAULT; 840 } 841 842 return 0; 843} 844 845static int compat_drm_agp_free(struct file *file, unsigned int cmd, 846 unsigned long arg) 847{ 848 drm_agp_buffer32_t __user *argp = (void __user *)arg; 849 drm_agp_buffer_t __user *request; 850 u32 handle; 851 852 request = compat_alloc_user_space(sizeof(*request)); 853 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 854 || get_user(handle, &argp->handle) 855 || __put_user(handle, &request->handle)) 856 return -EFAULT; 857 858 return drm_ioctl(file->f_dentry->d_inode, file, 859 DRM_IOCTL_AGP_FREE, (unsigned long) request); 860} 861 862typedef struct drm_agp_binding32 { 863 u32 handle; /**< From drm_agp_buffer */ 864 u32 offset; /**< In bytes -- will round to page boundary */ 865} drm_agp_binding32_t; 866 867static int compat_drm_agp_bind(struct file *file, unsigned int cmd, 868 unsigned long arg) 869{ 870 drm_agp_binding32_t __user *argp = (void __user *)arg; 871 drm_agp_binding32_t req32; 872 drm_agp_binding_t __user *request; 873 874 if (copy_from_user(&req32, argp, sizeof(req32))) 875 return -EFAULT; 876 877 request = compat_alloc_user_space(sizeof(*request)); 878 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 879 || __put_user(req32.handle, &request->handle) 880 || __put_user(req32.offset, &request->offset)) 881 return -EFAULT; 882 883 return drm_ioctl(file->f_dentry->d_inode, file, 884 DRM_IOCTL_AGP_BIND, (unsigned long) request); 885} 886 887static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, 888 unsigned long arg) 889{ 890 drm_agp_binding32_t __user *argp = (void __user *)arg; 891 drm_agp_binding_t __user *request; 892 u32 handle; 893 894 request = compat_alloc_user_space(sizeof(*request)); 895 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 896 || get_user(handle, &argp->handle) 897 || __put_user(handle, &request->handle)) 898 return -EFAULT; 899 900 return drm_ioctl(file->f_dentry->d_inode, file, 901 DRM_IOCTL_AGP_UNBIND, (unsigned long) request); 902} 903#endif /* __OS_HAS_AGP */ 904 905typedef struct drm_scatter_gather32 { 906 u32 size; /**< In bytes -- will round to page boundary */ 907 u32 handle; /**< Used for mapping / unmapping */ 908} drm_scatter_gather32_t; 909 910static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, 911 unsigned long arg) 912{ 913 drm_scatter_gather32_t __user *argp = (void __user *)arg; 914 drm_scatter_gather_t __user *request; 915 int err; 916 unsigned long x; 917 918 request = compat_alloc_user_space(sizeof(*request)); 919 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 920 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) 921 || __get_user(x, &argp->size) 922 || __put_user(x, &request->size)) 923 return -EFAULT; 924 925 err = drm_ioctl(file->f_dentry->d_inode, file, 926 DRM_IOCTL_SG_ALLOC, (unsigned long) request); 927 if (err) 928 return err; 929 930 /* XXX not sure about the handle conversion here... */ 931 if (__get_user(x, &request->handle) 932 || __put_user(x >> PAGE_SHIFT, &argp->handle)) 933 return -EFAULT; 934 935 return 0; 936} 937 938static int compat_drm_sg_free(struct file *file, unsigned int cmd, 939 unsigned long arg) 940{ 941 drm_scatter_gather32_t __user *argp = (void __user *)arg; 942 drm_scatter_gather_t __user *request; 943 unsigned long x; 944 945 request = compat_alloc_user_space(sizeof(*request)); 946 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 947 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) 948 || __get_user(x, &argp->handle) 949 || __put_user(x << PAGE_SHIFT, &request->handle)) 950 return -EFAULT; 951 952 return drm_ioctl(file->f_dentry->d_inode, file, 953 DRM_IOCTL_SG_FREE, (unsigned long) request); 954} 955 956struct drm_wait_vblank_request32 { 957 drm_vblank_seq_type_t type; 958 unsigned int sequence; 959 u32 signal; 960}; 961 962struct drm_wait_vblank_reply32 { 963 drm_vblank_seq_type_t type; 964 unsigned int sequence; 965 s32 tval_sec; 966 s32 tval_usec; 967}; 968 969typedef union drm_wait_vblank32 { 970 struct drm_wait_vblank_request32 request; 971 struct drm_wait_vblank_reply32 reply; 972} drm_wait_vblank32_t; 973 974static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, 975 unsigned long arg) 976{ 977 drm_wait_vblank32_t __user *argp = (void __user *)arg; 978 drm_wait_vblank32_t req32; 979 drm_wait_vblank_t __user *request; 980 int err; 981 982 if (copy_from_user(&req32, argp, sizeof(req32))) 983 return -EFAULT; 984 985 request = compat_alloc_user_space(sizeof(*request)); 986 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) 987 || __put_user(req32.request.type, &request->request.type) 988 || __put_user(req32.request.sequence, &request->request.sequence) 989 || __put_user(req32.request.signal, &request->request.signal)) 990 return -EFAULT; 991 992 err = drm_ioctl(file->f_dentry->d_inode, file, 993 DRM_IOCTL_WAIT_VBLANK, (unsigned long) request); 994 if (err) 995 return err; 996 997 if (__get_user(req32.reply.type, &request->reply.type) 998 || __get_user(req32.reply.sequence, &request->reply.sequence) 999 || __get_user(req32.reply.tval_sec, &request->reply.tval_sec) 1000 || __get_user(req32.reply.tval_usec, &request->reply.tval_usec)) 1001 return -EFAULT; 1002 1003 if (copy_to_user(argp, &req32, sizeof(req32))) 1004 return -EFAULT; 1005 1006 return 0; 1007} 1008 1009drm_ioctl_compat_t *drm_compat_ioctls[] = { 1010 [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, 1011 [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, 1012 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap, 1013 [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient, 1014 [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats, 1015 [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique, 1016 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap, 1017 [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs, 1018 [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs, 1019 [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs, 1020 [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs, 1021 [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs, 1022 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap, 1023 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx, 1024 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx, 1025 [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx, 1026 [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma, 1027#if __OS_HAS_AGP 1028 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable, 1029 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info, 1030 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc, 1031 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free, 1032 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind, 1033 [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind, 1034#endif 1035 [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc, 1036 [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free, 1037 [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, 1038}; 1039 1040/** 1041 * Called whenever a 32-bit process running under a 64-bit kernel 1042 * performs an ioctl on /dev/drm. 1043 * 1044 * \param filp file pointer. 1045 * \param cmd command. 1046 * \param arg user argument. 1047 * \return zero on success or negative number on failure. 1048 */ 1049long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 1050{ 1051 unsigned int nr = DRM_IOCTL_NR(cmd); 1052 drm_ioctl_compat_t *fn; 1053 int ret; 1054 1055 if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls)) 1056 return -ENOTTY; 1057 1058 fn = drm_compat_ioctls[nr]; 1059 1060 lock_kernel(); /* XXX for now */ 1061 if (fn != NULL) 1062 ret = (*fn)(filp, cmd, arg); 1063 else 1064 ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); 1065 unlock_kernel(); 1066 1067 return ret; 1068} 1069EXPORT_SYMBOL(drm_compat_ioctl);