Changeset 51a51be in mainline for uspace/drv/bus/usb/usbhub/usbhub.c


Ignore:
Timestamp:
2018-01-16T21:19:37Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1d218bf
Parents:
4603b35
Message:

usbhub: aggregate requests for default address

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r4603b35 r51a51be  
    116116        }
    117117        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);
    118121
    119122        /* Set hub's first configuration. (There should be only one) */
     
    603606
    604607/**
     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 */
     613int 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 */
     649int 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/**
    605663 * @}
    606664 */
Note: See TracChangeset for help on using the changeset viewer.