Ignore:
Timestamp:
2018-01-06T21:15:48Z (6 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).

File:
1 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}
Note: See TracChangeset for help on using the changeset viewer.