Changeset 00aece0 in mainline for uspace/lib/usbdev/src/pipesinit.c


Ignore:
Timestamp:
2012-02-18T16:47:38Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
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.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/src/pipesinit.c

    rbd5f3b7 r00aece0  
    3131 */
    3232/** @file
    33  * Initialization of endpoint pipes.
     33 * Non trivial initialization of endpoint pipes.
    3434 *
    3535 */
     
    3838#include <usb/dev/dp.h>
    3939#include <usb/dev/request.h>
    40 #include <usbhc_iface.h>
    4140#include <errno.h>
    4241#include <assert.h>
    4342
    44 #define CTRL_PIPE_MIN_PACKET_SIZE 8
    4543#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
    46 
    4744
    4845#define NESTING(parentname, childname) \
     
    5451
    5552/** Nesting pairs of standard descriptors. */
    56 static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
     53static const usb_dp_descriptor_nesting_t descriptor_nesting[] = {
    5754        NESTING(CONFIGURATION, INTERFACE),
    5855        NESTING(INTERFACE, ENDPOINT),
     
    6865 * @return Whether the given descriptor is endpoint descriptor.
    6966 */
    70 static inline bool is_endpoint_descriptor(uint8_t *descriptor)
     67static inline bool is_endpoint_descriptor(const uint8_t *descriptor)
    7168{
    7269        return descriptor[1] == USB_DESCTYPE_ENDPOINT;
     
    8077 */
    8178static bool endpoint_fits_description(const usb_endpoint_description_t *wanted,
    82     usb_endpoint_description_t *found)
     79    const usb_endpoint_description_t *found)
    8380{
    8481#define _SAME(fieldname) ((wanted->fieldname) == (found->fieldname))
     
    120117static usb_endpoint_mapping_t *find_endpoint_mapping(
    121118    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    122     usb_endpoint_description_t *found_endpoint,
     119    const usb_endpoint_description_t *found_endpoint,
    123120    int interface_number, int interface_setting)
    124121{
     
    160157    usb_device_connection_t *wire)
    161158{
    162         usb_endpoint_description_t description;
    163159
    164160        /*
     
    167163
    168164        /* 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        };
    183180
    184181        /*
     
    192189        }
    193190
    194         if (ep_mapping->pipe == NULL) {
    195                 return EBADMEM;
    196         }
    197191        if (ep_mapping->present) {
    198192                return EEXISTS;
    199193        }
    200194
    201         int rc = usb_pipe_initialize(ep_mapping->pipe, wire,
     195        int rc = usb_pipe_initialize(&ep_mapping->pipe, wire,
    202196            ep_no, description.transfer_type, endpoint->max_packet_size,
    203197            description.direction);
     
    224218static int process_interface(
    225219    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,
    230224            parser_data, interface_descriptor);
    231225
     
    254248 *
    255249 * The mapping array is expected to conform to following rules:
    256  * - @c pipe must point to already allocated structure with uninitialized pipe
     250 * - @c pipe must be uninitialized pipe
    257251 * - @c description must point to prepared endpoint description
    258252 * - @c descriptor does not need to be initialized (will be overwritten)
     
    284278int usb_pipe_initialize_from_configuration(
    285279    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,
    287281    usb_device_connection_t *connection)
    288282{
    289283        assert(connection);
    290284
    291         if (configuration_descriptor == NULL) {
     285        if (config_descriptor == NULL) {
    292286                return EBADMEM;
    293287        }
    294         if (configuration_descriptor_size
     288        if (config_descriptor_size
    295289            < sizeof(usb_standard_configuration_descriptor_t)) {
    296290                return ERANGE;
    297291        }
    298292
    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++) {
    304295                mapping[i].present = false;
    305296                mapping[i].descriptor = NULL;
     
    307298        }
    308299
    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 = {
    313302                .nesting = descriptor_nesting
    314303        };
    315         usb_dp_parser_data_t dp_data = {
    316                 .data = configuration_descriptor,
    317                 .size = configuration_descriptor_size,
     304        const usb_dp_parser_data_t dp_data = {
     305                .data = config_descriptor,
     306                .size = config_descriptor_size,
    318307                .arg = connection
    319308        };
     
    322311         * Iterate through all interfaces.
    323312         */
    324         uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,
    325             &dp_data, configuration_descriptor);
     313        const uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,
     314            &dp_data, config_descriptor);
    326315        if (interface == NULL) {
    327316                return ENOENT;
     
    329318        do {
    330319                (void) process_interface(mapping, mapping_count,
    331                     &dp_parser, &dp_data,
    332                     interface);
     320                    &dp_parser, &dp_data, interface);
    333321                interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
    334                     configuration_descriptor, interface);
     322                    config_descriptor, interface);
    335323        } while (interface != NULL);
    336324
    337325        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;
    393326}
    394327
     
    414347        }
    415348
    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;
    421349
    422350        usb_pipe_start_long_transfer(pipe);
     
    424352        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
    425353        size_t transferred_size;
    426         TRY_LOOP(failed_attempts) {
     354        int rc;
     355        for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) {
    427356                rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
    428357                    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
     
    448377}
    449378
    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 #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 _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(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 
    529379/**
    530380 * @}
Note: See TracChangeset for help on using the changeset viewer.