Changeset 9efad54 in mainline for uspace/lib/usbdev/src


Ignore:
Timestamp:
2018-01-06T21:15:48Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
56257ba
Parents:
c901632
Message:

usb: move endpoint descriptor parsing to HC

This better separates responsibilities. Now the device driver does not
care about the contents of an endpoint descriptor, and HC can parse the
values according to device's actual speed.

Currently, it is device driver's responsibility to fetch endpoint
descriptors, map them and register pipes - sending the endpoint
descriptor back to HC. HC then parses it, and fills the pipe
description, which then sends back to device driver. We shall probably
fetch the endpoint descriptor from inside the HC (also fixing the USB
spec violation of communication with EP0).

Location:
uspace/lib/usbdev/src
Files:
4 edited

Legend:

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

    rc901632 r9efad54  
    255255
    256256        /* Register created pipes. */
     257        unsigned pipes_registered = 0;
    257258        for (size_t i = 0; i < pipe_count; i++) {
    258259                if (pipes[i].present) {
    259                         rc = usb_pipe_register(&pipes[i].pipe);
     260                        rc = usb_pipe_register(&pipes[i].pipe, pipes[i].descriptor, pipes[i].companion_descriptor);
    260261                        if (rc != EOK) {
    261262                                goto rollback_unregister_endpoints;
    262263                        }
    263264                }
     265                pipes_registered++;
    264266        }
    265267
     
    276278         */
    277279rollback_unregister_endpoints:
    278         for (size_t i = 0; i < pipe_count; i++) {
     280        for (size_t i = 0; i < pipes_registered; i++) {
    279281                if (pipes[i].present) {
    280282                        usb_pipe_unregister(&pipes[i].pipe);
     
    419421        /* This pipe was registered by the hub driver,
    420422         * during device initialization. */
    421         int rc = usb_pipe_initialize_default_control(
    422             &usb_dev->ctrl_pipe, usb_dev->bus_session);
     423        int rc = usb_pipe_initialize_default_control(&usb_dev->ctrl_pipe, usb_dev->bus_session);
    423424        if (rc != EOK) {
    424425                usb_dev_disconnect(usb_dev->bus_session);
  • uspace/lib/usbdev/src/devpoll.c

    rc901632 r9efad54  
    9696                    (int) mapping->interface->interface_subclass,
    9797                    (int) mapping->interface->interface_protocol,
    98                     data->request_size, pipe->desc.max_packet_size);
     98                    data->request_size, pipe->desc.max_transfer_size);
    9999        }
    100100
  • uspace/lib/usbdev/src/pipes.c

    rc901632 r9efad54  
    272272 * @param pipe Endpoint pipe to be initialized.
    273273 * @param bus_session Endpoint pipe to be initialized.
    274  * @param ep_desc Prepared endpoint descriptor
    275  * @return Error code.
    276  */
    277 int usb_pipe_initialize(usb_pipe_t *pipe,
    278     usb_dev_session_t *bus_session,
    279     const usb_endpoint_desc_t *ep_desc)
    280 {
    281         int ret = EOK;
    282         assert(pipe);
    283 
    284         pipe->desc = *ep_desc;
     274 * @return Error code.
     275 */
     276int usb_pipe_initialize(usb_pipe_t *pipe, usb_dev_session_t *bus_session, usb_transfer_type_t transfer_type)
     277{
     278        assert(pipe);
     279
    285280        pipe->auto_reset_halt = false;
    286281        pipe->bus_session = bus_session;
    287282
    288         if (pipe->desc.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
    289                 ret = usb_isoch_session_initialize(pipe);
    290         }
    291 
    292         return ret;
    293 }
    294 
    295 static const usb_endpoint_desc_t default_control_ep_desc = {
    296         .max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
     283        if (transfer_type == USB_TRANSFER_ISOCHRONOUS)
     284                return usb_isoch_session_initialize(pipe);
     285
     286        return EOK;
     287}
     288
     289static const usb_pipe_desc_t default_control_pipe = {
     290        .endpoint_no = 0,
     291        .transfer_type = USB_TRANSFER_CONTROL,
    297292        .direction = USB_DIRECTION_BOTH,
    298         .packets = 1,
     293        .max_transfer_size = CTRL_PIPE_MIN_PACKET_SIZE,
    299294};
    300295
    301 /** Initialize USB endpoint pipe as the default zero control pipe.
     296/** Initialize USB default control pipe.
     297 *
     298 * This one is special because it must not be registered, it is registered automatically.
    302299 *
    303300 * @param pipe Endpoint pipe to be initialized.
    304  * @param bus_session
     301 * @param bus_session Endpoint pipe to be initialized.
    305302 * @return Error code.
    306303 */
    307304int usb_pipe_initialize_default_control(usb_pipe_t *pipe, usb_dev_session_t *bus_session)
    308305{
    309         return usb_pipe_initialize(pipe, bus_session, &default_control_ep_desc);
     306        const int ret = usb_pipe_initialize(pipe, bus_session, USB_TRANSFER_CONTROL);
     307        if (ret)
     308                return ret;
     309
     310        pipe->desc = default_control_pipe;
     311
     312        return EOK;
    310313}
    311314
     
    313316 *
    314317 * @param pipe Pipe to be registered.
    315  * @param interval Polling interval.
    316  * @return Error code.
    317  */
    318 int usb_pipe_register(usb_pipe_t *pipe)
     318 * @param ep_desc Matched endpoint descriptor
     319 * @param comp_desc Matched superspeed companion descriptro, if any
     320 * @return Error code.
     321 */
     322int usb_pipe_register(usb_pipe_t *pipe, const usb_standard_endpoint_descriptor_t *ep_desc, const usb_superspeed_endpoint_companion_descriptor_t *comp_desc)
    319323{
    320324        assert(pipe);
    321325        assert(pipe->bus_session);
     326        assert(ep_desc);
    322327
    323328        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     
    325330                return ENOMEM;
    326331
    327         const int ret = usbhc_register_endpoint(exch, &pipe->desc);
    328 
     332        usb_endpoint_descriptors_t descriptors;
     333
     334#define COPY(field) descriptors.endpoint.field = ep_desc->field
     335        COPY(endpoint_address);
     336        COPY(attributes);
     337        COPY(max_packet_size);
     338        COPY(poll_interval);
     339#undef COPY
     340
     341#define COPY(field) descriptors.companion.field = comp_desc->field
     342        if (comp_desc) {
     343                COPY(max_burst);
     344                COPY(attributes);
     345                COPY(bytes_per_interval);
     346        }
     347#undef COPY
     348
     349        const int ret = usbhc_register_endpoint(exch, &pipe->desc, &descriptors);
    329350        async_exchange_end(exch);
    330351        return ret;
  • uspace/lib/usbdev/src/pipesinit.c

    rc901632 r9efad54  
    156156}
    157157
    158 static void parse_endpoint_descriptors(usb_endpoint_desc_t *ep_desc,
    159     usb_standard_endpoint_descriptor_t *endpoint_desc,
    160     usb_superspeed_endpoint_companion_descriptor_t *companion_desc)
    161 {
    162         *ep_desc = (usb_endpoint_desc_t) {
    163                 /* Actual endpoint number is in bits 0..3 */
    164                 .endpoint_no = endpoint_desc->endpoint_address & 0x0F,
    165                 /* Transfer type is in bits 0..2 and
    166                  * the enum values corresponds 1:1 */
    167                 .transfer_type = endpoint_desc->attributes & 3,
    168                 /* Endpoint direction is set by bit 7 */
    169                 .direction = (endpoint_desc->endpoint_address & 128)
    170                     ? USB_DIRECTION_IN : USB_DIRECTION_OUT,
    171                 // FIXME: USB2 max_packet_size is limited to 1023 bytes, 1024+ doesn't work for USB3
    172                 // See 4.14.2.1.1 of XHCI specification -> possibly refactor into one somehow-named field
    173                 .max_packet_size
    174                         = ED_MPS_PACKET_SIZE_GET(uint16_usb2host(endpoint_desc->max_packet_size)),
    175                 .interval = endpoint_desc->poll_interval,
    176                 // FIXME: USB2 packets and USB3 max_burst are probably the same thing
    177                 .packets = ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(endpoint_desc->max_packet_size)),
    178         };
    179 
    180         if (companion_desc) {
    181                 ep_desc->usb3 = (usb3_endpoint_desc_t) {
    182                         .max_burst = companion_desc->max_burst,
    183                         .max_streams
    184                                 = SS_COMPANION_MAX_STREAMS(companion_desc->attributes),
    185                         .bytes_per_interval
    186                                 = companion_desc->bytes_per_interval,
    187                         .mult = SS_COMPANION_MULT(companion_desc->attributes),
    188                 };
    189         }
    190 }
    191 
    192 
    193158/** Process endpoint descriptor.
    194159 *
     
    211176         * Get endpoint characteristics.
    212177         */
    213         usb_endpoint_desc_t ep_desc;
    214         parse_endpoint_descriptors(&ep_desc, endpoint_desc, companion_desc);
    215 
    216178        const usb_endpoint_description_t description = {
    217                 .direction = ep_desc.direction,
    218                 .transfer_type = ep_desc.transfer_type,
     179                .transfer_type = USB_ED_GET_TRANSFER_TYPE(*endpoint_desc),
     180                .direction = USB_ED_GET_DIR(*endpoint_desc),
    219181
    220182                /* Get interface characteristics. */
     
    238200        }
    239201
    240         int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session, &ep_desc);
     202        int err = usb_pipe_initialize(&ep_mapping->pipe, bus_session, description.transfer_type);
    241203        if (err)
    242204                return err;
Note: See TracChangeset for help on using the changeset viewer.