Changeset 51a51be in mainline
- Timestamp:
- 2018-01-16T21:19:37Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1d218bf
- Parents:
- 4603b35
- Location:
- uspace/drv/bus/usb/usbhub
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhub/port.c
r4603b35 r51a51be 243 243 } 244 244 245 /* Reserve default address 246 * TODO: Make the request synchronous. 247 */ 248 while ((err = usbhc_reserve_default_address(exch)) == EAGAIN) { 249 fibril_condvar_wait_timeout(&port->state_cv, &port->guard, 500000); 250 if (port->state != PORT_CONNECTED) { 251 assert(port->state == PORT_ERROR); 252 port_change_state(port, PORT_DISABLED); 253 goto out_exch; 254 } 255 } 245 /* Reserve default address */ 246 err = usb_hub_reserve_default_address(port->hub, exch, &port->guard); 256 247 if (err != EOK) { 257 248 port_log(error, port, "Failed to reserve default address: %s", str_error(err)); 249 port_change_state(port, PORT_DISABLED); 250 goto out_exch; 251 } 252 253 /* Reservation of default address could have blocked */ 254 if (port->state != PORT_CONNECTED) { 255 assert(port->state == PORT_ERROR); 256 port_change_state(port, PORT_DISABLED); 258 257 goto out_exch; 259 258 } … … 282 281 if (port->state != PORT_ENABLED) 283 282 usb_hub_clear_port_feature(port->hub, port->port_number, USB_HUB_FEATURE_C_PORT_ENABLE); 284 285 283 out_address: 286 if ((err = usbhc_release_default_address(exch))) 287 port_log(error, port, "Failed to release default address: %s", str_error(err)); 288 284 usb_hub_release_default_address(port->hub, exch); 289 285 out_exch: 290 286 usb_device_bus_exchange_end(exch); 291 292 287 out: 293 288 assert(port->state == PORT_ENABLED || port->state == PORT_DISABLED); -
uspace/drv/bus/usb/usbhub/usbhub.c
r4603b35 r51a51be 116 116 } 117 117 hub_dev->usb_device = usb_dev; 118 119 fibril_mutex_initialize(&hub_dev->default_address_guard); 120 fibril_condvar_initialize(&hub_dev->default_address_cv); 118 121 119 122 /* Set hub's first configuration. (There should be only one) */ … … 603 606 604 607 /** 608 * Reserve a default address for a port across all other devices connected to 609 * the bus. We aggregate requests for ports to minimize delays between 610 * connecting multiple devices from one hub - which happens e.g. when the hub 611 * is connected with already attached devices. 612 */ 613 int usb_hub_reserve_default_address(usb_hub_dev_t *hub, async_exch_t *exch, fibril_mutex_t *guard) 614 { 615 assert(hub); 616 assert(exch); 617 assert(guard); 618 assert(fibril_mutex_is_locked(guard)); 619 620 fibril_mutex_lock(&hub->default_address_guard); 621 if (hub->default_address_requests++ == 0) { 622 /* We're the first to request the address, we can just do it */ 623 fibril_mutex_unlock(&hub->default_address_guard); 624 int err; 625 while ((err = usbhc_reserve_default_address(exch)) == EAGAIN) { 626 fibril_mutex_unlock(guard); 627 async_usleep(500000); 628 fibril_mutex_lock(guard); 629 err = usbhc_reserve_default_address(exch); 630 } 631 return err; 632 } else { 633 /* Drop the port guard, we're going to wait */ 634 fibril_mutex_unlock(guard); 635 636 /* Wait for a signal */ 637 fibril_condvar_wait(&hub->default_address_cv, &hub->default_address_guard); 638 639 /* Remember ABBA, first drop the hub guard */ 640 fibril_mutex_unlock(&hub->default_address_guard); 641 fibril_mutex_lock(guard); 642 return EOK; 643 } 644 } 645 646 /** 647 * Release the default address from a port. 648 */ 649 int usb_hub_release_default_address(usb_hub_dev_t *hub, async_exch_t *exch) 650 { 651 fibril_mutex_lock(&hub->default_address_guard); 652 if (--hub->default_address_requests == 0) { 653 fibril_mutex_unlock(&hub->default_address_guard); 654 return usbhc_release_default_address(exch); 655 } else { 656 fibril_condvar_signal(&hub->default_address_cv); 657 fibril_mutex_unlock(&hub->default_address_guard); 658 return EOK; 659 } 660 } 661 662 /** 605 663 * @} 606 664 */ -
uspace/drv/bus/usb/usbhub/usbhub.h
r4603b35 r51a51be 70 70 /** Each port is switched individually. */ 71 71 bool per_port_power; 72 73 /** Default address management */ 74 unsigned default_address_requests; 75 fibril_mutex_t default_address_guard; 76 fibril_condvar_t default_address_cv; 72 77 }; 73 78 … … 84 89 bool hub_port_changes_callback(usb_device_t *, uint8_t *, size_t, void *); 85 90 91 int usb_hub_reserve_default_address(usb_hub_dev_t *, async_exch_t *, fibril_mutex_t *); 92 int usb_hub_release_default_address(usb_hub_dev_t *, async_exch_t *); 93 86 94 #endif 87 95
Note:
See TracChangeset
for help on using the changeset viewer.