Changeset 423c749 in mainline
- Timestamp:
- 2013-07-27T07:49:45Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3aac088
- Parents:
- 2838486
- Location:
- uspace/lib
- Files:
-
- 2 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/usb.h
r2838486 r423c749 110 110 #define USB_ADDRESS_DEFAULT 0 111 111 /** Maximum address number in USB 1.1. */ 112 #define USB11_ADDRESS_MAX 128 112 #define USB11_ADDRESS_MAX 127 113 #define USB_ADDRESS_COUNT (USB11_ADDRESS_MAX + 1) 113 114 114 115 /** Check USB address for allowed values. … … 119 120 static inline bool usb_address_is_valid(usb_address_t a) 120 121 { 121 return (a >= USB_ADDRESS_DEFAULT) && (a < USB11_ADDRESS_MAX);122 return (a >= USB_ADDRESS_DEFAULT) && (a <= USB11_ADDRESS_MAX); 122 123 } 123 124 -
uspace/lib/usbhost/Makefile
r2838486 r423c749 40 40 src/hcd.c \ 41 41 src/iface.c \ 42 src/usb_device_manager.c \43 42 src/usb_endpoint_manager.c \ 44 43 src/usb_transfer_batch.c -
uspace/lib/usbhost/include/usb/host/hcd.h
r2838486 r423c749 41 41 #include <usbhc_iface.h> 42 42 43 #include <usb/host/usb_device_manager.h>44 43 #include <usb/host/usb_endpoint_manager.h> 45 44 #include <usb/host/usb_transfer_batch.h> … … 53 52 /** Generic host controller driver structure. */ 54 53 struct hcd { 55 /** Device manager storing handles and addresses. */56 usb_device_manager_t dev_manager;57 54 /** Endpoint manager. */ 58 55 usb_endpoint_manager_t ep_manager; -
uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h
r2838486 r423c749 50 50 /** 90% of total bandwidth is available for periodic transfers */ 51 51 #define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9) 52 /** 16 addresses per list */53 #define ENDPOINT_LIST_COUNT 854 52 55 53 typedef size_t (*bw_count_func_t)(usb_speed_t, usb_transfer_type_t, size_t, size_t); … … 59 57 /** Endpoint management structure */ 60 58 typedef struct usb_endpoint_manager { 61 /** Store endpoint_t instances */ 62 list_t endpoint_lists[ENDPOINT_LIST_COUNT]; 59 struct { 60 usb_speed_t speed; /**< Device speed */ 61 bool occupied; /**< The address is in use. */ 62 list_t endpoint_list; /**< Store endpoint_t instances */ 63 } devices[USB_ADDRESS_COUNT]; 63 64 /** Prevents races accessing lists */ 64 65 fibril_mutex_t guard; … … 67 68 /** Use this function to count bw required by EP */ 68 69 bw_count_func_t bw_count; 70 /** Maximum speed allowed. */ 71 usb_speed_t max_speed; 72 /** The last reserved address */ 73 usb_address_t last_address; 69 74 } usb_endpoint_manager_t; 70 75 … … 74 79 75 80 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 76 size_t available_bandwidth, bw_count_func_t bw_count );81 size_t available_bandwidth, bw_count_func_t bw_count, usb_speed_t max_speed); 77 82 78 83 int usb_endpoint_manager_register_ep( … … 98 103 void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance, 99 104 usb_address_t address, ep_remove_callback_t callback, void *arg); 105 106 int usb_endpoint_manager_request_address(usb_endpoint_manager_t *instance, 107 usb_address_t *address, bool strict, usb_speed_t speed); 108 109 int usb_endpoint_manager_release_address(usb_endpoint_manager_t *instance, 110 usb_address_t address); 111 112 int usb_endpoint_manager_get_info_by_address(usb_endpoint_manager_t *instance, 113 usb_address_t address, usb_speed_t *speed); 100 114 #endif 101 115 /** -
uspace/lib/usbhost/src/ddf_helpers.c
r2838486 r423c749 401 401 402 402 /* This checks whether the default address is reserved and gets speed */ 403 int ret = usb_ device_manager_get_info_by_address(&hcd->dev_manager,403 int ret = usb_endpoint_manager_get_info_by_address(&hcd->ep_manager, 404 404 USB_ADDRESS_DEFAULT, &speed); 405 405 if (ret != EOK) { -
uspace/lib/usbhost/src/hcd.c
r2838486 r423c749 95 95 { 96 96 assert(hcd); 97 usb_device_manager_init(&hcd->dev_manager, max_speed); 98 usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count); 97 usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count, max_speed); 99 98 100 99 hcd->private_data = NULL; … … 108 107 assert(hcd); 109 108 usb_address_t address = 0; 110 const int ret = usb_ device_manager_request_address(111 &hcd-> dev_manager, &address, false, speed);109 const int ret = usb_endpoint_manager_request_address( 110 &hcd->ep_manager, &address, false, speed); 112 111 if (ret != EOK) 113 112 return ret; … … 120 119 usb_endpoint_manager_remove_address(&hcd->ep_manager, address, 121 120 unregister_helper_warn, hcd); 122 usb_ device_manager_release_address(&hcd->dev_manager, address);121 usb_endpoint_manager_release_address(&hcd->ep_manager, address); 123 122 return EOK; 124 123 } … … 128 127 assert(hcd); 129 128 usb_address_t address = 0; 130 return usb_ device_manager_request_address(131 &hcd-> dev_manager, &address, true, speed);129 return usb_endpoint_manager_request_address( 130 &hcd->ep_manager, &address, true, speed); 132 131 } 133 132 … … 137 136 assert(hcd); 138 137 usb_speed_t speed = USB_SPEED_MAX; 139 const int ret = usb_ device_manager_get_info_by_address(140 &hcd-> dev_manager, target.address, &speed);138 const int ret = usb_endpoint_manager_get_info_by_address( 139 &hcd->ep_manager, target.address, &speed); 141 140 if (ret != EOK) { 142 141 return ret; -
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.