Changeset 867b375 in mainline
- Timestamp:
- 2017-10-15T02:04:10Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 20eaa82
- Parents:
- d7869d7e
- Location:
- uspace
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/vhc/main.c
rd7869d7e r867b375 111 111 * needs to be ready at this time. 112 112 */ 113 ret = hcd_setup_virtual_root_hub(dev );113 ret = hcd_setup_virtual_root_hub(dev_to_hcd(dev), dev); 114 114 if (ret != EOK) { 115 115 usb_log_error("Failed to init VHC root hub: %s\n", -
uspace/drv/bus/usb/xhci/main.c
rd7869d7e r867b375 42 42 43 43 #include "hc.h" 44 #include "rh.h" 44 45 #include "endpoint.h" 45 46 … … 50 51 static int hcd_claim(hcd_t *, ddf_dev_t *); 51 52 static int hcd_start(hcd_t *, bool); 53 static int hcd_setup_root_hub(hcd_t *, ddf_dev_t *); 52 54 static int hcd_status(hcd_t *, uint32_t *); 53 55 static void hcd_interrupt(hcd_t *, uint32_t); 54 56 static int hcd_schedule(hcd_t *, usb_transfer_batch_t *); 57 static int hcd_address_device(hcd_t *, usb_speed_t, usb_tt_address_t, usb_address_t *); 55 58 static void hc_driver_fini(hcd_t *); 56 59 … … 62 65 .claim = hcd_claim, 63 66 .start = hcd_start, 67 .setup_root_hub = hcd_setup_root_hub, 64 68 .fini = hc_driver_fini, 65 69 .ops = { … … 67 71 .irq_hook = hcd_interrupt, 68 72 .status_hook = hcd_status, 73 .address_device = hcd_address_device, 69 74 } 70 75 }; … … 116 121 } 117 122 123 static int hcd_setup_root_hub(hcd_t *hcd, ddf_dev_t *dev) 124 { 125 xhci_hc_t *hc = hcd_get_driver_data(hcd); 126 assert(hc); 127 128 hc->rh.hcd_rh = hcd_roothub_create(hcd, dev, USB_SPEED_SUPER); 129 return hc->rh.hcd_rh ? EOK : ENOMEM; 130 } 131 118 132 static int hcd_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 119 133 { … … 139 153 140 154 hc_interrupt(hc, status); 155 } 156 157 static int hcd_address_device(hcd_t *hcd, usb_speed_t speed, usb_tt_address_t tt, usb_address_t *address) 158 { 159 xhci_hc_t *hc = hcd_get_driver_data(hcd); 160 assert(hc); 161 162 return xhci_rh_address_device(&hc->rh, speed, tt, address); 141 163 } 142 164 -
uspace/drv/bus/usb/xhci/rh.c
rd7869d7e r867b375 38 38 #include <usb/debug.h> 39 39 #include <usb/host/utils/malloc32.h> 40 #include <usb/host/ddf_helpers.h> 41 40 42 #include "debug.h" 41 43 #include "commands.h" … … 69 71 // TODO: Check device deallocation, we free device_ctx in hc.c, not 70 72 // sure about the other structs. 71 static int alloc_dev(xhci_hc_t *hc, uint8_t port, uint32_t route_str) 73 // TODO: This currently assumes the device is attached to rh directly. 74 // Also, we should consider moving a lot of functionailty to xhci bus 75 int xhci_rh_address_device(xhci_rh_t *rh, usb_speed_t unused_speed, usb_tt_address_t tt, usb_address_t *address) 72 76 { 73 77 int err; 78 xhci_hc_t *hc = rh->hc; 74 79 75 80 xhci_cmd_t cmd; 76 81 xhci_cmd_init(&cmd); 77 82 78 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(&hc->rh, port); 83 uint8_t port = tt.port; 84 85 /* XXX Certainly not generic solution. */ 86 uint32_t route_str = 0; 87 88 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, port); 79 89 80 90 xhci_send_enable_slot_command(hc, &cmd); … … 127 137 XHCI_EP_ERROR_COUNT_SET(ictx->endpoint_ctx[0], 3); 128 138 129 // TODO: What's the alignment? 130 xhci_device_ctx_t *dctx = malloc(sizeof(xhci_device_ctx_t)); 139 xhci_device_ctx_t *dctx = malloc32(sizeof(xhci_device_ctx_t)); 131 140 if (!dctx) { 132 141 err = ENOMEM; … … 149 158 xhci_cmd_fini(&cmd); 150 159 151 usb_address_taddress = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);152 usb_log_debug2("Obtained USB address: %d.\n", address);160 *address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx); 161 usb_log_debug2("Obtained USB address: %d.\n", *address); 153 162 154 163 // TODO: Ask libusbhost to create a control endpoint for EP0. … … 174 183 } 175 184 185 static int rh_setup_device(xhci_rh_t *rh, uint8_t port_id) 186 { 187 /** This should ideally use the libusbhost in a clean and elegant way, 188 * to create child function. The refactoring of libusbhost is not over 189 * yet, so for now it is still quirky. 190 */ 191 192 return hcd_roothub_new_device(rh->hcd_rh, port_id); 193 } 194 176 195 static int handle_connected_device(xhci_rh_t *rh, uint8_t port_id) 177 196 { … … 186 205 if (link_state == 0) { 187 206 /* USB3 is automatically advanced to enabled. */ 188 return alloc_dev(rh->hc, port_id, 0);207 return rh_setup_device(rh, port_id); 189 208 } 190 209 else if (link_state == 5) { … … 270 289 * every time USB2 port is reset. This is a 271 290 * temporary workaround. */ 272 alloc_dev(rh->hc, i, 0);291 rh_setup_device(rh, i); 273 292 } 274 293 } -
uspace/drv/bus/usb/xhci/rh.h
rd7869d7e r867b375 51 51 } xhci_port_speed_t; 52 52 53 typedef struct hcd_roothub hcd_roothub_t; 54 53 55 /* XHCI root hub instance */ 54 56 typedef struct { … … 64 66 /* Number of hub ports. */ 65 67 uint8_t max_ports; 68 69 /* We need this to create child devices */ 70 hcd_roothub_t *hcd_rh; 66 71 } xhci_rh_t; 67 72 … … 74 79 void xhci_rh_handle_port_change(xhci_rh_t *); 75 80 81 int xhci_rh_address_device(xhci_rh_t *, usb_speed_t, usb_tt_address_t, usb_address_t *); 82 76 83 #endif 77 84 -
uspace/lib/usb/include/usb/usb.h
rd7869d7e r867b375 114 114 typedef int16_t usb_address_t; 115 115 116 typedef struct { 117 usb_address_t address; 118 unsigned port; 119 } usb_tt_address_t; 120 116 121 /** Default USB address. */ 117 122 #define USB_ADDRESS_DEFAULT 0 -
uspace/lib/usbhost/include/usb/host/ddf_helpers.h
rd7869d7e r867b375 49 49 typedef int (*claim_t)(hcd_t *, ddf_dev_t *); 50 50 typedef int (*driver_start_t)(hcd_t *, bool irq); 51 typedef int (*setup_root_hub_t)( ddf_dev_t *);51 typedef int (*setup_root_hub_t)(hcd_t *, ddf_dev_t *); 52 52 53 53 typedef void (*driver_stop_t)(hcd_t *); … … 81 81 void hcd_ddf_clean_hc(ddf_dev_t *device); 82 82 83 int hcd_setup_virtual_root_hub( ddf_dev_t *);83 int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *); 84 84 85 85 hcd_t *dev_to_hcd(ddf_dev_t *dev); … … 93 93 void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev); 94 94 95 /* For xHCI, we need to drive the roothub without roothub having assigned an 96 * address. Thus we cannot create function for it, and we have to carry the 97 * usb_dev_t somewhere. 98 * 99 * This is sort of hacky, but at least does not expose the internals of ddf_helpers. 100 */ 101 typedef struct hcd_roothub hcd_roothub_t; 102 103 hcd_roothub_t *hcd_roothub_create(hcd_t *, ddf_dev_t *, usb_speed_t); 104 int hcd_roothub_new_device(hcd_roothub_t *, unsigned port); 105 95 106 #endif 96 107 -
uspace/lib/usbhost/include/usb/host/endpoint.h
rd7869d7e r867b375 79 79 fibril_condvar_t avail; 80 80 /** High speed TT data */ 81 struct { 82 usb_address_t address; 83 unsigned port; 84 } tt; 81 usb_tt_address_t tt; 85 82 86 83 /* This structure is meant to be extended by overriding. */ -
uspace/lib/usbhost/include/usb/host/hcd.h
rd7869d7e r867b375 50 50 51 51 typedef int (*schedule_hook_t)(hcd_t *, usb_transfer_batch_t *); 52 typedef int (*ep_add_hook_t)(hcd_t *, endpoint_t *);53 typedef void (*ep_remove_hook_t)(hcd_t *, endpoint_t *);54 52 typedef void (*interrupt_hook_t)(hcd_t *, uint32_t); 55 53 typedef int (*status_hook_t)(hcd_t *, uint32_t *); 54 typedef int (*address_device_hook_t)(hcd_t *, usb_speed_t, usb_tt_address_t, usb_address_t *); 56 55 57 56 typedef struct { … … 62 61 /** Periodic polling hook */ 63 62 status_hook_t status_hook; 63 /** Hook to setup device address */ 64 address_device_hook_t address_device; 64 65 } hcd_ops_t; 65 66 … … 112 113 113 114 extern int hcd_add_ep(hcd_t *, usb_target_t, usb_direction_t, 114 usb_transfer_type_t, size_t, unsigned int, size_t, usb_address_t, 115 unsigned int); 115 usb_transfer_type_t, size_t, unsigned int, size_t, usb_tt_address_t); 116 116 117 117 extern int hcd_remove_ep(hcd_t *, usb_target_t, usb_direction_t); -
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 * @} -
uspace/lib/usbhost/src/hcd.c
rd7869d7e r867b375 129 129 int hcd_add_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir, 130 130 usb_transfer_type_t type, size_t max_packet_size, unsigned packets, 131 size_t size, usb_ address_t tt_address, unsigned tt_port)131 size_t size, usb_tt_address_t tt) 132 132 { 133 133 assert(hcd); … … 143 143 ep->max_packet_size = max_packet_size; 144 144 ep->packets = packets; 145 146 ep->tt.address = tt_address; 147 ep->tt.port = tt_port; 145 ep->tt = tt; 148 146 149 147 ep->bandwidth = bus_count_bw(ep, size);
Note:
See TracChangeset
for help on using the changeset viewer.