Ignore:
File:
1 edited

Legend:

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

    r70a422b r9d58539  
    3535
    3636#include <async.h>
    37 #include <macros.h>
    3837#include <errno.h>
    39 #include <devman.h>
    4038
    4139#include "usb_iface.h"
    4240#include "ddf/driver.h"
    43 
    44 
    45 usb_dev_session_t *usb_dev_connect(devman_handle_t handle)
    46 {
    47         // TODO All usb requests are atomic so this is safe,
    48         // it will need to change once USING EXCHANGE PARALLEL is safe with
    49         // devman_device_connect
    50         return devman_device_connect(EXCHANGE_ATOMIC, handle, IPC_FLAG_BLOCKING);
    51 }
    52 
    53 usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *dev)
    54 {
    55         // TODO All usb requests are atomic so this is safe,
    56         // it will need to change once USING EXCHANGE PARALLEL is safe with
    57         // devman_parent_device_connect
    58         return devman_parent_device_connect(EXCHANGE_ATOMIC,
    59             ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
    60 }
    61 
    62 void usb_dev_disconnect(usb_dev_session_t *sess)
    63 {
    64         if (sess)
    65                 async_hangup(sess);
    66 }
    6741
    6842typedef enum {
     
    7044        IPC_M_USB_GET_MY_INTERFACE,
    7145        IPC_M_USB_GET_HOST_CONTROLLER_HANDLE,
    72         IPC_M_USB_RESERVE_DEFAULT_ADDRESS,
    73         IPC_M_USB_RELEASE_DEFAULT_ADDRESS,
    74         IPC_M_USB_DEVICE_ENUMERATE,
    75         IPC_M_USB_DEVICE_REMOVE,
    76         IPC_M_USB_REGISTER_ENDPOINT,
    77         IPC_M_USB_UNREGISTER_ENDPOINT,
    7846} usb_iface_funcs_t;
    7947
     
    8856{
    8957        if (!exch)
    90                 return EBADMEM;
     58                return EINVAL;
    9159        sysarg_t addr;
    9260        const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     
    9765        return ret;
    9866}
    99 
     67/*----------------------------------------------------------------------------*/
    10068/** Tell interface number given device can use.
    10169 * @param[in] exch IPC communication exchange
     
    10775{
    10876        if (!exch)
    109                 return EBADMEM;
     77                return EINVAL;
    11078        sysarg_t iface_no;
    11179        const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     
    11583        return ret;
    11684}
    117 
     85/*----------------------------------------------------------------------------*/
    11886/** Tell devman handle of device host controller.
    11987 * @param[in] exch IPC communication exchange
     
    12492{
    12593        if (!exch)
    126                 return EBADMEM;
     94                return EINVAL;
    12795        devman_handle_t h;
    12896        const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     
    133101}
    134102
    135 /** Reserve default USB address.
    136  * @param[in] exch IPC communication exchange
    137  * @param[in] speed Communication speed of the newly attached device
    138  * @return Error code.
    139  */
    140 int usb_reserve_default_address(async_exch_t *exch, usb_speed_t speed)
    141 {
    142         if (!exch)
    143                 return EBADMEM;
    144         return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    145             IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed);
    146 }
    147 
    148 /** Release default USB address.
    149  * @param[in] exch IPC communication exchange
    150  * @return Error code.
    151  */
    152 int usb_release_default_address(async_exch_t *exch)
    153 {
    154         if (!exch)
    155                 return EBADMEM;
    156         return async_req_1_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    157             IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
    158 }
    159 
    160 /** Trigger USB device enumeration
    161  * @param[in] exch IPC communication exchange
    162  * @param[out] handle Identifier of the newly added device (if successful)
    163  * @return Error code.
    164  */
    165 int usb_device_enumerate(async_exch_t *exch, usb_device_handle_t *handle)
    166 {
    167         if (!exch || !handle)
    168                 return EBADMEM;
    169         sysarg_t h;
    170         const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    171             IPC_M_USB_DEVICE_ENUMERATE, &h);
    172         if (ret == EOK)
    173                 *handle = (usb_device_handle_t)h;
    174         return ret;
    175 }
    176 
    177 /** Trigger USB device enumeration
    178  * @param[in] exch IPC communication exchange
    179  * @param[in] handle Identifier of the device
    180  * @return Error code.
    181  */
    182 int usb_device_remove(async_exch_t *exch, usb_device_handle_t handle)
    183 {
    184         if (!exch)
    185                 return EBADMEM;
    186         return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    187             IPC_M_USB_DEVICE_REMOVE, handle);
    188 }
    189 
    190 int usb_register_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
    191     usb_transfer_type_t type, usb_direction_t direction,
    192     size_t mps, unsigned interval)
    193 {
    194         if (!exch)
    195                 return EBADMEM;
    196 #define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
    197 
    198         return async_req_4_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    199             IPC_M_USB_REGISTER_ENDPOINT, endpoint,
    200             _PACK2(type, direction), _PACK2(mps, interval));
    201 
    202 #undef _PACK2
    203 }
    204 
    205 int usb_unregister_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
    206     usb_direction_t direction)
    207 {
    208         if (!exch)
    209                 return EBADMEM;
    210         return async_req_3_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    211             IPC_M_USB_UNREGISTER_ENDPOINT, endpoint, direction);
    212 }
    213103
    214104static void remote_usb_get_my_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    215105static void remote_usb_get_my_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    216106static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    217 
    218 static void remote_usb_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    219 static void remote_usb_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    220 static void remote_usb_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    221 static void remote_usb_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    222 static void remote_usb_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    223 static void remote_usb_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    224107
    225108/** Remote USB interface operations. */
     
    228111        [IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface,
    229112        [IPC_M_USB_GET_HOST_CONTROLLER_HANDLE] = remote_usb_get_hc_handle,
    230         [IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usb_reserve_default_address,
    231         [IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usb_release_default_address,
    232         [IPC_M_USB_DEVICE_ENUMERATE] = remote_usb_device_enumerate,
    233         [IPC_M_USB_DEVICE_REMOVE] = remote_usb_device_remove,
    234         [IPC_M_USB_REGISTER_ENDPOINT] = remote_usb_register_endpoint,
    235         [IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usb_unregister_endpoint,
    236113};
    237114
     
    239116 */
    240117remote_iface_t remote_usb_iface = {
    241         .method_count = ARRAY_SIZE(remote_usb_iface_ops),
    242         .methods = remote_usb_iface_ops,
     118        .method_count = sizeof(remote_usb_iface_ops) /
     119            sizeof(remote_usb_iface_ops[0]),
     120        .methods = remote_usb_iface_ops
    243121};
    244122
    245 
     123/*----------------------------------------------------------------------------*/
    246124void remote_usb_get_my_address(ddf_fun_t *fun, void *iface,
    247125    ipc_callid_t callid, ipc_call_t *call)
     
    262140        }
    263141}
    264 
     142/*----------------------------------------------------------------------------*/
    265143void remote_usb_get_my_interface(ddf_fun_t *fun, void *iface,
    266144    ipc_callid_t callid, ipc_call_t *call)
     
    281159        }
    282160}
    283 
     161/*----------------------------------------------------------------------------*/
    284162void remote_usb_get_hc_handle(ddf_fun_t *fun, void *iface,
    285163    ipc_callid_t callid, ipc_call_t *call)
     
    300178        async_answer_1(callid, EOK, (sysarg_t) handle);
    301179}
    302 
    303 void remote_usb_reserve_default_address(ddf_fun_t *fun, void *iface,
    304     ipc_callid_t callid, ipc_call_t *call)
    305 {
    306         const usb_iface_t *usb_iface = (usb_iface_t *) iface;
    307 
    308         if (usb_iface->reserve_default_address == NULL) {
    309                 async_answer_0(callid, ENOTSUP);
    310                 return;
    311         }
    312 
    313         usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    314         const int ret = usb_iface->reserve_default_address(fun, speed);
    315         async_answer_0(callid, ret);
    316 }
    317 
    318 void remote_usb_release_default_address(ddf_fun_t *fun, void *iface,
    319     ipc_callid_t callid, ipc_call_t *call)
    320 {
    321         const usb_iface_t *usb_iface = (usb_iface_t *) iface;
    322 
    323         if (usb_iface->release_default_address == NULL) {
    324                 async_answer_0(callid, ENOTSUP);
    325                 return;
    326         }
    327 
    328         const int ret = usb_iface->release_default_address(fun);
    329         async_answer_0(callid, ret);
    330 }
    331 
    332 static void remote_usb_device_enumerate(ddf_fun_t *fun, void *iface,
    333     ipc_callid_t callid, ipc_call_t *call)
    334 {
    335         const usb_iface_t *usb_iface = (usb_iface_t *) iface;
    336 
    337         if (usb_iface->device_enumerate == NULL) {
    338                 async_answer_0(callid, ENOTSUP);
    339                 return;
    340         }
    341 
    342         usb_device_handle_t handle = 0;
    343         const int ret = usb_iface->device_enumerate(fun, &handle);
    344         if (ret != EOK) {
    345                 async_answer_0(callid, ret);
    346         }
    347 
    348         async_answer_1(callid, EOK, (sysarg_t) handle);
    349 }
    350 
    351 static void remote_usb_device_remove(ddf_fun_t *fun, void *iface,
    352     ipc_callid_t callid, ipc_call_t *call)
    353 {
    354         const usb_iface_t *usb_iface = (usb_iface_t *) iface;
    355 
    356         if (usb_iface->device_remove == NULL) {
    357                 async_answer_0(callid, ENOTSUP);
    358                 return;
    359         }
    360 
    361         usb_device_handle_t handle = DEV_IPC_GET_ARG1(*call);
    362         const int ret = usb_iface->device_remove(fun, handle);
    363         async_answer_0(callid, ret);
    364 }
    365 
    366 static void remote_usb_register_endpoint(ddf_fun_t *fun, void *iface,
    367     ipc_callid_t callid, ipc_call_t *call)
    368 {
    369         usb_iface_t *usb_iface = (usb_iface_t *) iface;
    370 
    371         if (!usb_iface->register_endpoint) {
    372                 async_answer_0(callid, ENOTSUP);
    373                 return;
    374         }
    375 
    376 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
    377         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)
    378 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
    379         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)
    380 
    381         const usb_endpoint_t endpoint = DEV_IPC_GET_ARG1(*call);
    382 
    383         _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);
    384         _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);
    385 
    386         _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
    387         _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
    388 
    389 #undef _INIT_FROM_HIGH_DATA2
    390 #undef _INIT_FROM_LOW_DATA2
    391 
    392         const int ret = usb_iface->register_endpoint(fun, endpoint,
    393             transfer_type, direction, max_packet_size, interval);
    394 
    395         async_answer_0(callid, ret);
    396 }
    397 
    398 static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface,
    399     ipc_callid_t callid, ipc_call_t *call)
    400 {
    401         usb_iface_t *usb_iface = (usb_iface_t *) iface;
    402 
    403         if (!usb_iface->unregister_endpoint) {
    404                 async_answer_0(callid, ENOTSUP);
    405                 return;
    406         }
    407 
    408         usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG1(*call);
    409         usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG2(*call);
    410 
    411         int rc = usb_iface->unregister_endpoint(fun, endpoint, direction);
    412 
    413         async_answer_0(callid, rc);
    414 }
    415180/**
    416181 * @}
Note: See TracChangeset for help on using the changeset viewer.