Changeset 00aece0 in mainline for uspace/lib/usbdev/src/pipesinit.c
- Timestamp:
- 2012-02-18T16:47:38Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4449c6c
- Parents:
- bd5f3b7 (diff), f943dd3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/pipesinit.c
rbd5f3b7 r00aece0 31 31 */ 32 32 /** @file 33 * Initialization of endpoint pipes.33 * Non trivial 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>41 40 #include <errno.h> 42 41 #include <assert.h> 43 42 44 #define CTRL_PIPE_MIN_PACKET_SIZE 845 43 #define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7 46 47 44 48 45 #define NESTING(parentname, childname) \ … … 54 51 55 52 /** Nesting pairs of standard descriptors. */ 56 static usb_dp_descriptor_nesting_t descriptor_nesting[] = {53 static const usb_dp_descriptor_nesting_t descriptor_nesting[] = { 57 54 NESTING(CONFIGURATION, INTERFACE), 58 55 NESTING(INTERFACE, ENDPOINT), … … 68 65 * @return Whether the given descriptor is endpoint descriptor. 69 66 */ 70 static inline bool is_endpoint_descriptor( uint8_t *descriptor)67 static inline bool is_endpoint_descriptor(const uint8_t *descriptor) 71 68 { 72 69 return descriptor[1] == USB_DESCTYPE_ENDPOINT; … … 80 77 */ 81 78 static bool endpoint_fits_description(const usb_endpoint_description_t *wanted, 82 usb_endpoint_description_t *found)79 const usb_endpoint_description_t *found) 83 80 { 84 81 #define _SAME(fieldname) ((wanted->fieldname) == (found->fieldname)) … … 120 117 static usb_endpoint_mapping_t *find_endpoint_mapping( 121 118 usb_endpoint_mapping_t *mapping, size_t mapping_count, 122 usb_endpoint_description_t *found_endpoint,119 const usb_endpoint_description_t *found_endpoint, 123 120 int interface_number, int interface_setting) 124 121 { … … 160 157 usb_device_connection_t *wire) 161 158 { 162 usb_endpoint_description_t description;163 159 164 160 /* … … 167 163 168 164 /* Actual endpoint number is in bits 0..3 */ 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; 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 }; 183 180 184 181 /* … … 192 189 } 193 190 194 if (ep_mapping->pipe == NULL) {195 return EBADMEM;196 }197 191 if (ep_mapping->present) { 198 192 return EEXISTS; 199 193 } 200 194 201 int rc = usb_pipe_initialize( ep_mapping->pipe, wire,195 int rc = usb_pipe_initialize(&ep_mapping->pipe, wire, 202 196 ep_no, description.transfer_type, endpoint->max_packet_size, 203 197 description.direction); … … 224 218 static int process_interface( 225 219 usb_endpoint_mapping_t *mapping, size_t mapping_count, 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,220 const usb_dp_parser_t *parser, const usb_dp_parser_data_t *parser_data, 221 const uint8_t *interface_descriptor) 222 { 223 const uint8_t *descriptor = usb_dp_get_nested_descriptor(parser, 230 224 parser_data, interface_descriptor); 231 225 … … 254 248 * 255 249 * The mapping array is expected to conform to following rules: 256 * - @c pipe must point to already allocated structure withuninitialized pipe250 * - @c pipe must be uninitialized pipe 257 251 * - @c description must point to prepared endpoint description 258 252 * - @c descriptor does not need to be initialized (will be overwritten) … … 284 278 int usb_pipe_initialize_from_configuration( 285 279 usb_endpoint_mapping_t *mapping, size_t mapping_count, 286 uint8_t *configuration_descriptor, size_t configuration_descriptor_size,280 const uint8_t *config_descriptor, size_t config_descriptor_size, 287 281 usb_device_connection_t *connection) 288 282 { 289 283 assert(connection); 290 284 291 if (config uration_descriptor == NULL) {285 if (config_descriptor == NULL) { 292 286 return EBADMEM; 293 287 } 294 if (config uration_descriptor_size288 if (config_descriptor_size 295 289 < sizeof(usb_standard_configuration_descriptor_t)) { 296 290 return ERANGE; 297 291 } 298 292 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++) { 293 /* Go through the mapping and set all endpoints to not present. */ 294 for (size_t i = 0; i < mapping_count; i++) { 304 295 mapping[i].present = false; 305 296 mapping[i].descriptor = NULL; … … 307 298 } 308 299 309 /* 310 * Prepare the descriptor parser. 311 */ 312 usb_dp_parser_t dp_parser = { 300 /* Prepare the descriptor parser. */ 301 const usb_dp_parser_t dp_parser = { 313 302 .nesting = descriptor_nesting 314 303 }; 315 usb_dp_parser_data_t dp_data = {316 .data = config uration_descriptor,317 .size = config uration_descriptor_size,304 const usb_dp_parser_data_t dp_data = { 305 .data = config_descriptor, 306 .size = config_descriptor_size, 318 307 .arg = connection 319 308 }; … … 322 311 * Iterate through all interfaces. 323 312 */ 324 uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,325 &dp_data, config uration_descriptor);313 const uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser, 314 &dp_data, config_descriptor); 326 315 if (interface == NULL) { 327 316 return ENOENT; … … 329 318 do { 330 319 (void) process_interface(mapping, mapping_count, 331 &dp_parser, &dp_data, 332 interface); 320 &dp_parser, &dp_data, interface); 333 321 interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data, 334 config uration_descriptor, interface);322 config_descriptor, interface); 335 323 } while (interface != NULL); 336 324 337 325 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;393 326 } 394 327 … … 414 347 } 415 348 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;421 349 422 350 usb_pipe_start_long_transfer(pipe); … … 424 352 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE]; 425 353 size_t transferred_size; 426 TRY_LOOP(failed_attempts) { 354 int rc; 355 for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) { 427 356 rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD, 428 357 USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE, … … 448 377 } 449 378 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 only468 * if the registered endpoint is of address 0 and there is no other way469 * to tell speed of the device at address 0.470 *471 * @param pipe Pipe to be registered.472 * @param speed Speed of the device473 * (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 #define _PACK2(high, low) (((high) << 16) + (low))489 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))490 491 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);492 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),493 IPC_M_USBHC_REGISTER_ENDPOINT,494 _PACK2(pipe->wire->address, pipe->endpoint_no),495 _PACK3(speed, pipe->transfer_type, pipe->direction),496 _PACK2(pipe->max_packet_size, interval));497 async_exchange_end(exch);498 499 #undef _PACK2500 #undef _PACK3501 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(hc_connection);516 517 if (!usb_hc_connection_is_opened(hc_connection))518 return EBADF;519 520 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);521 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),522 IPC_M_USBHC_UNREGISTER_ENDPOINT,523 pipe->wire->address, pipe->endpoint_no, pipe->direction);524 async_exchange_end(exch);525 526 return rc;527 }528 529 379 /** 530 380 * @}
Note:
See TracChangeset
for help on using the changeset viewer.