Changeset 20eaa82 in mainline for uspace/lib/usbhost/src/ddf_helpers.c
- Timestamp:
- 2017-10-15T13:44:39Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2770b66
- Parents:
- 867b375
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/ddf_helpers.c
r867b375 r20eaa82 35 35 36 36 #include <usb/classes/classes.h> 37 #include <usb/host/bus.h> 37 38 #include <usb/debug.h> 38 39 #include <usb/descriptor.h> … … 50 51 #include <fibril_synch.h> 51 52 #include <macros.h> 52 #include <stdio.h>53 53 #include <stdlib.h> 54 54 #include <str_error.h> … … 56 56 57 57 #include "ddf_helpers.h" 58 59 #define CTRL_PIPE_MIN_PACKET_SIZE 860 61 typedef struct usb_dev {62 link_t link;63 list_t devices;64 fibril_mutex_t guard;65 usb_address_t address;66 usb_speed_t speed;67 usb_tt_address_t tt;68 69 /* This must be set iff the usb_dev is managed by ddf_fun. */70 ddf_fun_t *fun;71 } usb_dev_t;72 58 73 59 typedef struct hc_dev { … … 92 78 93 79 94 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port);95 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);80 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port); 81 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port); 96 82 97 83 … … 115 101 assert(fun); 116 102 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 117 usb_dev_t *dev = ddf_fun_data_get(fun);103 device_t *dev = ddf_fun_data_get(fun); 118 104 assert(hcd); 105 assert(hcd->bus); 119 106 assert(dev); 120 107 const size_t size = max_packet_size; 121 const usb_target_t target =122 {{.address = dev->address, .endpoint = endpoint}};123 108 124 109 usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n", … … 126 111 usb_str_direction(direction), max_packet_size, interval); 127 112 128 return hcd_add_ep(hcd, target, direction, transfer_type,129 max_packet_size, packets, size , dev->tt);113 return bus_add_ep(hcd->bus, dev, endpoint, direction, transfer_type, 114 max_packet_size, packets, size); 130 115 } 131 116 … … 142 127 assert(fun); 143 128 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 144 usb_dev_t *dev = ddf_fun_data_get(fun);129 device_t *dev = ddf_fun_data_get(fun); 145 130 assert(hcd); 131 assert(hcd->bus); 146 132 assert(dev); 147 const usb_target_t target = 148 {{.address = dev->address, .endpoint = endpoint}}; 133 const usb_target_t target = {{ 134 .address = dev->address, 135 .endpoint = endpoint 136 }}; 149 137 usb_log_debug("Unregister endpoint %d:%d %s.\n", 150 138 dev->address, endpoint, usb_str_direction(direction)); 151 return hcd_remove_ep(hcd, target, direction);139 return bus_remove_ep(hcd->bus, target, direction); 152 140 } 153 141 … … 156 144 assert(fun); 157 145 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 158 usb_dev_t *dev = ddf_fun_data_get(fun);146 device_t *dev = ddf_fun_data_get(fun); 159 147 assert(hcd); 148 assert(hcd->bus); 160 149 assert(dev); 161 150 162 151 usb_log_debug("Device %d requested default address at %s speed\n", 163 152 dev->address, usb_str_speed(speed)); 164 return hcd_reserve_default_address(hcd, speed);153 return bus_reserve_default_address(hcd->bus, speed); 165 154 } 166 155 … … 169 158 assert(fun); 170 159 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 171 usb_dev_t *dev = ddf_fun_data_get(fun);160 device_t *dev = ddf_fun_data_get(fun); 172 161 assert(hcd); 162 assert(hcd->bus); 173 163 assert(dev); 174 164 175 165 usb_log_debug("Device %d released default address\n", dev->address); 176 return hcd_release_default_address(hcd);166 return bus_release_default_address(hcd->bus); 177 167 } 178 168 … … 184 174 hcd_t *hcd = dev_to_hcd(hc); 185 175 assert(hcd); 186 usb_dev_t *hub = ddf_fun_data_get(fun);176 device_t *hub = ddf_fun_data_get(fun); 187 177 assert(hub); 188 178 … … 196 186 assert(fun); 197 187 ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun); 198 usb_dev_t *dev = ddf_fun_data_get(fun);188 device_t *dev = ddf_fun_data_get(fun); 199 189 assert(ddf_dev); 200 190 assert(dev); … … 233 223 { 234 224 assert(fun); 235 usb_dev_t *usb_dev = ddf_fun_data_get(fun);236 assert( usb_dev);225 device_t *dev = ddf_fun_data_get(fun); 226 assert(dev); 237 227 const usb_target_t target = {{ 238 .address = usb_dev->address,228 .address = dev->address, 239 229 .endpoint = endpoint, 240 230 }}; … … 259 249 { 260 250 assert(fun); 261 usb_dev_t *usb_dev = ddf_fun_data_get(fun);262 assert( usb_dev);251 device_t *dev = ddf_fun_data_get(fun); 252 assert(dev); 263 253 const usb_target_t target = {{ 264 .address = usb_dev->address,254 .address = dev->address, 265 255 .endpoint = endpoint, 266 256 }}; … … 343 333 } 344 334 345 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub,335 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, 346 336 unsigned port) 347 337 { … … 350 340 hcd_t *hcd = dev_to_hcd(device); 351 341 assert(hcd); 342 assert(hcd->bus); 352 343 353 344 hc_dev_t *hc_dev = dev_to_hc_dev(device); … … 356 347 fibril_mutex_lock(&hub->guard); 357 348 358 usb_dev_t *victim = NULL;359 360 list_foreach(hub->devices, link, usb_dev_t, it) {361 if (it-> tt.port == port) {349 device_t *victim = NULL; 350 351 list_foreach(hub->devices, link, device_t, it) { 352 if (it->port == port) { 362 353 victim = it; 363 354 break; … … 366 357 if (victim) { 367 358 assert(victim->fun); 368 assert(victim->tt.port == port); 359 assert(victim->port == port); 360 assert(victim->hub == hub); 369 361 list_remove(&victim->link); 370 362 fibril_mutex_unlock(&hub->guard); … … 372 364 if (ret == EOK) { 373 365 usb_address_t address = victim->address; 366 bus_remove_device(hcd->bus, hcd, victim); 374 367 ddf_fun_destroy(victim->fun); 375 hcd_release_address(hcd, address);368 bus_release_address(hcd->bus, address); 376 369 } else { 377 370 usb_log_warning("Failed to unbind device `%s': %s\n", … … 384 377 } 385 378 386 #define GET_DEVICE_DESC(size) \ 387 { \ 388 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \ 389 | (USB_REQUEST_TYPE_STANDARD << 5) \ 390 | USB_REQUEST_RECIPIENT_DEVICE, \ 391 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 392 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \ 393 .index = uint16_host2usb(0), \ 394 .length = uint16_host2usb(size), \ 395 }; 396 397 #define SET_ADDRESS(address) \ 398 { \ 399 .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \ 400 | (USB_REQUEST_TYPE_STANDARD << 5) \ 401 | USB_REQUEST_RECIPIENT_DEVICE, \ 402 .request = USB_DEVREQ_SET_ADDRESS, \ 403 .value = uint16_host2usb(address), \ 404 .index = uint16_host2usb(0), \ 405 .length = uint16_host2usb(0), \ 406 }; 407 408 static int hcd_usb2_address_device(hcd_t *hcd, usb_speed_t speed, 409 usb_tt_address_t tt, usb_address_t *out_address) 410 { 411 int err; 412 413 static const usb_target_t default_target = {{ 414 .address = USB_ADDRESS_DEFAULT, 415 .endpoint = 0, 416 }}; 417 418 /** Reserve address early, we want pretty log messages */ 419 const usb_address_t address = hcd_request_address(hcd, speed); 420 if (address < 0) { 421 usb_log_error("Failed to reserve new address: %s.", 422 str_error(address)); 423 return address; 424 } 425 usb_log_debug("Device(%d): Reserved new address.", address); 426 427 /* Add default pipe on default address */ 428 usb_log_debug("Device(%d): Adding default target (0:0)", address); 429 err = hcd_add_ep(hcd, 430 default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 431 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, tt); 432 if (err != EOK) { 433 usb_log_error("Device(%d): Failed to add default target: %s.", 434 address, str_error(err)); 435 goto err_address; 436 } 437 438 /* Get max packet size for default pipe */ 439 usb_standard_device_descriptor_t desc = { 0 }; 440 const usb_device_request_setup_packet_t get_device_desc_8 = 441 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 442 443 usb_log_debug("Device(%d): Requesting first 8B of device descriptor.", 444 address); 445 ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN, 446 &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8, 447 "read first 8 bytes of dev descriptor"); 448 449 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 450 err = got < 0 ? got : EOVERFLOW; 451 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.", 452 address, str_error(err)); 453 goto err_default_target; 454 } 455 456 /* Set new address */ 457 const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address); 458 459 usb_log_debug("Device(%d): Setting USB address.", address); 460 err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 461 NULL, 0, *(uint64_t *)&set_address, "set address"); 462 if (err != 0) { 463 usb_log_error("Device(%d): Failed to set new address: %s.", 464 address, str_error(got)); 465 goto err_default_target; 466 } 467 468 *out_address = address; 469 470 usb_target_t control_ep = { 471 .address = address, 472 .endpoint = 0 473 }; 474 475 /* Register EP on the new address */ 476 usb_log_debug("Device(%d): Registering control EP.", address); 477 err = hcd_add_ep(hcd, control_ep, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 478 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 479 ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)), 480 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), tt); 481 if (err != EOK) { 482 usb_log_error("Device(%d): Failed to register EP0: %s", 483 address, str_error(err)); 484 goto err_default_target; 485 } 486 487 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 488 return EOK; 489 490 491 err_default_target: 492 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 493 err_address: 494 hcd_release_address(hcd, address); 495 return err; 496 } 497 498 static int usb_dev_init(usb_dev_t *usb_dev, usb_speed_t speed) 499 { 500 memset(usb_dev, 0, sizeof(*usb_dev)); 501 502 link_initialize(&usb_dev->link); 503 list_initialize(&usb_dev->devices); 504 fibril_mutex_initialize(&usb_dev->guard); 505 506 usb_dev->speed = speed; 507 508 return EOK; 509 } 510 511 static usb_dev_t *usb_dev_create(ddf_dev_t *hc, usb_speed_t speed) 379 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size) 512 380 { 513 381 /* Create DDF function for the new device */ … … 519 387 520 388 /* Create USB device node for the new device */ 521 usb_dev_t *usb_dev = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));522 if (! usb_dev) {389 device_t *dev = ddf_fun_data_alloc(fun, device_size); 390 if (!dev) { 523 391 ddf_fun_destroy(fun); 524 392 return NULL; 525 393 } 526 394 527 usb_dev_init(usb_dev, speed);528 usb_dev->fun = fun;529 return usb_dev;530 } 531 532 static void usb_dev_destroy(usb_dev_t *dev)395 device_init(dev); 396 dev->fun = fun; 397 return dev; 398 } 399 400 void hcd_ddf_device_destroy(device_t *dev) 533 401 { 534 402 assert(dev); … … 537 405 } 538 406 539 static int usb_dev_set_default_name(usb_dev_t *usb_dev) 540 { 541 assert(usb_dev); 542 543 char buf[10] = { 0 }; /* usbxyz-ss */ 544 snprintf(buf, sizeof(buf) - 1, "usb%u-%cs", 545 usb_dev->address, usb_str_speed(usb_dev->speed)[0]); 546 547 return ddf_fun_set_name(usb_dev->fun, buf); 548 } 549 550 static int usb_dev_explore(hcd_t *hcd, usb_dev_t *usb_dev) 407 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device) 551 408 { 552 409 int err; … … 556 413 init_match_ids(&mids); 557 414 558 usb_target_t control_ep = { 559 .address = usb_dev->address,415 usb_target_t control_ep = {{ 416 .address = device->address, 560 417 .endpoint = 0 561 } ;418 }}; 562 419 563 420 /* Get std device descriptor */ … … 566 423 567 424 usb_log_debug("Device(%d): Requesting full device descriptor.", 568 usb_dev->address);425 device->address); 569 426 ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN, 570 427 &desc, sizeof(desc), *(uint64_t *)&get_device_desc, … … 573 430 err = got < 0 ? got : EOVERFLOW; 574 431 usb_log_error("Device(%d): Failed to set get dev descriptor: %s", 575 usb_dev->address, str_error(err));432 device->address, str_error(err)); 576 433 goto out; 577 434 } 578 435 579 436 /* Create match ids from the device descriptor */ 580 usb_log_debug("Device(%d): Creating match IDs.", usb_dev->address);437 usb_log_debug("Device(%d): Creating match IDs.", device->address); 581 438 if ((err = create_match_ids(&mids, &desc))) { 582 usb_log_error("Device(%d): Failed to create match ids: %s", usb_dev->address, str_error(err));439 usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err)); 583 440 goto out; 584 441 } 585 442 586 443 list_foreach(mids.ids, link, const match_id_t, mid) { 587 ddf_fun_add_match_id( usb_dev->fun, mid->id, mid->score);444 ddf_fun_add_match_id(device->fun, mid->id, mid->score); 588 445 } 589 446 … … 593 450 } 594 451 595 static int hcd_address_device(hcd_t *hcd, usb_dev_t *usb_dev) 596 { 597 if (hcd->ops.address_device) 598 return hcd->ops.address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address); 599 else 600 return hcd_usb2_address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address); 601 } 602 603 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port) 452 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port) 604 453 { 605 454 int err; 606 455 assert(hcd); 607 assert(hub_dev); 456 assert(hcd->bus); 457 assert(hub); 608 458 assert(hc); 609 459 610 usb_speed_t speed = USB_SPEED_MAX; 611 /* The speed of the new device was reported by the hub when reserving 612 * default address. 460 device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size); 461 if (!dev) { 462 usb_log_error("Failed to create USB device function."); 463 return ENOMEM; 464 } 465 466 dev->hub = hub; 467 dev->port = port; 468 469 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 470 usb_log_error("Failed to initialize USB dev memory structures."); 471 return err; 472 } 473 474 /* If the driver didn't name the dev when enumerating, 475 * do it in some generic way. 613 476 */ 614 if ((err = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed))) { 615 usb_log_error("Failed to verify speed: %s.", str_error(err)); 616 return err; 617 } 618 usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed)); 619 620 usb_dev_t *usb_dev = usb_dev_create(hc, speed); 621 if (!usb_dev) { 622 usb_log_error("Failed to create USB device function."); 623 return err; 624 } 625 626 /* For devices under HS hub */ 627 /* TODO: How about SS hubs? */ 628 if (hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed)) { 629 usb_dev->tt.address = hub_dev->address; 630 } 631 else { 632 /* Inherit hub's TT */ 633 usb_dev->tt.address = hub_dev->tt.address; 634 } 635 usb_dev->tt.port = port; 636 637 /* Assign an address to the device */ 638 if ((err = hcd_address_device(hcd, usb_dev))) { 639 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 477 if (!ddf_fun_get_name(dev->fun)) { 478 device_set_default_name(dev); 479 } 480 481 if ((err = ddf_fun_bind(dev->fun))) { 482 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err)); 640 483 goto err_usb_dev; 641 484 } 642 485 643 /* Read the device descriptor, derive the match ids */ 644 if ((err = usb_dev_explore(hcd, usb_dev))) { 645 usb_log_error("Device(%d): Failed to explore device: %s", usb_dev->address, str_error(err)); 646 goto err_usb_dev; 647 } 648 649 /* If the driver didn't name the device when addressing/exploring, 650 * do it insome generic way. 651 */ 652 if (!ddf_fun_get_name(usb_dev->fun)) { 653 usb_dev_set_default_name(usb_dev); 654 } 655 656 if ((err = ddf_fun_bind(usb_dev->fun))) { 657 usb_log_error("Device(%d): Failed to register: %s.", usb_dev->address, str_error(err)); 658 goto err_usb_dev; 659 } 660 661 fibril_mutex_lock(&hub_dev->guard); 662 list_append(&usb_dev->link, &hub_dev->devices); 663 fibril_mutex_unlock(&hub_dev->guard); 486 fibril_mutex_lock(&hub->guard); 487 list_append(&dev->link, &hub->devices); 488 fibril_mutex_unlock(&hub->guard); 664 489 665 490 return EOK; 666 491 667 492 err_usb_dev: 668 usb_dev_destroy(usb_dev);493 hcd_ddf_device_destroy(dev); 669 494 return err; 670 495 } … … 681 506 assert(hc); 682 507 assert(hcd); 683 684 if ((err = hcd_reserve_default_address(hcd, USB_SPEED_MAX))) { 508 assert(hcd->bus); 509 510 if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) { 685 511 usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err)); 686 512 return err; 687 513 } 688 514 689 usb_dev_t *usb_dev = usb_dev_create(hc, USB_SPEED_MAX);690 if (! usb_dev) {515 device_t *dev = hcd_ddf_device_create(hc, USB_SPEED_MAX); 516 if (!dev) { 691 517 usb_log_error("Failed to create function for the root hub."); 692 518 goto err_default_address; 693 519 } 694 520 695 usb_dev->tt.address = -1; 696 usb_dev->tt.port = 0; 521 ddf_fun_set_name(dev->fun, "roothub"); 522 523 dev->tt = (usb_tt_address_t) { 524 .address = -1, 525 .port = 0, 526 }; 697 527 698 528 /* Assign an address to the device */ 699 if ((err = hcd_address_device(hcd, usb_dev))) {700 usb_log_error("Failed to setup roothub address: %s", str_error(err));529 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 530 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 701 531 goto err_usb_dev; 702 532 } 703 533 704 /* Read the device descriptor, derive the match ids */ 705 if ((err = usb_dev_explore(hcd, usb_dev))) { 706 usb_log_error("Failed to explore roothub: %s", str_error(err)); 707 goto err_usb_dev; 708 } 709 710 ddf_fun_set_name(usb_dev->fun, "roothub"); 711 712 if ((err = ddf_fun_bind(usb_dev->fun))) { 534 if ((err = ddf_fun_bind(dev->fun))) { 713 535 usb_log_error("Failed to register roothub: %s.", str_error(err)); 714 536 goto err_usb_dev; 715 537 } 716 538 717 hcd_release_default_address(hcd);539 bus_release_default_address(hcd->bus); 718 540 return EOK; 719 541 720 542 err_usb_dev: 721 usb_dev_destroy(usb_dev);543 hcd_ddf_device_destroy(dev); 722 544 err_default_address: 723 hcd_release_default_address(hcd);545 bus_release_default_address(hcd->bus); 724 546 return err; 725 547 } … … 1043 865 } 1044 866 1045 struct hcd_roothub {1046 hcd_t *hcd;1047 ddf_dev_t *hc_dev;1048 usb_dev_t rh_usb;1049 };1050 1051 hcd_roothub_t *hcd_roothub_create(hcd_t *hcd, ddf_dev_t *dev, usb_speed_t speed)1052 {1053 hcd_roothub_t *rh = malloc(sizeof(*rh));1054 1055 rh->hcd = hcd;1056 rh->hc_dev = dev;1057 usb_dev_init(&rh->rh_usb, speed);1058 1059 rh->rh_usb.tt.address = -1;1060 return rh;1061 }1062 1063 int hcd_roothub_new_device(hcd_roothub_t *rh, unsigned port) {1064 return hcd_ddf_new_device(rh->hcd, rh->hc_dev, &rh->rh_usb, port);1065 }1066 867 /** 1067 868 * @}
Note:
See TracChangeset
for help on using the changeset viewer.