Ignore:
Timestamp:
2011-12-18T14:02:30Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c868e2d
Parents:
3b71e84d (diff), 1761268 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r3b71e84d r7aaed09  
    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 */
     46static 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/*----------------------------------------------------------------------------*/
    4066/** Initialize device manager structure.
    4167 *
    4268 * @param[in] instance Memory place to initialize.
     69 * @param[in] max_speed Maximum allowed USB speed of devices (inclusive).
    4370 *
    4471 * Set all values to false/0.
    4572 */
    46 void usb_device_manager_init(usb_device_manager_t *instance)
     73void usb_device_manager_init(
     74    usb_device_manager_t *instance, usb_speed_t max_speed)
    4775{
    4876        assert(instance);
     
    5280                instance->devices[i].speed = USB_SPEED_MAX;
    5381        }
    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;
     82        instance->last_address = 1;
     83        instance->max_speed = max_speed;
    5884        fibril_mutex_initialize(&instance->guard);
    5985}
    6086/*----------------------------------------------------------------------------*/
    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  */
    67 usb_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) {
     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 */
     94int 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) {
    80113                        fibril_mutex_unlock(&instance->guard);
    81                         return ENOSPC;
     114                        return ENOENT;
    82115                }
    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;
     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;
    95127}
    96128/*----------------------------------------------------------------------------*/
     
    102134 * @return Error code.
    103135 */
    104 int usb_device_manager_bind(usb_device_manager_t *instance,
     136int usb_device_manager_bind_address(usb_device_manager_t *instance,
    105137    usb_address_t address, devman_handle_t handle)
    106138{
     
    132164 * @return Error code.
    133165 */
    134 int usb_device_manager_release(
     166int usb_device_manager_release_address(
    135167    usb_device_manager_t *instance, usb_address_t address)
    136168{
    137         if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     169        if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
    138170                return EINVAL;
    139171        }
     
    188220{
    189221        assert(instance);
    190         if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     222        if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
    191223                return EINVAL;
    192224        }
Note: See TracChangeset for help on using the changeset viewer.