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 break; 226 227 case DVACT_DEACTIVATE: 228 /* FIXME */ 229 break; 230 } 231 return (0); 232 } 233 234 struct cfattach drm_ca = { 235 sizeof(struct drm_device), drm_probe, drm_attach, 236 drm_detach, drm_activate 237 }; 238 239 struct cfdriver drm_cd = { 240 0, "drm", DV_DULL 241 }; 242 243 const struct drm_pcidev * 244 drm_find_description(int vendor, int device, const struct drm_pcidev *idlist) 245 { 246 int i = 0; 247 248 for (i = 0; idlist[i].vendor != 0; i++) { 249 if ((idlist[i].vendor == vendor) && 250 (idlist[i].device == device)) 251 return &idlist[i]; 252 } 253 return NULL; 254 } 255 256 int 257 drm_file_cmp(struct drm_file *f1, struct drm_file *f2) 258 { 259 return (f1->minor < f2->minor ? -1 : f1->minor > f2->minor); 260 } 261 262 SPLAY_GENERATE(drm_file_tree, drm_file, link, drm_file_cmp); 263 264 struct drm_file * 265 drm_find_file_by_minor(struct drm_device *dev, int minor) 266 { 267 struct drm_file key; 268 269 key.minor = minor; 270 return (SPLAY_FIND(drm_file_tree, &dev->files, &key)); 271 } 272 273 int 274 drm_firstopen(struct drm_device *dev) 275 { 276 struct drm_local_map *map; 277 int i; 278 279 /* prebuild the SAREA */ 280 i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, 281 _DRM_CONTAINS_LOCK, &map); 282 if (i != 0) 283 return i; 284 285 if (dev->driver->firstopen) 286 dev->driver->firstopen(dev); 287 288 if (dev->driver->flags & DRIVER_DMA) { 289 if ((i = drm_dma_setup(dev)) != 0) 290 return (i); 291 } 292 293 dev->magicid = 1; 294 295 dev->irq_enabled = 0; 296 dev->if_version = 0; 297 298 dev->buf_pgid = 0; 299 300 DRM_DEBUG("\n"); 301 302 return 0; 303 } 304 305 int 306 drm_lastclose(struct drm_device *dev) 307 { 308 struct drm_local_map *map, *mapsave; 309 310 DRM_DEBUG("\n"); 311 312 if (dev->driver->lastclose != NULL) 313 dev->driver->lastclose(dev); 314 315 if (dev->irq_enabled) 316 drm_irq_uninstall(dev); 317 318 drm_agp_takedown(dev); 319 drm_dma_takedown(dev); 320 321 DRM_LOCK(); 322 if (dev->sg != NULL) { 323 struct drm_sg_mem *sg = dev->sg; 324 dev->sg = NULL; 325 326 DRM_UNLOCK(); 327 drm_sg_cleanup(dev, sg); 328 DRM_LOCK(); 329 } 330 331 for (map = TAILQ_FIRST(&dev->maplist); map != TAILQ_END(&dev->maplist); 332 map = mapsave) { 333 mapsave = TAILQ_NEXT(map, link); 334 if ((map->flags & _DRM_DRIVER) == 0) 335 drm_rmmap_locked(dev, map); 336 } 337 338 if (dev->lock.hw_lock != NULL) { 339 dev->lock.hw_lock = NULL; /* SHM removed */ 340 dev->lock.file_priv = NULL; 341 wakeup(&dev->lock); /* there should be nothing sleeping on it */ 342 } 343 DRM_UNLOCK(); 344 345 return 0; 346 } 347 348 int 349 drmopen(dev_t kdev, int flags, int fmt, struct proc *p) 350 { 351 struct drm_device *dev = NULL; 352 struct drm_file *file_priv; 353 int ret = 0; 354 355 dev = drm_get_device_from_kdev(kdev); 356 if (dev == NULL) 357 return (ENXIO); 358 359 DRM_DEBUG("open_count = %d\n", dev->open_count); 360 361 if (flags & O_EXCL) 362 return (EBUSY); /* No exclusive opens */ 363 364 DRM_LOCK(); 365 if (dev->open_count++ == 0) { 366 DRM_UNLOCK(); 367 if ((ret = drm_firstopen(dev)) != 0) 368 goto err; 369 } else { 370 DRM_UNLOCK(); 371 } 372 373 /* always allocate at least enough space for our data */ 374 file_priv = drm_calloc(1, max(dev->driver->file_priv_size, 375 sizeof(*file_priv))); 376 if (file_priv == NULL) { 377 ret = ENOMEM; 378 goto err; 379 } 380 381 file_priv->kdev = kdev; 382 file_priv->flags = flags; 383 file_priv->minor = minor(kdev); 384 DRM_DEBUG("minor = %d\n", file_priv->minor); 385 386 /* for compatibility root is always authenticated */ 387 file_priv->authenticated = DRM_SUSER(p); 388 389 if (dev->driver->open) { 390 ret = dev->driver->open(dev, file_priv); 391 if (ret != 0) { 392 goto free_priv; 393 } 394 } 395 396 DRM_LOCK(); 397 /* first opener automatically becomes master if root */ 398 if (SPLAY_EMPTY(&dev->files) && !DRM_SUSER(p)) { 399 DRM_UNLOCK(); 400 ret = EPERM; 401 goto free_priv; 402 } 403 404 file_priv->master = SPLAY_EMPTY(&dev->files); 405 406 SPLAY_INSERT(drm_file_tree, &dev->files, file_priv); 407 DRM_UNLOCK(); 408 409 return (0); 410 411 free_priv: 412 drm_free(file_priv); 413 err: 414 DRM_LOCK(); 415 --dev->open_count; 416 DRM_UNLOCK(); 417 return (ret); 418 } 419 420 int 421 drmclose(dev_t kdev, int flags, int fmt, struct proc *p) 422 { 423 struct drm_device *dev = drm_get_device_from_kdev(kdev); 424 struct drm_file *file_priv; 425 int retcode = 0; 426 427 if (dev == NULL) 428 return (ENXIO); 429 430 DRM_DEBUG("open_count = %d\n", dev->open_count); 431 432 DRM_LOCK(); 433 file_priv = drm_find_file_by_minor(dev, minor(kdev)); 434 if (file_priv == NULL) { 435 DRM_ERROR("can't find authenticator\n"); 436 retcode = EINVAL; 437 goto done; 438 } 439 DRM_UNLOCK(); 440 441 if (dev->driver->close != NULL) 442 dev->driver->close(dev, file_priv); 443 444 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", 445 DRM_CURRENTPID, (long)&dev->device, dev->open_count); 446 447 if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) 448 && dev->lock.file_priv == file_priv) { 449 DRM_DEBUG("Process %d dead, freeing lock for context %d\n", 450 DRM_CURRENTPID, 451 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 452 if (dev->driver->reclaim_buffers_locked != NULL) 453 dev->driver->reclaim_buffers_locked(dev, file_priv); 454 455 drm_lock_free(&dev->lock, 456 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); 457 } else if (dev->driver->reclaim_buffers_locked != NULL && 458 dev->lock.hw_lock != NULL) { 459 mtx_enter(&dev->lock.spinlock); 460 /* The lock is required to reclaim buffers */ 461 for (;;) { 462 if (dev->lock.hw_lock == NULL) { 463 /* Device has been unregistered */ 464 retcode = EINTR; 465 break; 466 } 467 if (drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT)) { 468 dev->lock.file_priv = file_priv; 469 break; /* Got lock */ 470 } 471 /* Contention */ 472 retcode = msleep(&dev->lock, 473 &dev->lock.spinlock, PZERO | PCATCH, "drmlk2", 0); 474 if (retcode) 475 break; 476 } 477 mtx_leave(&dev->lock.spinlock); 478 if (retcode == 0) { 479 dev->driver->reclaim_buffers_locked(dev, file_priv); 480 drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT); 481 } 482 } 483 484 if (dev->driver->flags & DRIVER_DMA && 485 !dev->driver->reclaim_buffers_locked) 486 drm_reclaim_buffers(dev, file_priv); 487 488 dev->buf_pgid = 0; 489 490 DRM_LOCK(); 491 SPLAY_REMOVE(drm_file_tree, &dev->files, file_priv); 492 drm_free(file_priv); 493 494 done: 495 if (--dev->open_count == 0) { 496 DRM_UNLOCK(); 497 retcode = drm_lastclose(dev); 498 } 499 500 DRM_UNLOCK(); 501 502 return (retcode); 503 } 504 505 /* drmioctl is called whenever a process performs an ioctl on /dev/drm. 506 */ 507 int 508 drmioctl(dev_t kdev, u_long cmd, caddr_t data, int flags, 509 struct proc *p) 510 { 511 struct drm_device *dev = drm_get_device_from_kdev(kdev); 512 struct drm_file *file_priv; 513 514 if (dev == NULL) 515 return ENODEV; 516 517 DRM_LOCK(); 518 file_priv = drm_find_file_by_minor(dev, minor(kdev)); 519 DRM_UNLOCK(); 520 if (file_priv == NULL) { 521 DRM_ERROR("can't find authenticator\n"); 522 return EINVAL; 523 } 524 525 ++file_priv->ioctl_count; 526 527 DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", 528 DRM_CURRENTPID, cmd, DRM_IOCTL_NR(cmd), (long)&dev->device, 529 file_priv->authenticated); 530 531 switch (cmd) { 532 case FIONBIO: 533 case FIOASYNC: 534 return 0; 535 536 case TIOCSPGRP: 537 dev->buf_pgid = *(int *)data; 538 return 0; 539 540 case TIOCGPGRP: 541 *(int *)data = dev->buf_pgid; 542 return 0; 543 case DRM_IOCTL_VERSION: 544 return (drm_version(dev, data, file_priv)); 545 case DRM_IOCTL_GET_UNIQUE: 546 return (drm_getunique(dev, data, file_priv)); 547 case DRM_IOCTL_GET_MAGIC: 548 return (drm_getmagic(dev, data, file_priv)); 549 case DRM_IOCTL_WAIT_VBLANK: 550 return (drm_wait_vblank(dev, data, file_priv)); 551 case DRM_IOCTL_MODESET_CTL: 552 return (drm_modeset_ctl(dev, data, file_priv)); 553 554 /* removed */ 555 case DRM_IOCTL_GET_MAP: 556 /* FALLTHROUGH */ 557 case DRM_IOCTL_GET_CLIENT: 558 /* FALLTHROUGH */ 559 case DRM_IOCTL_GET_STATS: 560 return (EINVAL); 561 /* 562 * no-oped ioctls, we don't check permissions on them because 563 * they do nothing. they'll be removed as soon as userland is 564 * definitely purged 565 */ 566 case DRM_IOCTL_SET_SAREA_CTX: 567 case DRM_IOCTL_BLOCK: 568 case DRM_IOCTL_UNBLOCK: 569 case DRM_IOCTL_MOD_CTX: 570 case DRM_IOCTL_MARK_BUFS: 571 case DRM_IOCTL_FINISH: 572 case DRM_IOCTL_INFO_BUFS: 573 case DRM_IOCTL_SWITCH_CTX: 574 case DRM_IOCTL_NEW_CTX: 575 case DRM_IOCTL_GET_SAREA_CTX: 576 return (0); 577 } 578 579 if (file_priv->authenticated == 1) { 580 switch (cmd) { 581 case DRM_IOCTL_RM_MAP: 582 return (drm_rmmap_ioctl(dev, data, file_priv)); 583 case DRM_IOCTL_GET_CTX: 584 return (drm_getctx(dev, data, file_priv)); 585 case DRM_IOCTL_RES_CTX: 586 return (drm_resctx(dev, data, file_priv)); 587 case DRM_IOCTL_LOCK: 588 return (drm_lock(dev, data, file_priv)); 589 case DRM_IOCTL_UNLOCK: 590 return (drm_unlock(dev, data, file_priv)); 591 case DRM_IOCTL_MAP_BUFS: 592 return (drm_mapbufs(dev, data, file_priv)); 593 case DRM_IOCTL_FREE_BUFS: 594 return (drm_freebufs(dev, data, file_priv)); 595 case DRM_IOCTL_DMA: 596 return (drm_dma(dev, data, file_priv)); 597 case DRM_IOCTL_AGP_INFO: 598 return (drm_agp_info_ioctl(dev, data, file_priv)); 599 } 600 } 601 602 /* master is always root */ 603 if (file_priv->master == 1) { 604 switch(cmd) { 605 case DRM_IOCTL_SET_VERSION: 606 return (drm_setversion(dev, data, file_priv)); 607 case DRM_IOCTL_IRQ_BUSID: 608 return (drm_irq_by_busid(dev, data, file_priv)); 609 case DRM_IOCTL_AUTH_MAGIC: 610 return (drm_authmagic(dev, data, file_priv)); 611 case DRM_IOCTL_ADD_MAP: 612 return (drm_addmap_ioctl(dev, data, file_priv)); 613 case DRM_IOCTL_ADD_CTX: 614 return (drm_addctx(dev, data, file_priv)); 615 case DRM_IOCTL_RM_CTX: 616 return (drm_rmctx(dev, data, file_priv)); 617 case DRM_IOCTL_ADD_BUFS: 618 return (drm_addbufs(dev, (struct drm_buf_desc *)data)); 619 case DRM_IOCTL_CONTROL: 620 return (drm_control(dev, data, file_priv)); 621 case DRM_IOCTL_AGP_ACQUIRE: 622 return (drm_agp_acquire_ioctl(dev, data, file_priv)); 623 case DRM_IOCTL_AGP_RELEASE: 624 return (drm_agp_release_ioctl(dev, data, file_priv)); 625 case DRM_IOCTL_AGP_ENABLE: 626 return (drm_agp_enable_ioctl(dev, data, file_priv)); 627 case DRM_IOCTL_AGP_ALLOC: 628 return (drm_agp_alloc_ioctl(dev, data, file_priv)); 629 case DRM_IOCTL_AGP_FREE: 630 return (drm_agp_free_ioctl(dev, data, file_priv)); 631 case DRM_IOCTL_AGP_BIND: 632 return (drm_agp_bind_ioctl(dev, data, file_priv)); 633 case DRM_IOCTL_AGP_UNBIND: 634 return (drm_agp_unbind_ioctl(dev, data, file_priv)); 635 case DRM_IOCTL_SG_ALLOC: 636 return (drm_sg_alloc_ioctl(dev, data, file_priv)); 637 case DRM_IOCTL_SG_FREE: 638 return (drm_sg_free(dev, data, file_priv)); 639 case DRM_IOCTL_ADD_DRAW: 640 case DRM_IOCTL_RM_DRAW: 641 case DRM_IOCTL_UPDATE_DRAW: 642 /* 643 * Support removed from kernel since it's not used. 644 * just return zero until userland stops calling this 645 * ioctl. 646 */ 647 return (0); 648 case DRM_IOCTL_SET_UNIQUE: 649 /* 650 * Deprecated in DRM version 1.1, and will return EBUSY 651 * when setversion has 652 * requested version 1.1 or greater. 653 */ 654 return (EBUSY); 655 } 656 } 657 if (dev->driver->ioctl != NULL) 658 return (dev->driver->ioctl(dev, cmd, data, file_priv)); 659 else 660 return (EINVAL); 661 } 662 663 struct drm_local_map * 664 drm_getsarea(struct drm_device *dev) 665 { 666 struct drm_local_map *map; 667 668 DRM_LOCK(); 669 TAILQ_FOREACH(map, &dev->maplist, link) { 670 if (map->type == _DRM_SHM && (map->flags & _DRM_CONTAINS_LOCK)) 671 break; 672 } 673 DRM_UNLOCK(); 674 return (map); 675 } 676 677 paddr_t 678 drmmmap(dev_t kdev, off_t offset, int prot) 679 { 680 struct drm_device *dev = drm_get_device_from_kdev(kdev); 681 struct drm_local_map *map; 682 struct drm_file *file_priv; 683 enum drm_map_type type; 684 685 if (dev == NULL) 686 return (-1); 687 688 DRM_LOCK(); 689 file_priv = drm_find_file_by_minor(dev, minor(kdev)); 690 DRM_UNLOCK(); 691 if (file_priv == NULL) { 692 DRM_ERROR("can't find authenticator\n"); 693 return (-1); 694 } 695 696 if (!file_priv->authenticated) 697 return (-1); 698 699 if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) { 700 struct drm_device_dma *dma = dev->dma; 701 paddr_t phys = -1; 702 703 rw_enter_write(&dma->dma_lock); 704 if (dma->pagelist != NULL) 705 phys = atop(dma->pagelist[offset >> PAGE_SHIFT]); 706 rw_exit_write(&dma->dma_lock); 707 708 return (phys); 709 } 710 711 /* 712 * A sequential search of a linked list is 713 * fine here because: 1) there will only be 714 * about 5-10 entries in the list and, 2) a 715 * DRI client only has to do this mapping 716 * once, so it doesn't have to be optimized 717 * for performance, even if the list was a 718 * bit longer. 719 */ 720 DRM_LOCK(); 721 TAILQ_FOREACH(map, &dev->maplist, link) { 722 if (offset >= map->ext && 723 offset < map->ext + map->size) { 724 offset -= map->ext; 725 break; 726 } 727 } 728 729 if (map == NULL) { 730 DRM_UNLOCK(); 731 DRM_DEBUG("can't find map\n"); 732 return (-1); 733 } 734 if (((map->flags & _DRM_RESTRICTED) && file_priv->master == 0)) { 735 DRM_UNLOCK(); 736 DRM_DEBUG("restricted map\n"); 737 return (-1); 738 } 739 type = map->type; 740 DRM_UNLOCK(); 741 742 switch (type) { 743 case _DRM_FRAME_BUFFER: 744 case _DRM_REGISTERS: 745 case _DRM_AGP: 746 return (atop(offset + map->offset)); 747 break; 748 /* XXX unify all the bus_dmamem_mmap bits */ 749 case _DRM_SCATTER_GATHER: 750 return (bus_dmamem_mmap(dev->dmat, dev->sg->mem->segs, 751 dev->sg->mem->nsegs, map->offset - dev->sg->handle + 752 offset, prot, BUS_DMA_NOWAIT)); 753 case _DRM_SHM: 754 case _DRM_CONSISTENT: 755 return (bus_dmamem_mmap(dev->dmat, map->dmamem->segs, 756 map->dmamem->nsegs, offset, prot, BUS_DMA_NOWAIT)); 757 default: 758 DRM_ERROR("bad map type %d\n", type); 759 return (-1); /* This should never happen. */ 760 } 761 /* NOTREACHED */ 762 } 763 764 /* 765 * Beginning in revision 1.1 of the DRM interface, getunique will return 766 * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function) 767 * before setunique has been called. The format for the bus-specific part of 768 * the unique is not defined for any other bus. 769 */ 770 int 771 drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) 772 { 773 struct drm_unique *u = data; 774 775 if (u->unique_len >= dev->unique_len) { 776 if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len)) 777 return EFAULT; 778 } 779 u->unique_len = dev->unique_len; 780 781 return 0; 782 } 783 784 #define DRM_IF_MAJOR 1 785 #define DRM_IF_MINOR 2 786 787 int 788 drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) 789 { 790 struct drm_version *version = data; 791 int len; 792 793 #define DRM_COPY(name, value) \ 794 len = strlen( value ); \ 795 if ( len > name##_len ) len = name##_len; \ 796 name##_len = strlen( value ); \ 797 if ( len && name ) { \ 798 if ( DRM_COPY_TO_USER( name, value, len ) ) \ 799 return EFAULT; \ 800 } 801 802 version->version_major = dev->driver->major; 803 version->version_minor = dev->driver->minor; 804 version->version_patchlevel = dev->driver->patchlevel; 805 806 DRM_COPY(version->name, dev->driver->name); 807 DRM_COPY(version->date, dev->driver->date); 808 DRM_COPY(version->desc, dev->driver->desc); 809 810 return 0; 811 } 812 813 int 814 drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv) 815 { 816 struct drm_set_version ver, *sv = data; 817 int if_version; 818 819 /* Save the incoming data, and set the response before continuing 820 * any further. 821 */ 822 ver = *sv; 823 sv->drm_di_major = DRM_IF_MAJOR; 824 sv->drm_di_minor = DRM_IF_MINOR; 825 sv->drm_dd_major = dev->driver->major; 826 sv->drm_dd_minor = dev->driver->minor; 827 828 /* 829 * We no longer support interface versions less than 1.1, so error 830 * out if the xserver is too old. 1.1 always ties the drm to a 831 * certain busid, this was done on attach 832 */ 833 if (ver.drm_di_major != -1) { 834 if (ver.drm_di_major != DRM_IF_MAJOR || ver.drm_di_minor < 1 || 835 ver.drm_di_minor > DRM_IF_MINOR) { 836 return EINVAL; 837 } 838 if_version = DRM_IF_VERSION(ver.drm_di_major, ver.drm_dd_minor); 839 dev->if_version = imax(if_version, dev->if_version); 840 } 841 842 if (ver.drm_dd_major != -1) { 843 if (ver.drm_dd_major != dev->driver->major || 844 ver.drm_dd_minor < 0 || 845 ver.drm_dd_minor > dev->driver->minor) 846 return EINVAL; 847 } 848 849 return 0; 850 } 851 852 struct drm_dmamem * 853 drm_dmamem_alloc(bus_dma_tag_t dmat, bus_size_t size, bus_size_t alignment, 854 int nsegments, bus_size_t maxsegsz, int mapflags, int loadflags) 855 { 856 struct drm_dmamem *mem; 857 size_t strsize; 858 /* 859 * segs is the last member of the struct since we modify the size 860 * to allow extra segments if more than one are allowed. 861 */ 862 strsize = sizeof(*mem) + (sizeof(bus_dma_segment_t) * (nsegments - 1)); 863 mem = malloc(strsize, M_DRM, M_NOWAIT | M_ZERO); 864 if (mem == NULL) 865 return (NULL); 866 867 mem->size = size; 868 869 if (bus_dmamap_create(dmat, size, nsegments, maxsegsz, 0, 870 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mem->map) != 0) 871 goto strfree; 872 873 if (bus_dmamem_alloc(dmat, size, alignment, 0, mem->segs, nsegments, 874 &mem->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0) 875 goto destroy; 876 877 if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, size, 878 &mem->kva, BUS_DMA_NOWAIT | mapflags) != 0) 879 goto free; 880 881 if (bus_dmamap_load(dmat, mem->map, mem->kva, size, 882 NULL, BUS_DMA_NOWAIT | loadflags) != 0) 883 goto unmap; 884 885 return (mem); 886 887 unmap: 888 bus_dmamem_unmap(dmat, mem->kva, size); 889 free: 890 bus_dmamem_free(dmat, mem->segs, mem->nsegs); 891 destroy: 892 bus_dmamap_destroy(dmat, mem->map); 893 strfree: 894 free(mem, M_DRM); 895 896 return (NULL); 897 } 898 899 void 900 drm_dmamem_free(bus_dma_tag_t dmat, struct drm_dmamem *mem) 901 { 902 if (mem == NULL) 903 return; 904 905 bus_dmamap_unload(dmat, mem->map); 906 bus_dmamem_unmap(dmat, mem->kva, mem->size); 907 bus_dmamem_free(dmat, mem->segs, mem->nsegs); 908 bus_dmamap_destroy(dmat, mem->map); 909 free(mem, M_DRM); 910 } 911 912 /** 913 * Called by the client, this returns a unique magic number to be authorized 914 * by the master. 915 * 916 * The master may use its own knowledge of the client (such as the X 917 * connection that the magic is passed over) to determine if the magic number 918 * should be authenticated. 919 */ 920 int 921 drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) 922 { 923 struct drm_auth *auth = data; 924 925 if (dev->magicid == 0) 926 dev->magicid = 1; 927 928 /* Find unique magic */ 929 if (file_priv->magic) { 930 auth->magic = file_priv->magic; 931 } else { 932 DRM_LOCK(); 933 file_priv->magic = auth->magic = dev->magicid++; 934 DRM_UNLOCK(); 935 DRM_DEBUG("%d\n", auth->magic); 936 } 937 938 DRM_DEBUG("%u\n", auth->magic); 939 940 return (0); 941 } 942 943 /** 944 * Marks the client associated with the given magic number as authenticated. 945 */ 946 int 947 drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) 948 { 949 struct drm_file *p; 950 struct drm_auth *auth = data; 951 int ret = EINVAL; 952 953 DRM_DEBUG("%u\n", auth->magic); 954 955 if (auth->magic == 0) 956 return (ret); 957 958 DRM_LOCK(); 959 SPLAY_FOREACH(p, drm_file_tree, &dev->files) { 960 if (p->magic == auth->magic) { 961 p->authenticated = 1; 962 p->magic = 0; 963 ret = 0; 964 break; 965 } 966 } 967 DRM_UNLOCK(); 968 969 return (ret); 970 } 971