Changes in uspace/lib/drv/generic/remote_usbhid.c [9d58539:a44424f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhid.c
r9d58539 ra44424f 37 37 #include <assert.h> 38 38 #include <stdio.h> 39 #include <macros.h> 39 40 40 41 #include "usbhid_iface.h" 41 42 #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 } 42 284 43 285 static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); … … 48 290 49 291 /** Remote USB HID interface operations. */ 50 static 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 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 55 298 }; 56 299 57 300 /** Remote USB HID interface structure. 58 301 */ 59 remote_iface_t remote_usbhid_iface = { 60 .method_count = sizeof(remote_usbhid_iface_ops) / 61 sizeof(remote_usbhid_iface_ops[0]), 302 const remote_iface_t remote_usbhid_iface = { 303 .method_count = ARRAY_SIZE(remote_usbhid_iface_ops), 62 304 .methods = remote_usbhid_iface_ops 63 305 };
Note:
See TracChangeset
for help on using the changeset viewer.