Ignore:
File:
1 edited

Legend:

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

    r50b581d r7c10198  
    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 
    15286        /** Get data from device.
    15387         * See explanation at usb_iface_funcs_t (IN transaction).
     
    16195} usbhc_iface_funcs_t;
    16296
    163 int 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 /*----------------------------------------------------------------------------*/
    176 int 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 /*----------------------------------------------------------------------------*/
    185 int 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 /*----------------------------------------------------------------------------*/
    198 int 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 /*----------------------------------------------------------------------------*/
    206 int 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 /*----------------------------------------------------------------------------*/
    223 int 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 /*----------------------------------------------------------------------------*/
    23297int usbhc_read(async_exch_t *exch, usb_address_t address,
    23398    usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size,
    23499    size_t *rec_size)
    235100{
     101        if (!exch)
     102                return EBADMEM;
     103
    236104        if (size == 0 && setup == 0)
    237105                return EOK;
    238106
    239         if (!exch)
    240                 return EINVAL;
    241107        const usb_target_t target =
    242108            {{ .address = address, .endpoint = endpoint }};
     
    284150        return EOK;
    285151}
    286 /*----------------------------------------------------------------------------*/
     152
    287153int usbhc_write(async_exch_t *exch, usb_address_t address,
    288154    usb_endpoint_t endpoint, uint64_t setup, const void *data, size_t size)
    289155{
     156        if (!exch)
     157                return EBADMEM;
     158
    290159        if (size == 0 && setup == 0)
    291160                return EOK;
    292161
    293         if (!exch)
    294                 return EINVAL;
    295162        const usb_target_t target =
    296163            {{ .address = address, .endpoint = endpoint }};
     
    319186        return (int) opening_request_rc;
    320187}
    321 /*----------------------------------------------------------------------------*/
    322 
    323 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    324 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    325 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    326 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    327 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    328 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     188
    329189static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    330190static 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 *);
    332191
    333192/** Remote USB host controller interface operations. */
    334193static 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 
    343194        [IPC_M_USBHC_READ] = remote_usbhc_read,
    344195        [IPC_M_USBHC_WRITE] = remote_usbhc_write,
     
    384235        return trans;
    385236}
    386 /*----------------------------------------------------------------------------*/
    387 void 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 /*----------------------------------------------------------------------------*/
    409 void 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 /*----------------------------------------------------------------------------*/
    426 void 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 /*----------------------------------------------------------------------------*/
    447 void 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 /*----------------------------------------------------------------------------*/
    463 static void callback_out(ddf_fun_t *fun,
    464     int outcome, void *arg)
     237
     238static void callback_out(int outcome, void *arg)
    465239{
    466240        async_transaction_t *trans = arg;
     
    470244        async_transaction_destroy(trans);
    471245}
    472 /*----------------------------------------------------------------------------*/
    473 static void callback_in(ddf_fun_t *fun,
    474     int outcome, size_t actual_size, void *arg)
     246
     247static void callback_in(int outcome, size_t actual_size, void *arg)
    475248{
    476249        async_transaction_t *trans = (async_transaction_t *)arg;
     
    494267        async_transaction_destroy(trans);
    495268}
    496 /*----------------------------------------------------------------------------*/
    497 void 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 
    529 void 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 }
    548269
    549270void remote_usbhc_read(
     
    594315        }
    595316}
    596 /*----------------------------------------------------------------------------*/
     317
    597318void remote_usbhc_write(
    598319    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
Note: See TracChangeset for help on using the changeset viewer.