Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/remote_usbhc.c

    rb7fd2a0 r99172baf  
    8585 */
    8686typedef enum {
     87        /** Asks for address assignment by host controller.
     88         * Answer:
     89         * - ELIMIT - host controller run out of address
     90         * - EOK - address assigned
     91         * Answer arguments:
     92         * - assigned address
     93         *
     94         * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.
     95         */
     96        IPC_M_USBHC_REQUEST_ADDRESS,
     97
     98        /** Bind USB address with devman handle.
     99         * Parameters:
     100         * - USB address
     101         * - devman handle
     102         * Answer:
     103         * - EOK - address binded
     104         * - ENOENT - address is not in use
     105         */
     106        IPC_M_USBHC_BIND_ADDRESS,
     107
     108        /** Get handle binded with given USB address.
     109         * Parameters
     110         * - USB address
     111         * Answer:
     112         * - EOK - address binded, first parameter is the devman handle
     113         * - ENOENT - address is not in use at the moment
     114         */
     115        IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
     116
     117        /** Release address in use.
     118         * Arguments:
     119         * - address to be released
     120         * Answer:
     121         * - ENOENT - address not in use
     122         * - EPERM - trying to release default USB address
     123         */
     124        IPC_M_USBHC_RELEASE_ADDRESS,
     125
     126        /** Register endpoint attributes at host controller.
     127         * This is used to reserve portion of USB bandwidth.
     128         * When speed is invalid, speed of the device is used.
     129         * Parameters:
     130         * - USB address + endpoint number
     131         *   - packed as ADDR << 16 + EP
     132         * - speed + transfer type + direction
     133         *   - packed as ( SPEED << 8 + TYPE ) << 8 + DIR
     134         * - maximum packet size + interval (in milliseconds)
     135         *   - packed as MPS << 16 + INT
     136         * Answer:
     137         * - EOK - reservation successful
     138         * - ELIMIT - not enough bandwidth to satisfy the request
     139         */
     140        IPC_M_USBHC_REGISTER_ENDPOINT,
     141
     142        /** Revert endpoint registration.
     143         * Parameters:
     144         * - USB address
     145         * - endpoint number
     146         * - data direction
     147         * Answer:
     148         * - EOK - endpoint unregistered
     149         * - ENOENT - unknown endpoint
     150         */
     151        IPC_M_USBHC_UNREGISTER_ENDPOINT,
     152
    87153        /** Get data from device.
    88154         * See explanation at usb_iface_funcs_t (IN transaction).
     
    96162} usbhc_iface_funcs_t;
    97163
    98 errno_t usbhc_read(async_exch_t *exch, usb_address_t address,
     164int usbhc_request_address(async_exch_t *exch, usb_address_t *address,
     165    bool strict, usb_speed_t speed)
     166{
     167        if (!exch || !address)
     168                return EBADMEM;
     169        sysarg_t new_address;
     170        const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     171            IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address);
     172        if (ret == EOK)
     173                *address = (usb_address_t)new_address;
     174        return ret;
     175}
     176
     177int usbhc_bind_address(async_exch_t *exch, usb_address_t address,
     178    devman_handle_t handle)
     179{
     180        if (!exch)
     181                return EBADMEM;
     182        return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     183            IPC_M_USBHC_BIND_ADDRESS, address, handle);
     184}
     185
     186int usbhc_get_handle(async_exch_t *exch, usb_address_t address,
     187    devman_handle_t *handle)
     188{
     189        if (!exch)
     190                return EBADMEM;
     191        sysarg_t h;
     192        const int ret = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     193            IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, address, &h);
     194        if (ret == EOK && handle)
     195                *handle = (devman_handle_t)h;
     196        return ret;
     197}
     198
     199int usbhc_release_address(async_exch_t *exch, usb_address_t address)
     200{
     201        if (!exch)
     202                return EBADMEM;
     203        return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     204            IPC_M_USBHC_RELEASE_ADDRESS, address);
     205}
     206
     207int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address,
     208    usb_endpoint_t endpoint, usb_transfer_type_t type,
     209    usb_direction_t direction, size_t mps, unsigned interval)
     210{
     211        if (!exch)
     212                return EBADMEM;
     213        const usb_target_t target =
     214            {{ .address = address, .endpoint = endpoint }};
     215#define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
     216
     217        return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     218            IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,
     219            _PACK2(type, direction), _PACK2(mps, interval));
     220
     221#undef _PACK2
     222}
     223
     224int usbhc_unregister_endpoint(async_exch_t *exch, usb_address_t address,
     225    usb_endpoint_t endpoint, usb_direction_t direction)
     226{
     227        if (!exch)
     228                return EBADMEM;
     229        return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     230            IPC_M_USBHC_UNREGISTER_ENDPOINT, address, endpoint, direction);
     231}
     232
     233int usbhc_read(async_exch_t *exch, usb_address_t address,
    99234    usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size,
    100235    size_t *rec_size)
     
    131266
    132267        /* Wait for the answer. */
    133         errno_t data_request_rc;
    134         errno_t opening_request_rc;
     268        sysarg_t data_request_rc;
     269        sysarg_t opening_request_rc;
    135270        async_wait_for(data_request, &data_request_rc);
    136271        async_wait_for(opening_request, &opening_request_rc);
     
    139274                /* Prefer the return code of the opening request. */
    140275                if (opening_request_rc != EOK) {
    141                         return (errno_t) opening_request_rc;
     276                        return (int) opening_request_rc;
    142277                } else {
    143                         return (errno_t) data_request_rc;
     278                        return (int) data_request_rc;
    144279                }
    145280        }
    146281        if (opening_request_rc != EOK) {
    147                 return (errno_t) opening_request_rc;
     282                return (int) opening_request_rc;
    148283        }
    149284
     
    152287}
    153288
    154 errno_t usbhc_write(async_exch_t *exch, usb_address_t address,
     289int usbhc_write(async_exch_t *exch, usb_address_t address,
    155290    usb_endpoint_t endpoint, uint64_t setup, const void *data, size_t size)
    156291{
     
    174309        /* Send the data if any. */
    175310        if (size > 0) {
    176                 const errno_t ret = async_data_write_start(exch, data, size);
     311                const int ret = async_data_write_start(exch, data, size);
    177312                if (ret != EOK) {
    178313                        async_forget(opening_request);
     
    182317
    183318        /* Wait for the answer. */
    184         errno_t opening_request_rc;
     319        sysarg_t opening_request_rc;
    185320        async_wait_for(opening_request, &opening_request_rc);
    186321
    187         return (errno_t) opening_request_rc;
    188 }
    189 
     322        return (int) opening_request_rc;
     323}
     324
     325
     326static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     327static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     328static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     329static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     330static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     331static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    190332static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    191333static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     334//static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    192335
    193336/** Remote USB host controller interface operations. */
    194337static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
     338        [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
     339        [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
     340        [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address,
     341        [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle,
     342
     343        [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint,
     344        [IPC_M_USBHC_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint,
     345
    195346        [IPC_M_USBHC_READ] = remote_usbhc_read,
    196347        [IPC_M_USBHC_WRITE] = remote_usbhc_write,
     
    235386}
    236387
    237 static void callback_out(errno_t outcome, void *arg)
     388void remote_usbhc_request_address(ddf_fun_t *fun, void *iface,
     389    ipc_callid_t callid, ipc_call_t *call)
     390{
     391        const usbhc_iface_t *usb_iface = iface;
     392
     393        if (!usb_iface->request_address) {
     394                async_answer_0(callid, ENOTSUP);
     395                return;
     396        }
     397
     398        usb_address_t address = DEV_IPC_GET_ARG1(*call);
     399        const bool strict = DEV_IPC_GET_ARG2(*call);
     400        const usb_speed_t speed = DEV_IPC_GET_ARG3(*call);
     401
     402        const int rc = usb_iface->request_address(fun, &address, strict, speed);
     403        if (rc != EOK) {
     404                async_answer_0(callid, rc);
     405        } else {
     406                async_answer_1(callid, EOK, (sysarg_t) address);
     407        }
     408}
     409
     410void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface,
     411    ipc_callid_t callid, ipc_call_t *call)
     412{
     413        const usbhc_iface_t *usb_iface = iface;
     414
     415        if (!usb_iface->bind_address) {
     416                async_answer_0(callid, ENOTSUP);
     417                return;
     418        }
     419
     420        const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     421        const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
     422
     423        const int ret = usb_iface->bind_address(fun, address, handle);
     424        async_answer_0(callid, ret);
     425}
     426
     427void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface,
     428    ipc_callid_t callid, ipc_call_t *call)
     429{
     430        const usbhc_iface_t *usb_iface = iface;
     431
     432        if (!usb_iface->get_handle) {
     433                async_answer_0(callid, ENOTSUP);
     434                return;
     435        }
     436
     437        const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     438        devman_handle_t handle;
     439        const int ret = usb_iface->get_handle(fun, address, &handle);
     440
     441        if (ret == EOK) {
     442                async_answer_1(callid, ret, handle);
     443        } else {
     444                async_answer_0(callid, ret);
     445        }
     446}
     447
     448void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
     449    ipc_callid_t callid, ipc_call_t *call)
     450{
     451        const usbhc_iface_t *usb_iface = iface;
     452
     453        if (!usb_iface->release_address) {
     454                async_answer_0(callid, ENOTSUP);
     455                return;
     456        }
     457
     458        const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     459
     460        const int ret = usb_iface->release_address(fun, address);
     461        async_answer_0(callid, ret);
     462}
     463
     464static void callback_out(ddf_fun_t *fun,
     465    int outcome, void *arg)
    238466{
    239467        async_transaction_t *trans = arg;
     
    244472}
    245473
    246 static void callback_in(errno_t outcome, size_t actual_size, void *arg)
     474static void callback_in(ddf_fun_t *fun,
     475    int outcome, size_t actual_size, void *arg)
    247476{
    248477        async_transaction_t *trans = (async_transaction_t *)arg;
     
    267496}
    268497
     498void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,
     499    ipc_callid_t callid, ipc_call_t *call)
     500{
     501        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     502
     503        if (!usb_iface->register_endpoint) {
     504                async_answer_0(callid, ENOTSUP);
     505                return;
     506        }
     507
     508#define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
     509        type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)
     510#define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
     511        type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)
     512
     513        const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };
     514
     515        _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);
     516        _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);
     517
     518        _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
     519        _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
     520
     521#undef _INIT_FROM_HIGH_DATA2
     522#undef _INIT_FROM_LOW_DATA2
     523
     524        int rc = usb_iface->register_endpoint(fun, target.address,
     525            target.endpoint, transfer_type, direction, max_packet_size, interval);
     526
     527        async_answer_0(callid, rc);
     528}
     529
     530void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,
     531    ipc_callid_t callid, ipc_call_t *call)
     532{
     533        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     534
     535        if (!usb_iface->unregister_endpoint) {
     536                async_answer_0(callid, ENOTSUP);
     537                return;
     538        }
     539
     540        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     541        usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call);
     542        usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call);
     543
     544        int rc = usb_iface->unregister_endpoint(fun,
     545            address, endpoint, direction);
     546
     547        async_answer_0(callid, rc);
     548}
     549
    269550void remote_usbhc_read(
    270551    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     
    306587        }
    307588
    308         const errno_t rc = hc_iface->read(
     589        const int rc = hc_iface->read(
    309590            fun, target, setup, trans->buffer, size, callback_in, trans);
    310591
     
    344625        size_t size = 0;
    345626        if (data_buffer_len > 0) {
    346                 const errno_t rc = async_data_write_accept(&trans->buffer, false,
     627                const int rc = async_data_write_accept(&trans->buffer, false,
    347628                    1, USB_MAX_PAYLOAD_SIZE,
    348629                    0, &size);
     
    355636        }
    356637
    357         const errno_t rc = hc_iface->write(
     638        const int rc = hc_iface->write(
    358639            fun, target, setup, trans->buffer, size, callback_out, trans);
    359640
Note: See TracChangeset for help on using the changeset viewer.