1 /*- 2 * Copyright 2003 Eric Anholt 3 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Rickard E. (Rik) Faith <faith@valinux.com> 28 * Daryll Strauss <daryll@valinux.com> 29 * Gareth Hughes <gareth@valinux.com> 30 * 31 */ 32 33 /** @file drm_drv.c 34 * The catch-all file for DRM device support, including module setup/teardown, 35 * open/close, and ioctl dispatch. 36 */ 37 38 #include <sys/limits.h> 39 #include <sys/ttycom.h> /* for TIOCSGRP */ 40 41 #include "drmP.h" 42 #include "drm.h" 43 #include "drm_sarea.h" 44 45 #ifdef DRM_DEBUG_DEFAULT_ON 46 int drm_debug_flag = 1; 47 #else 48 int drm_debug_flag = 0; 49 #endif 50 51 int drm_firstopen(struct drm_device *); 52 int drm_lastclose(struct drm_device *); 53 void drm_attach(struct device *, struct device *, void *); 54 int drm_probe(struct device *, void *, void *); 55 int drm_detach(struct device *, int); 56 int drm_activate(struct device *, enum devact); 57 int drmprint(void *, const char *); 58 59 int drm_getunique(struct drm_device *, void *, struct drm_file *); 60 int drm_version(struct drm_device *, void *, struct drm_file *); 61 int drm_setversion(struct drm_device *, void *, struct drm_file *); 62 int drm_getmagic(struct drm_device *, void *, struct drm_file *); 63 int drm_authmagic(struct drm_device *, void *, struct drm_file *); 64 int drm_file_cmp(struct drm_file *, struct drm_file *); 65 SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp); 66 67 /* 68 * attach drm to a pci-based driver. 69 * 70 * This function does all the pci-specific calculations for the 71 * drm_attach_args. 72 */ 73 struct device * 74 drm_attach_pci(const struct drm_driver_info *driver, struct pci_attach_args *pa, 75 int is_agp, struct device *dev) 76 { 77 struct drm_attach_args arg; 78 79 arg.driver = driver; 80 arg.dmat = pa->pa_dmat; 81 arg.bst = pa->pa_memt; 82 arg.irq = pa->pa_intrline; 83 arg.is_agp = is_agp; 84 85 arg.busid_len = 20; 86 arg.busid = malloc(arg.busid_len + 1, M_DRM, M_NOWAIT); 87 if (arg.busid == NULL) { 88 printf("%s: no memory for drm\n", dev->dv_xname); 89 return (NULL); 90 } 91 snprintf(arg.busid, arg.busid_len, "pci:%04x:%02x:%02x.%1x", 92 pa->pa_domain, pa->pa_bus, pa->pa_device, pa->pa_function); 93 94 return (config_found(dev, &arg, drmprint)); 95 } 96 97 int 98 drmprint(void *aux, const char *pnp) 99 { 100 if (pnp != NULL) 101 printf("drm at %s", pnp); 102 return (UNCONF); 103 } 104 105 int 106 drm_pciprobe(struct pci_attach_args *pa, const struct drm_pcidev *idlist) 107 { 108 const struct drm_pcidev *id_entry; 109 110 id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), 111 PCI_PRODUCT(pa->pa_id), idlist); 112 if (id_entry != NULL) 113 return 1; 114 115 return 0; 116 } 117 118 int 119 drm_probe(struct device *parent, void *match, void *aux) 120 { 121 struct drm_attach_args *da = aux; 122 123 return (da->driver != NULL ? 1 : 0); 124 } 125 126 void 127 drm_attach(struct device *parent, struct device *self, void *aux) 128 { 129 struct drm_device *dev = (struct drm_device *)self; 130 struct drm_attach_args *da = aux; 131 132 dev->dev_private = parent; 133 dev->driver = da->driver; 134 135 dev->dmat = da->dmat; 136 dev->bst = da->bst; 137 dev->irq = da->irq; 138 dev->unique = da->busid; 139 dev->unique_len = da->busid_len; 140 141 rw_init(&dev->dev_lock, "drmdevlk"); 142 mtx_init(&dev->lock.spinlock, IPL_NONE); 143 144 TAILQ_INIT(&dev->maplist); 145 SPLAY_INIT(&dev->files); 146 147 if (dev->driver->vblank_pipes != 0 && drm_vblank_init(dev, 148 dev->driver->vblank_pipes)) { 149 printf(": failed to allocate vblank data\n"); 150 goto error; 151 } 152 153 /* 154 * the dma buffers api is just weird. offset 1Gb to ensure we don't 155 * conflict with it. 156 */ 157 dev->handle_ext = extent_create("drmext", 1024*1024*1024, LONG_MAX, 158 M_DRM, NULL, NULL, EX_NOWAIT | EX_NOCOALESCE); 159 if (dev->handle_ext == NULL) { 160 DRM_ERROR("Failed to initialise handle extent\n"); 161 goto error; 162 } 163 164 if (dev->driver->flags & DRIVER_AGP) { 165 if (da->is_agp) 166 dev->agp = drm_agp_init(); 167 if (dev->driver->flags & DRIVER_AGP_REQUIRE && 168 dev->agp == NULL) { 169 printf(": couldn't find agp\n"); 170 goto error; 171 } 172 if (dev->agp != NULL) { 173 if (drm_mtrr_add(dev->agp->info.ai_aperture_base, 174 dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0) 175 dev->agp->mtrr = 1; 176 } 177 } 178 179 if (drm_ctxbitmap_init(dev) != 0) { 180 printf(": couldn't allocate memory for context bitmap.\n"); 181 goto error; 182 } 183 printf("\n"); 184 return; 185 186 error: 187 drm_lastclose(dev); 188 } 189 190 int 191 drm_detach(struct device *self, int flags) 192 { 193 struct drm_device *dev = (struct drm_device *)self; 194 195 drm_lastclose(dev); 196 197 drm_ctxbitmap_cleanup(dev); 198 199 extent_destroy(dev->handle_ext); 200 201 drm_vblank_cleanup(dev); 202 203 if (dev->agp && dev->agp->mtrr) { 204 int retcode; 205 206 retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base, 207 dev->agp->info.ai_aperture_size, DRM_MTRR_WC); 208 DRM_DEBUG("mtrr_del = %d", retcode); 209 } 210 211 212 if (dev->agp != NULL) { 213 drm_free(dev->agp); 214 dev->agp = NULL; 215 } 216 217 return 0; 218 } 219 220 int 221 drm_activate(struct device *self, enum devact act) 222 { 223 switch (act) { 224 case DVACT_ACTIVATE: 225 return (EOPNOTSUPP); 226 break; 227 228 case DVACT_DEACTIVATE: 229 /* FIXME */ 230 break; 231 } 232 return (0); 233 } 234 235 struct cfattach drm_ca = { 236 sizeof(struct drm_device), drm_probe, drm_attach, 237 drm_detach, drm_activate 238 }; 239 240 struct cfdriver drm_cd = { 241 0, "drm", DV_DULL 242 }; 243 244 const struct drm_pcidev * 245 drm_find_description(int vendor, int device, const struct drm_pcidev *idlist) 246 { 247 int i = 0; 248 249 for (i = 0; idlist[i].vendor != 0; i++) { 250 if ((idlist[i].vendor == vendor) && 251 (idlist[i].device == device)) 252 return &idlist[i]; 253 } 254 return NULL; 255 } 256 257 int 258 drm_file_cmp(struct drm_file *f1, struct drm_file *f2) 259 { 260 return (f1->minor < f2->minor ? -1 : f1->minor > f2->minor); 261 } 262 263 SPLAY_GENERATE(drm_file_tree, drm_file, link, drm_file_cmp); 264 265 struct drm_file * 266 drm_find_file_by_minor(struct drm_device *dev, int minor) 267 { 268 struct drm_file key; 269 270 key.minor = minor; 271 return (SPLAY_FIND(drm_file_tree, &dev->files, &key)); 272 } 273 274 int 275 drm_firstopen(struct drm_device *dev) 276 { 277 struct drm_local_map *map; 278 int i; 279 280 /* prebuild the SAREA */ 281 i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, 282 _DRM_CONTAINS_LOCK, &map); 283 if (i != 0) 284 return i; 285 286 if (dev->driver->firstopen) 287 dev->driver->firstopen(dev); 288 289 if (dev->driver->flags & DRIVER_DMA) { 290 if ((i = drm_dma_setup(dev)) != 0) 291 return (i); 292 } 293 294 dev->magicid = 1; 295 296 dev->irq_enabled = 0; 297 dev->if_version = 0; 298 299 dev->buf_pgid = 0; 300 301 DRM_DEBUG("\n"); 302 303 return 0; 304 } 305 306 int 307 drm_lastclose(struct drm_device *dev) 308 { 309 struct drm_local_map *map, *mapsave; 310 311 DRM_DEBUG("\n"); 312 313 if (dev->driver->lastclose != NULL) 314 dev->driver->lastclose(dev); 315 316 if (dev->irq_enabled) 317 drm_irq_uninstall(dev); 318 319 drm_agp_takedown(dev); 320 drm_dma_takedown(dev); 321 322 DRM_LOCK(); 323 if (dev->sg != NULL) { 324 struct drm_sg_mem *sg = dev->sg; 325 dev->sg = NULL; 326 327 DRM_UNLOCK(); 328 drm_sg_cleanup(dev, sg); 329 DRM_LOCK(); 330 } 331 332 for (map = TAILQ_FIRST(&dev->maplist); map != TAILQ_END(&dev->maplist); 333 map = mapsave) { 334 mapsave = TAILQ_NEXT(map, link); 335 if ((map->flags & _DRM_DRIVER) == 0) 336 drm_rmmap_locked(dev, map); 337 } 338 339 if (dev->lock.hw_lock != NULL) { 340 dev->lock.hw_lock = NULL; /* SHM removed */ 341 dev->lock.file_priv = NULL; 342 wakeup(&dev->lock); /* there should be nothing sleeping on it */ 343 } 344 DRM_UNLOCK(); 345 346 return 0; 347 } 348 349 int 350 drmopen(dev_t kdev, int flags, int fmt, struct proc *p) 351 { 352 struct drm_device *dev = NULL; 353 struct drm_file *priv; 354 int ret = 0; 355 356 dev = drm_get_device_from_kdev(kdev); 357 if (dev == NULL) 358 return (ENXIO); 359 360 DRM_DEBUG("open_count = %d\n", dev->open_count); 361 362 if (flags & O_EXCL) 363 return (EBUSY); /* No exclusive opens */ 364 365 DRM_LOCK(); 366 if (dev->open_count++ == 0) { 367 DRM_UNLOCK(); 368 if ((ret = drm_firstopen(dev)) != 0) 369 goto err; 370 } else { 371 DRM_UNLOCK(); 372 } 373 374 /* always allocate at least enough space for our data */ 375 priv = drm_calloc(1, max(dev->driver->file_priv_size, 376 sizeof(*priv))); 377 if (priv == NULL) { 378 ret = ENOMEM; 379 goto err; 380 } 381 382 priv->kdev = kdev; 383 priv->flags = flags; 384 priv->minor = minor(kdev); 385 DRM_DEBUG("minor = %d\n", priv->minor); 386 387 /* for compatibility root is always authenticated */ 388 priv->authenticated = DRM_SUSER(p); 389 390 if (dev->driver->open) { 391 ret = dev->driver->open(dev, priv); 392 if (ret != 0) { 393 goto free_priv; 394 } 395 } 396 397 DRM_LOCK(); 398 /* first opener automatically becomes master if root */ 399 if (SPLAY_EMPTY(&dev->files) && !DRM_SUSER(p)) { 400 DRM_UNLOCK(); 401 ret = EPERM; 402 goto free_priv; 403 } 404 405 priv->master = SPLAY_EMPTY(&dev->files); 406 407 SPLAY_INSERT(drm_file_tree, &dev->files, priv); 408 DRM_UNLOCK(); 409 410 return (0); 411 412 free_priv: 413 drm_free(priv); 414 err: 415 DRM_LOCK(); 416 --dev->open_count; 417 DRM_UNLOCK(); 418 return (ret); 419 } 420 421 int 422 drmclose(dev_t kdev, int flags, int fmt, struct proc *p) 423 { 424 struct drm_device *dev = drm_get_device_from_kdev(kdev); 425 struct drm_file *file_priv; 426 int retcode = 0; 427 428 if (dev == NULL) 429 return (ENXIO); 430 431 DRM_DEBUG("open_count = %d\n", dev->open_count); 432 433 DRM_LOCK(); 434 file_priv = drm_find_file_by_minor(dev, minor(kdev)); 435 if (file_priv == NULL) { 436 DRM_ERROR("can't find authenticator\n"); 437 retcode = EINVAL; 438 goto done; 439 } 440 DRM_UNLOCK(); 441 442 if (dev->driver->close != NULL) 443 dev->driver->close(dev, file_priv); 444 445 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", 446 DRM_CURRENTPID, (long)&dev->device, dev->open_count); 447 448 if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) 449 && dev->lock.file_priv == file_priv) { 450 DRM_DEBUG("Process %d dead, freeing lock for context %d\n", 451 DRM_CURRENTPID, 452 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 453 if (dev->driver->reclaim_buffers_locked != NULL) 454 dev->driver->reclaim_buffers_locked(dev, file_priv); 455 456 drm_lock_free(&dev->lock, 457 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 458 } else if (dev->driver->reclaim_buffers_locked != NULL && 459 dev->lock.hw_lock != NULL) { 460 mtx_enter(&dev->lock.spinlock); 461 /* The lock is required to reclaim buffers */ 462 for (;;) { 463 if (dev->lock.hw_lock == NULL) { 464 /* Device has been unregistered */ 465 retcode = EINTR; 466 break; 467 } 468 if (drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT)) { 469 dev->lock.file_priv = file_priv; 470 break; /* Got lock */ 471 } 472 /* Contention */ 473 retcode = msleep(&dev->lock, 474 &dev->lock.spinlock, PZERO | PCATCH, "drmlk2", 0); 475 if (retcode) 476 break; 477 } 478 mtx_leave(&dev->lock.spinlock); 479 if (retcode == 0) { 480 dev->driver->reclaim_buffers_locked(dev, file_priv); 481 drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT); 482 } 483 } 484 485 if (dev->driver->flags & DRIVER_DMA && 486 !dev->driver->reclaim_buffers_locked) 487 drm_reclaim_buffers(dev, file_priv); 488 489 dev->buf_pgid = 0; 490 491 DRM_LOCK(); 492 SPLAY_REMOVE(drm_file_tree, &dev->files, file_priv); 493 drm_free(file_priv); 494 495 done: 496 if (--dev->open_count == 0) { 497 DRM_UNLOCK(); 498 retcode = drm_lastclose(dev); 499 } 500 501 DRM_UNLOCK(); 502 503 return (retcode); 504 } 505 506 /* drmioctl is called whenever a process performs an ioctl on /dev/drm. 507 */ 508 int 509 drmioctl(dev_t kdev, u_long cmd, caddr_t data, int flags, 510 struct proc *p) 511 { 512 struct drm_device *dev = drm_get_device_from_kdev(kdev); 513 struct drm_file *file_priv; 514 515 if (dev == NULL) 516 return ENODEV; 517 518 DRM_LOCK(); 519 file_priv = drm_find_file_by_minor(dev, minor(kdev)); 520 DRM_UNLOCK(); 521 if (file_priv == NULL) { 522 DRM_ERROR("can't find authenticator\n"); 523 return EINVAL; 524 } 525 526 ++file_priv->ioctl_count; 527 528 DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", 529 DRM_CURRENTPID, cmd, DRM_IOCTL_NR(cmd), (long)&dev->device, 530 file_priv->authenticated); 531 532 switch (cmd) { 533 case FIONBIO: 534 case FIOASYNC: 535 return 0; 536 537 case TIOCSPGRP: 538 dev->buf_pgid = *(int *)data; 539 return 0; 540 541 case TIOCGPGRP: 542 *(int *)data = dev->buf_pgid; 543 return 0; 544 case DRM_IOCTL_VERSION: 545 return (drm_version(dev, data, file_priv)); 546 case DRM_IOCTL_GET_UNIQUE: 547 return (drm_getunique(dev, data, file_priv)); 548 case DRM_IOCTL_GET_MAGIC: 549 return (drm_getmagic(dev, data, file_priv)); 550 case DRM_IOCTL_WAIT_VBLANK: 551 return (drm_wait_vblank(dev, data, file_priv)); 552 case DRM_IOCTL_MODESET_CTL: 553 return (drm_modeset_ctl(dev, data, file_priv)); 554 555 /* removed */ 556 case DRM_IOCTL_GET_MAP: 557 /* FALLTHROUGH */ 558 case DRM_IOCTL_GET_CLIENT: 559 /* FALLTHROUGH */ 560 case DRM_IOCTL_GET_STATS: 561 return (EINVAL); 562 /* 563 * no-oped ioctls, we don't check permissions on them because 564 * they do nothing. they'll be removed as soon as userland is 565 * definitely purged 566 */ 567 case DRM_IOCTL_SET_SAREA_CTX: 568 case DRM_IOCTL_BLOCK: 569 case DRM_IOCTL_UNBLOCK: 570 case DRM_IOCTL_MOD_CTX: 571 case DRM_IOCTL_MARK_BUFS: 572 case DRM_IOCTL_FINISH: 573 case DRM_IOCTL_INFO_BUFS: 574 case DRM_IOCTL_SWITCH_CTX: 575 case DRM_IOCTL_NEW_CTX: 576 case DRM_IOCTL_GET_SAREA_CTX: 577 return (0); 578 } 579 580 if (file_priv->authenticated == 1) { 581 switch (cmd) { 582 case DRM_IOCTL_RM_MAP: 583 return (drm_rmmap_ioctl(dev, data, file_priv)); 584 case DRM_IOCTL_GET_CTX: 585 return (drm_getctx(dev, data, file_priv)); 586 case DRM_IOCTL_RES_CTX: 587 return (drm_resctx(dev, data, file_priv)); 588 case DRM_IOCTL_LOCK: 589 return (drm_lock(dev, data, file_priv)); 590 case DRM_IOCTL_UNLOCK: 591 return (drm_unlock(dev, data, file_priv)); 592 case DRM_IOCTL_MAP_BUFS: 593 return (drm_mapbufs(dev, data, file_priv)); 594 case DRM_IOCTL_FREE_BUFS: 595 return (drm_freebufs(dev, data, file_priv)); 596 case DRM_IOCTL_DMA: 597 return (drm_dma(dev, data, file_priv)); 598 case DRM_IOCTL_AGP_INFO: 599 return (drm_agp_info_ioctl(dev, data, file_priv)); 600 } 601 } 602 603 /* master is always root */ 604 if (file_priv->master == 1) { 605 switch(cmd) { 606 case DRM_IOCTL_SET_VERSION: 607 return (drm_setversion(dev, data, file_priv)); 608 case DRM_IOCTL_IRQ_BUSID: 609 return (drm_irq_by_busid(dev, data, file_priv)); 610 case DRM_IOCTL_AUTH_MAGIC: 611 return (drm_authmagic(dev, data, file_priv)); 612 case DRM_IOCTL_ADD_MAP: 613 return (drm_addmap_ioctl(dev, data, file_priv)); 614 case DRM_IOCTL_ADD_CTX: 615 return (drm_addctx(dev, data, file_priv)); 616 case DRM_IOCTL_RM_CTX: 617 return (drm_rmctx(dev, data, file_priv)); 618 case DRM_IOCTL_ADD_BUFS: 619 return (drm_addbufs(dev, (struct drm_buf_desc *)data)); 620 case DRM_IOCTL_CONTROL: 621 return (drm_control(dev, data, file_priv)); 622 case DRM_IOCTL_AGP_ACQUIRE: 623 return (drm_agp_acquire_ioctl(dev, data, file_priv)); 624 case DRM_IOCTL_AGP_RELEASE: 625 return (drm_agp_release_ioctl(dev, data, file_priv)); 626 case DRM_IOCTL_AGP_ENABLE: 627 return (drm_agp_enable_ioctl(dev, data, file_priv)); 628 case DRM_IOCTL_AGP_ALLOC: 629 return (drm_agp_alloc_ioctl(dev, data, file_priv)); 630 case DRM_IOCTL_AGP_FREE: 631 return (drm_agp_free_ioctl(dev, data, file_priv)); 632 case DRM_IOCTL_AGP_BIND: 633 return (drm_agp_bind_ioctl(dev, data, file_priv)); 634 case DRM_IOCTL_AGP_UNBIND: 635 return (drm_agp_unbind_ioctl(dev, data, file_priv)); 636 case DRM_IOCTL_SG_ALLOC: 637 return (drm_sg_alloc_ioctl(dev, data, file_priv)); 638 case DRM_IOCTL_SG_FREE: 639 return (drm_sg_free(dev, data, file_priv)); 640 case DRM_IOCTL_ADD_DRAW: 641 case DRM_IOCTL_RM_DRAW: 642 case DRM_IOCTL_UPDATE_DRAW: 643 /* 644 * Support removed from kernel since it's not used. 645 * just return zero until userland stops calling this 646 * ioctl. 647 */ 648 return (0); 649 case DRM_IOCTL_SET_UNIQUE: 650 /* 651 * Deprecated in DRM version 1.1, and will return EBUSY 652 * when setversion has 653 * requested version 1.1 or greater. 654 */ 655 return (EBUSY); 656 } 657 } 658 if (dev->driver->ioctl != NULL) 659 return (dev->driver->ioctl(dev, cmd, data, file_priv)); 660 else 661 return (EINVAL); 662 } 663 664 struct drm_local_map * 665 drm_getsarea(struct drm_device *dev) 666 { 667 struct drm_local_map *map; 668 669 DRM_LOCK(); 670 TAILQ_FOREACH(map, &dev->maplist, link) { 671 if (map->type == _DRM_SHM && (map->flags & _DRM_CONTAINS_LOCK)) 672 break; 673 } 674 DRM_UNLOCK(); 675 return (map); 676 } 677 678 paddr_t 679 drmmmap(dev_t kdev, off_t offset, int prot) 680 { 681 struct drm_device *dev = drm_get_device_from_kdev(kdev); 682 struct drm_local_map *map; 683 struct drm_file *priv; 684 enum drm_map_type type; 685 686 if (dev == NULL) 687 return (-1); 688 689 DRM_LOCK(); 690 priv = drm_find_file_by_minor(dev, minor(kdev)); 691 DRM_UNLOCK(); 692 if (priv == NULL) { 693 DRM_ERROR("can't find authenticator\n"); 694 return (-1); 695 } 696 697 if (!priv->authenticated) 698 return (-1); 699 700 if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) { 701 struct drm_device_dma *dma = dev->dma; 702 paddr_t phys = -1; 703 704 rw_enter_write(&dma->dma_lock); 705 if (dma->pagelist != NULL) 706 phys = atop(dma->pagelist[offset >> PAGE_SHIFT]); 707 rw_exit_write(&dma->dma_lock); 708 709 return (phys); 710 } 711 712 /* 713 * A sequential search of a linked list is 714 * fine here because: 1) there will only be 715 * about 5-10 entries in the list and, 2) a 716 * DRI client only has to do this mapping 717 * once, so it doesn't have to be optimized 718 * for performance, even if the list was a 719 * bit longer. 720 */ 721 DRM_LOCK(); 722 TAILQ_FOREACH(map, &dev->maplist, link) { 723 if (offset >= map->ext && 724 offset < map->ext + map->size) { 725 offset -= map->ext; 726 break; 727 } 728 } 729 730 if (map == NULL) { 731 DRM_UNLOCK(); 732 DRM_DEBUG("can't find map\n"); 733 return (-1); 734 } 735 if (((map->flags & _DRM_RESTRICTED) && priv->master == 0)) { 736 DRM_UNLOCK(); 737 DRM_DEBUG("restricted map\n"); 738 return (-1); 739 } 740 type = map->type; 741 DRM_UNLOCK(); 742 743 switch (type) { 744 case _DRM_FRAME_BUFFER: 745 case _DRM_REGISTERS: 746 case _DRM_AGP: 747 return (atop(offset + map->offset)); 748 break; 749 /* XXX unify all the bus_dmamem_mmap bits */ 750 case _DRM_SCATTER_GATHER: 751 return (bus_dmamem_mmap(dev->dmat, dev->sg->mem->segs, 752 dev->sg->mem->nsegs, map->offset - dev->sg->handle + 753 offset, prot, BUS_DMA_NOWAIT)); 754 case _DRM_SHM: 755 case _DRM_CONSISTENT: 756 return (bus_dmamem_mmap(dev->dmat, map->dmamem->segs, 757 map->dmamem->nsegs, offset, prot, BUS_DMA_NOWAIT)); 758 default: 759 DRM_ERROR("bad map type %d\n", type); 760 return (-1); /* This should never happen. */ 761 } 762 /* NOTREACHED */ 763 } 764 765 /* 766 * Beginning in revision 1.1 of the DRM interface, getunique will return 767 * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function) 768 * before setunique has been called. The format for the bus-specific part of 769 * the unique is not defined for any other bus. 770 */ 771 int 772 drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) 773 { 774 struct drm_unique *u = data; 775 776 if (u->unique_len >= dev->unique_len) { 777 if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len)) 778 return EFAULT; 779 } 780 u->unique_len = dev->unique_len; 781 782 return 0; 783 } 784 785 #define DRM_IF_MAJOR 1 786 #define DRM_IF_MINOR 2 787 788 int 789 drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) 790 { 791 struct drm_version *version = data; 792 int len; 793 794 #define DRM_COPY(name, value) \ 795 len = strlen( value ); \ 796 if ( len > name##_len ) len = name##_len; \ 797 name##_len = strlen( value ); \ 798 if ( len && name ) { \ 799 if ( DRM_COPY_TO_USER( name, value, len ) ) \ 800 return EFAULT; \ 801 } 802 803 version->version_major = dev->driver->major; 804 version->version_minor = dev->driver->minor; 805 version->version_patchlevel = dev->driver->patchlevel; 806 807 DRM_COPY(version->name, dev->driver->name); 808 DRM_COPY(version->date, dev->driver->date); 809 DRM_COPY(version->desc, dev->driver->desc); 810 811 return 0; 812 } 813 814 int 815 drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv) 816 { 817 struct drm_set_version ver, *sv = data; 818 int if_version; 819 820 /* Save the incoming data, and set the response before continuing 821 * any further. 822 */ 823 ver = *sv; 824 sv->drm_di_major = DRM_IF_MAJOR; 825 sv->drm_di_minor = DRM_IF_MINOR; 826 sv->drm_dd_major = dev->driver->major; 827 sv->drm_dd_minor = dev->driver->minor; 828 829 /* 830 * We no longer support interface versions less than 1.1, so error 831 * out if the xserver is too old. 1.1 always ties the drm to a 832 * certain busid, this was done on attach 833 */ 834 if (ver.drm_di_major != -1) { 835 if (ver.drm_di_major != DRM_IF_MAJOR || ver.drm_di_minor < 1 || 836 ver.drm_di_minor > DRM_IF_MINOR) { 837 return EINVAL; 838 } 839 if_version = DRM_IF_VERSION(ver.drm_di_major, ver.drm_dd_minor); 840 dev->if_version = imax(if_version, dev->if_version); 841 } 842 843 if (ver.drm_dd_major != -1) { 844 if (ver.drm_dd_major != dev->driver->major || 845 ver.drm_dd_minor < 0 || 846 ver.drm_dd_minor > dev->driver->minor) 847 return EINVAL; 848 } 849 850 return 0; 851 } 852 853 struct drm_dmamem * 854 drm_dmamem_alloc(bus_dma_tag_t dmat, bus_size_t size, bus_size_t alignment, 855 int nsegments, bus_size_t maxsegsz, int mapflags, int loadflags) 856 { 857 struct drm_dmamem *mem; 858 size_t strsize; 859 /* 860 * segs is the last member of the struct since we modify the size 861 * to allow extra segments if more than one are allowed. 862 */ 863 strsize = sizeof(*mem) + (sizeof(bus_dma_segment_t) * (nsegments - 1)); 864 mem = malloc(strsize, M_DRM, M_NOWAIT | M_ZERO); 865 if (mem == NULL) 866 return (NULL); 867 868 mem->size = size; 869 870 if (bus_dmamap_create(dmat, size, nsegments, maxsegsz, 0, 871 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mem->map) != 0) 872 goto strfree; 873 874 if (bus_dmamem_alloc(dmat, size, alignment, 0, 875 mem->segs, nsegments, &mem->nsegs, BUS_DMA_NOWAIT) != 0) 876 goto destroy; 877 878 if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, size, 879 &mem->kva, BUS_DMA_NOWAIT | mapflags) != 0) 880 goto free; 881 882 if (bus_dmamap_load(dmat, mem->map, mem->kva, size, 883 NULL, BUS_DMA_NOWAIT | loadflags) != 0) 884 goto unmap; 885 bzero(mem->kva, size); 886 887 return (mem); 888 889 unmap: 890 bus_dmamem_unmap(dmat, mem->kva, size); 891 free: 892 bus_dmamem_free(dmat, mem->segs, mem->nsegs); 893 destroy: 894 bus_dmamap_destroy(dmat, mem->map); 895 strfree: 896 free(mem, M_DRM); 897 898 return (NULL); 899 } 900 901 void 902 drm_dmamem_free(bus_dma_tag_t dmat, struct drm_dmamem *mem) 903 { 904 if (mem == NULL) 905 return; 906 907 bus_dmamap_unload(dmat, mem->map); 908 bus_dmamem_unmap(dmat, mem->kva, mem->size); 909 bus_dmamem_free(dmat, mem->segs, mem->nsegs); 910 bus_dmamap_destroy(dmat, mem->map); 911 free(mem, M_DRM); 912 } 913 914 /** 915 * Called by the client, this returns a unique magic number to be authorized 916 * by the master. 917 * 918 * The master may use its own knowledge of the client (such as the X 919 * connection that the magic is passed over) to determine if the magic number 920 * should be authenticated. 921 */ 922 int 923 drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) 924 { 925 struct drm_auth *auth = data; 926 927 if (dev->magicid == 0) 928 dev->magicid = 1; 929 930 /* Find unique magic */ 931 if (file_priv->magic) { 932 auth->magic = file_priv->magic; 933 } else { 934 DRM_LOCK(); 935 file_priv->magic = auth->magic = dev->magicid++; 936 DRM_UNLOCK(); 937 DRM_DEBUG("%d\n", auth->magic); 938 } 939 940 DRM_DEBUG("%u\n", auth->magic); 941 942 return (0); 943 } 944 945 /** 946 * Marks the client associated with the given magic number as authenticated. 947 */ 948 int 949 drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) 950 { 951 struct drm_file *p; 952 struct drm_auth *auth = data; 953 int ret = EINVAL; 954 955 DRM_DEBUG("%u\n", auth->magic); 956 957 if (auth->magic == 0) 958 return (ret); 959 960 DRM_LOCK(); 961 SPLAY_FOREACH(p, drm_file_tree, &dev->files) { 962 if (p->magic == auth->magic) { 963 p->authenticated = 1; 964 p->magic = 0; 965 ret = 0; 966 break; 967 } 968 } 969 DRM_UNLOCK(); 970 971 return (ret); 972 } 973