source: mainline/uspace/lib/usbhid/src/hidiface.c@ 50b581d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 50b581d was 50b581d, checked in by Jakub Jermar <jakub@…>, 13 years ago

Replace the async_wait_for(msg, NULL) pattern in the error paths with
async_forget(msg).

  • Property mode set to 100644
File size: 6.1 KB
RevLine 
[27b85d9]1/*
2 * Copyright (c) 2011 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[160b75e]29/** @addtogroup libusbhid
[27b85d9]30 * @{
31 */
32/** @file
33 * Client functions for accessing USB HID interface (implementation).
34 */
35#include <dev_iface.h>
36#include <usbhid_iface.h>
[faa44e58]37#include <usb/hid/iface.h>
[27b85d9]38#include <errno.h>
39#include <str_error.h>
40#include <async.h>
41#include <assert.h>
42
43/** Ask for event array length.
44 *
[79ae36dd]45 * @param dev_sess Session to DDF device providing USB HID interface.
46 *
[27b85d9]47 * @return Number of usages returned or negative error code.
[79ae36dd]48 *
[27b85d9]49 */
[79ae36dd]50int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
[27b85d9]51{
[79ae36dd]52 if (!dev_sess)
[27b85d9]53 return EINVAL;
[79ae36dd]54
55 async_exch_t *exch = async_exchange_begin(dev_sess);
56
[27b85d9]57 sysarg_t len;
[79ae36dd]58 int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
[27b85d9]59 IPC_M_USBHID_GET_EVENT_LENGTH, &len);
[79ae36dd]60
61 async_exchange_end(exch);
62
[27b85d9]63 if (rc == EOK) {
[79ae36dd]64 if (size != NULL)
[9dddb3d]65 *size = (size_t) len;
[27b85d9]66 }
[e765ccb]67
68 return rc;
[27b85d9]69}
70
71/** Request for next event from HID device.
72 *
[79ae36dd]73 * @param[in] dev_sess Session to DDF device providing USB HID interface.
[27b85d9]74 * @param[out] usage_pages Where to store usage pages.
[79ae36dd]75 * @param[out] usages Where to store usages (actual data).
76 * @param[in] usage_count Length of @p usage_pages and @p usages buffer
77 * (in items, not bytes).
[27b85d9]78 * @param[out] actual_usage_count Number of usages actually returned by the
[79ae36dd]79 * device driver.
80 * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
81 *
[27b85d9]82 * @return Error code.
[79ae36dd]83 *
[27b85d9]84 */
[79ae36dd]85int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
[266fcd8]86 size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
[27b85d9]87{
[79ae36dd]88 if (!dev_sess)
[27b85d9]89 return EINVAL;
[79ae36dd]90
91 if ((buf == NULL))
[27b85d9]92 return ENOMEM;
[79ae36dd]93
94 if (size == 0)
[27b85d9]95 return EINVAL;
[4e78236]96
[e765ccb]97 size_t buffer_size = size;
[d7c72db]98 uint8_t *buffer = malloc(buffer_size);
[79ae36dd]99 if (buffer == NULL)
[27b85d9]100 return ENOMEM;
[79ae36dd]101
102 async_exch_t *exch = async_exchange_begin(dev_sess);
103
[266fcd8]104 ipc_call_t opening_request_call;
[79ae36dd]105 aid_t opening_request = async_send_2(exch,
[27b85d9]106 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
[266fcd8]107 flags, &opening_request_call);
[79ae36dd]108
[27b85d9]109 if (opening_request == 0) {
[79ae36dd]110 async_exchange_end(exch);
[27b85d9]111 free(buffer);
112 return ENOMEM;
113 }
[79ae36dd]114
[27b85d9]115 ipc_call_t data_request_call;
[79ae36dd]116 aid_t data_request = async_data_read(exch, buffer, buffer_size,
[27b85d9]117 &data_request_call);
[79ae36dd]118
119 async_exchange_end(exch);
120
[27b85d9]121 if (data_request == 0) {
[50b581d]122 async_forget(opening_request);
[27b85d9]123 free(buffer);
124 return ENOMEM;
125 }
[79ae36dd]126
[27b85d9]127 sysarg_t data_request_rc;
128 sysarg_t opening_request_rc;
129 async_wait_for(data_request, &data_request_rc);
130 async_wait_for(opening_request, &opening_request_rc);
[79ae36dd]131
[27b85d9]132 if (data_request_rc != EOK) {
133 /* Prefer return code of the opening request. */
[79ae36dd]134 if (opening_request_rc != EOK)
[27b85d9]135 return (int) opening_request_rc;
[79ae36dd]136 else
[27b85d9]137 return (int) data_request_rc;
138 }
[79ae36dd]139
140 if (opening_request_rc != EOK)
[27b85d9]141 return (int) opening_request_rc;
[79ae36dd]142
[e765ccb]143 size_t act_size = IPC_GET_ARG2(data_request_call);
[79ae36dd]144
[27b85d9]145 /* Copy the individual items. */
[e765ccb]146 memcpy(buf, buffer, act_size);
[79ae36dd]147
148 if (actual_size != NULL)
[e765ccb]149 *actual_size = act_size;
[266fcd8]150
[79ae36dd]151 if (event_nr != NULL)
[266fcd8]152 *event_nr = IPC_GET_ARG1(opening_request_call);
[79ae36dd]153
[27b85d9]154 return EOK;
155}
156
[79ae36dd]157int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
158 size_t *size)
[d7c72db]159{
[79ae36dd]160 if (!dev_sess)
[9dddb3d]161 return EINVAL;
[79ae36dd]162
163 async_exch_t *exch = async_exchange_begin(dev_sess);
164
[9dddb3d]165 sysarg_t arg_size;
[79ae36dd]166 int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
[9dddb3d]167 IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
[79ae36dd]168
169 async_exchange_end(exch);
170
[9dddb3d]171 if (rc == EOK) {
[79ae36dd]172 if (size != NULL)
[9dddb3d]173 *size = (size_t) arg_size;
174 }
[79ae36dd]175
[9dddb3d]176 return rc;
[d7c72db]177}
178
[79ae36dd]179int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
180 size_t size, size_t *actual_size)
[d7c72db]181{
[79ae36dd]182 if (!dev_sess)
[9dddb3d]183 return EINVAL;
[79ae36dd]184
185 if ((buf == NULL))
[9dddb3d]186 return ENOMEM;
[79ae36dd]187
188 if (size == 0)
[9dddb3d]189 return EINVAL;
[79ae36dd]190
191 async_exch_t *exch = async_exchange_begin(dev_sess);
192
193 aid_t opening_request = async_send_1(exch,
[9dddb3d]194 DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
195 NULL);
196 if (opening_request == 0) {
[79ae36dd]197 async_exchange_end(exch);
[9dddb3d]198 return ENOMEM;
199 }
[79ae36dd]200
[9dddb3d]201 ipc_call_t data_request_call;
[79ae36dd]202 aid_t data_request = async_data_read(exch, buf, size,
[9dddb3d]203 &data_request_call);
[79ae36dd]204
205 async_exchange_end(exch);
206
[9dddb3d]207 if (data_request == 0) {
[50b581d]208 async_forget(opening_request);
[9dddb3d]209 return ENOMEM;
210 }
[79ae36dd]211
[9dddb3d]212 sysarg_t data_request_rc;
213 sysarg_t opening_request_rc;
214 async_wait_for(data_request, &data_request_rc);
215 async_wait_for(opening_request, &opening_request_rc);
[79ae36dd]216
[9dddb3d]217 if (data_request_rc != EOK) {
218 /* Prefer return code of the opening request. */
[79ae36dd]219 if (opening_request_rc != EOK)
[9dddb3d]220 return (int) opening_request_rc;
[79ae36dd]221 else
[9dddb3d]222 return (int) data_request_rc;
223 }
[79ae36dd]224
225 if (opening_request_rc != EOK)
[9dddb3d]226 return (int) opening_request_rc;
[79ae36dd]227
[9dddb3d]228 size_t act_size = IPC_GET_ARG2(data_request_call);
[79ae36dd]229
230 if (actual_size != NULL)
[9dddb3d]231 *actual_size = act_size;
[79ae36dd]232
[9dddb3d]233 return EOK;
[d7c72db]234}
235
[27b85d9]236/**
237 * @}
238 */
Note: See TracBrowser for help on using the repository browser.