Changes in uspace/lib/usbdev/src/pipesinit.c [3538b0e:365e29e2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/pipesinit.c
r3538b0e r365e29e2 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), … … 65 68 * @return Whether the given descriptor is endpoint descriptor. 66 69 */ 67 static inline bool is_endpoint_descriptor( constuint8_t *descriptor)70 static inline bool is_endpoint_descriptor(uint8_t *descriptor) 68 71 { 69 72 return descriptor[1] == USB_DESCTYPE_ENDPOINT; … … 77 80 */ 78 81 static bool endpoint_fits_description(const usb_endpoint_description_t *wanted, 79 constusb_endpoint_description_t *found)82 usb_endpoint_description_t *found) 80 83 { 81 84 #define _SAME(fieldname) ((wanted->fieldname) == (found->fieldname)) … … 117 120 static usb_endpoint_mapping_t *find_endpoint_mapping( 118 121 usb_endpoint_mapping_t *mapping, size_t mapping_count, 119 constusb_endpoint_description_t *found_endpoint,122 usb_endpoint_description_t *found_endpoint, 120 123 int interface_number, int interface_setting) 121 124 { … … 157 160 usb_device_connection_t *wire) 158 161 { 162 usb_endpoint_description_t description; 159 163 160 164 /* … … 163 167 164 168 /* Actual endpoint number is in bits 0..3 */ 165 const usb_endpoint_t ep_no = endpoint->endpoint_address & 0x0F; 166 167 const usb_endpoint_description_t description = { 168 /* Endpoint direction is set by bit 7 */ 169 .direction = (endpoint->endpoint_address & 128) 170 ? USB_DIRECTION_IN : USB_DIRECTION_OUT, 171 /* Transfer type is in bits 0..2 and 172 * the enum values corresponds 1:1 */ 173 .transfer_type = endpoint->attributes & 3, 174 175 /* Get interface characteristics. */ 176 .interface_class = interface->interface_class, 177 .interface_subclass = interface->interface_subclass, 178 .interface_protocol = interface->interface_protocol, 179 }; 169 usb_endpoint_t ep_no = endpoint->endpoint_address & 0x0F; 170 171 /* Endpoint direction is set by bit 7 */ 172 description.direction = (endpoint->endpoint_address & 128) 173 ? USB_DIRECTION_IN : USB_DIRECTION_OUT; 174 /* Transfer type is in bits 0..2 and the enum values corresponds 1:1 */ 175 description.transfer_type = endpoint->attributes & 3; 176 177 /* 178 * Get interface characteristics. 179 */ 180 description.interface_class = interface->interface_class; 181 description.interface_subclass = interface->interface_subclass; 182 description.interface_protocol = interface->interface_protocol; 180 183 181 184 /* … … 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); … … 218 224 static int process_interface( 219 225 usb_endpoint_mapping_t *mapping, size_t mapping_count, 220 const usb_dp_parser_t *parser, constusb_dp_parser_data_t *parser_data,221 constuint8_t *interface_descriptor)222 { 223 constuint8_t *descriptor = usb_dp_get_nested_descriptor(parser,226 usb_dp_parser_t *parser, usb_dp_parser_data_t *parser_data, 227 uint8_t *interface_descriptor) 228 { 229 uint8_t *descriptor = usb_dp_get_nested_descriptor(parser, 224 230 parser_data, interface_descriptor); 225 231 … … 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) … … 278 284 int usb_pipe_initialize_from_configuration( 279 285 usb_endpoint_mapping_t *mapping, size_t mapping_count, 280 const uint8_t *config_descriptor, size_t config_descriptor_size,286 uint8_t *configuration_descriptor, size_t configuration_descriptor_size, 281 287 usb_device_connection_t *connection) 282 288 { 283 289 assert(connection); 284 290 285 if (config _descriptor == NULL) {291 if (configuration_descriptor == NULL) { 286 292 return EBADMEM; 287 293 } 288 if (config _descriptor_size294 if (configuration_descriptor_size 289 295 < sizeof(usb_standard_configuration_descriptor_t)) { 290 296 return ERANGE; 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. */ 301 const usb_dp_parser_t dp_parser = { 309 /* 310 * Prepare the descriptor parser. 311 */ 312 usb_dp_parser_t dp_parser = { 302 313 .nesting = descriptor_nesting 303 314 }; 304 constusb_dp_parser_data_t dp_data = {305 .data = config _descriptor,306 .size = config _descriptor_size,315 usb_dp_parser_data_t dp_data = { 316 .data = configuration_descriptor, 317 .size = configuration_descriptor_size, 307 318 .arg = connection 308 319 }; … … 311 322 * Iterate through all interfaces. 312 323 */ 313 constuint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,314 &dp_data, config _descriptor);324 uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser, 325 &dp_data, configuration_descriptor); 315 326 if (interface == NULL) { 316 327 return ENOENT; … … 318 329 do { 319 330 (void) process_interface(mapping, mapping_count, 320 &dp_parser, &dp_data, interface); 331 &dp_parser, &dp_data, 332 interface); 321 333 interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data, 322 config _descriptor, interface);334 configuration_descriptor, interface); 323 335 } while (interface != NULL); 324 336 325 337 return EOK; 338 } 339 340 /** Initialize USB endpoint pipe. 341 * 342 * @param pipe Endpoint pipe to be initialized. 343 * @param connection Connection to the USB device backing this pipe (the wire). 344 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15). 345 * @param transfer_type Transfer type (e.g. interrupt or bulk). 346 * @param max_packet_size Maximum packet size in bytes. 347 * @param direction Endpoint direction (in/out). 348 * @return Error code. 349 */ 350 int usb_pipe_initialize(usb_pipe_t *pipe, 351 usb_device_connection_t *connection, usb_endpoint_t endpoint_no, 352 usb_transfer_type_t transfer_type, size_t max_packet_size, 353 usb_direction_t direction) 354 { 355 assert(pipe); 356 assert(connection); 357 358 fibril_mutex_initialize(&pipe->guard); 359 pipe->wire = connection; 360 pipe->hc_sess = NULL; 361 fibril_mutex_initialize(&pipe->hc_sess_mutex); 362 pipe->endpoint_no = endpoint_no; 363 pipe->transfer_type = transfer_type; 364 pipe->max_packet_size = max_packet_size; 365 pipe->direction = direction; 366 pipe->refcount = 0; 367 pipe->refcount_soft = 0; 368 pipe->auto_reset_halt = false; 369 370 return EOK; 371 } 372 373 374 /** Initialize USB endpoint pipe as the default zero control pipe. 375 * 376 * @param pipe Endpoint pipe to be initialized. 377 * @param connection Connection to the USB device backing this pipe (the wire). 378 * @return Error code. 379 */ 380 int usb_pipe_initialize_default_control(usb_pipe_t *pipe, 381 usb_device_connection_t *connection) 382 { 383 assert(pipe); 384 assert(connection); 385 386 int rc = usb_pipe_initialize(pipe, connection, 387 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 388 USB_DIRECTION_BOTH); 389 390 pipe->auto_reset_halt = true; 391 392 return rc; 326 393 } 327 394 … … 347 414 } 348 415 416 #define TRY_LOOP(attempt_var) \ 417 for (attempt_var = 0; attempt_var < 3; attempt_var++) 418 419 size_t failed_attempts; 420 int rc; 349 421 350 422 usb_pipe_start_long_transfer(pipe); … … 352 424 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE]; 353 425 size_t transferred_size; 354 int rc; 355 for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) { 426 TRY_LOOP(failed_attempts) { 356 427 rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD, 357 428 USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE, … … 377 448 } 378 449 450 /** Register endpoint with the host controller. 451 * 452 * @param pipe Pipe to be registered. 453 * @param interval Polling interval. 454 * @param hc_connection Connection to the host controller (must be opened). 455 * @return Error code. 456 */ 457 int usb_pipe_register(usb_pipe_t *pipe, 458 unsigned int interval, 459 usb_hc_connection_t *hc_connection) 460 { 461 return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1, 462 interval, hc_connection); 463 } 464 465 /** Register endpoint with a speed at the host controller. 466 * 467 * You will rarely need to use this function because it is needed only 468 * if the registered endpoint is of address 0 and there is no other way 469 * to tell speed of the device at address 0. 470 * 471 * @param pipe Pipe to be registered. 472 * @param speed Speed of the device 473 * (invalid speed means use previously specified one). 474 * @param interval Polling interval. 475 * @param hc_connection Connection to the host controller (must be opened). 476 * @return Error code. 477 */ 478 int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed, 479 unsigned int interval, 480 usb_hc_connection_t *hc_connection) 481 { 482 assert(pipe); 483 assert(hc_connection); 484 485 if (!usb_hc_connection_is_opened(hc_connection)) 486 return EBADF; 487 488 const usb_target_t target = 489 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }}; 490 #define _PACK2(high, low) (((high) << 16) + (low)) 491 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low)) 492 493 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 494 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 495 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 496 _PACK3(speed, pipe->transfer_type, pipe->direction), 497 _PACK2(pipe->max_packet_size, interval)); 498 async_exchange_end(exch); 499 500 #undef _PACK2 501 #undef _PACK3 502 503 return rc; 504 } 505 506 /** Revert endpoint registration with the host controller. 507 * 508 * @param pipe Pipe to be unregistered. 509 * @param hc_connection Connection to the host controller (must be opened). 510 * @return Error code. 511 */ 512 int usb_pipe_unregister(usb_pipe_t *pipe, 513 usb_hc_connection_t *hc_connection) 514 { 515 assert(pipe); 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.