Ignore:
File:
1 edited

Legend:

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

    r1a2227d rb7fd2a0  
    3838#include <usb/dev/request.h>
    3939#include <usb/usb.h>
    40 #include <usb/debug.h>
    4140#include <usb/descriptor.h>
    4241
     
    6059        NESTING(INTERFACE, HID),
    6160        NESTING(HID, HID_REPORT),
    62         NESTING(ENDPOINT, SSPEED_EP_COMPANION),
    6361        LAST_NESTING
    6462};
     
    7270{
    7371        return descriptor[1] == USB_DESCTYPE_ENDPOINT;
    74 }
    75 
    76 /** Tells whether given descriptor is of superspeed companion type.
    77  *
    78  * @param descriptor Descriptor in question.
    79  * @return Whether the given descriptor is superspeed companion descriptor.
    80  */
    81 static inline bool is_superspeed_companion_descriptor(const uint8_t *descriptor)
    82 {
    83         return descriptor[1] == USB_DESCTYPE_SSPEED_EP_COMPANION;
    8472}
    8573
     
    146134                if (interface_number_fits
    147135                    && interface_setting_fits
    148                     && endpoint_descriptions_fits
    149                     && !mapping->present) {
     136                    && endpoint_descriptions_fits) {
    150137                        return mapping;
    151138                }
     
    154141                mapping_count--;
    155142        }
    156 
    157143        return NULL;
    158144}
     
    164150 * @param interface Interface descriptor under which belongs the @p endpoint.
    165151 * @param endpoint Endpoint descriptor.
    166  * @param companion Superspeed companion descriptor.
    167152 * @return Error code.
    168153 */
    169 static int process_endpoint(
     154static errno_t process_endpoint(
    170155    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    171156    usb_standard_interface_descriptor_t *interface,
    172157    usb_standard_endpoint_descriptor_t *endpoint_desc,
    173     usb_superspeed_endpoint_companion_descriptor_t *companion_desc,
    174158    usb_dev_session_t *bus_session)
    175159{
     
    178162         * Get endpoint characteristics.
    179163         */
     164
     165        /* Actual endpoint number is in bits 0..3 */
     166        const usb_endpoint_t ep_no = endpoint_desc->endpoint_address & 0x0F;
     167
    180168        const usb_endpoint_description_t description = {
    181                 .transfer_type = USB_ED_GET_TRANSFER_TYPE(*endpoint_desc),
    182                 .direction = USB_ED_GET_DIR(*endpoint_desc),
     169                /* Endpoint direction is set by bit 7 */
     170                .direction = (endpoint_desc->endpoint_address & 128)
     171                    ? USB_DIRECTION_IN : USB_DIRECTION_OUT,
     172                /* Transfer type is in bits 0..2 and
     173                 * the enum values corresponds 1:1 */
     174                .transfer_type = endpoint_desc->attributes & 3,
    183175
    184176                /* Get interface characteristics. */
     
    202194        }
    203195
    204         int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session);
    205         if (err)
    206                 return err;
     196        errno_t rc = usb_pipe_initialize(&ep_mapping->pipe,
     197            ep_no, description.transfer_type,
     198            ED_MPS_PACKET_SIZE_GET(
     199                uint16_usb2host(endpoint_desc->max_packet_size)),
     200            description.direction,
     201            ED_MPS_TRANS_OPPORTUNITIES_GET(
     202                uint16_usb2host(endpoint_desc->max_packet_size)), bus_session);
     203        if (rc != EOK) {
     204                return rc;
     205        }
    207206
    208207        ep_mapping->present = true;
    209208        ep_mapping->descriptor = endpoint_desc;
    210         ep_mapping->companion_descriptor = companion_desc;
    211209        ep_mapping->interface = interface;
    212210
     
    223221 * @return Error code.
    224222 */
    225 static int process_interface(
     223static errno_t process_interface(
    226224    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    227225    const usb_dp_parser_t *parser, const usb_dp_parser_data_t *parser_data,
     
    237235        do {
    238236                if (is_endpoint_descriptor(descriptor)) {
    239                         /* Check if companion descriptor is present too, it should immediatelly follow. */
    240                         const uint8_t *companion_desc = usb_dp_get_nested_descriptor(parser,
    241                                 parser_data, descriptor);
    242                         if (companion_desc && !is_superspeed_companion_descriptor(companion_desc)) {
    243                                 /* Not what we wanted, don't pass it further. */
    244                                 companion_desc = NULL;
    245                         }
    246 
    247237                        (void) process_endpoint(mapping, mapping_count,
    248238                            (usb_standard_interface_descriptor_t *)
     
    250240                            (usb_standard_endpoint_descriptor_t *)
    251241                                descriptor,
    252                             (usb_superspeed_endpoint_companion_descriptor_t *)
    253                                 companion_desc,
    254242                            bus_session);
    255243                }
     
    293281 * @return Error code.
    294282 */
    295 int usb_pipe_initialize_from_configuration(
     283errno_t usb_pipe_initialize_from_configuration(
    296284    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    297285    const uint8_t *config_descriptor, size_t config_descriptor_size,
     
    300288        if (config_descriptor == NULL)
    301289                return EBADMEM;
    302 
     290       
    303291        if (config_descriptor_size <
    304292            sizeof(usb_standard_configuration_descriptor_t)) {
     
    340328}
    341329
     330/** Probe default control pipe for max packet size.
     331 *
     332 * The function tries to get the correct value of max packet size several
     333 * time before giving up.
     334 *
     335 * The session on the pipe shall not be started.
     336 *
     337 * @param pipe Default control pipe.
     338 * @return Error code.
     339 */
     340errno_t usb_pipe_probe_default_control(usb_pipe_t *pipe)
     341{
     342        assert(pipe);
     343        static_assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
     344
     345        if ((pipe->direction != USB_DIRECTION_BOTH) ||
     346            (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
     347            (pipe->endpoint_no != 0)) {
     348                return EINVAL;
     349        }
     350
     351        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
     352        size_t transferred_size;
     353        errno_t rc;
     354        for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) {
     355                rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
     356                    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
     357                    0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE,
     358                    &transferred_size);
     359                if (rc == EOK) {
     360                        if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) {
     361                                rc = ELIMIT;
     362                                continue;
     363                        }
     364                        break;
     365                }
     366        }
     367        if (rc != EOK) {
     368                return rc;
     369        }
     370
     371        pipe->max_packet_size
     372            = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
     373
     374        return EOK;
     375}
     376
    342377/**
    343378 * @}
Note: See TracChangeset for help on using the changeset viewer.