source: mainline/uspace/drv/usbhid/hidreq.c@ d4beec3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d4beec3 was b330cb1f, checked in by Lubos Slovak <lubos.slovak@…>, 14 years ago

Minor changes to HID class-specific requests.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/*
2 * Copyright (c) 2011 Lubos Slovak
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
29/** @addtogroup drvusbhid
30 * @{
31 */
32/** @file
33 * HID class-specific requests.
34 */
35
36#include <stdint.h>
37#include <errno.h>
38#include <str_error.h>
39
40#include <usb/classes/hid.h>
41#include <usb/debug.h>
42#include <usb/request.h>
43
44#include "hidreq.h"
45#include "hiddev.h"
46
47/*----------------------------------------------------------------------------*/
48
49int usbhid_req_set_report(usbhid_dev_t *hid_dev,
50 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
51{
52 if (hid_dev == NULL) {
53 usb_log_error("usbhid_req_set_report(): no HID device structure"
54 " given.\n");
55 return EINVAL;
56 }
57
58 /*
59 * No need for checking other parameters, as they are checked in
60 * the called function (usb_control_request_set()).
61 */
62
63 int rc, sess_rc;
64
65 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
66 if (sess_rc != EOK) {
67 usb_log_warning("Failed to start a session: %s.\n",
68 str_error(sess_rc));
69 return sess_rc;
70 }
71
72 uint16_t value = 0;
73 value |= (type << 8);
74
75 usb_log_debug("Sending Set_Report request to the device.\n");
76
77 rc = usb_control_request_set(&hid_dev->ctrl_pipe,
78 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
79 USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
80
81 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
82
83 if (rc != EOK) {
84 usb_log_warning("Error sending output report to the keyboard: "
85 "%s.\n", str_error(rc));
86 return rc;
87 }
88
89 if (sess_rc != EOK) {
90 usb_log_warning("Error closing session: %s.\n",
91 str_error(sess_rc));
92 return sess_rc;
93 }
94
95 return EOK;
96}
97
98/*----------------------------------------------------------------------------*/
99
100int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
101{
102 if (hid_dev == NULL) {
103 usb_log_error("usbhid_req_set_protocol(): no HID device "
104 "structure given.\n");
105 return EINVAL;
106 }
107
108 /*
109 * No need for checking other parameters, as they are checked in
110 * the called function (usb_control_request_set()).
111 */
112
113 int rc, sess_rc;
114
115 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
116 if (sess_rc != EOK) {
117 usb_log_warning("Failed to start a session: %s.\n",
118 str_error(sess_rc));
119 return sess_rc;
120 }
121
122 usb_log_debug("Sending Set_Protocol request to the device ("
123 "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);
124
125 rc = usb_control_request_set(&hid_dev->ctrl_pipe,
126 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
127 USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);
128
129 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
130
131 if (rc != EOK) {
132 usb_log_warning("Error sending output report to the keyboard: "
133 "%s.\n", str_error(rc));
134 return rc;
135 }
136
137 if (sess_rc != EOK) {
138 usb_log_warning("Error closing session: %s.\n",
139 str_error(sess_rc));
140 return sess_rc;
141 }
142
143 return EOK;
144}
145
146/*----------------------------------------------------------------------------*/
147
148int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
149{
150 if (hid_dev == NULL) {
151 usb_log_error("usbhid_req_set_idle(): no HID device "
152 "structure given.\n");
153 return EINVAL;
154 }
155
156 /*
157 * No need for checking other parameters, as they are checked in
158 * the called function (usb_control_request_set()).
159 */
160
161 int rc, sess_rc;
162
163 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
164 if (sess_rc != EOK) {
165 usb_log_warning("Failed to start a session: %s.\n",
166 str_error(sess_rc));
167 return sess_rc;
168 }
169
170 usb_log_debug("Sending Set_Idle request to the device ("
171 "duration: %u, iface: %d).\n", duration, hid_dev->iface);
172
173 uint16_t value = duration << 8;
174
175 rc = usb_control_request_set(&hid_dev->ctrl_pipe,
176 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
177 USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);
178
179 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
180
181 if (rc != EOK) {
182 usb_log_warning("Error sending output report to the keyboard: "
183 "%s.\n", str_error(rc));
184 return rc;
185 }
186
187 if (sess_rc != EOK) {
188 usb_log_warning("Error closing session: %s.\n",
189 str_error(sess_rc));
190 return sess_rc;
191 }
192
193 return EOK;
194}
195
196/*----------------------------------------------------------------------------*/
197
198int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
199 uint8_t *buffer, size_t buf_size, size_t *actual_size)
200{
201 if (hid_dev == NULL) {
202 usb_log_error("usbhid_req_set_report(): no HID device structure"
203 " given.\n");
204 return EINVAL;
205 }
206
207 /*
208 * No need for checking other parameters, as they are checked in
209 * the called function (usb_control_request_set()).
210 */
211
212 int rc, sess_rc;
213
214 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
215 if (sess_rc != EOK) {
216 usb_log_warning("Failed to start a session: %s.\n",
217 str_error(sess_rc));
218 return sess_rc;
219 }
220
221 uint16_t value = 0;
222 value |= (type << 8);
223
224 usb_log_debug("Sending Get_Report request to the device.\n");
225
226 rc = usb_control_request_get(&hid_dev->ctrl_pipe,
227 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
228 USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
229 actual_size);
230
231 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
232
233 if (rc != EOK) {
234 usb_log_warning("Error sending output report to the keyboard: "
235 "%s.\n", str_error(rc));
236 return rc;
237 }
238
239 if (sess_rc != EOK) {
240 usb_log_warning("Error closing session: %s.\n",
241 str_error(sess_rc));
242 return sess_rc;
243 }
244
245 return EOK;
246}
247
248int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
249{
250 if (hid_dev == NULL) {
251 usb_log_error("usbhid_req_set_protocol(): no HID device "
252 "structure given.\n");
253 return EINVAL;
254 }
255
256 /*
257 * No need for checking other parameters, as they are checked in
258 * the called function (usb_control_request_set()).
259 */
260
261 int rc, sess_rc;
262
263 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
264 if (sess_rc != EOK) {
265 usb_log_warning("Failed to start a session: %s.\n",
266 str_error(sess_rc));
267 return sess_rc;
268 }
269
270 usb_log_debug("Sending Get_Protocol request to the device ("
271 "iface: %d).\n", hid_dev->iface);
272
273 uint8_t buffer[1];
274 size_t actual_size = 0;
275
276 rc = usb_control_request_get(&hid_dev->ctrl_pipe,
277 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
278 USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
279
280 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
281
282 if (rc != EOK) {
283 usb_log_warning("Error sending output report to the keyboard: "
284 "%s.\n", str_error(rc));
285 return rc;
286 }
287
288 if (sess_rc != EOK) {
289 usb_log_warning("Error closing session: %s.\n",
290 str_error(sess_rc));
291 return sess_rc;
292 }
293
294 if (actual_size != 1) {
295 usb_log_warning("Wrong data size: %zu, expected: 1.\n",
296 actual_size);
297 return ELIMIT;
298 }
299
300 *protocol = buffer[0];
301
302 return EOK;
303}
304
305int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
306{
307 if (hid_dev == NULL) {
308 usb_log_error("usbhid_req_set_idle(): no HID device "
309 "structure given.\n");
310 return EINVAL;
311 }
312
313 /*
314 * No need for checking other parameters, as they are checked in
315 * the called function (usb_control_request_set()).
316 */
317
318 int rc, sess_rc;
319
320 sess_rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
321 if (sess_rc != EOK) {
322 usb_log_warning("Failed to start a session: %s.\n",
323 str_error(sess_rc));
324 return sess_rc;
325 }
326
327 usb_log_debug("Sending Get_Idle request to the device ("
328 "iface: %d).\n", hid_dev->iface);
329
330 uint16_t value = 0;
331 uint8_t buffer[1];
332 size_t actual_size = 0;
333
334 rc = usb_control_request_get(&hid_dev->ctrl_pipe,
335 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
336 USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,
337 &actual_size);
338
339 sess_rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
340
341 if (rc != EOK) {
342 usb_log_warning("Error sending output report to the keyboard: "
343 "%s.\n", str_error(rc));
344 return rc;
345 }
346
347 if (sess_rc != EOK) {
348 usb_log_warning("Error closing session: %s.\n",
349 str_error(sess_rc));
350 return sess_rc;
351 }
352
353 if (actual_size != 1) {
354 usb_log_warning("Wrong data size: %zu, expected: 1.\n",
355 actual_size);
356 return ELIMIT;
357 }
358
359 *duration = buffer[0];
360
361 return EOK;
362}
363
364/*----------------------------------------------------------------------------*/
365
366/**
367 * @}
368 */
Note: See TracBrowser for help on using the repository browser.