Changeset 423c749 in mainline for uspace/lib/usbhost/src/usb_endpoint_manager.c
- Timestamp:
- 2013-07-27T07:49:45Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3aac088
- Parents:
- 2838486
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb_endpoint_manager.c
r2838486 r423c749 36 36 #include <assert.h> 37 37 #include <errno.h> 38 #include <macros.h> 38 39 39 40 #include <usb/debug.h> … … 71 72 assert(instance); 72 73 assert(addr >= 0); 73 return &instance-> endpoint_lists[addr % ENDPOINT_LIST_COUNT];74 return &instance->devices[addr % ARRAY_SIZE(instance->devices)].endpoint_list; 74 75 } 75 76 … … 96 97 } 97 98 return NULL; 99 } 100 101 /** Get a free USB address 102 * 103 * @param[in] instance Device manager structure to use. 104 * @return Free address, or error code. 105 */ 106 static usb_address_t usb_endpoint_manager_get_free_address( 107 usb_endpoint_manager_t *instance) 108 { 109 110 usb_address_t new_address = instance->last_address; 111 do { 112 new_address = (new_address + 1) % USB_ADDRESS_COUNT; 113 if (new_address == USB_ADDRESS_DEFAULT) 114 new_address = 1; 115 if (new_address == instance->last_address) 116 return ENOSPC; 117 } while (instance->devices[new_address].occupied); 118 119 assert(new_address != USB_ADDRESS_DEFAULT); 120 instance->last_address = new_address; 121 122 return new_address; 98 123 } 99 124 … … 156 181 */ 157 182 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 158 size_t available_bandwidth, bw_count_func_t bw_count )183 size_t available_bandwidth, bw_count_func_t bw_count, usb_speed_t max_speed) 159 184 { 160 185 assert(instance); … … 162 187 instance->free_bw = available_bandwidth; 163 188 instance->bw_count = bw_count; 164 for (unsigned i = 0; i < ENDPOINT_LIST_COUNT; ++i) { 165 list_initialize(&instance->endpoint_lists[i]); 189 instance->last_address = 1; 190 instance->max_speed = max_speed; 191 for (unsigned i = 0; i < ARRAY_SIZE(instance->devices); ++i) { 192 list_initialize(&instance->devices[i].endpoint_list); 193 instance->devices[i].speed = USB_SPEED_MAX; 194 instance->devices[i].occupied = false; 166 195 } 167 196 return EOK; … … 386 415 fibril_mutex_unlock(&instance->guard); 387 416 } 417 418 /** Request USB address. 419 * @param instance usb_device_manager 420 * @param address Pointer to requested address value, place to store new address 421 * @parma strict Fail if the requested address is not available. 422 * @return Error code. 423 * @note Default address is only available in strict mode. 424 */ 425 int usb_endpoint_manager_request_address(usb_endpoint_manager_t *instance, 426 usb_address_t *address, bool strict, usb_speed_t speed) 427 { 428 assert(instance); 429 assert(address); 430 if (speed > instance->max_speed) 431 return ENOTSUP; 432 433 if (!usb_address_is_valid(*address)) 434 return EINVAL; 435 436 usb_address_t addr = *address; 437 438 fibril_mutex_lock(&instance->guard); 439 /* Only grant default address to strict requests */ 440 if ((addr == USB_ADDRESS_DEFAULT) && !strict) { 441 addr = usb_endpoint_manager_get_free_address(instance); 442 } 443 444 if (instance->devices[addr].occupied) { 445 if (strict) { 446 fibril_mutex_unlock(&instance->guard); 447 return ENOENT; 448 } 449 addr = usb_endpoint_manager_get_free_address(instance); 450 } 451 if (usb_address_is_valid(addr)) { 452 assert(instance->devices[addr].occupied == false); 453 assert(addr != USB_ADDRESS_DEFAULT || strict); 454 455 instance->devices[addr].occupied = true; 456 instance->devices[addr].speed = speed; 457 *address = addr; 458 addr = 0; 459 } 460 461 fibril_mutex_unlock(&instance->guard); 462 return addr; 463 } 464 465 /** Release used USB address. 466 * 467 * @param[in] instance Device manager structure to use. 468 * @param[in] address Device address 469 * @return Error code. 470 */ 471 int usb_endpoint_manager_release_address( 472 usb_endpoint_manager_t *instance, usb_address_t address) 473 { 474 assert(instance); 475 if (!usb_address_is_valid(address)) 476 return EINVAL; 477 478 fibril_mutex_lock(&instance->guard); 479 480 const int rc = instance->devices[address].occupied ? EOK : ENOENT; 481 instance->devices[address].occupied = false; 482 483 fibril_mutex_unlock(&instance->guard); 484 return rc; 485 } 486 487 /** Get speed assigned to USB address. 488 * 489 * @param[in] instance Device manager structure to use. 490 * @param[in] address Address the caller wants to find. 491 * @param[out] speed Assigned speed. 492 * @return Error code. 493 */ 494 int usb_endpoint_manager_get_info_by_address(usb_endpoint_manager_t *instance, 495 usb_address_t address, usb_speed_t *speed) 496 { 497 assert(instance); 498 if (!usb_address_is_valid(address)) { 499 return EINVAL; 500 } 501 502 fibril_mutex_lock(&instance->guard); 503 504 const int rc = instance->devices[address].occupied ? EOK : ENOENT; 505 if (speed && instance->devices[address].occupied) { 506 *speed = instance->devices[address].speed; 507 } 508 509 fibril_mutex_unlock(&instance->guard); 510 return rc; 511 } 388 512 /** 389 513 * @}
Note:
See TracChangeset
for help on using the changeset viewer.