Ignore:
File:
1 edited

Legend:

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

    ra44424f r9d58539  
    3737#include <assert.h>
    3838#include <stdio.h>
    39 #include <macros.h>
    4039
    4140#include "usbhid_iface.h"
    4241#include "ddf/driver.h"
    43 
    44 /** IPC methods for USB HID device interface. */
    45 typedef enum {
    46         /** Get number of events reported in single burst.
    47          * Parameters: none
    48          * Answer:
    49          * - Size of one report in bytes.
    50          */
    51         IPC_M_USBHID_GET_EVENT_LENGTH,
    52         /** Get single event from the HID device.
    53          * The word single refers to set of individual events that were
    54          * available at particular point in time.
    55          * Parameters:
    56          * - flags
    57          * The call is followed by data read expecting two concatenated
    58          * arrays.
    59          * Answer:
    60          * - EOK - events returned
    61          * - EAGAIN - no event ready (only in non-blocking mode)
    62          *
    63          * It is okay if the client requests less data. Extra data must
    64          * be truncated by the driver.
    65          *
    66          * @todo Change this comment.
    67          */
    68         IPC_M_USBHID_GET_EVENT,
    69        
    70         /** Get the size of the report descriptor from the HID device.
    71          *
    72          * Parameters:
    73          * - none
    74          * Answer:
    75          * - EOK - method is implemented (expected always)
    76          * Parameters of the answer:
    77          * - Size of the report in bytes.
    78          */
    79         IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
    80        
    81         /** Get the report descriptor from the HID device.
    82          *
    83          * Parameters:
    84          * - none
    85          * The call is followed by data read expecting the descriptor itself.
    86          * Answer:
    87          * - EOK - report descriptor returned.
    88          */
    89         IPC_M_USBHID_GET_REPORT_DESCRIPTOR
    90 } usbhid_iface_funcs_t;
    91 
    92 /** Ask for event array length.
    93  *
    94  * @param dev_sess Session to DDF device providing USB HID interface.
    95  *
    96  * @return Number of usages returned or negative error code.
    97  *
    98  */
    99 int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
    100 {
    101         if (!dev_sess)
    102                 return EINVAL;
    103        
    104         async_exch_t *exch = async_exchange_begin(dev_sess);
    105        
    106         sysarg_t len;
    107         int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
    108             IPC_M_USBHID_GET_EVENT_LENGTH, &len);
    109        
    110         async_exchange_end(exch);
    111        
    112         if (rc == EOK) {
    113                 if (size != NULL)
    114                         *size = (size_t) len;
    115         }
    116        
    117         return rc;
    118 }
    119 
    120 /** Request for next event from HID device.
    121  *
    122  * @param[in]  dev_sess    Session to DDF device providing USB HID interface.
    123  * @param[out] usage_pages Where to store usage pages.
    124  * @param[out] usages      Where to store usages (actual data).
    125  * @param[in]  usage_count Length of @p usage_pages and @p usages buffer
    126  *                         (in items, not bytes).
    127  * @param[out] actual_usage_count Number of usages actually returned by the
    128  *                                device driver.
    129  * @param[in] flags        Flags (see USBHID_IFACE_FLAG_*).
    130  *
    131  * @return Error code.
    132  *
    133  */
    134 int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
    135     size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
    136 {
    137         if (!dev_sess)
    138                 return EINVAL;
    139        
    140         if (buf == NULL)
    141                 return ENOMEM;
    142        
    143         if (size == 0)
    144                 return EINVAL;
    145        
    146         size_t buffer_size =  size;
    147         uint8_t *buffer = malloc(buffer_size);
    148         if (buffer == NULL)
    149                 return ENOMEM;
    150        
    151         async_exch_t *exch = async_exchange_begin(dev_sess);
    152        
    153         ipc_call_t opening_request_call;
    154         aid_t opening_request = async_send_2(exch,
    155             DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
    156             flags, &opening_request_call);
    157        
    158         if (opening_request == 0) {
    159                 async_exchange_end(exch);
    160                 free(buffer);
    161                 return ENOMEM;
    162         }
    163        
    164         ipc_call_t data_request_call;
    165         aid_t data_request = async_data_read(exch, buffer, buffer_size,
    166             &data_request_call);
    167        
    168         async_exchange_end(exch);
    169        
    170         if (data_request == 0) {
    171                 async_forget(opening_request);
    172                 free(buffer);
    173                 return ENOMEM;
    174         }
    175        
    176         sysarg_t data_request_rc;
    177         sysarg_t opening_request_rc;
    178         async_wait_for(data_request, &data_request_rc);
    179         async_wait_for(opening_request, &opening_request_rc);
    180        
    181         if (data_request_rc != EOK) {
    182                 /* Prefer return code of the opening request. */
    183                 if (opening_request_rc != EOK)
    184                         return (int) opening_request_rc;
    185                 else
    186                         return (int) data_request_rc;
    187         }
    188        
    189         if (opening_request_rc != EOK)
    190                 return (int) opening_request_rc;
    191        
    192         size_t act_size = IPC_GET_ARG2(data_request_call);
    193        
    194         /* Copy the individual items. */
    195         memcpy(buf, buffer, act_size);
    196        
    197         if (actual_size != NULL)
    198                 *actual_size = act_size;
    199        
    200         if (event_nr != NULL)
    201                 *event_nr = IPC_GET_ARG1(opening_request_call);
    202        
    203         return EOK;
    204 }
    205 
    206 int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
    207     size_t *size)
    208 {
    209         if (!dev_sess)
    210                 return EINVAL;
    211        
    212         async_exch_t *exch = async_exchange_begin(dev_sess);
    213        
    214         sysarg_t arg_size;
    215         int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
    216             IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
    217        
    218         async_exchange_end(exch);
    219        
    220         if (rc == EOK) {
    221                 if (size != NULL)
    222                         *size = (size_t) arg_size;
    223         }
    224        
    225         return rc;
    226 }
    227 
    228 int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
    229     size_t size, size_t *actual_size)
    230 {
    231         if (!dev_sess)
    232                 return EINVAL;
    233        
    234         if (buf == NULL)
    235                 return ENOMEM;
    236        
    237         if (size == 0)
    238                 return EINVAL;
    239        
    240         async_exch_t *exch = async_exchange_begin(dev_sess);
    241        
    242         aid_t opening_request = async_send_1(exch,
    243             DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
    244             NULL);
    245         if (opening_request == 0) {
    246                 async_exchange_end(exch);
    247                 return ENOMEM;
    248         }
    249        
    250         ipc_call_t data_request_call;
    251         aid_t data_request = async_data_read(exch, buf, size,
    252             &data_request_call);
    253        
    254         async_exchange_end(exch);
    255        
    256         if (data_request == 0) {
    257                 async_forget(opening_request);
    258                 return ENOMEM;
    259         }
    260        
    261         sysarg_t data_request_rc;
    262         sysarg_t opening_request_rc;
    263         async_wait_for(data_request, &data_request_rc);
    264         async_wait_for(opening_request, &opening_request_rc);
    265        
    266         if (data_request_rc != EOK) {
    267                 /* Prefer return code of the opening request. */
    268                 if (opening_request_rc != EOK)
    269                         return (int) opening_request_rc;
    270                 else
    271                         return (int) data_request_rc;
    272         }
    273        
    274         if (opening_request_rc != EOK)
    275                 return (int) opening_request_rc;
    276        
    277         size_t act_size = IPC_GET_ARG2(data_request_call);
    278        
    279         if (actual_size != NULL)
    280                 *actual_size = act_size;
    281        
    282         return EOK;
    283 }
    28442
    28543static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     
    29048
    29149/** Remote USB HID interface operations. */
    292 static const remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
    293         [IPC_M_USBHID_GET_EVENT_LENGTH] = remote_usbhid_get_event_length,
    294         [IPC_M_USBHID_GET_EVENT] = remote_usbhid_get_event,
    295         [IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH] =
    296             remote_usbhid_get_report_descriptor_length,
    297         [IPC_M_USBHID_GET_REPORT_DESCRIPTOR] = remote_usbhid_get_report_descriptor
     50static remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
     51        remote_usbhid_get_event_length,
     52        remote_usbhid_get_event,
     53        remote_usbhid_get_report_descriptor_length,
     54        remote_usbhid_get_report_descriptor
    29855};
    29956
    30057/** Remote USB HID interface structure.
    30158 */
    302 const remote_iface_t remote_usbhid_iface = {
    303         .method_count = ARRAY_SIZE(remote_usbhid_iface_ops),
     59remote_iface_t remote_usbhid_iface = {
     60        .method_count = sizeof(remote_usbhid_iface_ops) /
     61            sizeof(remote_usbhid_iface_ops[0]),
    30462        .methods = remote_usbhid_iface_ops
    30563};
Note: See TracChangeset for help on using the changeset viewer.