Ignore:
File:
1 edited

Legend:

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

    r7c10198 r50b581d  
    8484 */
    8585typedef enum {
     86        /** Asks for address assignment by host controller.
     87         * Answer:
     88         * - ELIMIT - host controller run out of address
     89         * - EOK - address assigned
     90         * Answer arguments:
     91         * - assigned address
     92         *
     93         * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.
     94         */
     95        IPC_M_USBHC_REQUEST_ADDRESS,
     96
     97        /** Bind USB address with devman handle.
     98         * Parameters:
     99         * - USB address
     100         * - devman handle
     101         * Answer:
     102         * - EOK - address binded
     103         * - ENOENT - address is not in use
     104         */
     105        IPC_M_USBHC_BIND_ADDRESS,
     106
     107        /** Get handle binded with given USB address.
     108         * Parameters
     109         * - USB address
     110         * Answer:
     111         * - EOK - address binded, first parameter is the devman handle
     112         * - ENOENT - address is not in use at the moment
     113         */
     114        IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
     115
     116        /** Release address in use.
     117         * Arguments:
     118         * - address to be released
     119         * Answer:
     120         * - ENOENT - address not in use
     121         * - EPERM - trying to release default USB address
     122         */
     123        IPC_M_USBHC_RELEASE_ADDRESS,
     124
     125        /** Register endpoint attributes at host controller.
     126         * This is used to reserve portion of USB bandwidth.
     127         * When speed is invalid, speed of the device is used.
     128         * Parameters:
     129         * - USB address + endpoint number
     130         *   - packed as ADDR << 16 + EP
     131         * - speed + transfer type + direction
     132         *   - packed as ( SPEED << 8 + TYPE ) << 8 + DIR
     133         * - maximum packet size + interval (in milliseconds)
     134         *   - packed as MPS << 16 + INT
     135         * Answer:
     136         * - EOK - reservation successful
     137         * - ELIMIT - not enough bandwidth to satisfy the request
     138         */
     139        IPC_M_USBHC_REGISTER_ENDPOINT,
     140
     141        /** Revert endpoint registration.
     142         * Parameters:
     143         * - USB address
     144         * - endpoint number
     145         * - data direction
     146         * Answer:
     147         * - EOK - endpoint unregistered
     148         * - ENOENT - unknown endpoint
     149         */
     150        IPC_M_USBHC_UNREGISTER_ENDPOINT,
     151
    86152        /** Get data from device.
    87153         * See explanation at usb_iface_funcs_t (IN transaction).
     
    95161} usbhc_iface_funcs_t;
    96162
     163int usbhc_request_address(async_exch_t *exch, usb_address_t *address,
     164    bool strict, usb_speed_t speed)
     165{
     166        if (!exch || !address)
     167                return EINVAL;
     168        sysarg_t new_address;
     169        const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     170            IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address);
     171        if (ret == EOK)
     172                *address = (usb_address_t)new_address;
     173        return ret;
     174}
     175/*----------------------------------------------------------------------------*/
     176int usbhc_bind_address(async_exch_t *exch, usb_address_t address,
     177    devman_handle_t handle)
     178{
     179        if (!exch)
     180                return EINVAL;
     181        return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     182            IPC_M_USBHC_BIND_ADDRESS, address, handle);
     183}
     184/*----------------------------------------------------------------------------*/
     185int usbhc_get_handle(async_exch_t *exch, usb_address_t address,
     186    devman_handle_t *handle)
     187{
     188        if (!exch)
     189                return EINVAL;
     190        sysarg_t h;
     191        const int ret = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     192            IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, address, &h);
     193        if (ret == EOK && handle)
     194                *handle = (devman_handle_t)h;
     195        return ret;
     196}
     197/*----------------------------------------------------------------------------*/
     198int usbhc_release_address(async_exch_t *exch, usb_address_t address)
     199{
     200        if (!exch)
     201                return EINVAL;
     202        return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     203            IPC_M_USBHC_RELEASE_ADDRESS, address);
     204}
     205/*----------------------------------------------------------------------------*/
     206int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address,
     207    usb_endpoint_t endpoint, usb_transfer_type_t type,
     208    usb_direction_t direction, size_t mps, unsigned interval)
     209{
     210        if (!exch)
     211                return EINVAL;
     212        const usb_target_t target =
     213            {{ .address = address, .endpoint = endpoint }};
     214#define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
     215
     216        return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     217            IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,
     218            _PACK2(type, direction), _PACK2(mps, interval));
     219
     220#undef _PACK2
     221}
     222/*----------------------------------------------------------------------------*/
     223int usbhc_unregister_endpoint(async_exch_t *exch, usb_address_t address,
     224    usb_endpoint_t endpoint, usb_direction_t direction)
     225{
     226        if (!exch)
     227                return EINVAL;
     228        return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     229            IPC_M_USBHC_UNREGISTER_ENDPOINT, address, endpoint, direction);
     230}
     231/*----------------------------------------------------------------------------*/
    97232int usbhc_read(async_exch_t *exch, usb_address_t address,
    98233    usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size,
    99234    size_t *rec_size)
    100235{
    101         if (!exch)
    102                 return EBADMEM;
    103 
    104236        if (size == 0 && setup == 0)
    105237                return EOK;
    106238
     239        if (!exch)
     240                return EINVAL;
    107241        const usb_target_t target =
    108242            {{ .address = address, .endpoint = endpoint }};
     
    150284        return EOK;
    151285}
    152 
     286/*----------------------------------------------------------------------------*/
    153287int usbhc_write(async_exch_t *exch, usb_address_t address,
    154288    usb_endpoint_t endpoint, uint64_t setup, const void *data, size_t size)
    155289{
    156         if (!exch)
    157                 return EBADMEM;
    158 
    159290        if (size == 0 && setup == 0)
    160291                return EOK;
    161292
     293        if (!exch)
     294                return EINVAL;
    162295        const usb_target_t target =
    163296            {{ .address = address, .endpoint = endpoint }};
     
    186319        return (int) opening_request_rc;
    187320}
    188 
     321/*----------------------------------------------------------------------------*/
     322
     323static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     324static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     325static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     326static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     327static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     328static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    189329static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    190330static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     331//static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    191332
    192333/** Remote USB host controller interface operations. */
    193334static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
     335        [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
     336        [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
     337        [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address,
     338        [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle,
     339
     340        [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint,
     341        [IPC_M_USBHC_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint,
     342
    194343        [IPC_M_USBHC_READ] = remote_usbhc_read,
    195344        [IPC_M_USBHC_WRITE] = remote_usbhc_write,
     
    235384        return trans;
    236385}
    237 
    238 static void callback_out(int outcome, void *arg)
     386/*----------------------------------------------------------------------------*/
     387void remote_usbhc_request_address(ddf_fun_t *fun, void *iface,
     388    ipc_callid_t callid, ipc_call_t *call)
     389{
     390        const usbhc_iface_t *usb_iface = iface;
     391
     392        if (!usb_iface->request_address) {
     393                async_answer_0(callid, ENOTSUP);
     394                return;
     395        }
     396
     397        usb_address_t address = DEV_IPC_GET_ARG1(*call);
     398        const bool strict = DEV_IPC_GET_ARG2(*call);
     399        const usb_speed_t speed = DEV_IPC_GET_ARG3(*call);
     400
     401        const int rc = usb_iface->request_address(fun, &address, strict, speed);
     402        if (rc != EOK) {
     403                async_answer_0(callid, rc);
     404        } else {
     405                async_answer_1(callid, EOK, (sysarg_t) address);
     406        }
     407}
     408/*----------------------------------------------------------------------------*/
     409void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface,
     410    ipc_callid_t callid, ipc_call_t *call)
     411{
     412        const usbhc_iface_t *usb_iface = iface;
     413
     414        if (!usb_iface->bind_address) {
     415                async_answer_0(callid, ENOTSUP);
     416                return;
     417        }
     418
     419        const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     420        const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
     421
     422        const int ret = usb_iface->bind_address(fun, address, handle);
     423        async_answer_0(callid, ret);
     424}
     425/*----------------------------------------------------------------------------*/
     426void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface,
     427    ipc_callid_t callid, ipc_call_t *call)
     428{
     429        const usbhc_iface_t *usb_iface = iface;
     430
     431        if (!usb_iface->get_handle) {
     432                async_answer_0(callid, ENOTSUP);
     433                return;
     434        }
     435
     436        const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     437        devman_handle_t handle;
     438        const int ret = usb_iface->get_handle(fun, address, &handle);
     439
     440        if (ret == EOK) {
     441                async_answer_1(callid, ret, handle);
     442        } else {
     443                async_answer_0(callid, ret);
     444        }
     445}
     446/*----------------------------------------------------------------------------*/
     447void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
     448    ipc_callid_t callid, ipc_call_t *call)
     449{
     450        const usbhc_iface_t *usb_iface = iface;
     451
     452        if (!usb_iface->release_address) {
     453                async_answer_0(callid, ENOTSUP);
     454                return;
     455        }
     456
     457        const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     458
     459        const int ret = usb_iface->release_address(fun, address);
     460        async_answer_0(callid, ret);
     461}
     462/*----------------------------------------------------------------------------*/
     463static void callback_out(ddf_fun_t *fun,
     464    int outcome, void *arg)
    239465{
    240466        async_transaction_t *trans = arg;
     
    244470        async_transaction_destroy(trans);
    245471}
    246 
    247 static void callback_in(int outcome, size_t actual_size, void *arg)
     472/*----------------------------------------------------------------------------*/
     473static void callback_in(ddf_fun_t *fun,
     474    int outcome, size_t actual_size, void *arg)
    248475{
    249476        async_transaction_t *trans = (async_transaction_t *)arg;
     
    267494        async_transaction_destroy(trans);
    268495}
     496/*----------------------------------------------------------------------------*/
     497void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,
     498    ipc_callid_t callid, ipc_call_t *call)
     499{
     500        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     501
     502        if (!usb_iface->register_endpoint) {
     503                async_answer_0(callid, ENOTSUP);
     504                return;
     505        }
     506
     507#define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
     508        type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)
     509#define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
     510        type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)
     511
     512        const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };
     513
     514        _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);
     515        _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);
     516
     517        _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
     518        _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
     519
     520#undef _INIT_FROM_HIGH_DATA2
     521#undef _INIT_FROM_LOW_DATA2
     522
     523        int rc = usb_iface->register_endpoint(fun, target.address,
     524            target.endpoint, transfer_type, direction, max_packet_size, interval);
     525
     526        async_answer_0(callid, rc);
     527}
     528
     529void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,
     530    ipc_callid_t callid, ipc_call_t *call)
     531{
     532        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     533
     534        if (!usb_iface->unregister_endpoint) {
     535                async_answer_0(callid, ENOTSUP);
     536                return;
     537        }
     538
     539        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     540        usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call);
     541        usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call);
     542
     543        int rc = usb_iface->unregister_endpoint(fun,
     544            address, endpoint, direction);
     545
     546        async_answer_0(callid, rc);
     547}
    269548
    270549void remote_usbhc_read(
     
    315594        }
    316595}
    317 
     596/*----------------------------------------------------------------------------*/
    318597void remote_usbhc_write(
    319598    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
Note: See TracChangeset for help on using the changeset viewer.