Changes in uspace/lib/usbdev/src/pipesinit.c [9d58539:7c95d6f5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/pipesinit.c
r9d58539 r7c95d6f5 31 31 */ 32 32 /** @file 33 * Non trivial initialization of endpoint pipes.33 * Initialization of endpoint pipes. 34 34 * 35 35 */ … … 38 38 #include <usb/dev/dp.h> 39 39 #include <usb/dev/request.h> 40 #include <usbhc_iface.h> 40 41 #include <errno.h> 41 42 #include <assert.h> 42 43 44 #define CTRL_PIPE_MIN_PACKET_SIZE 8 43 45 #define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7 46 44 47 45 48 #define NESTING(parentname, childname) \ … … 51 54 52 55 /** Nesting pairs of standard descriptors. */ 53 static constusb_dp_descriptor_nesting_t descriptor_nesting[] = {56 static usb_dp_descriptor_nesting_t descriptor_nesting[] = { 54 57 NESTING(CONFIGURATION, INTERFACE), 55 58 NESTING(INTERFACE, ENDPOINT), … … 189 192 } 190 193 194 if (ep_mapping->pipe == NULL) { 195 return EBADMEM; 196 } 191 197 if (ep_mapping->present) { 192 198 return EEXISTS; 193 199 } 194 200 195 int rc = usb_pipe_initialize( &ep_mapping->pipe, wire,201 int rc = usb_pipe_initialize(ep_mapping->pipe, wire, 196 202 ep_no, description.transfer_type, endpoint->max_packet_size, 197 203 description.direction); … … 248 254 * 249 255 * The mapping array is expected to conform to following rules: 250 * - @c pipe must beuninitialized pipe256 * - @c pipe must point to already allocated structure with uninitialized pipe 251 257 * - @c description must point to prepared endpoint description 252 258 * - @c descriptor does not need to be initialized (will be overwritten) … … 291 297 } 292 298 293 /* Go through the mapping and set all endpoints to not present. */ 294 for (size_t i = 0; i < mapping_count; i++) { 299 /* 300 * Go through the mapping and set all endpoints to not present. 301 */ 302 size_t i; 303 for (i = 0; i < mapping_count; i++) { 295 304 mapping[i].present = false; 296 305 mapping[i].descriptor = NULL; … … 298 307 } 299 308 300 /* Prepare the descriptor parser. */ 309 /* 310 * Prepare the descriptor parser. 311 */ 301 312 const usb_dp_parser_t dp_parser = { 302 313 .nesting = descriptor_nesting … … 326 337 } 327 338 339 /** Initialize USB endpoint pipe. 340 * 341 * @param pipe Endpoint pipe to be initialized. 342 * @param connection Connection to the USB device backing this pipe (the wire). 343 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15). 344 * @param transfer_type Transfer type (e.g. interrupt or bulk). 345 * @param max_packet_size Maximum packet size in bytes. 346 * @param direction Endpoint direction (in/out). 347 * @return Error code. 348 */ 349 int usb_pipe_initialize(usb_pipe_t *pipe, 350 usb_device_connection_t *connection, usb_endpoint_t endpoint_no, 351 usb_transfer_type_t transfer_type, size_t max_packet_size, 352 usb_direction_t direction) 353 { 354 assert(pipe); 355 assert(connection); 356 357 fibril_mutex_initialize(&pipe->guard); 358 pipe->wire = connection; 359 pipe->hc_sess = NULL; 360 fibril_mutex_initialize(&pipe->hc_sess_mutex); 361 pipe->endpoint_no = endpoint_no; 362 pipe->transfer_type = transfer_type; 363 pipe->max_packet_size = max_packet_size; 364 pipe->direction = direction; 365 pipe->refcount = 0; 366 pipe->refcount_soft = 0; 367 pipe->auto_reset_halt = false; 368 369 return EOK; 370 } 371 372 373 /** Initialize USB endpoint pipe as the default zero control pipe. 374 * 375 * @param pipe Endpoint pipe to be initialized. 376 * @param connection Connection to the USB device backing this pipe (the wire). 377 * @return Error code. 378 */ 379 int usb_pipe_initialize_default_control(usb_pipe_t *pipe, 380 usb_device_connection_t *connection) 381 { 382 assert(pipe); 383 assert(connection); 384 385 int rc = usb_pipe_initialize(pipe, connection, 386 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 387 USB_DIRECTION_BOTH); 388 389 pipe->auto_reset_halt = true; 390 391 return rc; 392 } 393 328 394 /** Probe default control pipe for max packet size. 329 395 * … … 347 413 } 348 414 415 #define TRY_LOOP(attempt_var) \ 416 for (attempt_var = 0; attempt_var < 3; attempt_var++) 417 418 size_t failed_attempts; 419 int rc; 349 420 350 421 usb_pipe_start_long_transfer(pipe); … … 352 423 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE]; 353 424 size_t transferred_size; 354 int rc; 355 for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) { 425 TRY_LOOP(failed_attempts) { 356 426 rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD, 357 427 USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE, … … 377 447 } 378 448 449 /** Register endpoint with the host controller. 450 * 451 * @param pipe Pipe to be registered. 452 * @param interval Polling interval. 453 * @param hc_connection Connection to the host controller (must be opened). 454 * @return Error code. 455 */ 456 int usb_pipe_register(usb_pipe_t *pipe, 457 unsigned int interval, 458 usb_hc_connection_t *hc_connection) 459 { 460 return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1, 461 interval, hc_connection); 462 } 463 464 /** Register endpoint with a speed at the host controller. 465 * 466 * You will rarely need to use this function because it is needed only 467 * if the registered endpoint is of address 0 and there is no other way 468 * to tell speed of the device at address 0. 469 * 470 * @param pipe Pipe to be registered. 471 * @param speed Speed of the device 472 * (invalid speed means use previously specified one). 473 * @param interval Polling interval. 474 * @param hc_connection Connection to the host controller (must be opened). 475 * @return Error code. 476 */ 477 int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed, 478 unsigned int interval, 479 usb_hc_connection_t *hc_connection) 480 { 481 assert(pipe); 482 assert(hc_connection); 483 484 if (!usb_hc_connection_is_opened(hc_connection)) 485 return EBADF; 486 487 const usb_target_t target = 488 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }}; 489 #define _PACK2(high, low) (((high) << 16) + (low)) 490 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low)) 491 492 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 493 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 494 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 495 _PACK3(speed, pipe->transfer_type, pipe->direction), 496 _PACK2(pipe->max_packet_size, interval)); 497 async_exchange_end(exch); 498 499 #undef _PACK2 500 #undef _PACK3 501 502 return rc; 503 } 504 505 /** Revert endpoint registration with the host controller. 506 * 507 * @param pipe Pipe to be unregistered. 508 * @param hc_connection Connection to the host controller (must be opened). 509 * @return Error code. 510 */ 511 int usb_pipe_unregister(usb_pipe_t *pipe, 512 usb_hc_connection_t *hc_connection) 513 { 514 assert(pipe); 515 assert(pipe->wire); 516 assert(hc_connection); 517 518 if (!usb_hc_connection_is_opened(hc_connection)) 519 return EBADF; 520 521 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 522 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 523 IPC_M_USBHC_UNREGISTER_ENDPOINT, 524 pipe->wire->address, pipe->endpoint_no, pipe->direction); 525 async_exchange_end(exch); 526 527 return rc; 528 } 529 379 530 /** 380 531 * @}
Note:
See TracChangeset
for help on using the changeset viewer.