Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/usb_device_manager.c

    rbbd09694 r2fd1f0c6  
    3838#include <usb/host/usb_device_manager.h>
    3939
    40 /** Get a free USB address
    41  *
    42  * @param[in] instance Device manager structure to use.
    43  * @param[in] speed Speed of the device requiring address.
    44  * @return Free address, or error code.
    45  */
    46 static usb_address_t usb_device_manager_get_free_address(
    47     usb_device_manager_t *instance)
    48 {
    49 
    50         usb_address_t new_address = instance->last_address;
    51         do {
    52                 new_address = (new_address + 1) % USB_ADDRESS_COUNT;
    53                 if (new_address == USB_ADDRESS_DEFAULT)
    54                         new_address = 1;
    55                 if (new_address == instance->last_address) {
    56                         return ENOSPC;
    57                 }
    58         } while (instance->devices[new_address].occupied);
    59 
    60         assert(new_address != USB_ADDRESS_DEFAULT);
    61         instance->last_address = new_address;
    62 
    63         return new_address;
    64 }
    65 /*----------------------------------------------------------------------------*/
    6640/** Initialize device manager structure.
    6741 *
    6842 * @param[in] instance Memory place to initialize.
    69  * @param[in] max_speed Maximum allowed USB speed of devices (inclusive).
    7043 *
    7144 * Set all values to false/0.
    7245 */
    73 void usb_device_manager_init(
    74     usb_device_manager_t *instance, usb_speed_t max_speed)
     46void usb_device_manager_init(usb_device_manager_t *instance)
    7547{
    7648        assert(instance);
     
    8052                instance->devices[i].speed = USB_SPEED_MAX;
    8153        }
    82         instance->last_address = 1;
    83         instance->max_speed = max_speed;
     54        // TODO: is this hack enough?
     55        // (it is needed to allow smooth registration at default address)
     56        instance->devices[0].occupied = true;
     57        instance->last_address = 0;
    8458        fibril_mutex_initialize(&instance->guard);
    8559}
    8660/*----------------------------------------------------------------------------*/
    87 /** Request USB address.
    88  * @param instance usb_device_manager
    89  * @param address Pointer to requested address value, place to store new address
    90  * @parma strict Fail if the requested address is not available.
    91  * @return Error code.
    92  * @note Default address is only available in strict mode.
    93  */
    94 int usb_device_manager_request_address(usb_device_manager_t *instance,
    95     usb_address_t *address, bool strict, usb_speed_t speed)
    96 {
    97         assert(instance);
    98         assert(address);
    99         if (speed > instance->max_speed)
    100                 return ENOTSUP;
    101 
    102         if ((*address) < 0 || (*address) >= USB_ADDRESS_COUNT)
    103                 return EINVAL;
    104 
    105         fibril_mutex_lock(&instance->guard);
    106         /* Only grant default address to strict requests */
    107         if (( (*address) == USB_ADDRESS_DEFAULT) && !strict) {
    108                 *address = instance->last_address;
    109         }
    110 
    111         if (instance->devices[*address].occupied) {
    112                 if (strict) {
     61/** Get a free USB address
     62 *
     63 * @param[in] instance Device manager structure to use.
     64 * @param[in] speed Speed of the device requiring address.
     65 * @return Free address, or error code.
     66 */
     67usb_address_t usb_device_manager_get_free_address(
     68    usb_device_manager_t *instance, usb_speed_t speed)
     69{
     70        assert(instance);
     71        fibril_mutex_lock(&instance->guard);
     72
     73        usb_address_t new_address = instance->last_address;
     74        do {
     75                ++new_address;
     76                if (new_address > USB11_ADDRESS_MAX)
     77                        new_address = 1; // NOTE it should be safe to put 0 here
     78                                         // TODO Use mod
     79                if (new_address == instance->last_address) {
    11380                        fibril_mutex_unlock(&instance->guard);
    114                         return ENOENT;
     81                        return ENOSPC;
    11582                }
    116                 *address = usb_device_manager_get_free_address(instance);
    117         }
    118         assert(instance->devices[*address].occupied == false);
    119         assert(instance->devices[*address].handle == 0);
    120         assert(*address != USB_ADDRESS_DEFAULT || strict);
    121 
    122         instance->devices[*address].occupied = true;
    123         instance->devices[*address].speed = speed;
    124 
    125         fibril_mutex_unlock(&instance->guard);
    126         return EOK;
     83        } while (instance->devices[new_address].occupied);
     84
     85        assert(new_address != USB_ADDRESS_DEFAULT);
     86        assert(instance->devices[new_address].occupied == false);
     87        assert(instance->devices[new_address].handle == 0);
     88
     89        instance->devices[new_address].occupied = true;
     90        instance->devices[new_address].speed = speed;
     91        instance->last_address = new_address;
     92
     93        fibril_mutex_unlock(&instance->guard);
     94        return new_address;
    12795}
    12896/*----------------------------------------------------------------------------*/
     
    134102 * @return Error code.
    135103 */
    136 int usb_device_manager_bind_address(usb_device_manager_t *instance,
     104int usb_device_manager_bind(usb_device_manager_t *instance,
    137105    usb_address_t address, devman_handle_t handle)
    138106{
     
    164132 * @return Error code.
    165133 */
    166 int usb_device_manager_release_address(
     134int usb_device_manager_release(
    167135    usb_device_manager_t *instance, usb_address_t address)
    168136{
    169         if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
     137        if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
    170138                return EINVAL;
    171139        }
     
    220188{
    221189        assert(instance);
    222         if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
     190        if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
    223191                return EINVAL;
    224192        }
Note: See TracChangeset for help on using the changeset viewer.