Changeset 3238506 in mainline
- Timestamp:
- 2011-11-04T19:22:01Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2179cf95
- Parents:
- bbd09694
- Location:
- uspace/lib/usbdev
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/include/usb/dev/request.h
rbbd09694 r3238506 115 115 int usb_request_set_feature(usb_pipe_t *, usb_request_type_t, 116 116 usb_request_recipient_t, uint16_t, uint16_t); 117 int usb_request_set_address(usb_pipe_t *, usb_address_t);118 117 int usb_request_get_descriptor(usb_pipe_t *, usb_request_type_t, 119 usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 118 usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 120 119 size_t *); 121 120 int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t, -
uspace/lib/usbdev/src/hub.c
rbbd09694 r3238506 133 133 } 134 134 135 136 static void unregister_control_endpoint_on_default_address( 137 usb_hc_connection_t *connection) 135 /** Change address of connected device. 136 * This function automatically updates the backing connection to point to 137 * the new address. It also unregisterrs the old endpoint and registers 138 * a new one. 139 * This creates whole bunch of problems: 140 * 1. All pipes using this wire are broken because they are not 141 * registered for new address 142 * 2. All other pipes for this device are using wrong address, 143 * possibly targeting completely different device 144 * 145 * @param pipe Control endpoint pipe (session must be already started). 146 * @param new_address New USB address to be set (in native endianness). 147 * @return Error code. 148 */ 149 static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address, 150 usb_hc_connection_t *hc_conn) 138 151 { 139 usb_device_connection_t dev_conn; 140 int rc = usb_device_connection_initialize_on_default_address(&dev_conn, 141 connection); 142 if (rc != EOK) { 143 return; 144 } 145 146 usb_pipe_t ctrl_pipe; 147 rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn); 148 if (rc != EOK) { 149 return; 150 } 151 152 usb_pipe_unregister(&ctrl_pipe, connection); 152 if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) { 153 return EINVAL; 154 } 155 assert(pipe); 156 assert(hc_conn); 157 assert(pipe->wire != NULL); 158 159 const uint16_t addr = uint16_host2usb((uint16_t)new_address); 160 161 int rc = usb_control_request_set(pipe, 162 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 163 USB_DEVREQ_SET_ADDRESS, addr, 0, NULL, 0); 164 165 if (rc != EOK) { 166 return rc; 167 } 168 169 /* TODO: prevent others from accessing the wire now. */ 170 if (usb_pipe_unregister(pipe, hc_conn) != EOK) { 171 usb_log_warning( 172 "Failed to unregister the old pipe on address change.\n"); 173 } 174 /* The address is already changed so set it in the wire */ 175 pipe->wire->address = new_address; 176 rc = usb_pipe_register(pipe, 0, hc_conn); 177 if (rc != EOK) 178 return EADDRNOTAVAIL; 179 180 return EOK; 153 181 } 154 182 … … 225 253 */ 226 254 usb_address_t dev_addr = 227 usb_hc_request_address(&hc_conn, 1, false, dev_speed);255 usb_hc_request_address(&hc_conn, 0, false, dev_speed); 228 256 if (dev_addr < 0) { 229 257 rc = EADDRNOTAVAIL; … … 246 274 247 275 usb_pipe_t ctrl_pipe; 248 rc = usb_pipe_initialize_default_control(&ctrl_pipe, 249 &dev_conn); 276 rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn); 250 277 if (rc != EOK) { 251 278 rc = ENOTCONN; … … 256 283 rc = usb_hc_request_address(&hc_conn, USB_ADDRESS_DEFAULT, 257 284 true, dev_speed); 258 if (rc != USB_ADDRESS_DEFAULT) {285 if (rc == ENOENT) { 259 286 /* Do not overheat the CPU ;-). */ 260 287 async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC); 261 288 } 262 289 } while (rc == ENOENT); 263 if (rc != EOK) {290 if (rc < 0) { 264 291 goto leave_release_free_address; 265 292 } 266 293 294 /* Register control pipe on default address. */ 267 295 rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn); 268 296 if (rc != EOK) { … … 283 311 * above might use much of this time so we should only wait to fill 284 312 * up the 100ms quota*/ 285 suseconds_t elapsed = tv_sub(&end_time, &start_time);313 const suseconds_t elapsed = tv_sub(&end_time, &start_time); 286 314 if (elapsed < 100000) { 287 315 async_usleep(100000 - elapsed); 288 316 } 289 317 290 /* 291 * Endpoint is registered. We can enable the port and change 292 * device address. 293 */ 318 /* Endpoint is registered. We can enable the port and change address. */ 294 319 rc = enable_port(arg); 295 320 if (rc != EOK) { … … 303 328 async_usleep(10000); 304 329 330 /* Get max_packet_size value. */ 305 331 rc = usb_pipe_probe_default_control(&ctrl_pipe); 306 332 if (rc != EOK) { … … 309 335 } 310 336 311 rc = usb_request_set_address(&ctrl_pipe, dev_addr );337 rc = usb_request_set_address(&ctrl_pipe, dev_addr, &hc_conn); 312 338 if (rc != EOK) { 313 339 rc = ESTALL; … … 315 341 } 316 342 317 /* 318 * Address changed. We can release the original endpoint, thus 319 * allowing other to access the default address. 320 */ 321 unregister_control_endpoint_on_default_address(&hc_conn); 343 /* Address changed. We can release the default, thus 344 * allowing other to access the default address. */ 322 345 usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT); 323 346 324 /* 325 * Time to register the new endpoint. 326 */ 327 rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn); 328 if (rc != EOK) { 329 goto leave_release_free_address; 330 } 331 332 /* 333 * It is time to register the device with devman. 334 */ 347 /* Register the device with devman. */ 335 348 /* FIXME: create device_register that will get opened ctrl pipe. */ 336 349 ddf_fun_t *child_fun; … … 347 360 348 361 349 /* 350 * And now inform the host controller about the handle. 351 */ 362 /* Inform the host controller about the handle. */ 352 363 rc = usb_hc_register_device(&hc_conn, &new_device); 353 364 if (rc != EOK) { … … 361 372 } 362 373 363 /*364 * And we are done.365 */366 374 if (assigned_address != NULL) { 367 375 *assigned_address = dev_addr; 368 376 } 369 if (new_fun != NULL) { 370 *new_fun = child_fun; 371 } 377 378 *new_fun = child_fun; 372 379 373 380 rc = EOK; … … 382 389 383 390 leave_release_free_address: 384 if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK)385 usb_log_warning("%s: Failed to unregister device.\n",386 __FUNCTION__);387 391 /* This might be either 0:0 or dev_addr:0 */ 388 392 if (usb_pipe_unregister(&ctrl_pipe, &hc_conn) != EOK) … … 390 394 __FUNCTION__); 391 395 396 if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK) 397 usb_log_warning("%s: Failed to unregister device.\n", 398 __FUNCTION__); 399 392 400 close_connection: 393 401 if (usb_hc_connection_close(&hc_conn) != EOK) 394 usb_log_warning("%s: Failed to close connection.\n",402 usb_log_warning("%s: Failed to close hc connection.\n", 395 403 __FUNCTION__); 396 404 -
uspace/lib/usbdev/src/request.c
rbbd09694 r3238506 250 250 } 251 251 252 /** Change address of connected device.253 * This function automatically updates the backing connection to point to254 * the new address.255 *256 * @param pipe Control endpoint pipe (session must be already started).257 * @param new_address New USB address to be set (in native endianness).258 * @return Error code.259 */260 int usb_request_set_address(usb_pipe_t *pipe,261 usb_address_t new_address)262 {263 if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {264 return EINVAL;265 }266 267 uint16_t addr = uint16_host2usb((uint16_t)new_address);268 269 int rc = usb_control_request_set(pipe,270 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,271 USB_DEVREQ_SET_ADDRESS,272 addr, 0,273 NULL, 0);274 275 if (rc != EOK) {276 return rc;277 }278 279 assert(pipe->wire != NULL);280 /* TODO: prevent other from accessing wire now. */281 pipe->wire->address = new_address;282 283 return EOK;284 }285 286 252 /** Retrieve USB descriptor of a USB device. 287 253 *
Note:
See TracChangeset
for help on using the changeset viewer.