1 /*- 2 * Copyright (c) 2015-2016 Mellanox Technologies, Ltd. 3 * All rights reserved. 4 * Copyright (c) 2020-2022 The FreeBSD Foundation 5 * 6 * Portions of this software were developed by Björn Zeeb 7 * under sponsorship from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice unmodified, this list of conditions, and the following 14 * disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/bus.h> 37 #include <sys/malloc.h> 38 #include <sys/kernel.h> 39 #include <sys/sysctl.h> 40 #include <sys/lock.h> 41 #include <sys/mutex.h> 42 #include <sys/fcntl.h> 43 #include <sys/file.h> 44 #include <sys/filio.h> 45 #include <sys/pciio.h> 46 #include <sys/pctrie.h> 47 #include <sys/rwlock.h> 48 49 #include <vm/vm.h> 50 #include <vm/pmap.h> 51 52 #include <machine/stdarg.h> 53 54 #include <dev/pci/pcivar.h> 55 #include <dev/pci/pci_private.h> 56 #include <dev/pci/pci_iov.h> 57 #include <dev/backlight/backlight.h> 58 59 #include <linux/kobject.h> 60 #include <linux/device.h> 61 #include <linux/slab.h> 62 #include <linux/module.h> 63 #include <linux/cdev.h> 64 #include <linux/file.h> 65 #include <linux/sysfs.h> 66 #include <linux/mm.h> 67 #include <linux/io.h> 68 #include <linux/vmalloc.h> 69 #include <linux/pci.h> 70 #include <linux/compat.h> 71 72 #include <linux/backlight.h> 73 74 #include "backlight_if.h" 75 #include "pcib_if.h" 76 77 /* Undef the linux function macro defined in linux/pci.h */ 78 #undef pci_get_class 79 80 static device_probe_t linux_pci_probe; 81 static device_attach_t linux_pci_attach; 82 static device_detach_t linux_pci_detach; 83 static device_suspend_t linux_pci_suspend; 84 static device_resume_t linux_pci_resume; 85 static device_shutdown_t linux_pci_shutdown; 86 static pci_iov_init_t linux_pci_iov_init; 87 static pci_iov_uninit_t linux_pci_iov_uninit; 88 static pci_iov_add_vf_t linux_pci_iov_add_vf; 89 static int linux_backlight_get_status(device_t dev, struct backlight_props *props); 90 static int linux_backlight_update_status(device_t dev, struct backlight_props *props); 91 static int linux_backlight_get_info(device_t dev, struct backlight_info *info); 92 93 static device_method_t pci_methods[] = { 94 DEVMETHOD(device_probe, linux_pci_probe), 95 DEVMETHOD(device_attach, linux_pci_attach), 96 DEVMETHOD(device_detach, linux_pci_detach), 97 DEVMETHOD(device_suspend, linux_pci_suspend), 98 DEVMETHOD(device_resume, linux_pci_resume), 99 DEVMETHOD(device_shutdown, linux_pci_shutdown), 100 DEVMETHOD(pci_iov_init, linux_pci_iov_init), 101 DEVMETHOD(pci_iov_uninit, linux_pci_iov_uninit), 102 DEVMETHOD(pci_iov_add_vf, linux_pci_iov_add_vf), 103 104 /* backlight interface */ 105 DEVMETHOD(backlight_update_status, linux_backlight_update_status), 106 DEVMETHOD(backlight_get_status, linux_backlight_get_status), 107 DEVMETHOD(backlight_get_info, linux_backlight_get_info), 108 DEVMETHOD_END 109 }; 110 111 struct linux_dma_priv { 112 uint64_t dma_mask; 113 bus_dma_tag_t dmat; 114 uint64_t dma_coherent_mask; 115 bus_dma_tag_t dmat_coherent; 116 struct mtx lock; 117 struct pctrie ptree; 118 }; 119 #define DMA_PRIV_LOCK(priv) mtx_lock(&(priv)->lock) 120 #define DMA_PRIV_UNLOCK(priv) mtx_unlock(&(priv)->lock) 121 122 static bool 123 linux_is_drm(struct pci_driver *pdrv) 124 { 125 return (pdrv->name != NULL && strcmp(pdrv->name, "drmn") == 0); 126 } 127 128 static int 129 linux_pdev_dma_uninit(struct pci_dev *pdev) 130 { 131 struct linux_dma_priv *priv; 132 133 priv = pdev->dev.dma_priv; 134 if (priv->dmat) 135 bus_dma_tag_destroy(priv->dmat); 136 if (priv->dmat_coherent) 137 bus_dma_tag_destroy(priv->dmat_coherent); 138 mtx_destroy(&priv->lock); 139 pdev->dev.dma_priv = NULL; 140 free(priv, M_DEVBUF); 141 return (0); 142 } 143 144 static int 145 linux_pdev_dma_init(struct pci_dev *pdev) 146 { 147 struct linux_dma_priv *priv; 148 int error; 149 150 priv = malloc(sizeof(*priv), M_DEVBUF, M_WAITOK | M_ZERO); 151 152 mtx_init(&priv->lock, "lkpi-priv-dma", NULL, MTX_DEF); 153 pctrie_init(&priv->ptree); 154 155 pdev->dev.dma_priv = priv; 156 157 /* Create a default DMA tags. */ 158 error = linux_dma_tag_init(&pdev->dev, DMA_BIT_MASK(64)); 159 if (error != 0) 160 goto err; 161 /* Coherent is lower 32bit only by default in Linux. */ 162 error = linux_dma_tag_init_coherent(&pdev->dev, DMA_BIT_MASK(32)); 163 if (error != 0) 164 goto err; 165 166 return (error); 167 168 err: 169 linux_pdev_dma_uninit(pdev); 170 return (error); 171 } 172 173 int 174 linux_dma_tag_init(struct device *dev, u64 dma_mask) 175 { 176 struct linux_dma_priv *priv; 177 int error; 178 179 priv = dev->dma_priv; 180 181 if (priv->dmat) { 182 if (priv->dma_mask == dma_mask) 183 return (0); 184 185 bus_dma_tag_destroy(priv->dmat); 186 } 187 188 priv->dma_mask = dma_mask; 189 190 error = bus_dma_tag_create(bus_get_dma_tag(dev->bsddev), 191 1, 0, /* alignment, boundary */ 192 dma_mask, /* lowaddr */ 193 BUS_SPACE_MAXADDR, /* highaddr */ 194 NULL, NULL, /* filtfunc, filtfuncarg */ 195 BUS_SPACE_MAXSIZE, /* maxsize */ 196 1, /* nsegments */ 197 BUS_SPACE_MAXSIZE, /* maxsegsz */ 198 0, /* flags */ 199 NULL, NULL, /* lockfunc, lockfuncarg */ 200 &priv->dmat); 201 return (-error); 202 } 203 204 int 205 linux_dma_tag_init_coherent(struct device *dev, u64 dma_mask) 206 { 207 struct linux_dma_priv *priv; 208 int error; 209 210 priv = dev->dma_priv; 211 212 if (priv->dmat_coherent) { 213 if (priv->dma_coherent_mask == dma_mask) 214 return (0); 215 216 bus_dma_tag_destroy(priv->dmat_coherent); 217 } 218 219 priv->dma_coherent_mask = dma_mask; 220 221 error = bus_dma_tag_create(bus_get_dma_tag(dev->bsddev), 222 1, 0, /* alignment, boundary */ 223 dma_mask, /* lowaddr */ 224 BUS_SPACE_MAXADDR, /* highaddr */ 225 NULL, NULL, /* filtfunc, filtfuncarg */ 226 BUS_SPACE_MAXSIZE, /* maxsize */ 227 1, /* nsegments */ 228 BUS_SPACE_MAXSIZE, /* maxsegsz */ 229 0, /* flags */ 230 NULL, NULL, /* lockfunc, lockfuncarg */ 231 &priv->dmat_coherent); 232 return (-error); 233 } 234 235 static struct pci_driver * 236 linux_pci_find(device_t dev, const struct pci_device_id **idp) 237 { 238 const struct pci_device_id *id; 239 struct pci_driver *pdrv; 240 uint16_t vendor; 241 uint16_t device; 242 uint16_t subvendor; 243 uint16_t subdevice; 244 245 vendor = pci_get_vendor(dev); 246 device = pci_get_device(dev); 247 subvendor = pci_get_subvendor(dev); 248 subdevice = pci_get_subdevice(dev); 249 250 spin_lock(&pci_lock); 251 list_for_each_entry(pdrv, &pci_drivers, node) { 252 for (id = pdrv->id_table; id->vendor != 0; id++) { 253 if (vendor == id->vendor && 254 (PCI_ANY_ID == id->device || device == id->device) && 255 (PCI_ANY_ID == id->subvendor || subvendor == id->subvendor) && 256 (PCI_ANY_ID == id->subdevice || subdevice == id->subdevice)) { 257 *idp = id; 258 spin_unlock(&pci_lock); 259 return (pdrv); 260 } 261 } 262 } 263 spin_unlock(&pci_lock); 264 return (NULL); 265 } 266 267 static void 268 lkpi_pci_dev_release(struct device *dev) 269 { 270 271 lkpi_devres_release_free_list(dev); 272 spin_lock_destroy(&dev->devres_lock); 273 } 274 275 static void 276 lkpifill_pci_dev(device_t dev, struct pci_dev *pdev) 277 { 278 279 pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev)); 280 pdev->vendor = pci_get_vendor(dev); 281 pdev->device = pci_get_device(dev); 282 pdev->subsystem_vendor = pci_get_subvendor(dev); 283 pdev->subsystem_device = pci_get_subdevice(dev); 284 pdev->class = pci_get_class(dev); 285 pdev->revision = pci_get_revid(dev); 286 pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO); 287 /* 288 * This should be the upstream bridge; pci_upstream_bridge() 289 * handles that case on demand as otherwise we'll shadow the 290 * entire PCI hierarchy. 291 */ 292 pdev->bus->self = pdev; 293 pdev->bus->number = pci_get_bus(dev); 294 pdev->bus->domain = pci_get_domain(dev); 295 pdev->dev.bsddev = dev; 296 pdev->dev.parent = &linux_root_device; 297 pdev->dev.release = lkpi_pci_dev_release; 298 INIT_LIST_HEAD(&pdev->dev.irqents); 299 kobject_init(&pdev->dev.kobj, &linux_dev_ktype); 300 kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); 301 kobject_add(&pdev->dev.kobj, &linux_root_device.kobj, 302 kobject_name(&pdev->dev.kobj)); 303 spin_lock_init(&pdev->dev.devres_lock); 304 INIT_LIST_HEAD(&pdev->dev.devres_head); 305 } 306 307 static void 308 lkpinew_pci_dev_release(struct device *dev) 309 { 310 struct pci_dev *pdev; 311 312 pdev = to_pci_dev(dev); 313 if (pdev->root != NULL) 314 pci_dev_put(pdev->root); 315 if (pdev->bus->self != pdev) 316 pci_dev_put(pdev->bus->self); 317 free(pdev->bus, M_DEVBUF); 318 free(pdev, M_DEVBUF); 319 } 320 321 struct pci_dev * 322 lkpinew_pci_dev(device_t dev) 323 { 324 struct pci_dev *pdev; 325 326 pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO); 327 lkpifill_pci_dev(dev, pdev); 328 pdev->dev.release = lkpinew_pci_dev_release; 329 330 return (pdev); 331 } 332 333 struct pci_dev * 334 lkpi_pci_get_class(unsigned int class, struct pci_dev *from) 335 { 336 device_t dev; 337 device_t devfrom = NULL; 338 struct pci_dev *pdev; 339 340 if (from != NULL) 341 devfrom = from->dev.bsddev; 342 343 dev = pci_find_class_from(class >> 16, (class >> 8) & 0xFF, devfrom); 344 if (dev == NULL) 345 return (NULL); 346 347 pdev = lkpinew_pci_dev(dev); 348 return (pdev); 349 } 350 351 struct pci_dev * 352 lkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus, 353 unsigned int devfn) 354 { 355 device_t dev; 356 struct pci_dev *pdev; 357 358 dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); 359 if (dev == NULL) 360 return (NULL); 361 362 pdev = lkpinew_pci_dev(dev); 363 return (pdev); 364 } 365 366 static int 367 linux_pci_probe(device_t dev) 368 { 369 const struct pci_device_id *id; 370 struct pci_driver *pdrv; 371 372 if ((pdrv = linux_pci_find(dev, &id)) == NULL) 373 return (ENXIO); 374 if (device_get_driver(dev) != &pdrv->bsddriver) 375 return (ENXIO); 376 device_set_desc(dev, pdrv->name); 377 378 /* Assume BSS initialized (should never return BUS_PROBE_SPECIFIC). */ 379 if (pdrv->bsd_probe_return == 0) 380 return (BUS_PROBE_DEFAULT); 381 else 382 return (pdrv->bsd_probe_return); 383 } 384 385 static int 386 linux_pci_attach(device_t dev) 387 { 388 const struct pci_device_id *id; 389 struct pci_driver *pdrv; 390 struct pci_dev *pdev; 391 392 pdrv = linux_pci_find(dev, &id); 393 pdev = device_get_softc(dev); 394 395 MPASS(pdrv != NULL); 396 MPASS(pdev != NULL); 397 398 return (linux_pci_attach_device(dev, pdrv, id, pdev)); 399 } 400 401 int 402 linux_pci_attach_device(device_t dev, struct pci_driver *pdrv, 403 const struct pci_device_id *id, struct pci_dev *pdev) 404 { 405 struct resource_list_entry *rle; 406 device_t parent; 407 uintptr_t rid; 408 int error; 409 bool isdrm; 410 411 linux_set_current(curthread); 412 413 parent = device_get_parent(dev); 414 isdrm = pdrv != NULL && linux_is_drm(pdrv); 415 416 if (isdrm) { 417 struct pci_devinfo *dinfo; 418 419 dinfo = device_get_ivars(parent); 420 device_set_ivars(dev, dinfo); 421 } 422 423 lkpifill_pci_dev(dev, pdev); 424 if (isdrm) 425 PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid); 426 else 427 PCI_GET_ID(parent, dev, PCI_ID_RID, &rid); 428 pdev->devfn = rid; 429 pdev->pdrv = pdrv; 430 rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0, false); 431 if (rle != NULL) 432 pdev->dev.irq = rle->start; 433 else 434 pdev->dev.irq = LINUX_IRQ_INVALID; 435 pdev->irq = pdev->dev.irq; 436 error = linux_pdev_dma_init(pdev); 437 if (error) 438 goto out_dma_init; 439 440 TAILQ_INIT(&pdev->mmio); 441 442 spin_lock(&pci_lock); 443 list_add(&pdev->links, &pci_devices); 444 spin_unlock(&pci_lock); 445 446 if (pdrv != NULL) { 447 error = pdrv->probe(pdev, id); 448 if (error) 449 goto out_probe; 450 } 451 return (0); 452 453 out_probe: 454 free(pdev->bus, M_DEVBUF); 455 linux_pdev_dma_uninit(pdev); 456 out_dma_init: 457 spin_lock(&pci_lock); 458 list_del(&pdev->links); 459 spin_unlock(&pci_lock); 460 put_device(&pdev->dev); 461 return (-error); 462 } 463 464 static int 465 linux_pci_detach(device_t dev) 466 { 467 struct pci_dev *pdev; 468 469 pdev = device_get_softc(dev); 470 471 MPASS(pdev != NULL); 472 473 device_set_desc(dev, NULL); 474 475 return (linux_pci_detach_device(pdev)); 476 } 477 478 int 479 linux_pci_detach_device(struct pci_dev *pdev) 480 { 481 482 linux_set_current(curthread); 483 484 if (pdev->pdrv != NULL) 485 pdev->pdrv->remove(pdev); 486 487 if (pdev->root != NULL) 488 pci_dev_put(pdev->root); 489 free(pdev->bus, M_DEVBUF); 490 linux_pdev_dma_uninit(pdev); 491 492 spin_lock(&pci_lock); 493 list_del(&pdev->links); 494 spin_unlock(&pci_lock); 495 put_device(&pdev->dev); 496 497 return (0); 498 } 499 500 static int 501 lkpi_pci_disable_dev(struct device *dev) 502 { 503 504 (void) pci_disable_io(dev->bsddev, SYS_RES_MEMORY); 505 (void) pci_disable_io(dev->bsddev, SYS_RES_IOPORT); 506 return (0); 507 } 508 509 struct pci_devres * 510 lkpi_pci_devres_get_alloc(struct pci_dev *pdev) 511 { 512 struct pci_devres *dr; 513 514 dr = lkpi_devres_find(&pdev->dev, lkpi_pci_devres_release, NULL, NULL); 515 if (dr == NULL) { 516 dr = lkpi_devres_alloc(lkpi_pci_devres_release, sizeof(*dr), 517 GFP_KERNEL | __GFP_ZERO); 518 if (dr != NULL) 519 lkpi_devres_add(&pdev->dev, dr); 520 } 521 522 return (dr); 523 } 524 525 void 526 lkpi_pci_devres_release(struct device *dev, void *p) 527 { 528 struct pci_devres *dr; 529 struct pci_dev *pdev; 530 int bar; 531 532 pdev = to_pci_dev(dev); 533 dr = p; 534 535 if (pdev->msix_enabled) 536 lkpi_pci_disable_msix(pdev); 537 if (pdev->msi_enabled) 538 lkpi_pci_disable_msi(pdev); 539 540 if (dr->enable_io && lkpi_pci_disable_dev(dev) == 0) 541 dr->enable_io = false; 542 543 if (dr->region_mask == 0) 544 return; 545 for (bar = PCIR_MAX_BAR_0; bar >= 0; bar--) { 546 547 if ((dr->region_mask & (1 << bar)) == 0) 548 continue; 549 pci_release_region(pdev, bar); 550 } 551 } 552 553 struct pcim_iomap_devres * 554 lkpi_pcim_iomap_devres_find(struct pci_dev *pdev) 555 { 556 struct pcim_iomap_devres *dr; 557 558 dr = lkpi_devres_find(&pdev->dev, lkpi_pcim_iomap_table_release, 559 NULL, NULL); 560 if (dr == NULL) { 561 dr = lkpi_devres_alloc(lkpi_pcim_iomap_table_release, 562 sizeof(*dr), GFP_KERNEL | __GFP_ZERO); 563 if (dr != NULL) 564 lkpi_devres_add(&pdev->dev, dr); 565 } 566 567 if (dr == NULL) 568 device_printf(pdev->dev.bsddev, "%s: NULL\n", __func__); 569 570 return (dr); 571 } 572 573 void 574 lkpi_pcim_iomap_table_release(struct device *dev, void *p) 575 { 576 struct pcim_iomap_devres *dr; 577 struct pci_dev *pdev; 578 int bar; 579 580 dr = p; 581 pdev = to_pci_dev(dev); 582 for (bar = PCIR_MAX_BAR_0; bar >= 0; bar--) { 583 584 if (dr->mmio_table[bar] == NULL) 585 continue; 586 587 pci_iounmap(pdev, dr->mmio_table[bar]); 588 } 589 } 590 591 static int 592 linux_pci_suspend(device_t dev) 593 { 594 const struct dev_pm_ops *pmops; 595 struct pm_message pm = { }; 596 struct pci_dev *pdev; 597 int error; 598 599 error = 0; 600 linux_set_current(curthread); 601 pdev = device_get_softc(dev); 602 pmops = pdev->pdrv->driver.pm; 603 604 if (pdev->pdrv->suspend != NULL) 605 error = -pdev->pdrv->suspend(pdev, pm); 606 else if (pmops != NULL && pmops->suspend != NULL) { 607 error = -pmops->suspend(&pdev->dev); 608 if (error == 0 && pmops->suspend_late != NULL) 609 error = -pmops->suspend_late(&pdev->dev); 610 } 611 return (error); 612 } 613 614 static int 615 linux_pci_resume(device_t dev) 616 { 617 const struct dev_pm_ops *pmops; 618 struct pci_dev *pdev; 619 int error; 620 621 error = 0; 622 linux_set_current(curthread); 623 pdev = device_get_softc(dev); 624 pmops = pdev->pdrv->driver.pm; 625 626 if (pdev->pdrv->resume != NULL) 627 error = -pdev->pdrv->resume(pdev); 628 else if (pmops != NULL && pmops->resume != NULL) { 629 if (pmops->resume_early != NULL) 630 error = -pmops->resume_early(&pdev->dev); 631 if (error == 0 && pmops->resume != NULL) 632 error = -pmops->resume(&pdev->dev); 633 } 634 return (error); 635 } 636 637 static int 638 linux_pci_shutdown(device_t dev) 639 { 640 struct pci_dev *pdev; 641 642 linux_set_current(curthread); 643 pdev = device_get_softc(dev); 644 if (pdev->pdrv->shutdown != NULL) 645 pdev->pdrv->shutdown(pdev); 646 return (0); 647 } 648 649 static int 650 linux_pci_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *pf_config) 651 { 652 struct pci_dev *pdev; 653 int error; 654 655 linux_set_current(curthread); 656 pdev = device_get_softc(dev); 657 if (pdev->pdrv->bsd_iov_init != NULL) 658 error = pdev->pdrv->bsd_iov_init(dev, num_vfs, pf_config); 659 else 660 error = EINVAL; 661 return (error); 662 } 663 664 static void 665 linux_pci_iov_uninit(device_t dev) 666 { 667 struct pci_dev *pdev; 668 669 linux_set_current(curthread); 670 pdev = device_get_softc(dev); 671 if (pdev->pdrv->bsd_iov_uninit != NULL) 672 pdev->pdrv->bsd_iov_uninit(dev); 673 } 674 675 static int 676 linux_pci_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *vf_config) 677 { 678 struct pci_dev *pdev; 679 int error; 680 681 linux_set_current(curthread); 682 pdev = device_get_softc(dev); 683 if (pdev->pdrv->bsd_iov_add_vf != NULL) 684 error = pdev->pdrv->bsd_iov_add_vf(dev, vfnum, vf_config); 685 else 686 error = EINVAL; 687 return (error); 688 } 689 690 static int 691 _linux_pci_register_driver(struct pci_driver *pdrv, devclass_t dc) 692 { 693 int error; 694 695 linux_set_current(curthread); 696 spin_lock(&pci_lock); 697 list_add(&pdrv->node, &pci_drivers); 698 spin_unlock(&pci_lock); 699 if (pdrv->bsddriver.name == NULL) 700 pdrv->bsddriver.name = pdrv->name; 701 pdrv->bsddriver.methods = pci_methods; 702 pdrv->bsddriver.size = sizeof(struct pci_dev); 703 704 mtx_lock(&Giant); 705 error = devclass_add_driver(dc, &pdrv->bsddriver, 706 BUS_PASS_DEFAULT, &pdrv->bsdclass); 707 mtx_unlock(&Giant); 708 return (-error); 709 } 710 711 int 712 linux_pci_register_driver(struct pci_driver *pdrv) 713 { 714 devclass_t dc; 715 716 dc = devclass_find("pci"); 717 if (dc == NULL) 718 return (-ENXIO); 719 return (_linux_pci_register_driver(pdrv, dc)); 720 } 721 722 struct resource_list_entry * 723 linux_pci_reserve_bar(struct pci_dev *pdev, struct resource_list *rl, 724 int type, int rid) 725 { 726 device_t dev; 727 struct resource *res; 728 729 KASSERT(type == SYS_RES_IOPORT || type == SYS_RES_MEMORY, 730 ("trying to reserve non-BAR type %d", type)); 731 732 dev = pdev->pdrv != NULL && linux_is_drm(pdev->pdrv) ? 733 device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev; 734 res = pci_reserve_map(device_get_parent(dev), dev, type, &rid, 0, ~0, 735 1, 1, 0); 736 if (res == NULL) 737 return (NULL); 738 return (resource_list_find(rl, type, rid)); 739 } 740 741 unsigned long 742 pci_resource_start(struct pci_dev *pdev, int bar) 743 { 744 struct resource_list_entry *rle; 745 rman_res_t newstart; 746 device_t dev; 747 748 if ((rle = linux_pci_get_bar(pdev, bar, true)) == NULL) 749 return (0); 750 dev = pdev->pdrv != NULL && linux_is_drm(pdev->pdrv) ? 751 device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev; 752 if (BUS_TRANSLATE_RESOURCE(dev, rle->type, rle->start, &newstart)) { 753 device_printf(pdev->dev.bsddev, "translate of %#jx failed\n", 754 (uintmax_t)rle->start); 755 return (0); 756 } 757 return (newstart); 758 } 759 760 unsigned long 761 pci_resource_len(struct pci_dev *pdev, int bar) 762 { 763 struct resource_list_entry *rle; 764 765 if ((rle = linux_pci_get_bar(pdev, bar, true)) == NULL) 766 return (0); 767 return (rle->count); 768 } 769 770 int 771 pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) 772 { 773 struct resource *res; 774 struct pci_devres *dr; 775 struct pci_mmio_region *mmio; 776 int rid; 777 int type; 778 779 type = pci_resource_type(pdev, bar); 780 if (type < 0) 781 return (-ENODEV); 782 rid = PCIR_BAR(bar); 783 res = bus_alloc_resource_any(pdev->dev.bsddev, type, &rid, 784 RF_ACTIVE|RF_SHAREABLE); 785 if (res == NULL) { 786 device_printf(pdev->dev.bsddev, "%s: failed to alloc " 787 "bar %d type %d rid %d\n", 788 __func__, bar, type, PCIR_BAR(bar)); 789 return (-ENODEV); 790 } 791 792 /* 793 * It seems there is an implicit devres tracking on these if the device 794 * is managed; otherwise the resources are not automatiaclly freed on 795 * FreeBSD/LinuxKPI tough they should be/are expected to be by Linux 796 * drivers. 797 */ 798 dr = lkpi_pci_devres_find(pdev); 799 if (dr != NULL) { 800 dr->region_mask |= (1 << bar); 801 dr->region_table[bar] = res; 802 } 803 804 /* Even if the device is not managed we need to track it for iomap. */ 805 mmio = malloc(sizeof(*mmio), M_DEVBUF, M_WAITOK | M_ZERO); 806 mmio->rid = PCIR_BAR(bar); 807 mmio->type = type; 808 mmio->res = res; 809 TAILQ_INSERT_TAIL(&pdev->mmio, mmio, next); 810 811 return (0); 812 } 813 814 struct resource * 815 _lkpi_pci_iomap(struct pci_dev *pdev, int bar, int mmio_size __unused) 816 { 817 struct pci_mmio_region *mmio, *p; 818 int type; 819 820 type = pci_resource_type(pdev, bar); 821 if (type < 0) { 822 device_printf(pdev->dev.bsddev, "%s: bar %d type %d\n", 823 __func__, bar, type); 824 return (NULL); 825 } 826 827 /* 828 * Check for duplicate mappings. 829 * This can happen if a driver calls pci_request_region() first. 830 */ 831 TAILQ_FOREACH_SAFE(mmio, &pdev->mmio, next, p) { 832 if (mmio->type == type && mmio->rid == PCIR_BAR(bar)) { 833 return (mmio->res); 834 } 835 } 836 837 mmio = malloc(sizeof(*mmio), M_DEVBUF, M_WAITOK | M_ZERO); 838 mmio->rid = PCIR_BAR(bar); 839 mmio->type = type; 840 mmio->res = bus_alloc_resource_any(pdev->dev.bsddev, mmio->type, 841 &mmio->rid, RF_ACTIVE|RF_SHAREABLE); 842 if (mmio->res == NULL) { 843 device_printf(pdev->dev.bsddev, "%s: failed to alloc " 844 "bar %d type %d rid %d\n", 845 __func__, bar, type, PCIR_BAR(bar)); 846 free(mmio, M_DEVBUF); 847 return (NULL); 848 } 849 TAILQ_INSERT_TAIL(&pdev->mmio, mmio, next); 850 851 return (mmio->res); 852 } 853 854 int 855 linux_pci_register_drm_driver(struct pci_driver *pdrv) 856 { 857 devclass_t dc; 858 859 dc = devclass_create("vgapci"); 860 if (dc == NULL) 861 return (-ENXIO); 862 pdrv->name = "drmn"; 863 return (_linux_pci_register_driver(pdrv, dc)); 864 } 865 866 void 867 linux_pci_unregister_driver(struct pci_driver *pdrv) 868 { 869 devclass_t bus; 870 871 bus = devclass_find("pci"); 872 873 spin_lock(&pci_lock); 874 list_del(&pdrv->node); 875 spin_unlock(&pci_lock); 876 mtx_lock(&Giant); 877 if (bus != NULL) 878 devclass_delete_driver(bus, &pdrv->bsddriver); 879 mtx_unlock(&Giant); 880 } 881 882 void 883 linux_pci_unregister_drm_driver(struct pci_driver *pdrv) 884 { 885 devclass_t bus; 886 887 bus = devclass_find("vgapci"); 888 889 spin_lock(&pci_lock); 890 list_del(&pdrv->node); 891 spin_unlock(&pci_lock); 892 mtx_lock(&Giant); 893 if (bus != NULL) 894 devclass_delete_driver(bus, &pdrv->bsddriver); 895 mtx_unlock(&Giant); 896 } 897 898 int 899 pci_alloc_irq_vectors(struct pci_dev *pdev, int minv, int maxv, 900 unsigned int flags) 901 { 902 int error; 903 904 if (flags & PCI_IRQ_MSIX) { 905 struct msix_entry *entries; 906 int i; 907 908 entries = kcalloc(maxv, sizeof(*entries), GFP_KERNEL); 909 if (entries == NULL) { 910 error = -ENOMEM; 911 goto out; 912 } 913 for (i = 0; i < maxv; ++i) 914 entries[i].entry = i; 915 error = pci_enable_msix(pdev, entries, maxv); 916 out: 917 kfree(entries); 918 if (error == 0 && pdev->msix_enabled) 919 return (pdev->dev.irq_end - pdev->dev.irq_start); 920 } 921 if (flags & PCI_IRQ_MSI) { 922 error = pci_enable_msi(pdev); 923 if (error == 0 && pdev->msi_enabled) 924 return (pdev->dev.irq_end - pdev->dev.irq_start); 925 } 926 if (flags & PCI_IRQ_LEGACY) { 927 if (pdev->irq) 928 return (1); 929 } 930 931 return (-EINVAL); 932 } 933 934 CTASSERT(sizeof(dma_addr_t) <= sizeof(uint64_t)); 935 936 struct linux_dma_obj { 937 void *vaddr; 938 uint64_t dma_addr; 939 bus_dmamap_t dmamap; 940 bus_dma_tag_t dmat; 941 }; 942 943 static uma_zone_t linux_dma_trie_zone; 944 static uma_zone_t linux_dma_obj_zone; 945 946 static void 947 linux_dma_init(void *arg) 948 { 949 950 linux_dma_trie_zone = uma_zcreate("linux_dma_pctrie", 951 pctrie_node_size(), NULL, NULL, pctrie_zone_init, NULL, 952 UMA_ALIGN_PTR, 0); 953 linux_dma_obj_zone = uma_zcreate("linux_dma_object", 954 sizeof(struct linux_dma_obj), NULL, NULL, NULL, NULL, 955 UMA_ALIGN_PTR, 0); 956 957 } 958 SYSINIT(linux_dma, SI_SUB_DRIVERS, SI_ORDER_THIRD, linux_dma_init, NULL); 959 960 static void 961 linux_dma_uninit(void *arg) 962 { 963 964 uma_zdestroy(linux_dma_obj_zone); 965 uma_zdestroy(linux_dma_trie_zone); 966 } 967 SYSUNINIT(linux_dma, SI_SUB_DRIVERS, SI_ORDER_THIRD, linux_dma_uninit, NULL); 968 969 static void * 970 linux_dma_trie_alloc(struct pctrie *ptree) 971 { 972 973 return (uma_zalloc(linux_dma_trie_zone, M_NOWAIT)); 974 } 975 976 static void 977 linux_dma_trie_free(struct pctrie *ptree, void *node) 978 { 979 980 uma_zfree(linux_dma_trie_zone, node); 981 } 982 983 PCTRIE_DEFINE(LINUX_DMA, linux_dma_obj, dma_addr, linux_dma_trie_alloc, 984 linux_dma_trie_free); 985 986 #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) 987 static dma_addr_t 988 linux_dma_map_phys_common(struct device *dev, vm_paddr_t phys, size_t len, 989 bus_dma_tag_t dmat) 990 { 991 struct linux_dma_priv *priv; 992 struct linux_dma_obj *obj; 993 int error, nseg; 994 bus_dma_segment_t seg; 995 996 priv = dev->dma_priv; 997 998 /* 999 * If the resultant mapping will be entirely 1:1 with the 1000 * physical address, short-circuit the remainder of the 1001 * bus_dma API. This avoids tracking collisions in the pctrie 1002 * with the additional benefit of reducing overhead. 1003 */ 1004 if (bus_dma_id_mapped(dmat, phys, len)) 1005 return (phys); 1006 1007 obj = uma_zalloc(linux_dma_obj_zone, M_NOWAIT); 1008 if (obj == NULL) { 1009 return (0); 1010 } 1011 obj->dmat = dmat; 1012 1013 DMA_PRIV_LOCK(priv); 1014 if (bus_dmamap_create(obj->dmat, 0, &obj->dmamap) != 0) { 1015 DMA_PRIV_UNLOCK(priv); 1016 uma_zfree(linux_dma_obj_zone, obj); 1017 return (0); 1018 } 1019 1020 nseg = -1; 1021 if (_bus_dmamap_load_phys(obj->dmat, obj->dmamap, phys, len, 1022 BUS_DMA_NOWAIT, &seg, &nseg) != 0) { 1023 bus_dmamap_destroy(obj->dmat, obj->dmamap); 1024 DMA_PRIV_UNLOCK(priv); 1025 uma_zfree(linux_dma_obj_zone, obj); 1026 return (0); 1027 } 1028 1029 KASSERT(++nseg == 1, ("More than one segment (nseg=%d)", nseg)); 1030 obj->dma_addr = seg.ds_addr; 1031 1032 error = LINUX_DMA_PCTRIE_INSERT(&priv->ptree, obj); 1033 if (error != 0) { 1034 bus_dmamap_unload(obj->dmat, obj->dmamap); 1035 bus_dmamap_destroy(obj->dmat, obj->dmamap); 1036 DMA_PRIV_UNLOCK(priv); 1037 uma_zfree(linux_dma_obj_zone, obj); 1038 return (0); 1039 } 1040 DMA_PRIV_UNLOCK(priv); 1041 return (obj->dma_addr); 1042 } 1043 #else 1044 static dma_addr_t 1045 linux_dma_map_phys_common(struct device *dev __unused, vm_paddr_t phys, 1046 size_t len __unused, bus_dma_tag_t dmat __unused) 1047 { 1048 return (phys); 1049 } 1050 #endif 1051 1052 dma_addr_t 1053 linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len) 1054 { 1055 struct linux_dma_priv *priv; 1056 1057 priv = dev->dma_priv; 1058 return (linux_dma_map_phys_common(dev, phys, len, priv->dmat)); 1059 } 1060 1061 #if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) 1062 void 1063 linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len) 1064 { 1065 struct linux_dma_priv *priv; 1066 struct linux_dma_obj *obj; 1067 1068 priv = dev->dma_priv; 1069 1070 if (pctrie_is_empty(&priv->ptree)) 1071 return; 1072 1073 DMA_PRIV_LOCK(priv); 1074 obj = LINUX_DMA_PCTRIE_LOOKUP(&priv->ptree, dma_addr); 1075 if (obj == NULL) { 1076 DMA_PRIV_UNLOCK(priv); 1077 return; 1078 } 1079 LINUX_DMA_PCTRIE_REMOVE(&priv->ptree, dma_addr); 1080 bus_dmamap_unload(obj->dmat, obj->dmamap); 1081 bus_dmamap_destroy(obj->dmat, obj->dmamap); 1082 DMA_PRIV_UNLOCK(priv); 1083 1084 uma_zfree(linux_dma_obj_zone, obj); 1085 } 1086 #else 1087 void 1088 linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len) 1089 { 1090 } 1091 #endif 1092 1093 void * 1094 linux_dma_alloc_coherent(struct device *dev, size_t size, 1095 dma_addr_t *dma_handle, gfp_t flag) 1096 { 1097 struct linux_dma_priv *priv; 1098 vm_paddr_t high; 1099 size_t align; 1100 void *mem; 1101 1102 if (dev == NULL || dev->dma_priv == NULL) { 1103 *dma_handle = 0; 1104 return (NULL); 1105 } 1106 priv = dev->dma_priv; 1107 if (priv->dma_coherent_mask) 1108 high = priv->dma_coherent_mask; 1109 else 1110 /* Coherent is lower 32bit only by default in Linux. */ 1111 high = BUS_SPACE_MAXADDR_32BIT; 1112 align = PAGE_SIZE << get_order(size); 1113 /* Always zero the allocation. */ 1114 flag |= M_ZERO; 1115 mem = (void *)kmem_alloc_contig(size, flag & GFP_NATIVE_MASK, 0, high, 1116 align, 0, VM_MEMATTR_DEFAULT); 1117 if (mem != NULL) { 1118 *dma_handle = linux_dma_map_phys_common(dev, vtophys(mem), size, 1119 priv->dmat_coherent); 1120 if (*dma_handle == 0) { 1121 kmem_free((vm_offset_t)mem, size); 1122 mem = NULL; 1123 } 1124 } else { 1125 *dma_handle = 0; 1126 } 1127 return (mem); 1128 } 1129 1130 void 1131 linuxkpi_dma_sync(struct device *dev, dma_addr_t dma_addr, size_t size, 1132 bus_dmasync_op_t op) 1133 { 1134 struct linux_dma_priv *priv; 1135 struct linux_dma_obj *obj; 1136 1137 priv = dev->dma_priv; 1138 1139 if (pctrie_is_empty(&priv->ptree)) 1140 return; 1141 1142 DMA_PRIV_LOCK(priv); 1143 obj = LINUX_DMA_PCTRIE_LOOKUP(&priv->ptree, dma_addr); 1144 if (obj == NULL) { 1145 DMA_PRIV_UNLOCK(priv); 1146 return; 1147 } 1148 1149 bus_dmamap_sync(obj->dmat, obj->dmamap, op); 1150 DMA_PRIV_UNLOCK(priv); 1151 } 1152 1153 int 1154 linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, int nents, 1155 enum dma_data_direction direction, unsigned long attrs __unused) 1156 { 1157 struct linux_dma_priv *priv; 1158 struct scatterlist *sg; 1159 int i, nseg; 1160 bus_dma_segment_t seg; 1161 1162 priv = dev->dma_priv; 1163 1164 DMA_PRIV_LOCK(priv); 1165 1166 /* create common DMA map in the first S/G entry */ 1167 if (bus_dmamap_create(priv->dmat, 0, &sgl->dma_map) != 0) { 1168 DMA_PRIV_UNLOCK(priv); 1169 return (0); 1170 } 1171 1172 /* load all S/G list entries */ 1173 for_each_sg(sgl, sg, nents, i) { 1174 nseg = -1; 1175 if (_bus_dmamap_load_phys(priv->dmat, sgl->dma_map, 1176 sg_phys(sg), sg->length, BUS_DMA_NOWAIT, 1177 &seg, &nseg) != 0) { 1178 bus_dmamap_unload(priv->dmat, sgl->dma_map); 1179 bus_dmamap_destroy(priv->dmat, sgl->dma_map); 1180 DMA_PRIV_UNLOCK(priv); 1181 return (0); 1182 } 1183 KASSERT(nseg == 0, 1184 ("More than one segment (nseg=%d)", nseg + 1)); 1185 1186 sg_dma_address(sg) = seg.ds_addr; 1187 } 1188 1189 switch (direction) { 1190 case DMA_BIDIRECTIONAL: 1191 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_PREWRITE); 1192 break; 1193 case DMA_TO_DEVICE: 1194 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_PREREAD); 1195 break; 1196 case DMA_FROM_DEVICE: 1197 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_PREWRITE); 1198 break; 1199 default: 1200 break; 1201 } 1202 1203 DMA_PRIV_UNLOCK(priv); 1204 1205 return (nents); 1206 } 1207 1208 void 1209 linux_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl, 1210 int nents __unused, enum dma_data_direction direction, 1211 unsigned long attrs __unused) 1212 { 1213 struct linux_dma_priv *priv; 1214 1215 priv = dev->dma_priv; 1216 1217 DMA_PRIV_LOCK(priv); 1218 1219 switch (direction) { 1220 case DMA_BIDIRECTIONAL: 1221 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_POSTREAD); 1222 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_PREREAD); 1223 break; 1224 case DMA_TO_DEVICE: 1225 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_POSTWRITE); 1226 break; 1227 case DMA_FROM_DEVICE: 1228 bus_dmamap_sync(priv->dmat, sgl->dma_map, BUS_DMASYNC_POSTREAD); 1229 break; 1230 default: 1231 break; 1232 } 1233 1234 bus_dmamap_unload(priv->dmat, sgl->dma_map); 1235 bus_dmamap_destroy(priv->dmat, sgl->dma_map); 1236 DMA_PRIV_UNLOCK(priv); 1237 } 1238 1239 struct dma_pool { 1240 struct device *pool_device; 1241 uma_zone_t pool_zone; 1242 struct mtx pool_lock; 1243 bus_dma_tag_t pool_dmat; 1244 size_t pool_entry_size; 1245 struct pctrie pool_ptree; 1246 }; 1247 1248 #define DMA_POOL_LOCK(pool) mtx_lock(&(pool)->pool_lock) 1249 #define DMA_POOL_UNLOCK(pool) mtx_unlock(&(pool)->pool_lock) 1250 1251 static inline int 1252 dma_pool_obj_ctor(void *mem, int size, void *arg, int flags) 1253 { 1254 struct linux_dma_obj *obj = mem; 1255 struct dma_pool *pool = arg; 1256 int error, nseg; 1257 bus_dma_segment_t seg; 1258 1259 nseg = -1; 1260 DMA_POOL_LOCK(pool); 1261 error = _bus_dmamap_load_phys(pool->pool_dmat, obj->dmamap, 1262 vtophys(obj->vaddr), pool->pool_entry_size, BUS_DMA_NOWAIT, 1263 &seg, &nseg); 1264 DMA_POOL_UNLOCK(pool); 1265 if (error != 0) { 1266 return (error); 1267 } 1268 KASSERT(++nseg == 1, ("More than one segment (nseg=%d)", nseg)); 1269 obj->dma_addr = seg.ds_addr; 1270 1271 return (0); 1272 } 1273 1274 static void 1275 dma_pool_obj_dtor(void *mem, int size, void *arg) 1276 { 1277 struct linux_dma_obj *obj = mem; 1278 struct dma_pool *pool = arg; 1279 1280 DMA_POOL_LOCK(pool); 1281 bus_dmamap_unload(pool->pool_dmat, obj->dmamap); 1282 DMA_POOL_UNLOCK(pool); 1283 } 1284 1285 static int 1286 dma_pool_obj_import(void *arg, void **store, int count, int domain __unused, 1287 int flags) 1288 { 1289 struct dma_pool *pool = arg; 1290 struct linux_dma_obj *obj; 1291 int error, i; 1292 1293 for (i = 0; i < count; i++) { 1294 obj = uma_zalloc(linux_dma_obj_zone, flags); 1295 if (obj == NULL) 1296 break; 1297 1298 error = bus_dmamem_alloc(pool->pool_dmat, &obj->vaddr, 1299 BUS_DMA_NOWAIT, &obj->dmamap); 1300 if (error!= 0) { 1301 uma_zfree(linux_dma_obj_zone, obj); 1302 break; 1303 } 1304 1305 store[i] = obj; 1306 } 1307 1308 return (i); 1309 } 1310 1311 static void 1312 dma_pool_obj_release(void *arg, void **store, int count) 1313 { 1314 struct dma_pool *pool = arg; 1315 struct linux_dma_obj *obj; 1316 int i; 1317 1318 for (i = 0; i < count; i++) { 1319 obj = store[i]; 1320 bus_dmamem_free(pool->pool_dmat, obj->vaddr, obj->dmamap); 1321 uma_zfree(linux_dma_obj_zone, obj); 1322 } 1323 } 1324 1325 struct dma_pool * 1326 linux_dma_pool_create(char *name, struct device *dev, size_t size, 1327 size_t align, size_t boundary) 1328 { 1329 struct linux_dma_priv *priv; 1330 struct dma_pool *pool; 1331 1332 priv = dev->dma_priv; 1333 1334 pool = kzalloc(sizeof(*pool), GFP_KERNEL); 1335 pool->pool_device = dev; 1336 pool->pool_entry_size = size; 1337 1338 if (bus_dma_tag_create(bus_get_dma_tag(dev->bsddev), 1339 align, boundary, /* alignment, boundary */ 1340 priv->dma_mask, /* lowaddr */ 1341 BUS_SPACE_MAXADDR, /* highaddr */ 1342 NULL, NULL, /* filtfunc, filtfuncarg */ 1343 size, /* maxsize */ 1344 1, /* nsegments */ 1345 size, /* maxsegsz */ 1346 0, /* flags */ 1347 NULL, NULL, /* lockfunc, lockfuncarg */ 1348 &pool->pool_dmat)) { 1349 kfree(pool); 1350 return (NULL); 1351 } 1352 1353 pool->pool_zone = uma_zcache_create(name, -1, dma_pool_obj_ctor, 1354 dma_pool_obj_dtor, NULL, NULL, dma_pool_obj_import, 1355 dma_pool_obj_release, pool, 0); 1356 1357 mtx_init(&pool->pool_lock, "lkpi-dma-pool", NULL, MTX_DEF); 1358 pctrie_init(&pool->pool_ptree); 1359 1360 return (pool); 1361 } 1362 1363 void 1364 linux_dma_pool_destroy(struct dma_pool *pool) 1365 { 1366 1367 uma_zdestroy(pool->pool_zone); 1368 bus_dma_tag_destroy(pool->pool_dmat); 1369 mtx_destroy(&pool->pool_lock); 1370 kfree(pool); 1371 } 1372 1373 void 1374 lkpi_dmam_pool_destroy(struct device *dev, void *p) 1375 { 1376 struct dma_pool *pool; 1377 1378 pool = *(struct dma_pool **)p; 1379 LINUX_DMA_PCTRIE_RECLAIM(&pool->pool_ptree); 1380 linux_dma_pool_destroy(pool); 1381 } 1382 1383 void * 1384 linux_dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, 1385 dma_addr_t *handle) 1386 { 1387 struct linux_dma_obj *obj; 1388 1389 obj = uma_zalloc_arg(pool->pool_zone, pool, mem_flags & GFP_NATIVE_MASK); 1390 if (obj == NULL) 1391 return (NULL); 1392 1393 DMA_POOL_LOCK(pool); 1394 if (LINUX_DMA_PCTRIE_INSERT(&pool->pool_ptree, obj) != 0) { 1395 DMA_POOL_UNLOCK(pool); 1396 uma_zfree_arg(pool->pool_zone, obj, pool); 1397 return (NULL); 1398 } 1399 DMA_POOL_UNLOCK(pool); 1400 1401 *handle = obj->dma_addr; 1402 return (obj->vaddr); 1403 } 1404 1405 void 1406 linux_dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma_addr) 1407 { 1408 struct linux_dma_obj *obj; 1409 1410 DMA_POOL_LOCK(pool); 1411 obj = LINUX_DMA_PCTRIE_LOOKUP(&pool->pool_ptree, dma_addr); 1412 if (obj == NULL) { 1413 DMA_POOL_UNLOCK(pool); 1414 return; 1415 } 1416 LINUX_DMA_PCTRIE_REMOVE(&pool->pool_ptree, dma_addr); 1417 DMA_POOL_UNLOCK(pool); 1418 1419 uma_zfree_arg(pool->pool_zone, obj, pool); 1420 } 1421 1422 static int 1423 linux_backlight_get_status(device_t dev, struct backlight_props *props) 1424 { 1425 struct pci_dev *pdev; 1426 1427 linux_set_current(curthread); 1428 pdev = device_get_softc(dev); 1429 1430 props->brightness = pdev->dev.bd->props.brightness; 1431 props->brightness = props->brightness * 100 / pdev->dev.bd->props.max_brightness; 1432 props->nlevels = 0; 1433 1434 return (0); 1435 } 1436 1437 static int 1438 linux_backlight_get_info(device_t dev, struct backlight_info *info) 1439 { 1440 struct pci_dev *pdev; 1441 1442 linux_set_current(curthread); 1443 pdev = device_get_softc(dev); 1444 1445 info->type = BACKLIGHT_TYPE_PANEL; 1446 strlcpy(info->name, pdev->dev.bd->name, BACKLIGHTMAXNAMELENGTH); 1447 return (0); 1448 } 1449 1450 static int 1451 linux_backlight_update_status(device_t dev, struct backlight_props *props) 1452 { 1453 struct pci_dev *pdev; 1454 1455 linux_set_current(curthread); 1456 pdev = device_get_softc(dev); 1457 1458 pdev->dev.bd->props.brightness = pdev->dev.bd->props.max_brightness * 1459 props->brightness / 100; 1460 pdev->dev.bd->props.power = props->brightness == 0 ? 1461 4/* FB_BLANK_POWERDOWN */ : 0/* FB_BLANK_UNBLANK */; 1462 return (pdev->dev.bd->ops->update_status(pdev->dev.bd)); 1463 } 1464 1465 struct backlight_device * 1466 linux_backlight_device_register(const char *name, struct device *dev, 1467 void *data, const struct backlight_ops *ops, struct backlight_properties *props) 1468 { 1469 1470 dev->bd = malloc(sizeof(*dev->bd), M_DEVBUF, M_WAITOK | M_ZERO); 1471 dev->bd->ops = ops; 1472 dev->bd->props.type = props->type; 1473 dev->bd->props.max_brightness = props->max_brightness; 1474 dev->bd->props.brightness = props->brightness; 1475 dev->bd->props.power = props->power; 1476 dev->bd->data = data; 1477 dev->bd->dev = dev; 1478 dev->bd->name = strdup(name, M_DEVBUF); 1479 1480 dev->backlight_dev = backlight_register(name, dev->bsddev); 1481 1482 return (dev->bd); 1483 } 1484 1485 void 1486 linux_backlight_device_unregister(struct backlight_device *bd) 1487 { 1488 1489 backlight_destroy(bd->dev->backlight_dev); 1490 free(bd->name, M_DEVBUF); 1491 free(bd, M_DEVBUF); 1492 } 1493