Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 9efad54 in mainline


Ignore:
Timestamp:
2018-01-06T21:15:48Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
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
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/block/usbmast/main.c

    rc901632 r9efad54  
    172172            usb_device_get_name(dev));
    173173        usb_log_debug("Bulk in endpoint: %d [%zuB].\n",
    174             epm_in->pipe.desc.endpoint_no, epm_in->pipe.desc.max_packet_size);
     174            epm_in->pipe.desc.endpoint_no, epm_in->pipe.desc.max_transfer_size);
    175175        usb_log_debug("Bulk out endpoint: %d [%zuB].\n",
    176             epm_out->pipe.desc.endpoint_no, epm_out->pipe.desc.max_packet_size);
     176            epm_out->pipe.desc.endpoint_no, epm_out->pipe.desc.max_transfer_size);
    177177
    178178        usb_log_debug("Get LUN count...\n");
  • uspace/drv/bus/usb/ehci/ehci_bus.c

    rc901632 r9efad54  
    7878/** Creates new hcd endpoint representation.
    7979 */
    80 static endpoint_t *ehci_endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc)
     80static endpoint_t *ehci_endpoint_create(device_t *dev, const usb_endpoint_descriptors_t *desc)
    8181{
    8282        assert(dev);
  • uspace/drv/bus/usb/ehci/hw_struct/queue_head.c

    rc901632 r9efad54  
    8282        }
    8383        uint32_t ep_cap = QH_EP_CAP_C_MASK_SET(3 << 2) |
    84                     QH_EP_CAP_MULTI_SET(ep->packets);
     84                    QH_EP_CAP_MULTI_SET(ep->packets_per_uframe);
    8585        if (ep->device->speed != USB_SPEED_HIGH) {
    8686                ep_cap |=
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    rc901632 r9efad54  
    7272/** Creates new hcd endpoint representation.
    7373 */
    74 static endpoint_t *ohci_endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc)
     74static endpoint_t *ohci_endpoint_create(device_t *dev, const usb_endpoint_descriptors_t *desc)
    7575{
    7676        assert(dev);
  • uspace/drv/bus/usb/xhci/bus.c

    rc901632 r9efad54  
    5151
    5252/** Initial descriptor used for control endpoint 0 before more configuration is retrieved. */
    53 static const usb_endpoint_desc_t ep0_initial_desc = {
    54         .endpoint_no = 0,
    55         .direction = USB_DIRECTION_BOTH,
    56         .transfer_type = USB_TRANSFER_CONTROL,
    57         .max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
    58         .packets = 1,
     53static const usb_endpoint_descriptors_t ep0_initial_desc = {
     54        .endpoint.max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
    5955};
    6056
    61 static endpoint_t *endpoint_create(device_t *, const usb_endpoint_desc_t *);
     57static endpoint_t *endpoint_create(device_t *, const usb_endpoint_descriptors_t *);
    6258
    6359/** Assign address and control endpoint to a new XHCI device.
     
    368364}
    369365
    370 static endpoint_t *endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc)
     366static endpoint_t *endpoint_create(device_t *dev, const usb_endpoint_descriptors_t *desc)
    371367{
    372368        xhci_endpoint_t *ep = calloc(1, sizeof(xhci_endpoint_t));
  • uspace/drv/bus/usb/xhci/endpoint.c

    rc901632 r9efad54  
    5252 * @return Error code.
    5353 */
    54 int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, device_t *dev, const usb_endpoint_desc_t *desc)
     54int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, device_t *dev, const usb_endpoint_descriptors_t *desc)
    5555{
    5656        assert(xhci_ep);
     
    6060        endpoint_init(ep, dev, desc);
    6161
    62         xhci_ep->max_streams = desc->usb3.max_streams;
    63         xhci_ep->max_burst = desc->usb3.max_burst;
    64         xhci_ep->mult = desc->usb3.mult;
    65 
    66         // TODO: process according to 6.2.3.6 of XHCI specification; hardcoded for HS/SS EPs
    67         xhci_ep->interval = desc->interval - 1;
     62        xhci_ep->max_streams = USB_SSC_MAX_STREAMS(desc->companion);
     63        xhci_ep->max_burst = desc->companion.max_burst + 1;
     64        xhci_ep->mult = USB_SSC_MULT(desc->companion) + 1;
     65
     66        /* In USB 3, the semantics of wMaxPacketSize changed. Now the number of
     67         * packets per service interval is determined from max_burst and mult.
     68         */
     69        if (dev->speed >= USB_SPEED_SUPER) {
     70                ep->packets_per_uframe = xhci_ep->max_burst * xhci_ep->mult;
     71                ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe;
     72        }
     73
     74        xhci_ep->interval = desc->endpoint.poll_interval;
     75        /* Only Low/Full speed interrupt endpoints have interval set directly,
     76         * others have 2-based log of it.
     77         */
     78        if (dev->speed >= USB_SPEED_HIGH || ep->transfer_type != USB_TRANSFER_INTERRUPT) {
     79                xhci_ep->interval = 1 << (xhci_ep->interval - 1);
     80        }
    6881
    6982        if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
    70                 xhci_ep->isoch_max_size = desc->usb3.bytes_per_interval
    71                         ? desc->usb3.bytes_per_interval
    72                         : desc->max_packet_size * (desc->packets + 1);
     83                xhci_ep->isoch_max_size = desc->companion.bytes_per_interval
     84                        ? desc->companion.bytes_per_interval
     85                        : ep->max_transfer_size;
    7386                /* Technically there could be superspeed plus too. */
    7487
     
    497510        dev->endpoints[ep->base.endpoint] = NULL;
    498511        ep->base.device = NULL;
    499 
    500         endpoint_del_ref(&ep->base);
    501512}
    502513
  • uspace/drv/bus/usb/xhci/endpoint.h

    rc901632 r9efad54  
    149149#define XHCI_DEV_ARGS(dev)               ddf_fun_get_name((dev).base.fun), (dev).slot_id
    150150
    151 int xhci_endpoint_init(xhci_endpoint_t *, device_t *, const usb_endpoint_desc_t *);
     151int xhci_endpoint_init(xhci_endpoint_t *, device_t *, const usb_endpoint_descriptors_t *);
    152152void xhci_endpoint_fini(xhci_endpoint_t *);
    153153int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *);
  • uspace/drv/hid/usbhid/main.c

    rc901632 r9efad54  
    9595           usb_hid_polling_callback,
    9696           /* How much data to request. */
    97            hid_dev->poll_pipe_mapping->pipe.desc.max_packet_size,
     97           hid_dev->poll_pipe_mapping->pipe.desc.max_transfer_size,
    9898           /* Delay */
    9999           -1,
  • uspace/lib/drv/generic/remote_usbhc.c

    rc901632 r9efad54  
    116116}
    117117
    118 int static_assert[sizeof(sysarg_t) >= 4 ? 1 : -1];
    119 typedef union {
    120         uint8_t arr[sizeof(sysarg_t)];
    121         sysarg_t arg;
    122 } pack8_t;
    123 
    124 int usbhc_register_endpoint(async_exch_t *exch,
    125         usb_endpoint_desc_t *endpoint_desc)
    126 {
    127         if (!exch)
    128                 return EBADMEM;
     118int usbhc_register_endpoint(async_exch_t *exch, usb_pipe_desc_t *pipe_desc,
     119    const usb_endpoint_descriptors_t *desc)
     120{
     121        if (!exch)
     122                return EBADMEM;
     123
     124        if (!desc)
     125                return EINVAL;
    129126
    130127        aid_t opening_request = async_send_1(exch,
     
    135132        }
    136133
    137         const int ret = async_data_write_start(exch, (void *) endpoint_desc,
    138                 sizeof(usb_endpoint_desc_t));
    139 
     134        int ret = async_data_write_start(exch, desc, sizeof(*desc));
    140135        if (ret != EOK) {
    141136                async_forget(opening_request);
     
    147142        async_wait_for(opening_request, &opening_request_rc);
    148143
    149         return (int) opening_request_rc;
    150 }
    151 
    152 int usbhc_unregister_endpoint(async_exch_t *exch,
    153         usb_endpoint_desc_t *endpoint_desc)
     144        if (opening_request_rc)
     145                return (int) opening_request_rc;
     146
     147        usb_pipe_desc_t dest;
     148        ret = async_data_read_start(exch, &dest, sizeof(dest));
     149        if (ret != EOK) {
     150                return ret;
     151        }
     152
     153        if (pipe_desc)
     154                *pipe_desc = dest;
     155
     156        return EOK;
     157}
     158
     159int usbhc_unregister_endpoint(async_exch_t *exch, const usb_pipe_desc_t *pipe_desc)
    154160{
    155161        if (!exch)
     
    163169        }
    164170
    165         const int ret = async_data_write_start(exch, endpoint_desc,
    166                 sizeof(usb_endpoint_desc_t));
     171        const int ret = async_data_write_start(exch, pipe_desc, sizeof(*pipe_desc));
    167172        if (ret != EOK) {
    168173                async_forget(opening_request);
     
    368373        }
    369374
    370         void *buffer = NULL;
    371         size_t size = 0;
    372         int rc = async_data_write_accept(&buffer, false,
    373                 sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size);
    374 
    375         if (rc != EOK) {
    376                 free(buffer);
    377                 async_answer_0(callid, rc);
    378                 return;
    379         }
    380 
    381         usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer;
    382         rc = usbhc_iface->register_endpoint(fun, endpoint_desc);
    383 
    384         free(buffer);
     375        usb_endpoint_descriptors_t ep_desc;
     376        ipc_callid_t data_callid;
     377        size_t len;
     378
     379        if (!async_data_write_receive(&data_callid, &len)
     380            || len != sizeof(ep_desc)) {
     381                async_answer_0(callid, EINVAL);
     382                return;
     383        }
     384        async_data_write_finalize(data_callid, &ep_desc, sizeof(ep_desc));
     385
     386        usb_pipe_desc_t pipe_desc;
     387
     388        const int rc = usbhc_iface->register_endpoint(fun, &pipe_desc, &ep_desc);
    385389        async_answer_0(callid, rc);
     390
     391        if (!async_data_read_receive(&data_callid, &len)
     392            || len != sizeof(pipe_desc)) {
     393                return;
     394        }
     395        async_data_read_finalize(data_callid, &pipe_desc, sizeof(pipe_desc));
    386396}
    387397
     
    400410        }
    401411
    402         void *buffer = NULL;
    403         size_t size = 0;
    404         int rc = async_data_write_accept(&buffer, false,
    405                 sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size);
    406 
    407         if (rc != EOK) {
    408                 free(buffer);
    409                 async_answer_0(callid, rc);
    410                 return;
    411         }
    412 
    413         usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer;
    414         usbhc_iface->unregister_endpoint(fun, endpoint_desc);
    415 
    416         free(buffer);
     412        usb_pipe_desc_t pipe_desc;
     413        ipc_callid_t data_callid;
     414        size_t len;
     415
     416        if (!async_data_write_receive(&data_callid, &len)
     417            || len != sizeof(pipe_desc)) {
     418                async_answer_0(callid, EINVAL);
     419                return;
     420        }
     421        async_data_write_finalize(data_callid, &pipe_desc, sizeof(pipe_desc));
     422
     423        const int rc = usbhc_iface->unregister_endpoint(fun, &pipe_desc);
    417424        async_answer_0(callid, rc);
    418425}
  • uspace/lib/drv/include/usb_iface.h

    rc901632 r9efad54  
    100100} usb_target_t;
    101101
    102 /** Description of an usb endpoint.
    103  */
    104 typedef struct {
    105         unsigned max_burst;
    106         unsigned max_streams;
    107         unsigned mult;
    108         unsigned bytes_per_interval;
    109 } usb3_endpoint_desc_t;
    110 
    111 typedef struct usb_endpoint_desc {
    112         /** Endpoint number. */
    113         usb_endpoint_t endpoint_no;
    114 
    115         /** Endpoint transfer type. */
    116         usb_transfer_type_t transfer_type;
    117 
    118         /** Endpoint direction. */
    119         usb_direction_t direction;
    120 
    121         /** Maximum packet size for the endpoint. */
    122         size_t max_packet_size;
    123 
    124         /** Scheduling interval for HC. Only valid for interrupt/isoch transfer. */
    125         size_t interval;
    126 
    127         /** Number of packets per frame/uframe.
    128          * Only valid for HS INT and ISO transfers. All others should set to 1*/
    129         unsigned packets;
    130 
    131         /** Superspeed-specific information */
    132         usb3_endpoint_desc_t usb3;
    133 } usb_endpoint_desc_t;
    134 
    135 
    136102extern usb_dev_session_t *usb_dev_connect(devman_handle_t);
    137103extern usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *);
  • uspace/lib/drv/include/usbhc_iface.h

    rc901632 r9efad54  
    4444#include <async.h>
    4545
     46typedef struct usb_pipe_desc {
     47        /** Endpoint number. */
     48        usb_endpoint_t endpoint_no;
     49
     50        /** Endpoint transfer type. */
     51        usb_transfer_type_t transfer_type;
     52
     53        /** Endpoint direction. */
     54        usb_direction_t direction;
     55
     56        /** Maximum size of one transfer */
     57        size_t max_transfer_size;
     58} usb_pipe_desc_t;
     59
     60/** This structure follows standard endpoint descriptor + superspeed companion
     61 * descriptor, and exists to avoid dependency of libdrv on libusb. Keep the
     62 * internal fields named exactly like their source (because we want to use the
     63 * same macros to access them).
     64 * Callers shall fill it with bare contents of respective descriptors (in usb endianity).
     65 */
     66typedef struct {
     67        struct {
     68                uint8_t endpoint_address;
     69                uint8_t attributes;
     70                uint16_t max_packet_size;
     71                uint8_t poll_interval;
     72        } endpoint;
     73
     74        /* Superspeed companion descriptor */
     75        struct companion_desc_t {
     76                uint8_t max_burst;
     77                uint8_t attributes;
     78                uint16_t bytes_per_interval;
     79        } companion;
     80} usb_endpoint_descriptors_t;
     81
    4682extern int usbhc_reserve_default_address(async_exch_t *, usb_speed_t);
    4783extern int usbhc_release_default_address(async_exch_t *);
     
    5086extern int usbhc_device_remove(async_exch_t *, unsigned port);
    5187
    52 extern int usbhc_register_endpoint(async_exch_t *, usb_endpoint_desc_t *);
    53 extern int usbhc_unregister_endpoint(async_exch_t *, usb_endpoint_desc_t *);
     88extern int usbhc_register_endpoint(async_exch_t *, usb_pipe_desc_t *, const usb_endpoint_descriptors_t *);
     89extern int usbhc_unregister_endpoint(async_exch_t *, const usb_pipe_desc_t *);
     90
    5491extern int usbhc_read(async_exch_t *, usb_endpoint_t, uint64_t, void *, size_t,
    5592    size_t *);
     
    68105        int (*device_remove)(ddf_fun_t *, unsigned);
    69106
    70         int (*register_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
    71         int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
     107        int (*register_endpoint)(ddf_fun_t *, usb_pipe_desc_t *, const usb_endpoint_descriptors_t *);
     108        int (*unregister_endpoint)(ddf_fun_t *, const usb_pipe_desc_t *);
    72109
    73110        int (*read)(ddf_fun_t *, usb_target_t,
  • uspace/lib/usb/include/usb/descriptor.h

    rc901632 r9efad54  
    200200        /** Endpoint address together with data flow direction. */
    201201        uint8_t endpoint_address;
     202#define USB_ED_GET_EP(ed)       ((ed).endpoint_address & 0xf)
     203#define USB_ED_GET_DIR(ed)      (!(((ed).endpoint_address >> 7) & 0x1))
     204
    202205        /** Endpoint attributes.
    203206         * Includes transfer type (usb_transfer_type_t).
    204207         */
    205208        uint8_t attributes;
     209#define USB_ED_GET_TRANSFER_TYPE(ed)    ((ed).attributes & 0x3)
    206210        /** Maximum packet size.
    207211         * Lower 10 bits represent the actuall size
     
    209213         * HS INT and ISO transfers. */
    210214        uint16_t max_packet_size;
    211 
    212 #define ED_MPS_PACKET_SIZE_MASK  0x3ff
    213 #define ED_MPS_PACKET_SIZE_GET(value) \
    214         ((value) & ED_MPS_PACKET_SIZE_MASK)
    215 #define ED_MPS_TRANS_OPPORTUNITIES_GET(value) \
    216         ((((value) >> 10) & 0x3) + 1)
    217 
     215#define USB_ED_GET_MPS(ed) \
     216        (uint16_usb2host((ed).max_packet_size) & 0x7ff)
     217#define USB_ED_GET_ADD_OPPS(ed) \
     218        ((uint16_usb2host((ed).max_packet_size) >> 11) & 0x3)
    218219        /** Polling interval in milliseconds.
    219220         * Ignored for bulk and control endpoints.
     
    246247         */
    247248        uint8_t attributes;
    248 #define SS_COMPANION_MAX_STREAMS(attributes) \
    249         (attributes & 0x1f)
    250 #define SS_COMPANION_MULT(attributes) \
    251         (attributes & 0x3)
     249#define USB_SSC_MAX_STREAMS(sscd) ((sscd).attributes & 0x1f)
     250#define USB_SSC_MULT(sscd) ((sscd).attributes & 0x3)
    252251        /** The total number of bytes this endpoint will transfer
    253252         * every service interval (SI).
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    rc901632 r9efad54  
    3737#include <usb/usb.h>
    3838#include <usb/descriptor.h>
    39 #include <usb_iface.h>
     39#include <usbhc_iface.h>
    4040
    4141#include <stdbool.h>
     
    4444
    4545#define CTRL_PIPE_MIN_PACKET_SIZE 8
     46
    4647/** Abstraction of a logical connection to USB device endpoint.
    47  * It encapsulates endpoint attributes (transfer type etc.).
     48 * It contains some vital information about the pipe.
    4849 * This endpoint must be bound with existing usb_device_connection_t
    4950 * (i.e. the wire to send data over).
    5051 */
    5152typedef struct {
    52         /** Endpoint description */
    53         usb_endpoint_desc_t desc;
     53        /** Pipe description received from HC */
     54        usb_pipe_desc_t desc;
     55
    5456        /** Whether to automatically reset halt on the endpoint.
    5557         * Valid only for control endpoint zero.
     
    100102} usb_endpoint_mapping_t;
    101103
    102 int usb_pipe_initialize(usb_pipe_t *, usb_dev_session_t *, const usb_endpoint_desc_t *);
     104int usb_pipe_initialize(usb_pipe_t *, usb_dev_session_t *, usb_transfer_type_t);
    103105int usb_pipe_initialize_default_control(usb_pipe_t *, usb_dev_session_t *);
    104106
     
    106108    size_t, const uint8_t *, size_t, usb_dev_session_t *);
    107109
    108 int usb_pipe_register(usb_pipe_t *);
     110int usb_pipe_register(usb_pipe_t *, const usb_standard_endpoint_descriptor_t *, const usb_superspeed_endpoint_companion_descriptor_t *);
    109111int usb_pipe_unregister(usb_pipe_t *);
    110112
  • 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;
  • uspace/lib/usbhost/include/usb/host/bus.h

    rc901632 r9efad54  
    109109        int (*device_offline)(device_t *);                      /**< Optional */
    110110        endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t);
    111         endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_desc_t *);
     111        endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_descriptors_t *);
    112112
    113113        /* Operations on endpoint */
     
    163163    const char *);
    164164
    165 int bus_endpoint_add(device_t *, const usb_endpoint_desc_t *, endpoint_t **);
     165int bus_endpoint_add(device_t *, const usb_endpoint_descriptors_t *, endpoint_t **);
    166166endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t);
    167167int bus_endpoint_remove(endpoint_t *);
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    rc901632 r9efad54  
    4646#include <usb/usb.h>
    4747#include <usb/host/bus.h>
     48#include <usbhc_iface.h>
    4849
    4950typedef struct bus bus_t;
     
    5960        /** Reference count. */
    6061        atomic_t refcnt;
    61         /** Enpoint number */
    62         usb_endpoint_t endpoint;
    63         /** Communication direction. */
    64         usb_direction_t direction;
    65         /** USB transfer type. */
    66         usb_transfer_type_t transfer_type;
    67         /** Maximum size of data packets. */
    68         size_t max_packet_size;
    69         /** Additional opportunities per uframe */
    70         unsigned packets;
    7162        /** Reserved bandwidth. */
    7263        size_t bandwidth;
     
    8071        fibril_condvar_t avail;
    8172
     73        /** Enpoint number */
     74        usb_endpoint_t endpoint;
     75        /** Communication direction. */
     76        usb_direction_t direction;
     77        /** USB transfer type. */
     78        usb_transfer_type_t transfer_type;
     79        /** Maximum size of one packet */
     80        size_t max_packet_size;
     81
     82        /** Maximum size of one transfer */
     83        size_t max_transfer_size;
     84        /** Number of packats that can be sent in one service interval (not necessarily uframe) */
     85        unsigned packets_per_uframe;
     86
    8287        /* This structure is meant to be extended by overriding. */
    8388} endpoint_t;
    8489
    85 extern void endpoint_init(endpoint_t *, device_t *, const usb_endpoint_desc_t *);
     90extern void endpoint_init(endpoint_t *, device_t *, const usb_endpoint_descriptors_t *);
    8691
    8792extern void endpoint_add_ref(endpoint_t *);
  • uspace/lib/usbhost/src/bus.c

    rc901632 r9efad54  
    128128}
    129129
    130 int bus_endpoint_add(device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep)
     130int bus_endpoint_add(device_t *device, const usb_endpoint_descriptors_t *desc, endpoint_t **out_ep)
    131131{
    132132        int err;
     
    134134
    135135        bus_t *bus = device->bus;
    136 
    137         if (desc->max_packet_size == 0 || desc->packets == 0) {
    138                 usb_log_warning("Invalid endpoint description (mps %zu, %u packets)", desc->max_packet_size, desc->packets);
    139                 return EINVAL;
    140         }
    141136
    142137        const bus_ops_t *create_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_create);
     
    149144                return ENOMEM;
    150145
    151         /* Temporary reference */
     146        /* Bus reference */
    152147        endpoint_add_ref(ep);
     148
     149        if (ep->max_transfer_size == 0) {
     150                usb_log_warning("Invalid endpoint description (mps %zu, "
     151                        "%u packets)", ep->max_packet_size, ep->packets_per_uframe);
     152                /* Bus reference */
     153                endpoint_del_ref(ep);
     154                return EINVAL;
     155        }
     156
     157        usb_log_debug("Register endpoint %d:%d %s-%s %zuB.\n",
     158            device->address, ep->endpoint,
     159            usb_str_transfer_type(ep->transfer_type),
     160            usb_str_direction(ep->direction),
     161            ep->max_transfer_size);
    153162
    154163        fibril_mutex_lock(&bus->guard);
     
    162171        }
    163172
    164         /* Temporary reference */
    165         endpoint_del_ref(ep);
    166173        return err;
    167174}
     
    193200{
    194201        assert(ep);
     202        assert(ep->device);
     203        assert(ep->device->bus);
     204        assert(ep->device->bus->ops);
    195205
    196206        bus_t *bus = endpoint_get_bus(ep);
    197207
    198         const bus_ops_t *ops = BUS_OPS_LOOKUP(ep->device->bus->ops, endpoint_unregister);
    199         if (!ops)
    200                 return ENOTSUP;
     208        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, endpoint_unregister);
     209        if (!ops)
     210                return ENOTSUP;
     211
     212        usb_log_debug("Unregister endpoint %d:%d %s-%s %zuB.\n",
     213            ep->device->address, ep->endpoint,
     214            usb_str_transfer_type(ep->transfer_type),
     215            usb_str_direction(ep->direction),
     216            ep->max_transfer_size);
    201217
    202218        fibril_mutex_lock(&bus->guard);
  • uspace/lib/usbhost/src/ddf_helpers.c

    rc901632 r9efad54  
    5050
    5151#include "bus.h"
     52#include "endpoint.h"
    5253
    5354#include "ddf_helpers.h"
     
    6566 * @return Error code.
    6667 */
    67 static int register_endpoint(
    68         ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
     68static int register_endpoint(ddf_fun_t *fun, usb_pipe_desc_t *pipe_desc,
     69     const usb_endpoint_descriptors_t *ep_desc)
    6970{
    7071        assert(fun);
     
    7576        assert(dev);
    7677
    77         usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n",
    78                 dev->address, endpoint_desc->endpoint_no,
    79                 usb_str_transfer_type(endpoint_desc->transfer_type),
    80                 usb_str_direction(endpoint_desc->direction),
    81                 endpoint_desc->max_packet_size, endpoint_desc->interval);
    82 
    83         return bus_endpoint_add(dev, endpoint_desc, NULL);
     78        endpoint_t *ep;
     79        const int err = bus_endpoint_add(dev, ep_desc, &ep);
     80        if (err)
     81                return err;
     82
     83        if (pipe_desc) {
     84                pipe_desc->endpoint_no = ep->endpoint;
     85                pipe_desc->direction = ep->direction;
     86                pipe_desc->transfer_type = ep->transfer_type;
     87                pipe_desc->max_transfer_size = ep->max_transfer_size;
     88        }
     89        endpoint_del_ref(ep);
     90
     91        return EOK;
    8492}
    8593
     
    8997  * @return Error code.
    9098  */
    91 static int unregister_endpoint(
    92         ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
     99static int unregister_endpoint(ddf_fun_t *fun, const usb_pipe_desc_t *endpoint_desc)
    93100{
    94101        assert(fun);
     
    103110                .endpoint = endpoint_desc->endpoint_no
    104111        }};
    105 
    106         usb_log_debug("Unregister endpoint %d:%d %s.\n",
    107                 dev->address, endpoint_desc->endpoint_no,
    108                 usb_str_direction(endpoint_desc->direction));
    109112
    110113        endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction);
  • uspace/lib/usbhost/src/endpoint.c

    rc901632 r9efad54  
    4141#include <str_error.h>
    4242#include <usb/debug.h>
     43#include <usb/descriptor.h>
    4344#include <usb/host/hcd.h>
    4445
     
    5051/** Initialize provided endpoint structure.
    5152 */
    52 void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_desc_t *desc)
     53void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_descriptors_t *desc)
    5354{
    5455        memset(ep, 0, sizeof(endpoint_t));
     
    6263        fibril_condvar_initialize(&ep->avail);
    6364
    64         ep->endpoint = desc->endpoint_no;
    65         ep->direction = desc->direction;
    66         ep->transfer_type = desc->transfer_type;
    67         ep->max_packet_size = desc->max_packet_size;
    68         ep->packets = desc->packets;
    69 
    70         ep->bandwidth = endpoint_count_bw(ep, desc->max_packet_size);
     65        ep->endpoint = USB_ED_GET_EP(desc->endpoint);
     66        ep->direction = USB_ED_GET_DIR(desc->endpoint);
     67        ep->transfer_type = USB_ED_GET_TRANSFER_TYPE(desc->endpoint);
     68        ep->max_packet_size = USB_ED_GET_MPS(desc->endpoint);
     69        ep->packets_per_uframe = USB_ED_GET_ADD_OPPS(desc->endpoint) + 1;
     70
     71        /** Direction both is our construct never present in descriptors */
     72        if (ep->transfer_type == USB_TRANSFER_CONTROL)
     73                ep->direction = USB_DIRECTION_BOTH;
     74
     75        ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe;
     76
     77        ep->bandwidth = endpoint_count_bw(ep, ep->max_transfer_size);
    7178}
    7279
  • uspace/lib/usbhost/src/usb2_bus.c

    rc901632 r9efad54  
    186186}
    187187
    188 static const usb_endpoint_desc_t usb2_default_control_ep = {
    189         .endpoint_no = 0,
    190         .transfer_type = USB_TRANSFER_CONTROL,
    191         .direction = USB_DIRECTION_BOTH,
    192         .max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
    193         .packets = 1,
    194 };
    195 
    196 
    197188static const usb_target_t usb2_default_target = {{
    198189        .address = USB_ADDRESS_DEFAULT,
     
    221212        usb_log_debug("Device(%d): Adding default target (0:0)", address);
    222213
     214        usb_endpoint_descriptors_t ep0_desc = {
     215            .endpoint.max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
     216        };
    223217        endpoint_t *default_ep;
    224         err = bus_endpoint_add(dev, &usb2_default_control_ep, &default_ep);
     218        err = bus_endpoint_add(dev, &ep0_desc, &default_ep);
    225219        if (err != EOK) {
    226220                usb_log_error("Device(%d): Failed to add default target: %s.",
     
    229223        }
    230224
    231         uint16_t max_packet_size;
    232         if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, &bus->base, dev)))
     225        if ((err = hcd_get_ep0_max_packet_size(&ep0_desc.endpoint.max_packet_size, &bus->base, dev)))
    233226                goto err_address;
    234227
     
    254247        dev->address = address;
    255248
    256         const usb_endpoint_desc_t control_ep = {
    257                 .endpoint_no = 0,
    258                 .transfer_type = USB_TRANSFER_CONTROL,
    259                 .direction = USB_DIRECTION_BOTH,
    260                 .max_packet_size = max_packet_size,
    261                 .packets = 1,
    262         };
    263 
    264249        /* Register EP on the new address */
    265250        usb_log_debug("Device(%d): Registering control EP.", address);
    266         err = bus_endpoint_add(dev, &control_ep, NULL);
     251        err = bus_endpoint_add(dev, &ep0_desc, NULL);
    267252        if (err != EOK) {
    268253                usb_log_error("Device(%d): Failed to register EP0: %s",
     
    352337}
    353338
    354 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_desc_t *desc)
     339static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc)
    355340{
    356341        endpoint_t *ep = malloc(sizeof(endpoint_t));
Note: See TracChangeset for help on using the changeset viewer.