Changeset 56257ba in mainline for uspace/lib/usbhost/src/usb2_bus.c
- Timestamp:
- 2018-01-07T01:01:42Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63431db2
- Parents:
- 9efad54
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:41)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:42)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb2_bus.c
r9efad54 r56257ba 57 57 } 58 58 59 /** Get list that holds endpoints for given address.60 * @param bus usb2_bus structure, non-null.61 * @param addr USB address, must be >= 0.62 * @return Pointer to the appropriate list.63 */64 static list_t * get_list(usb2_bus_t *bus, usb_address_t addr)65 {66 assert(bus);67 assert(addr >= 0);68 return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list;69 }70 71 /** Get speed assigned to USB address.72 *73 * @param[in] bus Device manager structure to use.74 * @param[in] address Address the caller wants to find.75 * @param[out] speed Assigned speed.76 * @return Error code.77 */78 static int get_speed(usb2_bus_t *bus, usb_address_t address, usb_speed_t *speed)79 {80 if (!usb_address_is_valid(address))81 return EINVAL;82 83 if (!bus->devices[address].occupied)84 return ENOENT;85 86 if (speed)87 *speed = bus->devices[address].speed;88 89 return EOK;90 }91 92 59 /** Get a free USB address 93 60 * … … 104 71 if (new_address == bus->last_address) 105 72 return ENOSPC; 106 } while (bus-> devices[new_address].occupied);73 } while (bus->address_occupied[new_address]); 107 74 108 75 assert(new_address != USB_ADDRESS_DEFAULT); … … 125 92 return EINVAL; 126 93 127 const int ret = bus->devices[address].occupied ? EOK : ENOENT; 128 bus->devices[address].occupied = false; 129 130 list_t *list = get_list(bus, address); 131 for (link_t *link = list_first(list); link != NULL; ) { 132 endpoint_t *ep = list_get_instance(link, endpoint_t, link); 133 link = list_next(link, list); 134 135 assert(ep->device->address == address); 136 list_remove(&ep->link); 137 138 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 139 address, ep->endpoint, usb_str_direction(ep->direction)); 140 141 /* Drop bus reference */ 142 endpoint_del_ref(ep); 143 } 144 94 const int ret = bus->address_occupied[address] ? EOK : ENOENT; 95 bus->address_occupied[address] = false; 145 96 return ret; 146 97 } … … 153 104 * @note Default address is only available in strict mode. 154 105 */ 155 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict , usb_speed_t speed)106 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict) 156 107 { 157 108 int err; … … 168 119 return err; 169 120 } 170 else if (bus-> devices[*addr].occupied) {121 else if (bus->address_occupied[*addr]) { 171 122 if (strict) { 172 123 return ENOENT; … … 177 128 178 129 assert(usb_address_is_valid(*addr)); 179 assert(bus-> devices[*addr].occupied== false);130 assert(bus->address_occupied[*addr] == false); 180 131 assert(*addr != USB_ADDRESS_DEFAULT || strict); 181 132 182 bus->devices[*addr].occupied = true; 183 bus->devices[*addr].speed = speed; 133 bus->address_occupied[*addr] = true; 184 134 185 135 return EOK; … … 202 152 /** Reserve address early, we want pretty log messages */ 203 153 usb_address_t address = USB_ADDRESS_DEFAULT; 204 if ((err = request_address(bus, &address, false , dev->speed))) {154 if ((err = request_address(bus, &address, false))) { 205 155 usb_log_error("Failed to reserve new address: %s.", 206 156 str_error(err)); … … 281 231 * default address. 282 232 */ 283 if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) { 284 usb_log_error("Failed to verify speed: %s.", str_error(err)); 285 return err; 286 } 233 dev->speed = bus->default_address_speed; 287 234 usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed)); 288 235 … … 313 260 } 314 261 315 /** Find endpoint.316 * @param bus usb_bus structure, non-null.317 * @param target Endpoint address.318 * @param direction Communication direction.319 * @return Pointer to endpoint_t structure representing given communication320 * target, NULL if there is no such endpoint registered.321 * @note Assumes that the internal mutex is locked.322 */323 static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)324 {325 usb2_bus_t *bus = bus_to_usb2_bus(device->bus);326 327 assert(device->address == target.address);328 329 list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {330 if (((direction == ep->direction)331 || (ep->direction == USB_DIRECTION_BOTH)332 || (direction == USB_DIRECTION_BOTH))333 && (target.endpoint == ep->endpoint))334 return ep;335 }336 return NULL;337 }338 339 262 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc) 340 263 { … … 347 270 } 348 271 349 static usb_target_t usb2_ep_to_target(endpoint_t *ep)350 {351 assert(ep);352 assert(ep->device);353 354 return (usb_target_t) {{355 .address = ep->device->address,356 .endpoint = ep->endpoint,357 }};358 }359 360 272 /** Register an endpoint to the bus. Reserves bandwidth. 361 273 * @param bus usb_bus structure, non-null. … … 368 280 assert(ep); 369 281 370 /* Check for existence */371 if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))372 return EEXIST;373 374 282 /* Check for available bandwidth */ 375 283 if (ep->bandwidth > bus->free_bw) 376 284 return ENOSPC; 377 285 378 endpoint_add_ref(ep);379 list_append(&ep->link, get_list(bus, ep->device->address));380 286 bus->free_bw -= ep->bandwidth; 381 287 … … 390 296 assert(ep); 391 297 392 list_remove(&ep->link);393 394 298 bus->free_bw += ep->bandwidth; 395 endpoint_del_ref(ep); 396 397 return EOK; 398 } 399 400 static int usb2_bus_reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode) 401 { 402 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 403 404 if (!usb_target_is_valid(target)) 405 return EINVAL; 406 407 if (mode == RESET_NONE) 408 return EOK; 409 410 int ret = ENOENT; 411 412 list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) { 413 assert(ep->device->address == target.address); 414 415 if (mode == RESET_ALL || ep->endpoint == target.endpoint) { 416 endpoint_toggle_set(ep, 0); 417 ret = EOK; 418 } 419 } 420 return ret; 299 300 return EOK; 421 301 } 422 302 … … 425 305 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 426 306 usb_address_t addr = USB_ADDRESS_DEFAULT; 427 return request_address(bus, &addr, true, speed); 307 const int err = request_address(bus, &addr, true); 308 if (err) 309 return err; 310 bus->default_address_speed = speed; 311 return EOK; 428 312 } 429 313 … … 437 321 .reserve_default_address = usb2_bus_register_default_address, 438 322 .release_default_address = usb2_bus_release_default_address, 439 .reset_toggle = usb2_bus_reset_toggle,440 323 .device_enumerate = usb2_bus_device_enumerate, 441 .device_find_endpoint = usb2_bus_find_ep,442 324 .endpoint_create = usb2_bus_create_ep, 443 325 .endpoint_register = usb2_bus_register_ep, … … 460 342 461 343 bus->free_bw = available_bandwidth; 462 bus->last_address = 0; 463 for (unsigned i = 0; i < ARRAY_SIZE(bus->devices); ++i) { 464 list_initialize(&bus->devices[i].endpoint_list); 465 bus->devices[i].speed = USB_SPEED_MAX; 466 bus->devices[i].occupied = false; 467 } 344 468 345 return EOK; 469 346 }
Note:
See TracChangeset
for help on using the changeset viewer.