1 |
|
|
/*************************************************************************** |
2 |
|
|
* Copyright (c) 2024 Microsoft Corporation |
3 |
|
|
* |
4 |
|
|
* This program and the accompanying materials are made available under the |
5 |
|
|
* terms of the MIT License which is available at |
6 |
|
|
* https://opensource.org/licenses/MIT. |
7 |
|
|
* |
8 |
|
|
* SPDX-License-Identifier: MIT |
9 |
|
|
**************************************************************************/ |
10 |
|
|
|
11 |
|
|
/**************************************************************************/ |
12 |
|
|
/** */ |
13 |
|
|
/** USBX Component */ |
14 |
|
|
/** */ |
15 |
|
|
/** Device HID Class */ |
16 |
|
|
/** */ |
17 |
|
|
/**************************************************************************/ |
18 |
|
|
/**************************************************************************/ |
19 |
|
|
|
20 |
|
|
#define UX_SOURCE_CODE |
21 |
|
|
|
22 |
|
|
|
23 |
|
|
/* Include necessary system files. */ |
24 |
|
|
|
25 |
|
|
#include "ux_api.h" |
26 |
|
|
#include "ux_device_class_hid.h" |
27 |
|
|
#include "ux_device_stack.h" |
28 |
|
|
|
29 |
|
|
|
30 |
|
|
/**************************************************************************/ |
31 |
|
|
/* */ |
32 |
|
|
/* FUNCTION RELEASE */ |
33 |
|
|
/* */ |
34 |
|
|
/* _ux_device_class_hid_initialize PORTABLE C */ |
35 |
|
|
/* 6.3.0 */ |
36 |
|
|
/* AUTHOR */ |
37 |
|
|
/* */ |
38 |
|
|
/* Chaoqiong Xiao, Microsoft Corporation */ |
39 |
|
|
/* */ |
40 |
|
|
/* DESCRIPTION */ |
41 |
|
|
/* */ |
42 |
|
|
/* This function initializes the USB HID device. */ |
43 |
|
|
/* This function is called by the class register function. It is only */ |
44 |
|
|
/* done once. */ |
45 |
|
|
/* */ |
46 |
|
|
/* INPUT */ |
47 |
|
|
/* */ |
48 |
|
|
/* command Pointer to hid command */ |
49 |
|
|
/* */ |
50 |
|
|
/* OUTPUT */ |
51 |
|
|
/* */ |
52 |
|
|
/* Completion Status */ |
53 |
|
|
/* */ |
54 |
|
|
/* CALLS */ |
55 |
|
|
/* */ |
56 |
|
|
/* _ux_utility_memory_allocate Allocate memory */ |
57 |
|
|
/* _ux_utility_memory_free Free memory */ |
58 |
|
|
/* _ux_device_thread_create Create thread */ |
59 |
|
|
/* _ux_device_thread_delete Delete thread */ |
60 |
|
|
/* _ux_utility_event_flags_create Create event flags group */ |
61 |
|
|
/* */ |
62 |
|
|
/* CALLED BY */ |
63 |
|
|
/* */ |
64 |
|
|
/* USBX Source Code */ |
65 |
|
|
/* */ |
66 |
|
|
/* RELEASE HISTORY */ |
67 |
|
|
/* */ |
68 |
|
|
/* DATE NAME DESCRIPTION */ |
69 |
|
|
/* */ |
70 |
|
|
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ |
71 |
|
|
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ |
72 |
|
|
/* used UX prefix to refer to */ |
73 |
|
|
/* TX symbols instead of using */ |
74 |
|
|
/* them directly, */ |
75 |
|
|
/* resulting in version 6.1 */ |
76 |
|
|
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ |
77 |
|
|
/* added standalone support, */ |
78 |
|
|
/* added interrupt OUT support,*/ |
79 |
|
|
/* resulting in version 6.1.10 */ |
80 |
|
|
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ |
81 |
|
|
/* resulting in version 6.1.11 */ |
82 |
|
|
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ |
83 |
|
|
/* added standalone receiver, */ |
84 |
|
|
/* fixed parameter/variable */ |
85 |
|
|
/* names conflict C++ keyword, */ |
86 |
|
|
/* resulting in version 6.1.12 */ |
87 |
|
|
/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ |
88 |
|
|
/* fixed compile warnings, */ |
89 |
|
|
/* resulting in version 6.2.0 */ |
90 |
|
|
/* 10-31-2023 Chaoqiong Xiao Modified comment(s), */ |
91 |
|
|
/* added zero copy support, */ |
92 |
|
|
/* added a new mode to manage */ |
93 |
|
|
/* endpoint buffer in classes, */ |
94 |
|
|
/* checked compile options, */ |
95 |
|
|
/* resulting in version 6.3.0 */ |
96 |
|
|
/* */ |
97 |
|
|
/**************************************************************************/ |
98 |
|
206 |
UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) |
99 |
|
|
{ |
100 |
|
|
|
101 |
|
|
UX_SLAVE_CLASS_HID *hid; |
102 |
|
|
UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; |
103 |
|
|
UX_SLAVE_CLASS *class_ptr; |
104 |
|
206 |
UINT status = UX_SUCCESS; |
105 |
|
|
ULONG array_memory_size; |
106 |
|
|
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) |
107 |
|
|
UINT i; |
108 |
|
|
UCHAR *buffer; |
109 |
|
|
#endif |
110 |
|
|
|
111 |
|
|
|
112 |
|
|
/* Compile option checks. */ |
113 |
|
|
UX_ASSERT(UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH <= UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH); |
114 |
|
|
#if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 0 |
115 |
|
|
UX_ASSERT(UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH); |
116 |
|
|
#endif |
117 |
|
|
|
118 |
|
|
|
119 |
|
|
/* Get the pointer to the application parameters for the hid class. */ |
120 |
|
206 |
hid_parameter = command -> ux_slave_class_command_parameter; |
121 |
|
|
|
122 |
|
|
/* Get the class container. */ |
123 |
|
206 |
class_ptr = command -> ux_slave_class_command_class_ptr; |
124 |
|
|
|
125 |
|
|
/* Create an instance of the device hid class. */ |
126 |
|
206 |
hid = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_HID)); |
127 |
|
|
|
128 |
|
|
/* Check for successful allocation. */ |
129 |
✓✓ |
206 |
if (hid == UX_NULL) |
130 |
|
24 |
return(UX_MEMORY_INSUFFICIENT); |
131 |
|
|
|
132 |
|
|
/* Save the address of the HID instance inside the HID container. */ |
133 |
|
182 |
class_ptr -> ux_slave_class_instance = (VOID *) hid; |
134 |
|
|
|
135 |
|
|
#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) |
136 |
|
|
|
137 |
|
|
/* Allocate buffer(s) for endpoint(s). */ |
138 |
|
|
UX_ASSERT(!UX_DEVICE_CLASS_HID_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW); |
139 |
|
|
hid -> ux_device_class_hid_endpoint_buffer = _ux_utility_memory_allocate( |
140 |
|
|
UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, |
141 |
|
|
UX_DEVICE_CLASS_HID_ENDPOINT_BUFFER_SIZE); |
142 |
|
|
if (hid -> ux_device_class_hid_endpoint_buffer == UX_NULL) |
143 |
|
|
{ |
144 |
|
|
_ux_utility_memory_free(hid); |
145 |
|
|
return(UX_MEMORY_INSUFFICIENT); |
146 |
|
|
} |
147 |
|
|
#endif |
148 |
|
|
|
149 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
150 |
|
|
|
151 |
|
|
/* Allocate some memory for the thread stack. */ |
152 |
|
182 |
class_ptr -> ux_slave_class_thread_stack = |
153 |
|
182 |
_ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE); |
154 |
|
|
|
155 |
|
|
/* Check for successful allocation. */ |
156 |
✓✓ |
182 |
if (class_ptr -> ux_slave_class_thread_stack == UX_NULL) |
157 |
|
6 |
status = UX_MEMORY_INSUFFICIENT; |
158 |
|
|
|
159 |
|
|
/* This instance needs to be running in a different thread. So start |
160 |
|
|
a new thread. We pass a pointer to the class to the new thread. This thread |
161 |
|
|
does not start until we have a instance of the class. */ |
162 |
✓✓ |
182 |
if (status == UX_SUCCESS) |
163 |
|
176 |
status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", |
164 |
|
|
_ux_device_class_hid_interrupt_thread, |
165 |
|
|
(ULONG) (ALIGN_TYPE) class_ptr, (VOID *) class_ptr -> ux_slave_class_thread_stack, |
166 |
|
|
UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, |
167 |
|
|
UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); |
168 |
|
|
#else |
169 |
|
|
|
170 |
|
|
#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) |
171 |
|
|
|
172 |
|
|
/* Set event buffer. */ |
173 |
|
|
hid -> ux_device_class_hid_event.ux_device_class_hid_event_buffer = |
174 |
|
|
UX_DEVICE_CLASS_HID_INTERRUPTIN_BUFFER(hid); |
175 |
|
|
#endif |
176 |
|
|
|
177 |
|
|
/* Set task function. */ |
178 |
|
|
class_ptr -> ux_slave_class_task_function = _ux_device_class_hid_tasks_run; |
179 |
|
|
#endif |
180 |
|
|
|
181 |
|
|
/* Check the creation of this thread. */ |
182 |
✓✓ |
182 |
if (status == UX_SUCCESS) |
183 |
|
|
{ |
184 |
|
|
|
185 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
186 |
|
|
UX_THREAD_EXTENSION_PTR_SET(&(class_ptr -> ux_slave_class_thread), class_ptr) |
187 |
|
|
#endif |
188 |
|
|
|
189 |
|
|
|
190 |
|
|
/* Store all the application parameter information about the report. */ |
191 |
|
175 |
hid -> ux_device_class_hid_report_address = hid_parameter -> ux_device_class_hid_parameter_report_address; |
192 |
|
175 |
hid -> ux_device_class_hid_report_length = hid_parameter -> ux_device_class_hid_parameter_report_length; |
193 |
|
175 |
hid -> ux_device_class_hid_report_id = hid_parameter -> ux_device_class_hid_parameter_report_id; |
194 |
|
|
|
195 |
|
|
/* Store the callback function. */ |
196 |
|
175 |
hid -> ux_device_class_hid_callback = hid_parameter -> ux_device_class_hid_parameter_callback; |
197 |
|
175 |
hid -> ux_device_class_hid_get_callback = hid_parameter -> ux_device_class_hid_parameter_get_callback; |
198 |
|
|
|
199 |
|
|
#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) |
200 |
|
|
|
201 |
|
|
/* If event length is invalid, UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH is used. */ |
202 |
|
|
if (UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter) == 0 || |
203 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter) > UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH) |
204 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter) = UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH; |
205 |
|
|
|
206 |
|
|
/* If event queue size is invalid, UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE is used. */ |
207 |
|
|
if (UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter) < 2 || |
208 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter) > UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE) |
209 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter) = UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE; |
210 |
|
|
|
211 |
|
|
/* Save event size. */ |
212 |
|
|
UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid) = UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter); |
213 |
|
|
#endif |
214 |
|
|
|
215 |
|
|
/* Create the event array. */ |
216 |
|
|
UX_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG( |
217 |
|
|
UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid), |
218 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter))); |
219 |
|
175 |
array_memory_size = UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid) * UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter); |
220 |
|
175 |
hid -> ux_device_class_hid_event_array = _ux_utility_memory_allocate(UX_NO_ALIGN, |
221 |
|
|
UX_REGULAR_MEMORY, array_memory_size); |
222 |
|
|
|
223 |
|
|
/* Do we need event buffer? |
224 |
|
|
* 1. Even zero copy, report copy is kept to avoid keep buffers in application. |
225 |
|
|
* 2. Other cases, buffer must be allocated. |
226 |
|
|
*/ |
227 |
|
|
/* Allocate buffer if needed. */ |
228 |
|
|
{ |
229 |
|
|
|
230 |
|
|
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) |
231 |
|
|
|
232 |
|
|
/* Allocate cache safe event buffers. */ |
233 |
|
|
buffer = _ux_utility_memory_allocate_mulv_safe(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, |
234 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter), |
235 |
|
|
UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter)); |
236 |
|
|
|
237 |
|
|
/* Allocation error check. */ |
238 |
|
|
if (buffer == UX_NULL) |
239 |
|
|
{ |
240 |
|
|
if (hid -> ux_device_class_hid_event_array != UX_NULL) |
241 |
|
|
{ |
242 |
|
|
_ux_utility_memory_free(hid -> ux_device_class_hid_event_array); |
243 |
|
|
hid -> ux_device_class_hid_event_array = UX_NULL; |
244 |
|
|
} |
245 |
|
|
} |
246 |
|
|
else |
247 |
|
|
{ |
248 |
|
|
|
249 |
|
|
/* Assign event buffers. */ |
250 |
|
|
for (i = 0; i < UX_DEVICE_CLASS_HID_PARAM_EVENT_QUEUE_SIZE(hid_parameter); i ++) |
251 |
|
|
{ |
252 |
|
|
hid -> ux_device_class_hid_event_array[i].ux_device_class_hid_event_buffer = buffer; |
253 |
|
|
buffer += UX_DEVICE_CLASS_HID_PARAM_EVENT_MAX_LENGTH(hid_parameter); |
254 |
|
|
} |
255 |
|
|
} |
256 |
|
|
#else |
257 |
|
|
|
258 |
|
|
/* Regular event place data following id,type and length. */ |
259 |
|
|
#endif |
260 |
|
|
} |
261 |
|
|
|
262 |
|
|
/* Check for successful allocation. */ |
263 |
✓✓ |
175 |
if (hid -> ux_device_class_hid_event_array != UX_NULL) |
264 |
|
|
{ |
265 |
|
|
|
266 |
|
|
/* Initialize the head and tail of the notification round robin buffers. |
267 |
|
|
At first, the head and tail are pointing to the beginning of the array. */ |
268 |
|
169 |
hid -> ux_device_class_hid_event_array_head = hid -> ux_device_class_hid_event_array; |
269 |
|
169 |
hid -> ux_device_class_hid_event_array_tail = hid -> ux_device_class_hid_event_array; |
270 |
|
169 |
hid -> ux_device_class_hid_event_array_end = (UX_DEVICE_CLASS_HID_EVENT*)((UCHAR*)hid -> ux_device_class_hid_event_array + array_memory_size); |
271 |
|
|
|
272 |
|
|
/* Store the start and stop signals if needed by the application. */ |
273 |
|
169 |
hid -> ux_slave_class_hid_instance_activate = hid_parameter -> ux_slave_class_hid_instance_activate; |
274 |
|
169 |
hid -> ux_slave_class_hid_instance_deactivate = hid_parameter -> ux_slave_class_hid_instance_deactivate; |
275 |
|
|
|
276 |
|
|
/* By default no event wait timeout. */ |
277 |
|
169 |
hid -> ux_device_class_hid_event_wait_timeout = UX_WAIT_FOREVER; |
278 |
|
|
|
279 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
280 |
|
|
|
281 |
|
|
/* Create a event flag group for the hid class to synchronize with the event interrupt thread. */ |
282 |
|
169 |
status = _ux_utility_event_flags_create(&hid -> ux_device_class_hid_event_flags_group, "ux_device_class_hid_event_flag"); |
283 |
|
|
|
284 |
|
|
/* Check status. */ |
285 |
✓✓ |
169 |
if (status != UX_SUCCESS) |
286 |
|
1 |
status = UX_EVENT_ERROR; |
287 |
|
|
else |
288 |
|
|
#endif |
289 |
|
|
{ |
290 |
|
|
#if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) |
291 |
|
|
|
292 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
293 |
|
|
|
294 |
|
|
/* Create a mutex for reading reentry check. */ |
295 |
|
|
status = _ux_utility_mutex_create(&hid -> ux_device_class_hid_read_mutex, |
296 |
|
|
"ux_device_class_hid_read_mutex"); |
297 |
|
|
if (status == UX_SUCCESS) |
298 |
|
|
{ |
299 |
|
|
#endif |
300 |
|
|
|
301 |
|
|
/* If receiver is enabled by parameter, initialize it. */ |
302 |
|
|
if (hid_parameter -> ux_device_class_hid_parameter_receiver_initialize) |
303 |
|
|
{ |
304 |
|
|
|
305 |
|
|
/* Allocate buffer for receiver and receiver events. */ |
306 |
|
|
status = hid_parameter -> |
307 |
|
|
ux_device_class_hid_parameter_receiver_initialize(hid, |
308 |
|
|
hid_parameter, |
309 |
|
|
&hid -> ux_device_class_hid_receiver); |
310 |
|
|
} |
311 |
|
|
|
312 |
|
|
/* Done success, return. */ |
313 |
|
|
if (status == UX_SUCCESS) |
314 |
|
|
return(status); |
315 |
|
|
|
316 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
317 |
|
|
|
318 |
|
|
/* There is error, delete mutex. */ |
319 |
|
|
_ux_device_mutex_delete(&hid -> ux_device_class_hid_read_mutex); |
320 |
|
|
} |
321 |
|
|
else |
322 |
|
|
status = UX_MUTEX_ERROR; |
323 |
|
|
|
324 |
|
|
/* There is error, delete event flags. */ |
325 |
|
|
_ux_utility_event_flags_delete(&hid -> ux_device_class_hid_event_flags_group); |
326 |
|
|
#endif |
327 |
|
|
#else |
328 |
|
168 |
return(status); |
329 |
|
|
#endif |
330 |
|
|
|
331 |
|
|
} |
332 |
|
|
|
333 |
|
|
#if !defined(UX_DEVICE_STANDALONE) || defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) |
334 |
|
|
|
335 |
|
|
/* There is still initialization activities after array creation, |
336 |
|
|
* and some error occurs in this stage. */ |
337 |
|
|
/* Free allocated event array memory. */ |
338 |
|
|
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_HID_ZERO_COPY) |
339 |
|
|
_ux_utility_memory_free(hid -> ux_device_class_hid_event_array -> ux_device_class_hid_event_buffer); |
340 |
|
|
#endif |
341 |
|
1 |
_ux_utility_memory_free(hid -> ux_device_class_hid_event_array); |
342 |
|
|
#endif |
343 |
|
|
|
344 |
|
|
} |
345 |
|
|
else |
346 |
|
6 |
status = UX_MEMORY_INSUFFICIENT; |
347 |
|
|
|
348 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
349 |
|
|
|
350 |
|
|
/* Delete thread. */ |
351 |
|
7 |
_ux_device_thread_delete(&class_ptr -> ux_slave_class_thread); |
352 |
|
|
#endif |
353 |
|
|
} |
354 |
|
|
else |
355 |
|
7 |
status = (UX_THREAD_ERROR); |
356 |
|
|
|
357 |
|
|
#if !defined(UX_DEVICE_STANDALONE) |
358 |
|
|
|
359 |
|
|
/* Free stack. */ |
360 |
✓✓ |
14 |
if (class_ptr -> ux_slave_class_thread_stack) |
361 |
|
8 |
_ux_utility_memory_free(class_ptr -> ux_slave_class_thread_stack); |
362 |
|
|
#endif |
363 |
|
|
|
364 |
|
|
#if defined(UX_DEVICE_CLASS_HID_OWN_ENDPOINT_BUFFER) |
365 |
|
|
_ux_utility_memory_free(hid -> ux_device_class_hid_endpoint_buffer); |
366 |
|
|
#endif |
367 |
|
|
|
368 |
|
|
/* Unmount instance. */ |
369 |
|
14 |
class_ptr -> ux_slave_class_instance = UX_NULL; |
370 |
|
|
|
371 |
|
|
/* Free HID instance. */ |
372 |
|
14 |
_ux_utility_memory_free(hid); |
373 |
|
|
|
374 |
|
|
/* Return completion status. */ |
375 |
|
14 |
return(status); |
376 |
|
|
} |
377 |
|
|
|
378 |
|
|
|
379 |
|
|
/**************************************************************************/ |
380 |
|
|
/* */ |
381 |
|
|
/* FUNCTION RELEASE */ |
382 |
|
|
/* */ |
383 |
|
|
/* _uxe_device_class_hid_initialize PORTABLE C */ |
384 |
|
|
/* 6.3.0 */ |
385 |
|
|
/* AUTHOR */ |
386 |
|
|
/* */ |
387 |
|
|
/* Chaoqiong Xiao, Microsoft Corporation */ |
388 |
|
|
/* */ |
389 |
|
|
/* DESCRIPTION */ |
390 |
|
|
/* */ |
391 |
|
|
/* This function checks errors in HID initialize function call. */ |
392 |
|
|
/* */ |
393 |
|
|
/* INPUT */ |
394 |
|
|
/* */ |
395 |
|
|
/* command Pointer to hid command */ |
396 |
|
|
/* */ |
397 |
|
|
/* OUTPUT */ |
398 |
|
|
/* */ |
399 |
|
|
/* None */ |
400 |
|
|
/* */ |
401 |
|
|
/* CALLS */ |
402 |
|
|
/* */ |
403 |
|
|
/* _ux_device_class_hid_initialize Initialize HID instance */ |
404 |
|
|
/* */ |
405 |
|
|
/* CALLED BY */ |
406 |
|
|
/* */ |
407 |
|
|
/* Device Stack */ |
408 |
|
|
/* */ |
409 |
|
|
/* RELEASE HISTORY */ |
410 |
|
|
/* */ |
411 |
|
|
/* DATE NAME DESCRIPTION */ |
412 |
|
|
/* */ |
413 |
|
|
/* 10-31-2023 Chaoqiong Xiao Initial Version 6.3.0 */ |
414 |
|
|
/* */ |
415 |
|
|
/**************************************************************************/ |
416 |
|
|
UINT _uxe_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) |
417 |
|
|
{ |
418 |
|
|
|
419 |
|
|
UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; |
420 |
|
|
|
421 |
|
|
/* Get the pointer to the application parameters for the hid class. */ |
422 |
|
|
hid_parameter = command -> ux_slave_class_command_parameter; |
423 |
|
|
|
424 |
|
|
/* Check input parameters. */ |
425 |
|
|
if ((hid_parameter -> ux_device_class_hid_parameter_report_address == UX_NULL) || |
426 |
|
|
(hid_parameter -> ux_device_class_hid_parameter_report_length == 0) || |
427 |
|
|
(hid_parameter -> ux_device_class_hid_parameter_report_length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)) |
428 |
|
|
{ |
429 |
|
|
return(UX_INVALID_PARAMETER); |
430 |
|
|
} |
431 |
|
|
|
432 |
|
|
/* Invoke initialize function. */ |
433 |
|
|
return(_ux_device_class_hid_initialize(command)); |
434 |
|
|
} |