Ignore:
Timestamp:
2016-07-22T08:24:47Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f76d2c2
Parents:
5b18137 (diff), 8351f9a4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jan.vesely/helenos/usb

File:
1 edited

Legend:

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

    r5b18137 rb4b534ac  
    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 
    15387        /** Get data from device.
    15488         * See explanation at usb_iface_funcs_t (IN transaction).
     
    16195        IPC_M_USBHC_WRITE,
    16296} usbhc_iface_funcs_t;
    163 
    164 int 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 
    177 int 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 
    186 int 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 
    199 int 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 
    207 int 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 
    224 int 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 }
    23297
    23398int usbhc_read(async_exch_t *exch, usb_address_t address,
     
    323188}
    324189
    325 
    326 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    327 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    328 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    329 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    330 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    331 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    332190static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    333191static 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 *);
    335192
    336193/** Remote USB host controller interface operations. */
    337194static 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 
    346195        [IPC_M_USBHC_READ] = remote_usbhc_read,
    347196        [IPC_M_USBHC_WRITE] = remote_usbhc_write,
     
    386235}
    387236
    388 void 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 
    410 void 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 
    427 void 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 
    448 void 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 
    464 static void callback_out(ddf_fun_t *fun,
    465     int outcome, void *arg)
     237static void callback_out(int outcome, void *arg)
    466238{
    467239        async_transaction_t *trans = arg;
     
    472244}
    473245
    474 static void callback_in(ddf_fun_t *fun,
    475     int outcome, size_t actual_size, void *arg)
     246static void callback_in(int outcome, size_t actual_size, void *arg)
    476247{
    477248        async_transaction_t *trans = (async_transaction_t *)arg;
     
    496267}
    497268
    498 void 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 
    530 void 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 
    550269void remote_usbhc_read(
    551270    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
Note: See TracChangeset for help on using the changeset viewer.