Ignore:
File:
1 edited

Legend:

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

    rb7fd2a0 r1a2227d  
    3838#include <usb/dev/request.h>
    3939#include <usb/usb.h>
     40#include <usb/debug.h>
    4041#include <usb/descriptor.h>
    4142
     
    5960        NESTING(INTERFACE, HID),
    6061        NESTING(HID, HID_REPORT),
     62        NESTING(ENDPOINT, SSPEED_EP_COMPANION),
    6163        LAST_NESTING
    6264};
     
    7072{
    7173        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 */
     81static inline bool is_superspeed_companion_descriptor(const uint8_t *descriptor)
     82{
     83        return descriptor[1] == USB_DESCTYPE_SSPEED_EP_COMPANION;
    7284}
    7385
     
    134146                if (interface_number_fits
    135147                    && interface_setting_fits
    136                     && endpoint_descriptions_fits) {
     148                    && endpoint_descriptions_fits
     149                    && !mapping->present) {
    137150                        return mapping;
    138151                }
     
    141154                mapping_count--;
    142155        }
     156
    143157        return NULL;
    144158}
     
    150164 * @param interface Interface descriptor under which belongs the @p endpoint.
    151165 * @param endpoint Endpoint descriptor.
     166 * @param companion Superspeed companion descriptor.
    152167 * @return Error code.
    153168 */
    154 static errno_t process_endpoint(
     169static int process_endpoint(
    155170    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    156171    usb_standard_interface_descriptor_t *interface,
    157172    usb_standard_endpoint_descriptor_t *endpoint_desc,
     173    usb_superspeed_endpoint_companion_descriptor_t *companion_desc,
    158174    usb_dev_session_t *bus_session)
    159175{
     
    162178         * Get endpoint characteristics.
    163179         */
    164 
    165         /* Actual endpoint number is in bits 0..3 */
    166         const usb_endpoint_t ep_no = endpoint_desc->endpoint_address & 0x0F;
    167 
    168180        const usb_endpoint_description_t description = {
    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,
     181                .transfer_type = USB_ED_GET_TRANSFER_TYPE(*endpoint_desc),
     182                .direction = USB_ED_GET_DIR(*endpoint_desc),
    175183
    176184                /* Get interface characteristics. */
     
    194202        }
    195203
    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         }
     204        int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session);
     205        if (err)
     206                return err;
    206207
    207208        ep_mapping->present = true;
    208209        ep_mapping->descriptor = endpoint_desc;
     210        ep_mapping->companion_descriptor = companion_desc;
    209211        ep_mapping->interface = interface;
    210212
     
    221223 * @return Error code.
    222224 */
    223 static errno_t process_interface(
     225static int process_interface(
    224226    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    225227    const usb_dp_parser_t *parser, const usb_dp_parser_data_t *parser_data,
     
    235237        do {
    236238                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
    237247                        (void) process_endpoint(mapping, mapping_count,
    238248                            (usb_standard_interface_descriptor_t *)
     
    240250                            (usb_standard_endpoint_descriptor_t *)
    241251                                descriptor,
     252                            (usb_superspeed_endpoint_companion_descriptor_t *)
     253                                companion_desc,
    242254                            bus_session);
    243255                }
     
    281293 * @return Error code.
    282294 */
    283 errno_t usb_pipe_initialize_from_configuration(
     295int usb_pipe_initialize_from_configuration(
    284296    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    285297    const uint8_t *config_descriptor, size_t config_descriptor_size,
     
    288300        if (config_descriptor == NULL)
    289301                return EBADMEM;
    290        
     302
    291303        if (config_descriptor_size <
    292304            sizeof(usb_standard_configuration_descriptor_t)) {
     
    328340}
    329341
    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  */
    340 errno_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 
    377342/**
    378343 * @}
Note: See TracChangeset for help on using the changeset viewer.