Changeset 54464f6a in mainline for uspace/lib/usbhost/src/usb_device_manager.c
- Timestamp:
- 2011-11-11T19:48:33Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 50a01a9
- Parents:
- c2e50d7 (diff), 747ef72 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb_device_manager.c
rc2e50d7 r54464f6a 38 38 #include <usb/host/usb_device_manager.h> 39 39 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 /*----------------------------------------------------------------------------*/ 40 66 /** Initialize device manager structure. 41 67 * 42 68 * @param[in] instance Memory place to initialize. 69 * @param[in] max_speed Maximum allowed USB speed of devices (inclusive). 43 70 * 44 71 * Set all values to false/0. 45 72 */ 46 void usb_device_manager_init(usb_device_manager_t *instance) 73 void usb_device_manager_init( 74 usb_device_manager_t *instance, usb_speed_t max_speed) 47 75 { 48 76 assert(instance); … … 52 80 instance->devices[i].speed = USB_SPEED_MAX; 53 81 } 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; 58 84 fibril_mutex_initialize(&instance->guard); 59 85 } 60 86 /*----------------------------------------------------------------------------*/ 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 */ 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) { 80 113 fibril_mutex_unlock(&instance->guard); 81 return ENO SPC;114 return ENOENT; 82 115 } 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; 95 127 } 96 128 /*----------------------------------------------------------------------------*/ … … 102 134 * @return Error code. 103 135 */ 104 int usb_device_manager_bind (usb_device_manager_t *instance,136 int usb_device_manager_bind_address(usb_device_manager_t *instance, 105 137 usb_address_t address, devman_handle_t handle) 106 138 { … … 132 164 * @return Error code. 133 165 */ 134 int usb_device_manager_release (166 int usb_device_manager_release_address( 135 167 usb_device_manager_t *instance, usb_address_t address) 136 168 { 137 if ((address < =0) || (address >= USB_ADDRESS_COUNT)) {169 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 138 170 return EINVAL; 139 171 } … … 188 220 { 189 221 assert(instance); 190 if ((address < =0) || (address >= USB_ADDRESS_COUNT)) {222 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 191 223 return EINVAL; 192 224 }
Note:
See TracChangeset
for help on using the changeset viewer.