1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016,2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_host_config.h"
10 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
11 #include "usb_host.h"
12 #include "usb_host_hub.h"
13
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17
18 /*******************************************************************************
19 * Prototypes
20 ******************************************************************************/
21 /*!
22 * @brief hub control transfer callback.
23 *
24 * @param param callback parameter.
25 * @param transfer callback transfer.
26 * @param status transfer status.
27 */
28 static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
29
30 /*!
31 * @brief hub interrupt in transfer callback.
32 *
33 * @param param callback parameter.
34 * @param transfer callback transfer.
35 * @param status transfer status.
36 */
37 static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
38
39 /*!
40 * @brief USB_HostHubSendPortReset's transfer callback.
41 *
42 * @param param callback parameter.
43 * @param transfer callback transfer.
44 * @param status transfer status.
45 */
46 static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
47
48 /*!
49 * @brief hub control transfer common code.
50 *
51 * @param classHandle the class handle.
52 * @param requestType request type.
53 * @param request setup packet request field.
54 * @param wvalue setup packet wValue field.
55 * @param windex setup packet wIndex field.
56 * @param buffer the buffer pointer.
57 * @param bufferLength the buffer length.
58 * @param callbackFn this callback is called after this function completes.
59 * @param callbackParam the first parameter in the callback function.
60 *
61 * @return kStatus_USB_Success or error codes.
62 */
63 static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
64 uint8_t requestType,
65 uint8_t request,
66 uint16_t wvalue,
67 uint16_t windex,
68 uint8_t *buffer,
69 uint16_t bufferLength,
70 transfer_callback_t callbackFn,
71 void *callbackParam);
72
73 /*******************************************************************************
74 * Variables
75 ******************************************************************************/
76
77 /*******************************************************************************
78 * Code
79 ******************************************************************************/
80
USB_HostHubControlCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)81 static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
82 {
83 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
84
85 hubInstance->controlTransfer = NULL;
86 if (NULL != hubInstance->controlCallbackFn)
87 {
88 /* callback to application, callback function is initialized in the USB_HostPrinterControl,
89 USB_HostPrinterSetInterface
90 or USB_HostHubClassRequestCommon, but is the same function */
91 hubInstance->controlCallbackFn(hubInstance->controlCallbackParam, transfer->transferBuffer,
92 transfer->transferSofar, status); /* callback to application */
93 }
94 (void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
95 }
96
USB_HostHubInPipeCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)97 static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
98 {
99 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
100
101 if (NULL != hubInstance->inCallbackFn)
102 {
103 /* callback to application, callback function is initialized in the USB_HostHubInterruptRecv */
104 hubInstance->inCallbackFn(hubInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
105 status); /* callback to application */
106 }
107 (void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
108 }
109
USB_HostHubResetCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)110 static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
111 {
112 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
113
114 /* note: there is not callback to application, the re-enumeration will start automatically after reset. */
115 (void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
116 }
117
USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,uint8_t requestType,uint8_t request,uint16_t wvalue,uint16_t windex,uint8_t * buffer,uint16_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)118 static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
119 uint8_t requestType,
120 uint8_t request,
121 uint16_t wvalue,
122 uint16_t windex,
123 uint8_t *buffer,
124 uint16_t bufferLength,
125 transfer_callback_t callbackFn,
126 void *callbackParam)
127 {
128 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
129 usb_host_transfer_t *transfer;
130
131 if (hubInstance->controlTransfer != NULL)
132 {
133 return kStatus_USB_Busy;
134 }
135
136 /* get transfer */
137 if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
138 {
139 #ifdef HOST_ECHO
140 usb_echo("error to get transfer\r\n");
141 #endif
142 return kStatus_USB_Error;
143 }
144
145 /* save hub application callback */
146 hubInstance->controlCallbackFn = callbackFn;
147 hubInstance->controlCallbackParam = callbackParam;
148
149 /* initialize transfer */
150 transfer->transferBuffer = buffer;
151 transfer->transferLength = bufferLength;
152 transfer->callbackFn = USB_HostHubControlCallback;
153 transfer->callbackParam = hubInstance;
154 transfer->setupPacket->bmRequestType = requestType;
155 transfer->setupPacket->bRequest = request;
156 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
157 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
158 transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(bufferLength);
159
160 /* send transfer */
161 if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
162 {
163 #ifdef HOST_ECHO
164 usb_echo("Error in hid get report descriptor\r\n");
165 #endif
166 (void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
167 return kStatus_USB_Error;
168 }
169 hubInstance->controlTransfer = transfer; /* record the on-going setup transfer */
170 return kStatus_USB_Success;
171 }
172
USB_HostHubInit(usb_device_handle deviceHandle,usb_host_class_handle * classHandle)173 usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
174 {
175 /* malloc the hub instance */
176 usb_host_hub_instance_t *hubInstance =
177 (usb_host_hub_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_hub_instance_t));
178 uint32_t *temp;
179 uint32_t infoValue = 0U;
180
181 if (hubInstance == NULL)
182 {
183 return kStatus_USB_AllocFail;
184 }
185
186 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
187 hubInstance->hubDescriptor = (uint8_t *)SDK_Malloc(7 + (USB_HOST_HUB_MAX_PORT >> 3) + 1, USB_CACHE_LINESIZE);
188 hubInstance->portStatusBuffer = (uint8_t *)SDK_Malloc(4, USB_CACHE_LINESIZE);
189 hubInstance->hubStatusBuffer = (uint8_t *)SDK_Malloc(4, USB_CACHE_LINESIZE);
190 hubInstance->hubBitmapBuffer = (uint8_t *)SDK_Malloc((USB_HOST_HUB_MAX_PORT >> 3) + 1, USB_CACHE_LINESIZE);
191 #endif
192
193 /* initialize hub instance structure */
194 hubInstance->deviceHandle = deviceHandle;
195 hubInstance->interfaceHandle = NULL;
196 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetHostHandle, &infoValue);
197 temp = (uint32_t *)infoValue;
198 hubInstance->hostHandle = (usb_host_handle)temp;
199 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceControlPipe, &infoValue);
200 temp = (uint32_t *)infoValue;
201 hubInstance->controlPipe = (usb_host_pipe_handle)temp;
202 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceLevel, &infoValue);
203 hubInstance->hubLevel = (uint8_t)infoValue;
204
205 *classHandle = hubInstance; /* return the hub class handle */
206 return kStatus_USB_Success;
207 }
208
USB_HostHubSetInterface(usb_host_class_handle classHandle,usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,transfer_callback_t callbackFn,void * callbackParam)209 usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
210 usb_host_interface_handle interfaceHandle,
211 uint8_t alternateSetting,
212 transfer_callback_t callbackFn,
213 void *callbackParam)
214 {
215 usb_status_t status;
216 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
217 usb_host_interface_t *interface = (usb_host_interface_t *)interfaceHandle;
218 usb_descriptor_endpoint_t *epDesc = NULL;
219 usb_host_pipe_init_t pipeInit;
220 uint8_t epIndex;
221
222 if (classHandle == NULL)
223 {
224 return kStatus_USB_InvalidHandle;
225 }
226
227 hubInstance->interfaceHandle = interfaceHandle; /* save the interface handle */
228
229 /* notify the host driver that the interface is used by class */
230 status = USB_HostOpenDeviceInterface(hubInstance->deviceHandle, interfaceHandle);
231 if (status != kStatus_USB_Success)
232 {
233 return status;
234 }
235
236 /* close opened hub interrupt pipe */
237 if (hubInstance->interruptPipe != NULL)
238 {
239 status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
240 if (status != kStatus_USB_Success)
241 {
242 #ifdef HOST_ECHO
243 usb_echo("error when Cancel pipe\r\n");
244 #endif
245 }
246 status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
247 if (status != kStatus_USB_Success)
248 {
249 #ifdef HOST_ECHO
250 usb_echo("error when close pipe\r\n");
251 #endif
252 }
253 hubInstance->interruptPipe = NULL;
254 }
255
256 /* open hub interrupt pipe */
257 for (epIndex = 0; epIndex < interface->epCount; ++epIndex)
258 {
259 epDesc = interface->epList[epIndex].epDesc;
260 if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
261 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
262 ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
263 {
264 /* get pipe information from endpoint descriptor */
265 pipeInit.devInstance = hubInstance->deviceHandle;
266 pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
267 pipeInit.direction = USB_IN;
268 pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
269 pipeInit.interval = epDesc->bInterval;
270 pipeInit.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
271 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
272 pipeInit.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
273 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
274 pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
275
276 /* open hub interrupt in pipe */
277 status = USB_HostOpenPipe(hubInstance->hostHandle, &hubInstance->interruptPipe, &pipeInit);
278 if (status != kStatus_USB_Success)
279 {
280 #ifdef HOST_ECHO
281 usb_echo("usb_host_hid_set_interface fail to open pipe\r\n");
282 #endif
283 return kStatus_USB_Error;
284 }
285 break;
286 }
287 }
288
289 /* hub don't support alternatesetting that is not 0 */
290 if (alternateSetting == 0U)
291 {
292 if (callbackFn != NULL)
293 {
294 callbackFn(callbackParam, NULL, 0, kStatus_USB_Success);
295 }
296 }
297 else
298 {
299 #ifdef HOST_ECHO
300 usb_echo("host don't support alternate setting\r\n");
301 #endif
302 return kStatus_USB_Error;
303 }
304
305 return status;
306 }
307
USB_HostHubDeinit(usb_device_handle deviceHandle,usb_host_class_handle classHandle)308 usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
309 {
310 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
311 usb_status_t status = kStatus_USB_Success;
312 if (deviceHandle == NULL)
313 {
314 return kStatus_USB_InvalidHandle;
315 }
316
317 if (classHandle != NULL)
318 {
319 /* close opened hub interrupt pipe */
320 if (hubInstance->interruptPipe != NULL)
321 {
322 status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
323 if (status != kStatus_USB_Success)
324 {
325 #ifdef HOST_ECHO
326 usb_echo("error when Cancel pipe\r\n");
327 #endif
328 }
329 status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
330 if (status != kStatus_USB_Success)
331 {
332 #ifdef HOST_ECHO
333 usb_echo("hub close interrupt pipe error\r\n");
334 #endif
335 }
336 hubInstance->interruptPipe = NULL;
337 }
338
339 /* cancel control transfer if exist */
340 if ((hubInstance->controlPipe != NULL) && (hubInstance->controlTransfer != NULL))
341 {
342 status =
343 USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->controlPipe, hubInstance->controlTransfer);
344 }
345
346 /* notify host driver that the interface will not be used */
347 (void)USB_HostCloseDeviceInterface(deviceHandle, hubInstance->interfaceHandle);
348 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
349 SDK_Free(hubInstance->hubDescriptor);
350 SDK_Free(hubInstance->portStatusBuffer);
351 SDK_Free(hubInstance->hubStatusBuffer);
352 SDK_Free(hubInstance->hubBitmapBuffer);
353 #endif
354 OSA_MemoryFree(hubInstance);
355 }
356 else
357 {
358 /* notify host driver that the interface will not be used */
359 (void)USB_HostCloseDeviceInterface(deviceHandle, NULL);
360 }
361
362 return status;
363 }
364
USB_HostHubInterruptRecv(usb_host_class_handle classHandle,uint8_t * buffer,uint16_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)365 usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
366 uint8_t *buffer,
367 uint16_t bufferLength,
368 transfer_callback_t callbackFn,
369 void *callbackParam)
370 {
371 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
372 usb_host_transfer_t *transfer;
373
374 if (classHandle == NULL)
375 {
376 return kStatus_USB_InvalidHandle;
377 }
378
379 /* get transfer */
380 if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
381 {
382 #ifdef HOST_ECHO
383 usb_echo("error to get transfer\r\n");
384 #endif
385 return kStatus_USB_Error;
386 }
387
388 /* save hub application callback */
389 hubInstance->inCallbackFn = callbackFn;
390 hubInstance->inCallbackParam = callbackParam;
391
392 /* initialize transfer */
393 transfer->transferBuffer = buffer;
394 transfer->transferLength = bufferLength;
395 transfer->callbackFn = USB_HostHubInPipeCallback;
396 transfer->callbackParam = hubInstance;
397
398 /* call host driver API to receive data */
399 if (USB_HostRecv(hubInstance->hostHandle, hubInstance->interruptPipe, transfer) != kStatus_USB_Success)
400 {
401 #ifdef HOST_ECHO
402 usb_echo("failed to USB_HostRecv\r\n");
403 #endif
404 (void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
405 return kStatus_USB_Error;
406 }
407
408 return kStatus_USB_Success;
409 }
410
USB_HostHubSendPortReset(usb_host_class_handle classHandle,uint8_t portNumber)411 usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber)
412 {
413 usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
414 usb_host_transfer_t *transfer;
415
416 if (classHandle == NULL)
417 {
418 return kStatus_USB_InvalidHandle;
419 }
420
421 /* get transfer */
422 if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
423 {
424 #ifdef HOST_ECHO
425 usb_echo("error to get transfer\r\n");
426 #endif
427 return kStatus_USB_Busy;
428 }
429
430 /* initialize transfer */
431 transfer->transferBuffer = NULL;
432 transfer->transferLength = 0;
433 transfer->callbackFn = USB_HostHubResetCallback;
434 transfer->callbackParam = hubInstance;
435 transfer->setupPacket->bmRequestType =
436 USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER;
437 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_FEATURE;
438 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(PORT_RESET);
439 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(portNumber);
440 transfer->setupPacket->wLength = 0;
441
442 /* send the transfer */
443 if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
444 {
445 #ifdef HOST_ECHO
446 usb_echo("Error in hid get report descriptor\r\n");
447 #endif
448 (void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
449 return kStatus_USB_Error;
450 }
451 return kStatus_USB_Success;
452 }
453
454 /*!
455 * @brief hub get descriptor.
456 *
457 * This function implements get hub descriptor specific request.
458 *
459 * @param classHandle the class handle.
460 * @param buffer the buffer pointer.
461 * @param bufferLength the buffer length.
462 * @param callbackFn this callback is called after this function completes.
463 * @param callbackParam the first parameter in the callback function.
464 *
465 * @retval kStatus_USB_Success send successfully.
466 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
467 * @retval kStatus_USB_Busy There is no idle transfer.
468 * @retval kStatus_USB_Error pipe is not initialized.
469 * Or, send transfer fail, please reference to USB_HostSendSetup.
470 */
USB_HostHubGetDescriptor(usb_host_class_handle classHandle,uint8_t * buffer,uint16_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)471 usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
472 uint8_t *buffer,
473 uint16_t bufferLength,
474 transfer_callback_t callbackFn,
475 void *callbackParam)
476 {
477 return USB_HostHubClassRequestCommon(
478 classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_DEVICE,
479 USB_REQUEST_STANDARD_GET_DESCRIPTOR, 0x00, 0, buffer, bufferLength, callbackFn, callbackParam);
480 }
481
482 /*!
483 * @brief hub clear feature.
484 *
485 * This function implements clear hub feature specific request.
486 *
487 * @param classHandle the class handle.
488 * @param buffer the buffer pointer.
489 * @param bufferLength the buffer length.
490 * @param callbackFn this callback is called after this function completes.
491 * @param callbackParam the first parameter in the callback function.
492 *
493 * @retval kStatus_USB_Success send successfully.
494 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
495 * @retval kStatus_USB_Busy There is no idle transfer.
496 * @retval kStatus_USB_Error pipe is not initialized.
497 * Or, send transfer fail, please reference to USB_HostSendSetup.
498 */
USB_HostHubClearFeature(usb_host_class_handle classHandle,uint8_t feature,transfer_callback_t callbackFn,void * callbackParam)499 usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
500 uint8_t feature,
501 transfer_callback_t callbackFn,
502 void *callbackParam)
503 {
504 return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS,
505 USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, 0, NULL, 0, callbackFn,
506 callbackParam);
507 }
508
509 /*!
510 * @brief hub get status.
511 *
512 * This function implements get hub status specific request.
513 *
514 * @param classHandle the class handle.
515 * @param buffer the buffer pointer.
516 * @param bufferLength the buffer length.
517 * @param callbackFn this callback is called after this function completes.
518 * @param callbackParam the first parameter in the callback function.
519 *
520 * @retval kStatus_USB_Success send successfully.
521 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
522 * @retval kStatus_USB_Busy There is no idle transfer.
523 * @retval kStatus_USB_Error pipe is not initialized.
524 * Or, send transfer fail, please reference to USB_HostSendSetup.
525 */
USB_HostHubGetStatus(usb_host_class_handle classHandle,uint8_t * buffer,uint16_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)526 usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
527 uint8_t *buffer,
528 uint16_t bufferLength,
529 transfer_callback_t callbackFn,
530 void *callbackParam)
531 {
532 return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS,
533 USB_REQUEST_STANDARD_GET_STATUS, 0, 0, buffer, bufferLength, callbackFn,
534 callbackParam);
535 }
536
537 /*!
538 * @brief hub set feature.
539 *
540 * This function implements set hub feature specific request.
541 *
542 * @param classHandle the class handle.
543 * @param buffer the buffer pointer.
544 * @param bufferLength the buffer length.
545 * @param callbackFn this callback is called after this function completes.
546 * @param callbackParam the first parameter in the callback function.
547 *
548 * @retval kStatus_USB_Success send successfully.
549 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
550 * @retval kStatus_USB_Busy There is no idle transfer.
551 * @retval kStatus_USB_Error pipe is not initialized.
552 * Or, send transfer fail, please reference to USB_HostSendSetup.
553 */
USB_HostHubSetPortFeature(usb_host_class_handle classHandle,uint8_t portNumber,uint8_t feature,transfer_callback_t callbackFn,void * callbackParam)554 usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
555 uint8_t portNumber,
556 uint8_t feature,
557 transfer_callback_t callbackFn,
558 void *callbackParam)
559 {
560 return USB_HostHubClassRequestCommon(
561 classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
562 USB_REQUEST_STANDARD_SET_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
563 }
564
565 /*!
566 * @brief hub clear port feature.
567 *
568 * This function implements clear hub port feature specific request.
569 *
570 * @param classHandle the class handle.
571 * @param buffer the buffer pointer.
572 * @param bufferLength the buffer length.
573 * @param callbackFn this callback is called after this function completes.
574 * @param callbackParam the first parameter in the callback function.
575 *
576 * @retval kStatus_USB_Success send successfully.
577 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
578 * @retval kStatus_USB_Busy There is no idle transfer.
579 * @retval kStatus_USB_Error pipe is not initialized.
580 * Or, send transfer fail, please reference to USB_HostSendSetup.
581 */
USB_HostHubClearPortFeature(usb_host_class_handle classHandle,uint8_t portNumber,uint8_t feature,transfer_callback_t callbackFn,void * callbackParam)582 usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
583 uint8_t portNumber,
584 uint8_t feature,
585 transfer_callback_t callbackFn,
586 void *callbackParam)
587 {
588 return USB_HostHubClassRequestCommon(
589 classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
590 USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
591 }
592
593 /*!
594 * @brief hub port get status.
595 *
596 * This function implements get hub port status specific request.
597 *
598 * @param classHandle the class handle.
599 * @param buffer the buffer pointer.
600 * @param bufferLength the buffer length.
601 * @param callbackFn this callback is called after this function completes.
602 * @param callbackParam the first parameter in the callback function.
603 *
604 * @retval kStatus_USB_Success send successfully.
605 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
606 * @retval kStatus_USB_Busy There is no idle transfer.
607 * @retval kStatus_USB_Error pipe is not initialized.
608 * Or, send transfer fail, please reference to USB_HostSendSetup.
609 */
USB_HostHubGetPortStatus(usb_host_class_handle classHandle,uint8_t portNumber,uint8_t * buffer,uint16_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)610 usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
611 uint8_t portNumber,
612 uint8_t *buffer,
613 uint16_t bufferLength,
614 transfer_callback_t callbackFn,
615 void *callbackParam)
616 {
617 return USB_HostHubClassRequestCommon(
618 classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
619 USB_REQUEST_STANDARD_GET_STATUS, 0, portNumber, buffer, bufferLength, callbackFn, callbackParam);
620 }
621
622 #endif /* USB_HOST_CONFIG_HUB */
623