1 /* $FreeBSD$ */ 2 /*- 3 * Copyright (c) 2013 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <bsd_global.h> 28 29 struct usb_process usb_process[USB_PROC_MAX]; 30 31 static device_t usb_pci_root; 32 33 /*------------------------------------------------------------------------* 34 * Implementation of mutex API 35 *------------------------------------------------------------------------*/ 36 37 struct mtx Giant; 38 int (*bus_alloc_resource_any_cb)(struct resource *res, device_t dev, 39 int type, int *rid, unsigned int flags); 40 int (*ofw_bus_status_ok_cb)(device_t dev); 41 int (*ofw_bus_is_compatible_cb)(device_t dev, char *name); 42 43 static void 44 mtx_system_init(void *arg) 45 { 46 mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE); 47 } 48 SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL); 49 50 int 51 bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, 52 bus_size_t boundary, bus_addr_t lowaddr, 53 bus_addr_t highaddr, bus_dma_filter_t *filter, 54 void *filterarg, bus_size_t maxsize, int nsegments, 55 bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, 56 void *lockfuncarg, bus_dma_tag_t *dmat) 57 { 58 struct bus_dma_tag *ret; 59 60 ret = malloc(sizeof(struct bus_dma_tag), XXX, XXX); 61 if (*dmat == NULL) 62 return (ENOMEM); 63 ret->alignment = alignment; 64 ret->maxsize = maxsize; 65 66 *dmat = ret; 67 68 return (0); 69 } 70 71 int 72 bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 73 bus_dmamap_t *mapp) 74 { 75 void *addr; 76 77 addr = malloc(dmat->maxsize + dmat->alignment, XXX, XXX); 78 if (addr == NULL) 79 return (ENOMEM); 80 81 *mapp = addr; 82 addr = (void*)(((uintptr_t)addr + dmat->alignment - 1) & ~(dmat->alignment - 1)); 83 84 *vaddr = addr; 85 return (0); 86 } 87 88 int 89 bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 90 bus_size_t buflen, bus_dmamap_callback_t *callback, 91 void *callback_arg, int flags) 92 { 93 bus_dma_segment_t segs[1]; 94 95 segs[0].ds_addr = (uintptr_t)buf; 96 segs[0].ds_len = buflen; 97 98 (*callback)(callback_arg, segs, 1, 0); 99 100 return (0); 101 } 102 103 void 104 bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) 105 { 106 107 free(map, XXX); 108 } 109 110 int 111 bus_dma_tag_destroy(bus_dma_tag_t dmat) 112 { 113 114 free(dmat, XXX); 115 return (0); 116 } 117 118 struct resource * 119 bus_alloc_resource_any(device_t dev, int type, int *rid, unsigned int flags) 120 { 121 struct resource *res; 122 int ret = EINVAL; 123 124 res = malloc(sizeof(*res), XXX, XXX); 125 if (res == NULL) 126 return (NULL); 127 128 res->__r_i = malloc(sizeof(struct resource_i), XXX, XXX); 129 if (res->__r_i == NULL) { 130 free(res, XXX); 131 return (NULL); 132 } 133 134 if (bus_alloc_resource_any_cb != NULL) 135 ret = (*bus_alloc_resource_any_cb)(res, dev, type, rid, flags); 136 if (ret == 0) 137 return (res); 138 139 free(res->__r_i, XXX); 140 free(res, XXX); 141 return (NULL); 142 } 143 144 int 145 bus_alloc_resources(device_t dev, struct resource_spec *rs, 146 struct resource **res) 147 { 148 int i; 149 150 for (i = 0; rs[i].type != -1; i++) 151 res[i] = NULL; 152 for (i = 0; rs[i].type != -1; i++) { 153 res[i] = bus_alloc_resource_any(dev, 154 rs[i].type, &rs[i].rid, rs[i].flags); 155 if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) { 156 bus_release_resources(dev, rs, res); 157 return (ENXIO); 158 } 159 } 160 return (0); 161 } 162 163 void 164 bus_release_resources(device_t dev, const struct resource_spec *rs, 165 struct resource **res) 166 { 167 int i; 168 169 for (i = 0; rs[i].type != -1; i++) 170 if (res[i] != NULL) { 171 bus_release_resource( 172 dev, rs[i].type, rs[i].rid, res[i]); 173 res[i] = NULL; 174 } 175 } 176 177 int 178 bus_setup_intr(device_t dev, struct resource *r, int flags, 179 driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep) 180 { 181 182 dev->dev_irq_filter = filter; 183 dev->dev_irq_fn = handler; 184 dev->dev_irq_arg = arg; 185 186 return (0); 187 } 188 189 int 190 bus_teardown_intr(device_t dev, struct resource *r, void *cookie) 191 { 192 193 dev->dev_irq_filter = NULL; 194 dev->dev_irq_fn = NULL; 195 dev->dev_irq_arg = NULL; 196 197 return (0); 198 } 199 200 int 201 bus_release_resource(device_t dev, int type, int rid, struct resource *r) 202 { 203 /* Resource releasing is not supported */ 204 return (EINVAL); 205 } 206 207 int 208 bus_generic_attach(device_t dev) 209 { 210 device_t child; 211 212 TAILQ_FOREACH(child, &dev->dev_children, dev_link) { 213 device_probe_and_attach(child); 214 } 215 216 return (0); 217 } 218 219 bus_space_tag_t 220 rman_get_bustag(struct resource *r) 221 { 222 223 return (r->r_bustag); 224 } 225 226 bus_space_handle_t 227 rman_get_bushandle(struct resource *r) 228 { 229 230 return (r->r_bushandle); 231 } 232 233 u_long 234 rman_get_size(struct resource *r) 235 { 236 237 return (r->__r_i->r_end - r->__r_i->r_start + 1); 238 } 239 240 int 241 ofw_bus_status_okay(device_t dev) 242 { 243 if (ofw_bus_status_ok_cb == NULL) 244 return (0); 245 246 return ((*ofw_bus_status_ok_cb)(dev)); 247 } 248 249 int 250 ofw_bus_is_compatible(device_t dev, char *name) 251 { 252 if (ofw_bus_is_compatible_cb == NULL) 253 return (0); 254 255 return ((*ofw_bus_is_compatible_cb)(dev, name)); 256 } 257 258 void 259 mtx_init(struct mtx *mtx, const char *name, const char *type, int opt) 260 { 261 mtx->owned = 0; 262 mtx->parent = mtx; 263 } 264 265 void 266 mtx_lock(struct mtx *mtx) 267 { 268 mtx = mtx->parent; 269 mtx->owned++; 270 } 271 272 void 273 mtx_unlock(struct mtx *mtx) 274 { 275 mtx = mtx->parent; 276 mtx->owned--; 277 } 278 279 int 280 mtx_owned(struct mtx *mtx) 281 { 282 mtx = mtx->parent; 283 return (mtx->owned != 0); 284 } 285 286 void 287 mtx_destroy(struct mtx *mtx) 288 { 289 /* NOP */ 290 } 291 292 /*------------------------------------------------------------------------* 293 * Implementation of shared/exclusive mutex API 294 *------------------------------------------------------------------------*/ 295 296 void 297 sx_init_flags(struct sx *sx, const char *name, int flags) 298 { 299 sx->owned = 0; 300 } 301 302 void 303 sx_destroy(struct sx *sx) 304 { 305 /* NOP */ 306 } 307 308 void 309 sx_xlock(struct sx *sx) 310 { 311 sx->owned++; 312 } 313 314 void 315 sx_xunlock(struct sx *sx) 316 { 317 sx->owned--; 318 } 319 320 int 321 sx_xlocked(struct sx *sx) 322 { 323 return (sx->owned != 0); 324 } 325 326 /*------------------------------------------------------------------------* 327 * Implementaiton of condition variable API 328 *------------------------------------------------------------------------*/ 329 330 void 331 cv_init(struct cv *cv, const char *desc) 332 { 333 cv->sleeping = 0; 334 } 335 336 void 337 cv_destroy(struct cv *cv) 338 { 339 /* NOP */ 340 } 341 342 void 343 cv_wait(struct cv *cv, struct mtx *mtx) 344 { 345 cv_timedwait(cv, mtx, -1); 346 } 347 348 int 349 cv_timedwait(struct cv *cv, struct mtx *mtx, int timo) 350 { 351 int start = ticks; 352 int delta; 353 int time = 0; 354 355 if (cv->sleeping) 356 return (EWOULDBLOCK); /* not allowed */ 357 358 cv->sleeping = 1; 359 360 while (cv->sleeping) { 361 if (timo >= 0) { 362 delta = ticks - start; 363 if (delta >= timo || delta < 0) 364 break; 365 } 366 mtx_unlock(mtx); 367 368 usb_idle(); 369 370 if (++time >= (1000000 / hz)) { 371 time = 0; 372 callout_process(1); 373 } 374 375 /* Sleep for 1 us */ 376 delay(1); 377 378 mtx_lock(mtx); 379 } 380 381 if (cv->sleeping) { 382 cv->sleeping = 0; 383 return (EWOULDBLOCK); /* not allowed */ 384 } 385 return (0); 386 } 387 388 void 389 cv_signal(struct cv *cv) 390 { 391 cv->sleeping = 0; 392 } 393 394 void 395 cv_broadcast(struct cv *cv) 396 { 397 cv->sleeping = 0; 398 } 399 400 /*------------------------------------------------------------------------* 401 * Implementation of callout API 402 *------------------------------------------------------------------------*/ 403 404 static void callout_proc_msg(struct usb_proc_msg *); 405 406 volatile int ticks = 0; 407 408 static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout); 409 410 static struct mtx mtx_callout; 411 static struct usb_proc_msg callout_msg[2]; 412 413 static void 414 callout_system_init(void *arg) 415 { 416 mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE); 417 418 callout_msg[0].pm_callback = &callout_proc_msg; 419 callout_msg[1].pm_callback = &callout_proc_msg; 420 } 421 SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL); 422 423 static void 424 callout_callback(struct callout *c) 425 { 426 mtx_lock(c->mtx); 427 428 mtx_lock(&mtx_callout); 429 if (c->entry.le_prev != NULL) { 430 LIST_REMOVE(c, entry); 431 c->entry.le_prev = NULL; 432 } 433 mtx_unlock(&mtx_callout); 434 435 if (c->c_func != NULL) 436 (c->c_func) (c->c_arg); 437 438 if (!(c->flags & CALLOUT_RETURNUNLOCKED)) 439 mtx_unlock(c->mtx); 440 } 441 442 void 443 callout_process(int timeout) 444 { 445 ticks += timeout; 446 usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]); 447 } 448 449 static void 450 callout_proc_msg(struct usb_proc_msg *pmsg) 451 { 452 struct callout *c; 453 int delta; 454 455 repeat: 456 mtx_lock(&mtx_callout); 457 458 LIST_FOREACH(c, &head_callout, entry) { 459 460 delta = c->timeout - ticks; 461 if (delta < 0) { 462 mtx_unlock(&mtx_callout); 463 464 callout_callback(c); 465 466 goto repeat; 467 } 468 } 469 mtx_unlock(&mtx_callout); 470 } 471 472 void 473 callout_init_mtx(struct callout *c, struct mtx *mtx, int flags) 474 { 475 memset(c, 0, sizeof(*c)); 476 477 if (mtx == NULL) 478 mtx = &Giant; 479 480 c->mtx = mtx; 481 c->flags = (flags & CALLOUT_RETURNUNLOCKED); 482 } 483 484 void 485 callout_reset(struct callout *c, int to_ticks, 486 void (*func) (void *), void *arg) 487 { 488 callout_stop(c); 489 490 c->c_func = func; 491 c->c_arg = arg; 492 c->timeout = ticks + to_ticks; 493 494 mtx_lock(&mtx_callout); 495 LIST_INSERT_HEAD(&head_callout, c, entry); 496 mtx_unlock(&mtx_callout); 497 } 498 499 void 500 callout_stop(struct callout *c) 501 { 502 mtx_lock(&mtx_callout); 503 504 if (c->entry.le_prev != NULL) { 505 LIST_REMOVE(c, entry); 506 c->entry.le_prev = NULL; 507 } 508 mtx_unlock(&mtx_callout); 509 510 c->c_func = NULL; 511 c->c_arg = NULL; 512 } 513 514 void 515 callout_drain(struct callout *c) 516 { 517 if (c->mtx == NULL) 518 return; /* not initialised */ 519 520 mtx_lock(c->mtx); 521 callout_stop(c); 522 mtx_unlock(c->mtx); 523 } 524 525 int 526 callout_pending(struct callout *c) 527 { 528 int retval; 529 530 mtx_lock(&mtx_callout); 531 retval = (c->entry.le_prev != NULL); 532 mtx_unlock(&mtx_callout); 533 534 return (retval); 535 } 536 537 /*------------------------------------------------------------------------* 538 * Implementation of device API 539 *------------------------------------------------------------------------*/ 540 541 static const char unknown_string[] = { "unknown" }; 542 543 static TAILQ_HEAD(, module_data) module_head = 544 TAILQ_HEAD_INITIALIZER(module_head); 545 546 static uint8_t 547 devclass_equal(const char *a, const char *b) 548 { 549 char ta, tb; 550 551 if (a == b) 552 return (1); 553 554 while (1) { 555 ta = *a; 556 tb = *b; 557 if (ta != tb) 558 return (0); 559 if (ta == 0) 560 break; 561 a++; 562 b++; 563 } 564 return (1); 565 } 566 567 int 568 bus_generic_resume(device_t dev) 569 { 570 return (0); 571 } 572 573 int 574 bus_generic_shutdown(device_t dev) 575 { 576 return (0); 577 } 578 579 int 580 bus_generic_suspend(device_t dev) 581 { 582 return (0); 583 } 584 585 int 586 bus_generic_print_child(device_t dev, device_t child) 587 { 588 return (0); 589 } 590 591 void 592 bus_generic_driver_added(device_t dev, driver_t *driver) 593 { 594 return; 595 } 596 597 device_t 598 device_get_parent(device_t dev) 599 { 600 return (dev ? dev->dev_parent : NULL); 601 } 602 603 void 604 device_set_interrupt(device_t dev, driver_filter_t *filter, 605 driver_intr_t *fn, void *arg) 606 { 607 dev->dev_irq_filter = filter; 608 dev->dev_irq_fn = fn; 609 dev->dev_irq_arg = arg; 610 } 611 612 void 613 device_run_interrupts(device_t parent) 614 { 615 device_t child; 616 617 if (parent == NULL) 618 return; 619 620 TAILQ_FOREACH(child, &parent->dev_children, dev_link) { 621 int status; 622 if (child->dev_irq_filter != NULL) 623 status = child->dev_irq_filter(child->dev_irq_arg); 624 else 625 status = FILTER_SCHEDULE_THREAD; 626 627 if (status == FILTER_SCHEDULE_THREAD) { 628 if (child->dev_irq_fn != NULL) 629 (child->dev_irq_fn) (child->dev_irq_arg); 630 } 631 } 632 } 633 634 void 635 device_set_ivars(device_t dev, void *ivars) 636 { 637 dev->dev_aux = ivars; 638 } 639 640 void * 641 device_get_ivars(device_t dev) 642 { 643 return (dev ? dev->dev_aux : NULL); 644 } 645 646 int 647 device_get_unit(device_t dev) 648 { 649 return (dev ? dev->dev_unit : 0); 650 } 651 652 int 653 bus_generic_detach(device_t dev) 654 { 655 device_t child; 656 int error; 657 658 if (!dev->dev_attached) 659 return (EBUSY); 660 661 TAILQ_FOREACH(child, &dev->dev_children, dev_link) { 662 if ((error = device_detach(child)) != 0) 663 return (error); 664 } 665 return (0); 666 } 667 668 const char * 669 device_get_nameunit(device_t dev) 670 { 671 if (dev && dev->dev_nameunit[0]) 672 return (dev->dev_nameunit); 673 674 return (unknown_string); 675 } 676 677 static uint8_t 678 devclass_create(devclass_t *dc_pp) 679 { 680 if (dc_pp == NULL) { 681 return (1); 682 } 683 if (dc_pp[0] == NULL) { 684 dc_pp[0] = malloc(sizeof(**(dc_pp)), 685 M_DEVBUF, M_WAITOK | M_ZERO); 686 687 if (dc_pp[0] == NULL) { 688 return (1); 689 } 690 } 691 return (0); 692 } 693 694 static const struct module_data * 695 devclass_find_create(const char *classname) 696 { 697 const struct module_data *mod; 698 699 TAILQ_FOREACH(mod, &module_head, entry) { 700 if (devclass_equal(mod->mod_name, classname)) { 701 if (devclass_create(mod->devclass_pp)) { 702 continue; 703 } 704 return (mod); 705 } 706 } 707 return (NULL); 708 } 709 710 static uint8_t 711 devclass_add_device(const struct module_data *mod, device_t dev) 712 { 713 device_t *pp_dev; 714 device_t *end; 715 uint8_t unit; 716 717 pp_dev = mod->devclass_pp[0]->dev_list; 718 end = pp_dev + DEVCLASS_MAXUNIT; 719 unit = 0; 720 721 while (pp_dev != end) { 722 if (*pp_dev == NULL) { 723 *pp_dev = dev; 724 dev->dev_unit = unit; 725 dev->dev_module = mod; 726 snprintf(dev->dev_nameunit, 727 sizeof(dev->dev_nameunit), 728 "%s%d", device_get_name(dev), unit); 729 return (0); 730 } 731 pp_dev++; 732 unit++; 733 } 734 DPRINTF("Could not add device to devclass.\n"); 735 return (1); 736 } 737 738 static void 739 devclass_delete_device(const struct module_data *mod, device_t dev) 740 { 741 if (mod == NULL) { 742 return; 743 } 744 mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL; 745 dev->dev_module = NULL; 746 } 747 748 static device_t 749 make_device(device_t parent, const char *name) 750 { 751 device_t dev = NULL; 752 const struct module_data *mod = NULL; 753 754 if (name) { 755 756 mod = devclass_find_create(name); 757 758 if (!mod) { 759 760 DPRINTF("%s:%d:%s: can't find device " 761 "class %s\n", __FILE__, __LINE__, 762 __FUNCTION__, name); 763 764 goto done; 765 } 766 } 767 dev = malloc(sizeof(*dev), 768 M_DEVBUF, M_WAITOK | M_ZERO); 769 770 if (dev == NULL) 771 goto done; 772 773 dev->dev_parent = parent; 774 TAILQ_INIT(&dev->dev_children); 775 776 if (name) { 777 dev->dev_fixed_class = 1; 778 if (devclass_add_device(mod, dev)) { 779 goto error; 780 } 781 } 782 done: 783 return (dev); 784 785 error: 786 if (dev) { 787 free(dev, M_DEVBUF); 788 } 789 return (NULL); 790 } 791 792 device_t 793 device_add_child(device_t dev, const char *name, int unit) 794 { 795 device_t child; 796 797 if (unit != -1) { 798 device_printf(dev, "Unit is not -1\n"); 799 } 800 child = make_device(dev, name); 801 if (child == NULL) { 802 device_printf(dev, "Could not add child '%s'\n", name); 803 goto done; 804 } 805 if (dev == NULL) { 806 /* no parent */ 807 goto done; 808 } 809 TAILQ_INSERT_TAIL(&dev->dev_children, child, dev_link); 810 done: 811 return (child); 812 } 813 814 int 815 device_delete_child(device_t dev, device_t child) 816 { 817 int error = 0; 818 device_t grandchild; 819 820 /* detach parent before deleting children, if any */ 821 error = device_detach(child); 822 if (error) 823 goto done; 824 825 /* remove children second */ 826 while ((grandchild = TAILQ_FIRST(&child->dev_children))) { 827 error = device_delete_child(child, grandchild); 828 if (error) { 829 device_printf(dev, "Error deleting child!\n"); 830 goto done; 831 } 832 } 833 834 devclass_delete_device(child->dev_module, child); 835 836 if (dev != NULL) { 837 /* remove child from parent */ 838 TAILQ_REMOVE(&dev->dev_children, child, dev_link); 839 } 840 free(child, M_DEVBUF); 841 842 done: 843 return (error); 844 } 845 846 int 847 device_delete_children(device_t dev) 848 { 849 device_t child; 850 int error = 0; 851 852 while ((child = TAILQ_FIRST(&dev->dev_children))) { 853 error = device_delete_child(dev, child); 854 if (error) { 855 device_printf(dev, "Error deleting child!\n"); 856 break; 857 } 858 } 859 return (error); 860 } 861 862 void 863 device_quiet(device_t dev) 864 { 865 dev->dev_quiet = 1; 866 } 867 868 const char * 869 device_get_desc(device_t dev) 870 { 871 if (dev) 872 return &(dev->dev_desc[0]); 873 return (unknown_string); 874 } 875 876 static int 877 default_method(void) 878 { 879 /* do nothing */ 880 DPRINTF("Default method called\n"); 881 return (0); 882 } 883 884 void * 885 device_get_method(device_t dev, const char *what) 886 { 887 const struct device_method *mtod; 888 889 mtod = dev->dev_module->driver->methods; 890 while (mtod->func != NULL) { 891 if (devclass_equal(mtod->desc, what)) { 892 return (mtod->func); 893 } 894 mtod++; 895 } 896 return ((void *)&default_method); 897 } 898 899 const char * 900 device_get_name(device_t dev) 901 { 902 if (dev == NULL) 903 return (unknown_string); 904 905 return (dev->dev_module->driver->name); 906 } 907 908 static int 909 device_allocate_softc(device_t dev) 910 { 911 const struct module_data *mod; 912 913 mod = dev->dev_module; 914 915 if ((dev->dev_softc_alloc == 0) && 916 (mod->driver->size != 0)) { 917 dev->dev_sc = malloc(mod->driver->size, 918 M_DEVBUF, M_WAITOK | M_ZERO); 919 920 if (dev->dev_sc == NULL) 921 return (ENOMEM); 922 923 dev->dev_softc_alloc = 1; 924 } 925 return (0); 926 } 927 928 int 929 device_probe_and_attach(device_t dev) 930 { 931 const struct module_data *mod; 932 const char *bus_name_parent; 933 934 bus_name_parent = device_get_name(device_get_parent(dev)); 935 936 if (dev->dev_attached) 937 return (0); /* fail-safe */ 938 939 if (dev->dev_fixed_class) { 940 941 mod = dev->dev_module; 942 943 if (DEVICE_PROBE(dev) <= 0) { 944 945 if (device_allocate_softc(dev) == 0) { 946 947 if (DEVICE_ATTACH(dev) == 0) { 948 /* success */ 949 dev->dev_attached = 1; 950 return (0); 951 } 952 } 953 } 954 device_detach(dev); 955 956 goto error; 957 } 958 /* 959 * Else find a module for our device, if any 960 */ 961 962 TAILQ_FOREACH(mod, &module_head, entry) { 963 if (devclass_equal(mod->bus_name, bus_name_parent)) { 964 if (devclass_create(mod->devclass_pp)) { 965 continue; 966 } 967 if (devclass_add_device(mod, dev)) { 968 continue; 969 } 970 if (DEVICE_PROBE(dev) <= 0) { 971 972 if (device_allocate_softc(dev) == 0) { 973 974 if (DEVICE_ATTACH(dev) == 0) { 975 /* success */ 976 dev->dev_attached = 1; 977 return (0); 978 } 979 } 980 } 981 /* else try next driver */ 982 983 device_detach(dev); 984 } 985 } 986 987 error: 988 return (ENODEV); 989 } 990 991 int 992 device_detach(device_t dev) 993 { 994 const struct module_data *mod = dev->dev_module; 995 int error; 996 997 if (dev->dev_attached) { 998 999 error = DEVICE_DETACH(dev); 1000 if (error) { 1001 return error; 1002 } 1003 dev->dev_attached = 0; 1004 } 1005 device_set_softc(dev, NULL); 1006 1007 if (dev->dev_fixed_class == 0) 1008 devclass_delete_device(mod, dev); 1009 1010 return (0); 1011 } 1012 1013 void 1014 device_set_softc(device_t dev, void *softc) 1015 { 1016 if (dev->dev_softc_alloc) { 1017 free(dev->dev_sc, M_DEVBUF); 1018 dev->dev_sc = NULL; 1019 } 1020 dev->dev_sc = softc; 1021 dev->dev_softc_alloc = 0; 1022 } 1023 1024 void * 1025 device_get_softc(device_t dev) 1026 { 1027 if (dev == NULL) 1028 return (NULL); 1029 1030 return (dev->dev_sc); 1031 } 1032 1033 int 1034 device_is_attached(device_t dev) 1035 { 1036 return (dev->dev_attached); 1037 } 1038 1039 void 1040 device_set_desc(device_t dev, const char *desc) 1041 { 1042 snprintf(dev->dev_desc, sizeof(dev->dev_desc), "%s", desc); 1043 } 1044 1045 void 1046 device_set_desc_copy(device_t dev, const char *desc) 1047 { 1048 device_set_desc(dev, desc); 1049 } 1050 1051 void * 1052 devclass_get_softc(devclass_t dc, int unit) 1053 { 1054 return (device_get_softc(devclass_get_device(dc, unit))); 1055 } 1056 1057 int 1058 devclass_get_maxunit(devclass_t dc) 1059 { 1060 int max_unit = 0; 1061 1062 if (dc) { 1063 max_unit = DEVCLASS_MAXUNIT; 1064 while (max_unit--) { 1065 if (dc->dev_list[max_unit]) { 1066 break; 1067 } 1068 } 1069 max_unit++; 1070 } 1071 return (max_unit); 1072 } 1073 1074 device_t 1075 devclass_get_device(devclass_t dc, int unit) 1076 { 1077 return (((unit < 0) || (unit >= DEVCLASS_MAXUNIT) || (dc == NULL)) ? 1078 NULL : dc->dev_list[unit]); 1079 } 1080 1081 devclass_t 1082 devclass_find(const char *classname) 1083 { 1084 const struct module_data *mod; 1085 1086 TAILQ_FOREACH(mod, &module_head, entry) { 1087 if (devclass_equal(mod->driver->name, classname)) 1088 return (mod->devclass_pp[0]); 1089 } 1090 return (NULL); 1091 } 1092 1093 void 1094 module_register(void *data) 1095 { 1096 struct module_data *mdata = data; 1097 1098 TAILQ_INSERT_TAIL(&module_head, mdata, entry); 1099 } 1100 1101 /*------------------------------------------------------------------------* 1102 * System startup 1103 *------------------------------------------------------------------------*/ 1104 1105 static void 1106 sysinit_run(const void **ppdata) 1107 { 1108 const struct sysinit *psys; 1109 1110 while ((psys = *ppdata) != NULL) { 1111 (psys->func) (psys->data); 1112 ppdata++; 1113 } 1114 } 1115 1116 /*------------------------------------------------------------------------* 1117 * USB process API 1118 *------------------------------------------------------------------------*/ 1119 1120 static int usb_do_process(struct usb_process *); 1121 static int usb_proc_level = -1; 1122 static struct mtx usb_proc_mtx; 1123 1124 void 1125 usb_idle(void) 1126 { 1127 int old_level = usb_proc_level; 1128 int old_giant = Giant.owned; 1129 int worked; 1130 1131 device_run_interrupts(usb_pci_root); 1132 1133 do { 1134 worked = 0; 1135 Giant.owned = 0; 1136 1137 while (++usb_proc_level < USB_PROC_MAX) 1138 worked |= usb_do_process(usb_process + usb_proc_level); 1139 1140 usb_proc_level = old_level; 1141 Giant.owned = old_giant; 1142 1143 } while (worked); 1144 } 1145 1146 void 1147 usb_init(void) 1148 { 1149 sysinit_run(sysinit_data); 1150 } 1151 1152 void 1153 usb_uninit(void) 1154 { 1155 sysinit_run(sysuninit_data); 1156 } 1157 1158 static void 1159 usb_process_init_sub(struct usb_process *up) 1160 { 1161 TAILQ_INIT(&up->up_qhead); 1162 1163 cv_init(&up->up_cv, "-"); 1164 cv_init(&up->up_drain, "usbdrain"); 1165 1166 up->up_mtx = &usb_proc_mtx; 1167 } 1168 1169 static void 1170 usb_process_init(void *arg) 1171 { 1172 uint8_t x; 1173 1174 mtx_init(&usb_proc_mtx, "usb-proc-mtx", NULL, MTX_DEF | MTX_RECURSE); 1175 1176 for (x = 0; x != USB_PROC_MAX; x++) 1177 usb_process_init_sub(&usb_process[x]); 1178 1179 } 1180 SYSINIT(usb_process_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, usb_process_init, NULL); 1181 1182 static int 1183 usb_do_process(struct usb_process *up) 1184 { 1185 struct usb_proc_msg *pm; 1186 int worked = 0; 1187 1188 mtx_lock(&usb_proc_mtx); 1189 1190 repeat: 1191 pm = TAILQ_FIRST(&up->up_qhead); 1192 1193 if (pm != NULL) { 1194 1195 worked = 1; 1196 1197 (pm->pm_callback) (pm); 1198 1199 if (pm == TAILQ_FIRST(&up->up_qhead)) { 1200 /* nothing changed */ 1201 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry); 1202 pm->pm_qentry.tqe_prev = NULL; 1203 } 1204 goto repeat; 1205 } 1206 mtx_unlock(&usb_proc_mtx); 1207 1208 return (worked); 1209 } 1210 1211 void * 1212 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1) 1213 { 1214 struct usb_proc_msg *pm0 = _pm0; 1215 struct usb_proc_msg *pm1 = _pm1; 1216 struct usb_proc_msg *pm2; 1217 usb_size_t d; 1218 uint8_t t; 1219 1220 t = 0; 1221 1222 if (pm0->pm_qentry.tqe_prev) { 1223 t |= 1; 1224 } 1225 if (pm1->pm_qentry.tqe_prev) { 1226 t |= 2; 1227 } 1228 if (t == 0) { 1229 /* 1230 * No entries are queued. Queue "pm0" and use the existing 1231 * message number. 1232 */ 1233 pm2 = pm0; 1234 } else if (t == 1) { 1235 /* Check if we need to increment the message number. */ 1236 if (pm0->pm_num == up->up_msg_num) { 1237 up->up_msg_num++; 1238 } 1239 pm2 = pm1; 1240 } else if (t == 2) { 1241 /* Check if we need to increment the message number. */ 1242 if (pm1->pm_num == up->up_msg_num) { 1243 up->up_msg_num++; 1244 } 1245 pm2 = pm0; 1246 } else if (t == 3) { 1247 /* 1248 * Both entries are queued. Re-queue the entry closest to 1249 * the end. 1250 */ 1251 d = (pm1->pm_num - pm0->pm_num); 1252 1253 /* Check sign after subtraction */ 1254 if (d & 0x80000000) { 1255 pm2 = pm0; 1256 } else { 1257 pm2 = pm1; 1258 } 1259 1260 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry); 1261 } else { 1262 pm2 = NULL; /* panic - should not happen */ 1263 } 1264 1265 /* Put message last on queue */ 1266 1267 pm2->pm_num = up->up_msg_num; 1268 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry); 1269 1270 return (pm2); 1271 } 1272 1273 /*------------------------------------------------------------------------* 1274 * usb_proc_is_gone 1275 * 1276 * Return values: 1277 * 0: USB process is running 1278 * Else: USB process is tearing down 1279 *------------------------------------------------------------------------*/ 1280 uint8_t 1281 usb_proc_is_gone(struct usb_process *up) 1282 { 1283 return (0); 1284 } 1285 1286 /*------------------------------------------------------------------------* 1287 * usb_proc_mwait 1288 * 1289 * This function will return when the USB process message pointed to 1290 * by "pm" is no longer on a queue. This function must be called 1291 * having "usb_proc_mtx" locked. 1292 *------------------------------------------------------------------------*/ 1293 void 1294 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) 1295 { 1296 struct usb_proc_msg *pm0 = _pm0; 1297 struct usb_proc_msg *pm1 = _pm1; 1298 1299 /* Just remove the messages from the queue. */ 1300 if (pm0->pm_qentry.tqe_prev) { 1301 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry); 1302 pm0->pm_qentry.tqe_prev = NULL; 1303 } 1304 if (pm1->pm_qentry.tqe_prev) { 1305 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry); 1306 pm1->pm_qentry.tqe_prev = NULL; 1307 } 1308 } 1309 1310 /*------------------------------------------------------------------------* 1311 * SYSTEM attach 1312 *------------------------------------------------------------------------*/ 1313 1314 #ifdef USB_PCI_PROBE_LIST 1315 static device_method_t pci_methods[] = { 1316 DEVMETHOD_END 1317 }; 1318 1319 static driver_t pci_driver = { 1320 .name = "pci", 1321 .methods = pci_methods, 1322 }; 1323 1324 static devclass_t pci_devclass; 1325 1326 DRIVER_MODULE(pci, pci, pci_driver, pci_devclass, 0, 0); 1327 1328 static const char *usb_pci_devices[] = { 1329 USB_PCI_PROBE_LIST 1330 }; 1331 1332 #define USB_PCI_USB_MAX (sizeof(usb_pci_devices) / sizeof(void *)) 1333 1334 static device_t usb_pci_dev[USB_PCI_USB_MAX]; 1335 1336 static void 1337 usb_pci_mod_load(void *arg) 1338 { 1339 uint32_t x; 1340 1341 usb_pci_root = device_add_child(NULL, "pci", -1); 1342 if (usb_pci_root == NULL) 1343 return; 1344 1345 for (x = 0; x != USB_PCI_USB_MAX; x++) { 1346 usb_pci_dev[x] = device_add_child(usb_pci_root, usb_pci_devices[x], -1); 1347 if (usb_pci_dev[x] == NULL) 1348 continue; 1349 if (device_probe_and_attach(usb_pci_dev[x])) { 1350 device_printf(usb_pci_dev[x], 1351 "WARNING: Probe and attach failed!\n"); 1352 } 1353 } 1354 } 1355 SYSINIT(usb_pci_mod_load, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_load, 0); 1356 1357 static void 1358 usb_pci_mod_unload(void *arg) 1359 { 1360 uint32_t x; 1361 1362 for (x = 0; x != USB_PCI_USB_MAX; x++) { 1363 if (usb_pci_dev[x]) { 1364 device_detach(usb_pci_dev[x]); 1365 device_delete_child(usb_pci_root, usb_pci_dev[x]); 1366 } 1367 } 1368 if (usb_pci_root) 1369 device_delete_child(NULL, usb_pci_root); 1370 } 1371 SYSUNINIT(usb_pci_mod_unload, SI_SUB_RUN_SCHEDULER, SI_ORDER_MIDDLE, usb_pci_mod_unload, 0); 1372 #endif 1373 1374 /*------------------------------------------------------------------------* 1375 * MALLOC API 1376 *------------------------------------------------------------------------*/ 1377 1378 #ifndef HAVE_MALLOC 1379 #define USB_POOL_ALIGN 8 1380 1381 static uint8_t usb_pool[USB_POOL_SIZE] __aligned(USB_POOL_ALIGN); 1382 static uint32_t usb_pool_rem = USB_POOL_SIZE; 1383 static uint32_t usb_pool_entries; 1384 1385 struct malloc_hdr { 1386 TAILQ_ENTRY(malloc_hdr) entry; 1387 uint32_t size; 1388 } __aligned(USB_POOL_ALIGN); 1389 1390 static TAILQ_HEAD(, malloc_hdr) malloc_head = 1391 TAILQ_HEAD_INITIALIZER(malloc_head); 1392 1393 void * 1394 usb_malloc(unsigned long size) 1395 { 1396 struct malloc_hdr *hdr; 1397 1398 size = (size + USB_POOL_ALIGN - 1) & ~(USB_POOL_ALIGN - 1); 1399 size += sizeof(struct malloc_hdr); 1400 1401 TAILQ_FOREACH(hdr, &malloc_head, entry) { 1402 if (hdr->size == size) 1403 break; 1404 } 1405 1406 if (hdr) { 1407 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n", 1408 (int)usb_pool_entries, (int)usb_pool_rem, (int)size); 1409 1410 TAILQ_REMOVE(&malloc_head, hdr, entry); 1411 memset(hdr + 1, 0, hdr->size - sizeof(*hdr)); 1412 return (hdr + 1); 1413 } 1414 if (usb_pool_rem >= size) { 1415 hdr = (void *)(usb_pool + USB_POOL_SIZE - usb_pool_rem); 1416 hdr->size = size; 1417 1418 usb_pool_rem -= size; 1419 usb_pool_entries++; 1420 1421 DPRINTF("MALLOC: Entries = %d; Remainder = %d; Size = %d\n", 1422 (int)usb_pool_entries, (int)usb_pool_rem, (int)size); 1423 1424 memset(hdr + 1, 0, hdr->size - sizeof(*hdr)); 1425 return (hdr + 1); 1426 } 1427 return (NULL); 1428 } 1429 1430 void 1431 usb_free(void *arg) 1432 { 1433 struct malloc_hdr *hdr; 1434 1435 if (arg == NULL) 1436 return; 1437 1438 hdr = arg; 1439 hdr--; 1440 1441 TAILQ_INSERT_TAIL(&malloc_head, hdr, entry); 1442 } 1443 #endif 1444 1445 char * 1446 usb_strdup(const char *str) 1447 { 1448 char *tmp; 1449 int len; 1450 1451 len = 1 + strlen(str); 1452 1453 tmp = malloc(len,XXX,XXX); 1454 if (tmp == NULL) 1455 return (NULL); 1456 1457 memcpy(tmp, str, len); 1458 return (tmp); 1459 } 1460