Changeset 20eaa82 in mainline for uspace/lib/usbhost/src/usb2_bus.c
- Timestamp:
- 2017-10-15T13:44:39Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2770b66
- Parents:
- 867b375
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb2_bus.c
r867b375 r20eaa82 36 36 #include <usb/host/usb2_bus.h> 37 37 #include <usb/host/endpoint.h> 38 #include <usb/host/ddf_helpers.h> 38 39 #include <usb/debug.h> 40 #include <usb/request.h> 41 #include <usb/descriptor.h> 42 #include <usb/usb.h> 39 43 40 44 #include <assert.h> 41 45 #include <errno.h> 42 46 #include <macros.h> 47 #include <str_error.h> 43 48 #include <stdlib.h> 44 49 #include <stdbool.h> … … 61 66 assert(addr >= 0); 62 67 return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list; 68 } 69 70 /** Get speed assigned to USB address. 71 * 72 * @param[in] bus Device manager structure to use. 73 * @param[in] address Address the caller wants to find. 74 * @param[out] speed Assigned speed. 75 * @return Error code. 76 */ 77 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed) 78 { 79 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 80 81 if (!usb_address_is_valid(address)) { 82 return EINVAL; 83 } 84 85 const int ret = bus->devices[address].occupied ? EOK : ENOENT; 86 if (speed && bus->devices[address].occupied) { 87 *speed = bus->devices[address].speed; 88 } 89 90 return ret; 91 } 92 93 static int usb2_bus_address_device(bus_t *bus, hcd_t *hcd, device_t *dev) 94 { 95 int err; 96 97 static const usb_target_t default_target = {{ 98 .address = USB_ADDRESS_DEFAULT, 99 .endpoint = 0, 100 }}; 101 102 /** Reserve address early, we want pretty log messages */ 103 const usb_address_t address = bus_reserve_default_address(bus, dev->speed); 104 if (address < 0) { 105 usb_log_error("Failed to reserve new address: %s.", 106 str_error(address)); 107 return address; 108 } 109 usb_log_debug("Device(%d): Reserved new address.", address); 110 111 /* Add default pipe on default address */ 112 usb_log_debug("Device(%d): Adding default target (0:0)", address); 113 err = bus_add_ep(bus, dev, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 114 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1); 115 if (err != EOK) { 116 usb_log_error("Device(%d): Failed to add default target: %s.", 117 address, str_error(err)); 118 goto err_address; 119 } 120 121 /* Get max packet size for default pipe */ 122 usb_standard_device_descriptor_t desc = { 0 }; 123 const usb_device_request_setup_packet_t get_device_desc_8 = 124 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 125 126 usb_log_debug("Device(%d): Requesting first 8B of device descriptor.", 127 address); 128 ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN, 129 &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8, 130 "read first 8 bytes of dev descriptor"); 131 132 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 133 err = got < 0 ? got : EOVERFLOW; 134 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.", 135 address, str_error(err)); 136 goto err_default_target; 137 } 138 139 /* Set new address */ 140 const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address); 141 142 usb_log_debug("Device(%d): Setting USB address.", address); 143 err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 144 NULL, 0, *(uint64_t *)&set_address, "set address"); 145 if (err != 0) { 146 usb_log_error("Device(%d): Failed to set new address: %s.", 147 address, str_error(got)); 148 goto err_default_target; 149 } 150 151 dev->address = address; 152 153 /* Register EP on the new address */ 154 usb_log_debug("Device(%d): Registering control EP.", address); 155 err = bus_add_ep(bus, dev, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 156 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 157 ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)), 158 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size))); 159 if (err != EOK) { 160 usb_log_error("Device(%d): Failed to register EP0: %s", 161 address, str_error(err)); 162 goto err_default_target; 163 } 164 165 bus_remove_ep(bus, default_target, USB_DIRECTION_BOTH); 166 return EOK; 167 168 err_default_target: 169 bus_remove_ep(bus, default_target, USB_DIRECTION_BOTH); 170 err_address: 171 bus_release_address(bus, address); 172 return err; 173 } 174 175 /** Enumerate a new USB device 176 */ 177 static int usb2_bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev) 178 { 179 int err; 180 181 /* The speed of the new device was reported by the hub when reserving 182 * default address. 183 */ 184 if ((err = usb2_bus_get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) { 185 usb_log_error("Failed to verify speed: %s.", str_error(err)); 186 return err; 187 } 188 usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed)); 189 190 /* Manage TT */ 191 if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) { 192 /* For LS devices under HS hub */ 193 /* TODO: How about SS hubs? */ 194 dev->tt.address = dev->hub->address; 195 dev->tt.port = dev->port; 196 } 197 else { 198 /* Inherit hub's TT */ 199 dev->tt = dev->hub->tt; 200 } 201 202 /* Assign an address to the device */ 203 if ((err = usb2_bus_address_device(bus, hcd, dev))) { 204 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 205 return err; 206 } 207 208 /* Read the device descriptor, derive the match ids */ 209 if ((err = hcd_ddf_device_explore(hcd, dev))) { 210 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 211 bus_release_address(bus, dev->address); 212 return err; 213 } 214 215 return EOK; 63 216 } 64 217 … … 190 343 * @param endpoint USB endpoint number. 191 344 * @param direction Communication direction. 192 * @param callback Function to call after unregister, before destruction.193 * @arg Argument to pass to the callback function.194 345 * @return Error code. 195 346 */ … … 211 362 list_remove(&ep->link); 212 363 364 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 365 ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction)); 366 213 367 /* Drop bus reference */ 214 368 endpoint_del_ref(ep); … … 258 412 } 259 413 260 /** Get speed assigned to USB address.261 *262 * @param[in] bus Device manager structure to use.263 * @param[in] address Address the caller wants to find.264 * @param[out] speed Assigned speed.265 * @return Error code.266 */267 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)268 {269 usb2_bus_t *bus = bus_to_usb2_bus(bus_base);270 271 if (!usb_address_is_valid(address)) {272 return EINVAL;273 }274 275 const int ret = bus->devices[address].occupied ? EOK : ENOENT;276 if (speed && bus->devices[address].occupied) {277 *speed = bus->devices[address].speed;278 }279 280 return ret;281 }282 283 414 static const bus_ops_t usb2_bus_ops = { 415 .enumerate_device = usb2_bus_enumerate_device, 284 416 .create_endpoint = usb2_bus_create_ep, 285 417 .find_endpoint = usb2_bus_find_ep, … … 289 421 .release_address = usb2_bus_release_address, 290 422 .reset_toggle = usb2_bus_reset_toggle, 291 .get_speed = usb2_bus_get_speed,292 423 }; 293 424 … … 303 434 assert(bus); 304 435 305 bus_init(&bus->base );436 bus_init(&bus->base, sizeof(device_t)); 306 437 307 438 bus->base.ops = usb2_bus_ops;
Note:
See TracChangeset
for help on using the changeset viewer.