Changeset 867b375 in mainline for uspace/lib/usbhost/src/ddf_helpers.c
- Timestamp:
- 2017-10-15T02:04:10Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 20eaa82
- Parents:
- d7869d7e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/ddf_helpers.c
rd7869d7e r867b375 63 63 list_t devices; 64 64 fibril_mutex_t guard; 65 ddf_fun_t *fun;66 65 usb_address_t address; 67 66 usb_speed_t speed; 68 usb_address_t tt_address; 69 unsigned port; 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; 70 71 } usb_dev_t; 71 72 … … 73 74 ddf_fun_t *ctl_fun; 74 75 hcd_t hcd; 75 usb_dev_t *root_hub;76 76 } hc_dev_t; 77 77 … … 92 92 93 93 94 static int hcd_ddf_new_device( ddf_dev_t *device, usb_dev_t *hub, unsigned port);94 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port); 95 95 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port); 96 96 … … 127 127 128 128 return hcd_add_ep(hcd, target, direction, transfer_type, 129 max_packet_size, packets, size, dev->tt _address, dev->port);129 max_packet_size, packets, size, dev->tt); 130 130 } 131 131 … … 180 180 { 181 181 assert(fun); 182 ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun); 183 usb_dev_t *dev = ddf_fun_data_get(fun); 184 assert(ddf_dev); 185 assert(dev); 182 ddf_dev_t *hc = ddf_fun_get_dev(fun); 183 assert(hc); 184 hcd_t *hcd = dev_to_hcd(hc); 185 assert(hcd); 186 usb_dev_t *hub = ddf_fun_data_get(fun); 187 assert(hub); 188 186 189 usb_log_debug("Hub %d reported a new USB device on port: %u\n", 187 dev->address, port);188 return hcd_ddf_new_device( ddf_dev, dev, port);190 hub->address, port); 191 return hcd_ddf_new_device(hcd, hc, hub, port); 189 192 } 190 193 … … 291 294 292 295 /* DDF HELPERS */ 293 294 #define GET_DEVICE_DESC(size) \295 { \296 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \297 | (USB_REQUEST_TYPE_STANDARD << 5) \298 | USB_REQUEST_RECIPIENT_DEVICE, \299 .request = USB_DEVREQ_GET_DESCRIPTOR, \300 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \301 .index = uint16_host2usb(0), \302 .length = uint16_host2usb(size), \303 };304 305 #define SET_ADDRESS(address) \306 { \307 .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \308 | (USB_REQUEST_TYPE_STANDARD << 5) \309 | USB_REQUEST_RECIPIENT_DEVICE, \310 .request = USB_DEVREQ_SET_ADDRESS, \311 .value = uint16_host2usb(address), \312 .index = uint16_host2usb(0), \313 .length = uint16_host2usb(0), \314 };315 316 static int hcd_ddf_add_device(ddf_dev_t *parent, usb_dev_t *hub_dev,317 unsigned port, usb_address_t address, usb_speed_t speed, const char *name,318 const match_id_list_t *mids)319 {320 assert(parent);321 322 char default_name[10] = { 0 }; /* usbxyz-ss */323 if (!name) {324 snprintf(default_name, sizeof(default_name) - 1,325 "usb%u-%cs", address, usb_str_speed(speed)[0]);326 name = default_name;327 }328 329 ddf_fun_t *fun = ddf_fun_create(parent, fun_inner, name);330 if (!fun)331 return ENOMEM;332 usb_dev_t *info = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));333 if (!info) {334 ddf_fun_destroy(fun);335 return ENOMEM;336 }337 info->address = address;338 info->speed = speed;339 info->fun = fun;340 info->port = port;341 info->tt_address = hub_dev ? hub_dev->tt_address : -1;342 link_initialize(&info->link);343 list_initialize(&info->devices);344 fibril_mutex_initialize(&info->guard);345 346 if (hub_dev && hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed))347 info->tt_address = hub_dev->address;348 349 ddf_fun_set_ops(fun, &usb_ops);350 list_foreach(mids->ids, link, const match_id_t, mid) {351 ddf_fun_add_match_id(fun, mid->id, mid->score);352 }353 354 int ret = ddf_fun_bind(fun);355 if (ret != EOK) {356 ddf_fun_destroy(fun);357 return ret;358 }359 360 if (hub_dev) {361 fibril_mutex_lock(&hub_dev->guard);362 list_append(&info->link, &hub_dev->devices);363 fibril_mutex_unlock(&hub_dev->guard);364 } else {365 hc_dev_t *hc_dev = dev_to_hc_dev(parent);366 assert(hc_dev->root_hub == NULL);367 hc_dev->root_hub = info;368 }369 return EOK;370 }371 296 372 297 #define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \ … … 416 341 417 342 return EOK; 418 419 343 } 420 344 … … 435 359 436 360 list_foreach(hub->devices, link, usb_dev_t, it) { 437 if (it-> port == port) {361 if (it->tt.port == port) { 438 362 victim = it; 439 363 break; … … 441 365 } 442 366 if (victim) { 443 assert(victim->port == port); 367 assert(victim->fun); 368 assert(victim->tt.port == port); 444 369 list_remove(&victim->link); 445 370 fibril_mutex_unlock(&hub->guard); … … 459 384 } 460 385 461 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port) 462 { 463 assert(device); 464 465 hcd_t *hcd = dev_to_hcd(device); 466 assert(hcd); 467 468 usb_speed_t speed = USB_SPEED_MAX; 469 470 /* This checks whether the default address is reserved and gets speed */ 471 int ret = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed); 472 if (ret != EOK) { 473 usb_log_error("Failed to verify speed: %s.", str_error(ret)); 474 return ret; 475 } 476 477 usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed)); 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; 478 412 479 413 static const usb_target_t default_target = {{ … … 482 416 }}; 483 417 418 /** Reserve address early, we want pretty log messages */ 484 419 const usb_address_t address = hcd_request_address(hcd, speed); 485 420 if (address < 0) { … … 488 423 return address; 489 424 } 490 491 usb_log_debug("Reserved new address: %d\n", address); 492 493 const usb_target_t target = {{ 494 .address = address, 495 .endpoint = 0, 496 }}; 497 498 const usb_address_t tt_address = hub ? hub->tt_address : -1; 425 usb_log_debug("Device(%d): Reserved new address.", address); 499 426 500 427 /* Add default pipe on default address */ 501 usb_log_debug("Device(%d): Adding default target (0:0)\n", address);502 ret= hcd_add_ep(hcd,428 usb_log_debug("Device(%d): Adding default target (0:0)", address); 429 err = hcd_add_ep(hcd, 503 430 default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 504 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, 505 tt_address, port); 506 if (ret != EOK) { 431 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, tt); 432 if (err != EOK) { 507 433 usb_log_error("Device(%d): Failed to add default target: %s.", 508 address, str_error(ret)); 509 hcd_release_address(hcd, address); 510 return ret; 434 address, str_error(err)); 435 goto err_address; 511 436 } 512 437 … … 516 441 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 517 442 518 // TODO CALLBACKS519 443 usb_log_debug("Device(%d): Requesting first 8B of device descriptor.", 520 444 address); … … 524 448 525 449 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 526 ret= got < 0 ? got : EOVERFLOW;450 err = got < 0 ? got : EOVERFLOW; 527 451 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.", 528 address, str_error(ret)); 529 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 530 hcd_release_address(hcd, address); 531 return ret; 532 } 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 }; 533 474 534 475 /* Register EP on the new address */ 535 476 usb_log_debug("Device(%d): Registering control EP.", address); 536 ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,477 err = hcd_add_ep(hcd, control_ep, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 537 478 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 538 479 ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)), 539 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 540 tt_address, port); 541 if (ret != EOK) { 480 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), tt); 481 if (err != EOK) { 542 482 usb_log_error("Device(%d): Failed to register EP0: %s", 543 address, str_error(ret)); 544 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 545 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 546 hcd_release_address(hcd, address); 547 return ret; 548 } 549 550 /* Set new address */ 551 const usb_device_request_setup_packet_t set_address = 552 SET_ADDRESS(target.address); 553 554 usb_log_debug("Device(%d): Setting USB address.", address); 555 got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 556 NULL, 0, *(uint64_t *)&set_address, "set address"); 557 558 usb_log_debug("Device(%d): Removing default (0:0) EP.", address); 483 address, str_error(err)); 484 goto err_default_target; 485 } 486 559 487 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 560 561 if (got != 0) { 562 usb_log_error("Device(%d): Failed to set new address: %s.", 563 address, str_error(got)); 564 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 565 hcd_release_address(hcd, address); 566 return got; 567 } 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) 512 { 513 /* Create DDF function for the new device */ 514 ddf_fun_t *fun = ddf_fun_create(hc, fun_inner, NULL); 515 if (!fun) 516 return NULL; 517 518 ddf_fun_set_ops(fun, &usb_ops); 519 520 /* 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) { 523 ddf_fun_destroy(fun); 524 return NULL; 525 } 526 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) 533 { 534 assert(dev); 535 assert(dev->fun); 536 ddf_fun_destroy(dev->fun); 537 } 538 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) 551 { 552 int err; 553 match_id_list_t mids; 554 usb_standard_device_descriptor_t desc = { 0 }; 555 556 init_match_ids(&mids); 557 558 usb_target_t control_ep = { 559 .address = usb_dev->address, 560 .endpoint = 0 561 }; 568 562 569 563 /* Get std device descriptor */ … … 572 566 573 567 usb_log_debug("Device(%d): Requesting full device descriptor.", 574 address);575 got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,568 usb_dev->address); 569 ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN, 576 570 &desc, sizeof(desc), *(uint64_t *)&get_device_desc, 577 571 "read device descriptor"); 578 if (ret != EOK) { 572 if (got < 0) { 573 err = got < 0 ? got : EOVERFLOW; 579 574 usb_log_error("Device(%d): Failed to set get dev descriptor: %s", 580 address, str_error(ret)); 581 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 582 hcd_release_address(hcd, target.address); 583 return ret; 575 usb_dev->address, str_error(err)); 576 goto out; 584 577 } 585 578 586 579 /* Create match ids from the device descriptor */ 587 match_id_list_t mids; 588 init_match_ids(&mids); 589 590 usb_log_debug("Device(%d): Creating match IDs.", address); 591 ret = create_match_ids(&mids, &desc); 592 if (ret != EOK) { 593 usb_log_error("Device(%d): Failed to create match ids: %s", 594 address, str_error(ret)); 595 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 596 hcd_release_address(hcd, target.address); 597 return ret; 598 } 599 600 /* Register device */ 601 usb_log_debug("Device(%d): Registering DDF device.", address); 602 ret = hcd_ddf_add_device(device, hub, port, address, speed, NULL, &mids); 580 usb_log_debug("Device(%d): Creating match IDs.", usb_dev->address); 581 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)); 583 goto out; 584 } 585 586 list_foreach(mids.ids, link, const match_id_t, mid) { 587 ddf_fun_add_match_id(usb_dev->fun, mid->id, mid->score); 588 } 589 590 out: 603 591 clean_match_ids(&mids); 604 if (ret != EOK) { 605 usb_log_error("Device(%d): Failed to register: %s.", 606 address, str_error(ret)); 607 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 608 hcd_release_address(hcd, target.address); 609 } 610 611 return ret; 592 return err; 593 } 594 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) 604 { 605 int err; 606 assert(hcd); 607 assert(hub_dev); 608 assert(hc); 609 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. 613 */ 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)); 640 goto err_usb_dev; 641 } 642 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); 664 665 return EOK; 666 667 err_usb_dev: 668 usb_dev_destroy(usb_dev); 669 return err; 612 670 } 613 671 … … 617 675 * @return Error code 618 676 */ 619 int hcd_setup_virtual_root_hub(ddf_dev_t *device) 620 { 621 assert(device); 622 hcd_t *hcd = dev_to_hcd(device); 677 int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc) 678 { 679 int err; 680 681 assert(hc); 623 682 assert(hcd); 624 683 625 hcd_reserve_default_address(hcd, USB_SPEED_MAX); 626 const int ret = hcd_ddf_new_device(device, NULL, 0); 684 if ((err = hcd_reserve_default_address(hcd, USB_SPEED_MAX))) { 685 usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err)); 686 return err; 687 } 688 689 usb_dev_t *usb_dev = usb_dev_create(hc, USB_SPEED_MAX); 690 if (!usb_dev) { 691 usb_log_error("Failed to create function for the root hub."); 692 goto err_default_address; 693 } 694 695 usb_dev->tt.address = -1; 696 usb_dev->tt.port = 0; 697 698 /* 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)); 701 goto err_usb_dev; 702 } 703 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))) { 713 usb_log_error("Failed to register roothub: %s.", str_error(err)); 714 goto err_usb_dev; 715 } 716 627 717 hcd_release_default_address(hcd); 628 return ret; 718 return EOK; 719 720 err_usb_dev: 721 usb_dev_destroy(usb_dev); 722 err_default_address: 723 hcd_release_default_address(hcd); 724 return err; 629 725 } 630 726 … … 648 744 return ENOMEM; 649 745 } 650 instance->root_hub = NULL;651 746 hcd_init(&instance->hcd); 652 747 … … 920 1015 */ 921 1016 if (driver->setup_root_hub) 922 ret = driver->setup_root_hub( device);1017 ret = driver->setup_root_hub(hcd, device); 923 1018 if (ret != EOK) { 924 1019 usb_log_error("Failed to setup HC root hub: %s.\n", … … 947 1042 return ret; 948 1043 } 1044 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 } 949 1066 /** 950 1067 * @}
Note:
See TracChangeset
for help on using the changeset viewer.