Changeset 10cd715 in mainline
- Timestamp:
- 2017-12-14T14:25:40Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bd05140
- Parents:
- 6455d39
- git-author:
- Ondřej Hlavatý <aearsis@…> (2017-12-14 14:24:28)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2017-12-14 14:25:40)
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r6455d39 r10cd715 209 209 210 210 err_address: 211 bus_release_address(&bus->base, dev->address);211 // TODO: deaddress device 212 212 return err; 213 213 } … … 505 505 } 506 506 507 static int request_address(bus_t *bus_base, usb_address_t *addr, bool strict, usb_speed_t speed) 508 { 509 assert(addr); 510 511 if (*addr != USB_ADDRESS_DEFAULT) 512 /* xHCI does not allow software to assign addresses. */ 513 return ENOTSUP; 514 515 assert(strict); 516 507 static int reserve_default_address(bus_t *bus_base, usb_speed_t speed) 508 { 517 509 xhci_bus_t *xhci_bus = bus_to_xhci_bus(bus_base); 518 510 … … 525 517 } 526 518 527 static int release_address(bus_t *bus_base, usb_address_t addr) 528 { 529 if (addr != USB_ADDRESS_DEFAULT) 530 return ENOTSUP; 531 519 static int release_default_address(bus_t *bus_base) 520 { 532 521 xhci_bus_t *xhci_bus = bus_to_xhci_bus(bus_base); 533 522 … … 562 551 BIND_OP(find_endpoint) 563 552 564 BIND_OP(request_address) 565 BIND_OP(release_address) 553 BIND_OP(reserve_default_address) 554 BIND_OP(release_default_address) 555 566 556 BIND_OP(reset_toggle) 567 568 557 BIND_OP(count_bw) 569 558 -
uspace/lib/usbhost/include/usb/host/bus.h
r6455d39 r10cd715 96 96 void (*endpoint_set_toggle)(endpoint_t *, bool); /**< Optional */ 97 97 98 int (*re quest_address)(bus_t *, usb_address_t*, bool, usb_speed_t);99 int (*release_ address)(bus_t *, usb_address_t);98 int (*reserve_default_address)(bus_t *, usb_speed_t); 99 int (*release_default_address)(bus_t *); 100 100 101 101 int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t); … … 137 137 size_t bus_count_bw(endpoint_t *, size_t); 138 138 139 int bus_request_address(bus_t *, usb_address_t *, bool, usb_speed_t); 140 int bus_release_address(bus_t *, usb_address_t); 141 142 143 static inline int bus_reserve_default_address(bus_t *bus, usb_speed_t speed) { 144 usb_address_t addr = USB_ADDRESS_DEFAULT; 145 146 const int r = bus_request_address(bus, &addr, true, speed); 147 assert(addr == USB_ADDRESS_DEFAULT); 148 return r; 149 } 150 151 static inline int bus_release_default_address(bus_t *bus) { 152 return bus_release_address(bus, USB_ADDRESS_DEFAULT); 153 } 139 int bus_reserve_default_address(bus_t *, usb_speed_t); 140 int bus_release_default_address(bus_t *); 154 141 155 142 int bus_reset_toggle(bus_t *, usb_target_t, bool); -
uspace/lib/usbhost/src/bus.c
r6455d39 r10cd715 199 199 } 200 200 201 int bus_re quest_address(bus_t *bus, usb_address_t *hint, bool strict, usb_speed_t speed)202 { 203 assert(bus); 204 205 if (!bus->ops.re quest_address)206 return ENOTSUP; 207 208 fibril_mutex_lock(&bus->guard); 209 const int r = bus->ops.re quest_address(bus, hint, strict, speed);201 int bus_reserve_default_address(bus_t *bus, usb_speed_t speed) 202 { 203 assert(bus); 204 205 if (!bus->ops.reserve_default_address) 206 return ENOTSUP; 207 208 fibril_mutex_lock(&bus->guard); 209 const int r = bus->ops.reserve_default_address(bus, speed); 210 210 fibril_mutex_unlock(&bus->guard); 211 211 return r; 212 212 } 213 213 214 int bus_release_address(bus_t *bus, usb_address_t address) 215 { 216 assert(bus); 217 218 if (!bus->ops.release_address) 219 return ENOTSUP; 220 221 fibril_mutex_lock(&bus->guard); 222 const int r = bus->ops.release_address(bus, address); 214 int bus_release_default_address(bus_t *bus) 215 { 216 assert(bus); 217 218 /* If this op is not set, allow everything */ 219 if (!bus->ops.release_default_address) 220 return ENOTSUP; 221 222 fibril_mutex_lock(&bus->guard); 223 const int r = bus->ops.release_default_address(bus); 223 224 fibril_mutex_unlock(&bus->guard); 224 225 return r; -
uspace/lib/usbhost/src/ddf_helpers.c
r6455d39 r10cd715 362 362 const int ret = ddf_fun_unbind(victim->fun); 363 363 if (ret == EOK) { 364 usb_address_t address = victim->address;365 364 bus_remove_device(hcd->bus, hcd, victim); 366 365 ddf_fun_destroy(victim->fun); 367 bus_release_address(hcd->bus, address);368 366 } else { 369 367 usb_log_warning("Failed to unbind device `%s': %s\n", -
uspace/lib/usbhost/src/usb2_bus.c
r6455d39 r10cd715 76 76 * @return Error code. 77 77 */ 78 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed) 79 { 80 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 81 82 if (!usb_address_is_valid(address)) { 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)) 83 81 return EINVAL; 84 } 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 /** Get a free USB address 93 * 94 * @param[in] bus Device manager structure to use. 95 * @return Free address, or error code. 96 */ 97 static int get_free_address(usb2_bus_t *bus, usb_address_t *addr) 98 { 99 usb_address_t new_address = bus->last_address; 100 do { 101 new_address = (new_address + 1) % USB_ADDRESS_COUNT; 102 if (new_address == USB_ADDRESS_DEFAULT) 103 new_address = 1; 104 if (new_address == bus->last_address) 105 return ENOSPC; 106 } while (bus->devices[new_address].occupied); 107 108 assert(new_address != USB_ADDRESS_DEFAULT); 109 bus->last_address = new_address; 110 111 *addr = new_address; 112 return EOK; 113 } 114 115 /** Unregister and destroy all endpoints using given address. 116 * @param bus usb_bus structure, non-null. 117 * @param address USB address. 118 * @param endpoint USB endpoint number. 119 * @param direction Communication direction. 120 * @return Error code. 121 */ 122 static int release_address(usb2_bus_t *bus, usb_address_t address) 123 { 124 if (!usb_address_is_valid(address)) 125 return EINVAL; 85 126 86 127 const int ret = bus->devices[address].occupied ? EOK : ENOENT; 87 if (speed && bus->devices[address].occupied) { 88 *speed = bus->devices[address].speed; 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); 89 143 } 90 144 91 145 return ret; 146 } 147 148 /** Request USB address. 149 * @param bus usb_device_manager 150 * @param addr Pointer to requested address value, place to store new address 151 * @parma strict Fail if the requested address is not available. 152 * @return Error code. 153 * @note Default address is only available in strict mode. 154 */ 155 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict, usb_speed_t speed) 156 { 157 int err; 158 159 assert(bus); 160 assert(addr); 161 162 if (!usb_address_is_valid(*addr)) 163 return EINVAL; 164 165 /* Only grant default address to strict requests */ 166 if ((*addr == USB_ADDRESS_DEFAULT) && !strict) { 167 if ((err = get_free_address(bus, addr))) 168 return err; 169 } 170 else if (bus->devices[*addr].occupied) { 171 if (strict) { 172 return ENOENT; 173 } 174 if ((err = get_free_address(bus, addr))) 175 return err; 176 } 177 178 assert(usb_address_is_valid(*addr)); 179 assert(bus->devices[*addr].occupied == false); 180 assert(*addr != USB_ADDRESS_DEFAULT || strict); 181 182 bus->devices[*addr].occupied = true; 183 bus->devices[*addr].speed = speed; 184 185 return EOK; 92 186 } 93 187 … … 106 200 }}; 107 201 108 static int usb2_bus_address_device(bus_t *bus, hcd_t *hcd, device_t *dev)202 static int address_device(usb2_bus_t *bus, hcd_t *hcd, device_t *dev) 109 203 { 110 204 int err; … … 115 209 /** Reserve address early, we want pretty log messages */ 116 210 usb_address_t address; 117 if ((err = bus_request_address(bus, &address, false, dev->speed))) {211 if ((err = request_address(bus, &address, false, dev->speed))) { 118 212 usb_log_error("Failed to reserve new address: %s.", 119 213 str_error(err)); … … 126 220 127 221 endpoint_t *default_ep; 128 err = bus_add_endpoint( bus, dev, &usb2_default_control_ep, &default_ep);222 err = bus_add_endpoint(&bus->base, dev, &usb2_default_control_ep, &default_ep); 129 223 if (err != EOK) { 130 224 usb_log_error("Device(%d): Failed to add default target: %s.", … … 150 244 151 245 /* We need to remove ep before we change the address */ 152 if ((err = bus_remove_endpoint( bus, default_ep))) {246 if ((err = bus_remove_endpoint(&bus->base, default_ep))) { 153 247 usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err)); 154 248 goto err_address; … … 168 262 /* Register EP on the new address */ 169 263 usb_log_debug("Device(%d): Registering control EP.", address); 170 err = bus_add_endpoint( bus, dev, &control_ep, NULL);264 err = bus_add_endpoint(&bus->base, dev, &control_ep, NULL); 171 265 if (err != EOK) { 172 266 usb_log_error("Device(%d): Failed to register EP0: %s", … … 178 272 179 273 err_default_control_ep: 180 bus_remove_endpoint( bus, default_ep);274 bus_remove_endpoint(&bus->base, default_ep); 181 275 endpoint_del_ref(default_ep); 182 276 err_address: 183 bus_release_address(bus, address);277 release_address(bus, address); 184 278 return err; 185 279 } … … 187 281 /** Enumerate a new USB device 188 282 */ 189 static int usb2_bus_enumerate_device(bus_t *bus , hcd_t *hcd, device_t *dev)283 static int usb2_bus_enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev) 190 284 { 191 285 int err; 286 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 192 287 193 288 /* The speed of the new device was reported by the hub when reserving 194 289 * default address. 195 290 */ 196 if ((err = usb2_bus_get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {291 if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) { 197 292 usb_log_error("Failed to verify speed: %s.", str_error(err)); 198 293 return err; … … 211 306 212 307 /* Assign an address to the device */ 213 if ((err = usb2_bus_address_device(bus, hcd, dev))) {308 if ((err = address_device(bus, hcd, dev))) { 214 309 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 215 310 return err; … … 219 314 if ((err = hcd_ddf_device_explore(hcd, dev))) { 220 315 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 221 bus_release_address(bus, dev->address);316 release_address(bus, dev->address); 222 317 return err; 223 318 } 224 319 225 return EOK;226 }227 228 /** Get a free USB address229 *230 * @param[in] bus Device manager structure to use.231 * @return Free address, or error code.232 */233 static int usb_bus_get_free_address(usb2_bus_t *bus, usb_address_t *addr)234 {235 usb_address_t new_address = bus->last_address;236 do {237 new_address = (new_address + 1) % USB_ADDRESS_COUNT;238 if (new_address == USB_ADDRESS_DEFAULT)239 new_address = 1;240 if (new_address == bus->last_address)241 return ENOSPC;242 } while (bus->devices[new_address].occupied);243 244 assert(new_address != USB_ADDRESS_DEFAULT);245 bus->last_address = new_address;246 247 *addr = new_address;248 320 return EOK; 249 321 } … … 367 439 } 368 440 369 /** Unregister and destroy all endpoints using given address. 370 * @param bus usb_bus structure, non-null. 371 * @param address USB address. 372 * @param endpoint USB endpoint number. 373 * @param direction Communication direction. 374 * @return Error code. 375 */ 376 static int usb2_bus_release_address(bus_t *bus_base, usb_address_t address) 377 { 378 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 379 380 if (!usb_address_is_valid(address)) 381 return EINVAL; 382 383 const int ret = bus->devices[address].occupied ? EOK : ENOENT; 384 bus->devices[address].occupied = false; 385 386 list_t *list = get_list(bus, address); 387 for (link_t *link = list_first(list); link != NULL; ) { 388 endpoint_t *ep = list_get_instance(link, endpoint_t, link); 389 link = list_next(link, list); 390 391 assert(ep->device->address == address); 392 list_remove(&ep->link); 393 394 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 395 address, ep->endpoint, usb_str_direction(ep->direction)); 396 397 /* Drop bus reference */ 398 endpoint_del_ref(ep); 399 } 400 401 return ret; 402 } 403 404 /** Request USB address. 405 * @param bus usb_device_manager 406 * @param addr Pointer to requested address value, place to store new address 407 * @parma strict Fail if the requested address is not available. 408 * @return Error code. 409 * @note Default address is only available in strict mode. 410 */ 411 static int usb2_bus_request_address(bus_t *bus_base, usb_address_t *addr, bool strict, usb_speed_t speed) 412 { 413 int err; 414 415 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 416 assert(addr); 417 418 if (!usb_address_is_valid(*addr)) 419 return EINVAL; 420 421 /* Only grant default address to strict requests */ 422 if ((*addr == USB_ADDRESS_DEFAULT) && !strict) { 423 if ((err = usb_bus_get_free_address(bus, addr))) 424 return err; 425 } 426 else if (bus->devices[*addr].occupied) { 427 if (strict) { 428 return ENOENT; 429 } 430 if ((err = usb_bus_get_free_address(bus, addr))) 431 return err; 432 } 433 434 assert(usb_address_is_valid(*addr)); 435 assert(bus->devices[*addr].occupied == false); 436 assert(*addr != USB_ADDRESS_DEFAULT || strict); 437 438 bus->devices[*addr].occupied = true; 439 bus->devices[*addr].speed = speed; 440 441 return EOK; 441 static int usb2_bus_register_default_address(bus_t *bus_base, usb_speed_t speed) 442 { 443 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 444 usb_address_t addr = USB_ADDRESS_DEFAULT; 445 return request_address(bus, &addr, true, speed); 446 } 447 448 static int usb2_bus_release_default_address(bus_t *bus_base) 449 { 450 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 451 return release_address(bus, USB_ADDRESS_DEFAULT); 442 452 } 443 453 444 454 static const bus_ops_t usb2_bus_ops = { 455 .reserve_default_address = usb2_bus_register_default_address, 456 .release_default_address = usb2_bus_release_default_address, 445 457 .enumerate_device = usb2_bus_enumerate_device, 446 458 .create_endpoint = usb2_bus_create_ep, … … 448 460 .unregister_endpoint = usb2_bus_unregister_ep, 449 461 .register_endpoint = usb2_bus_register_ep, 450 .request_address = usb2_bus_request_address,451 .release_address = usb2_bus_release_address,452 462 .reset_toggle = usb2_bus_reset_toggle, 453 463 };
Note:
See TracChangeset
for help on using the changeset viewer.