Changes in uspace/lib/usbhost/src/usb_device_manager.c [8b54fe6:bbd09694] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb_device_manager.c
r8b54fe6 rbbd09694 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 } 40 65 /*----------------------------------------------------------------------------*/ 41 66 /** Initialize device manager structure. 42 67 * 43 68 * @param[in] instance Memory place to initialize. 69 * @param[in] max_speed Maximum allowed USB speed of devices (inclusive). 44 70 * 45 71 * Set all values to false/0. 46 72 */ 47 void usb_device_manager_init( usb_device_manager_t *instance)48 { 49 assert(instance); 50 unsigned i = 0;51 for ( ; i < USB_ADDRESS_COUNT; ++i) {73 void usb_device_manager_init( 74 usb_device_manager_t *instance, usb_speed_t max_speed) 75 { 76 assert(instance); 77 for (unsigned i = 0; i < USB_ADDRESS_COUNT; ++i) { 52 78 instance->devices[i].occupied = false; 53 79 instance->devices[i].handle = 0; 54 80 instance->devices[i].speed = USB_SPEED_MAX; 55 81 } 56 // TODO: is this hack enough? 57 // (it is needed to allow smooth registration at default address) 58 instance->devices[0].occupied = true; 59 instance->last_address = 0; 82 instance->last_address = 1; 83 instance->max_speed = max_speed; 60 84 fibril_mutex_initialize(&instance->guard); 61 85 } 62 86 /*----------------------------------------------------------------------------*/ 63 /** Get a free USB address 64 * 65 * @param[in] instance Device manager structure to use. 66 * @param[in] speed Speed of the device requiring address. 67 * @return Free address, or error code. 68 */ 69 usb_address_t usb_device_manager_get_free_address( 70 usb_device_manager_t *instance, usb_speed_t speed) 71 { 72 assert(instance); 73 fibril_mutex_lock(&instance->guard); 74 75 usb_address_t new_address = instance->last_address; 76 do { 77 ++new_address; 78 if (new_address > USB11_ADDRESS_MAX) 79 new_address = 1; 80 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) { 81 113 fibril_mutex_unlock(&instance->guard); 82 return ENO SPC;114 return ENOENT; 83 115 } 84 } while (instance->devices[new_address].occupied);85 86 assert( new_address != USB_ADDRESS_DEFAULT);87 assert(instance->devices[ new_address].occupied == false);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 /*----------------------------------------------------------------------------*/ … … 100 132 * @param[in] address Device address 101 133 * @param[in] handle Devman handle of the device. 102 */ 103 void usb_device_manager_bind(usb_device_manager_t *instance, 134 * @return Error code. 135 */ 136 int usb_device_manager_bind_address(usb_device_manager_t *instance, 104 137 usb_address_t address, devman_handle_t handle) 105 138 { 106 assert(instance); 107 fibril_mutex_lock(&instance->guard); 108 109 assert(address > 0); 110 assert(address <= USB11_ADDRESS_MAX); 111 assert(instance->devices[address].occupied); 112 139 if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) { 140 return EINVAL; 141 } 142 assert(instance); 143 144 fibril_mutex_lock(&instance->guard); 145 /* Not reserved */ 146 if (!instance->devices[address].occupied) { 147 fibril_mutex_unlock(&instance->guard); 148 return ENOENT; 149 } 150 /* Already bound */ 151 if (instance->devices[address].handle != 0) { 152 fibril_mutex_unlock(&instance->guard); 153 return EEXISTS; 154 } 113 155 instance->devices[address].handle = handle; 114 156 fibril_mutex_unlock(&instance->guard); 157 return EOK; 115 158 } 116 159 /*----------------------------------------------------------------------------*/ … … 119 162 * @param[in] instance Device manager structure to use. 120 163 * @param[in] address Device address 121 */ 122 void usb_device_manager_release( 164 * @return Error code. 165 */ 166 int usb_device_manager_release_address( 123 167 usb_device_manager_t *instance, usb_address_t address) 124 168 { 125 assert(instance); 126 assert(address > 0); 127 assert(address <= USB11_ADDRESS_MAX); 128 129 fibril_mutex_lock(&instance->guard); 130 assert(instance->devices[address].occupied); 169 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 170 return EINVAL; 171 } 172 assert(instance); 173 174 fibril_mutex_lock(&instance->guard); 175 if (!instance->devices[address].occupied) { 176 fibril_mutex_unlock(&instance->guard); 177 return ENOENT; 178 } 131 179 132 180 instance->devices[address].occupied = false; 133 fibril_mutex_unlock(&instance->guard); 181 instance->devices[address].handle = 0; 182 fibril_mutex_unlock(&instance->guard); 183 return EOK; 134 184 } 135 185 /*----------------------------------------------------------------------------*/ … … 140 190 * @return USB Address, or error code. 141 191 */ 142 usb_address_t usb_device_manager_find (192 usb_address_t usb_device_manager_find_address( 143 193 usb_device_manager_t *instance, devman_handle_t handle) 144 194 { 145 195 assert(instance); 146 196 fibril_mutex_lock(&instance->guard); 147 usb_address_t address = 1;148 while (address <= USB11_ADDRESS_MAX){197 for (usb_address_t address = 1; address <= USB11_ADDRESS_MAX; ++address) 198 { 149 199 if (instance->devices[address].handle == handle) { 150 200 assert(instance->devices[address].occupied); … … 152 202 return address; 153 203 } 154 ++address;155 204 } 156 205 fibril_mutex_unlock(&instance->guard); 157 206 return ENOENT; 158 207 } 159 160 /** Find devman handle a ssigned to USB address.161 * Intentionally refuse to find handle ofdefault address.208 /*----------------------------------------------------------------------------*/ 209 /** Find devman handle and speed assigned to USB address. 210 * Intentionally refuse to work on default address. 162 211 * 163 212 * @param[in] instance Device manager structure to use. 164 213 * @param[in] address Address the caller wants to find. 165 214 * @param[out] handle Where to store found handle. 166 * @return Whether such address is currently occupied. 167 */ 168 bool usb_device_manager_find_by_address(usb_device_manager_t *instance, 169 usb_address_t address, devman_handle_t *handle) 170 { 171 assert(instance); 172 fibril_mutex_lock(&instance->guard); 173 if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) { 174 fibril_mutex_unlock(&instance->guard); 175 return false; 176 } 215 * @param[out] speed Assigned speed. 216 * @return Error code. 217 */ 218 int usb_device_manager_get_info_by_address(usb_device_manager_t *instance, 219 usb_address_t address, devman_handle_t *handle, usb_speed_t *speed) 220 { 221 assert(instance); 222 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 223 return EINVAL; 224 } 225 226 fibril_mutex_lock(&instance->guard); 177 227 if (!instance->devices[address].occupied) { 178 228 fibril_mutex_unlock(&instance->guard); 179 return false;229 return ENOENT; 180 230 } 181 231 … … 183 233 *handle = instance->devices[address].handle; 184 234 } 185 186 fibril_mutex_unlock(&instance->guard); 187 return true; 188 } 189 190 /*----------------------------------------------------------------------------*/ 191 /** Get speed associated with the address 192 * 193 * @param[in] instance Device manager structure to use. 194 * @param[in] address Address of the device. 195 * @return USB speed. 196 */ 197 usb_speed_t usb_device_manager_get_speed( 198 usb_device_manager_t *instance, usb_address_t address) 199 { 200 assert(instance); 201 assert(address >= 0); 202 assert(address <= USB11_ADDRESS_MAX); 203 204 return instance->devices[address].speed; 235 if (speed != NULL) { 236 *speed = instance->devices[address].speed; 237 } 238 239 fibril_mutex_unlock(&instance->guard); 240 return EOK; 205 241 } 206 242 /**
Note:
See TracChangeset
for help on using the changeset viewer.