Changeset 9efad54 in mainline for uspace/lib/drv


Ignore:
Timestamp:
2018-01-06T21:15:48Z (8 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/drv
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • 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,
Note: See TracChangeset for help on using the changeset viewer.