1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016,2019 NXP
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "usb_host_config.h"
9 #include "usb_host.h"
10 #include "usb_host_hci.h"
11 #include "usb_host_devices.h"
12 #include "usb_host_framework.h"
13 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
14 #include "usb_host_hub.h"
15 #include "usb_host_hub_app.h"
16 #endif /* USB_HOST_CONFIG_HUB */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 #ifndef USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH
23 #define USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH (5000U)
24 #endif
25 
26 /*******************************************************************************
27  * Prototypes
28  ******************************************************************************/
29 
30 /*!
31  * @brief enumeration transfer callback function.
32  *
33  * @param param      callback parameter.
34  * @param transfer   the transfer.
35  * @param status     transfer result status.
36  */
37 static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
38 
39 /*!
40  * @brief process the new step state.
41  *
42  * @param deviceInstance    device instance pointer.
43  *
44  * @return kStatus_USB_Success or error codes
45  */
46 static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance);
47 
48 /*!
49  * @brief process the previous step transfer result.
50  *
51  * @param deviceInstance    device instance pointer.
52  *
53  * @return kStatus_USB_Success or error codes
54  */
55 static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance, uint32_t dataLength);
56 
57 /*!
58  * @brief notify the application event, the callback is registered when initializing host.
59  *
60  * @param deviceInstance   device instance pointer.
61  * @param eventCode        event code.
62  *
63  * @return kStatus_USB_Success or error codes
64  */
65 static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
66                                          usb_host_device_instance_t *deviceInstance,
67                                          uint32_t eventCode,
68                                          uint32_t eventParameter);
69 
70 /*!
71  * @brief allocate one address.
72  *
73  * @param hostInstance    host instance pointer.
74  *
75  * @return address, 0 is invalid.
76  */
77 static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance);
78 
79 /*!
80  * @brief release one address.
81  *
82  * @param hostInstance    host instance pointer.
83  * @param address     releasing address.
84  */
85 static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address);
86 
87 /*!
88  * @brief release device resource.
89  *
90  * @param hostInstance   host instance pointer.
91  * @param deviceInstance    device instance pointer.
92  */
93 static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance,
94                                           usb_host_device_instance_t *deviceInstance);
95 
96 /*!
97  * @brief parse device configuration descriptor.
98  *
99  * @param deviceHandle    device handle.
100  *
101  * @return kStatus_USB_Success or error codes.
102  */
103 static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle);
104 
105 /*!
106  * @brief remove device instance from host device list.
107  *
108  * @param hostHandle   host instance handle.
109  * @param deviceHandle    device handle.
110  *
111  * @return kStatus_USB_Success or error codes.
112  */
113 static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle);
114 
115 /*!
116  * @brief control the bus.
117  *
118  * This function control the host bus.
119  *
120  * @param[in] hostHandle     the host handle.
121  * @param[in] controlType    the control code, please reference to bus_event_t.
122  *
123  * @retval kStatus_USB_Success              control successfully.
124  * @retval kStatus_USB_InvalidHandle        The hostHandle is a NULL pointer.
125  */
126 static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType);
127 
128 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
129 
130 #endif
131 
132 /*******************************************************************************
133  * Variables
134  ******************************************************************************/
135 
136 /*! @brief enumeration step process array */
137 static const usb_host_enum_process_entry_t s_EnumEntries[] = {
138     /* kStatus_dev_initial */
139     {
140         kStatus_DEV_Notinit,
141         kStatus_DEV_Notinit,
142         NULL,
143     },
144     /* kStatus_DEV_GetDes8 */
145     {
146         kStatus_DEV_SetAddress,
147         kStatus_DEV_GetDes8,
148         USB_HostProcessCallback,
149     },
150     /* kStatus_DEV_SetAddress */
151     {
152         kStatus_DEV_GetDes,
153         kStatus_DEV_SetAddress,
154         USB_HostProcessCallback,
155     },
156     /* kStatus_DEV_GetDes */
157     {
158         kStatus_DEV_GetCfg9,
159         kStatus_DEV_GetDes,
160         NULL,
161     },
162     /* kStatus_DEV_GetCfg9 */
163     {
164         kStatus_DEV_GetCfg,
165         kStatus_DEV_GetCfg9,
166         USB_HostProcessCallback,
167     },
168     /* kStatus_DEV_GetCfg */
169     {
170         kStatus_DEV_SetCfg,
171         kStatus_DEV_GetCfg9,
172         USB_HostProcessCallback,
173     },
174     /* kStatus_DEV_SetCfg */
175     {
176         kStatus_DEV_EnumDone,
177         kStatus_DEV_SetCfg,
178         NULL,
179     },
180 };
181 
182 /*******************************************************************************
183  * Code
184  ******************************************************************************/
185 
USB_HostEnumerationTransferCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)186 static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
187 {
188     /* 0 - retry current transfer, 1 - transfer success process,
189      * 2 - retry whole process, 3 - fail process
190      */
191     uint8_t nextStep                           = 0U;
192     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)param;
193     usb_status_t failReason                    = kStatus_USB_Success;
194     uint32_t dataLength;
195 
196     dataLength = transfer->transferSofar;
197     (void)USB_HostFreeTransfer(deviceInstance->hostHandle, transfer); /* free transfer */
198 
199     if (status == kStatus_USB_Success)
200     {
201         nextStep = 1U;
202     }
203     else if (status == kStatus_USB_TransferStall)
204     {
205 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
206         (void)usb_echo("no response from device\r\n");
207 #endif                                         /* USB_HOST_CONFIG_COMPLIANCE_TEST */
208         if (deviceInstance->stallRetries > 0U) /* retry same transfer when stall */
209         {
210             nextStep = 0U;
211             deviceInstance->stallRetries--;
212         }
213         else
214         {
215             failReason = kStatus_USB_TransferFailed;
216             nextStep   = 2U;
217         }
218     }
219     else if (status == kStatus_USB_TransferCancel)
220     {
221         failReason = kStatus_USB_TransferCancel;
222         nextStep   = 3U;
223     }
224     else
225     {
226         failReason = kStatus_USB_TransferFailed;
227         nextStep   = 2U;
228     }
229 
230     if (nextStep == 1U)
231     {
232         deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
233         if (s_EnumEntries[deviceInstance->state - 1U].process == NULL)
234         {
235             deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].successState; /* next state */
236         }
237         else
238         {
239             status = s_EnumEntries[deviceInstance->state - 1U].process(
240                 deviceInstance, dataLength);   /* process the previous state result */
241             if (status == kStatus_USB_Success) /* process success */
242             {
243                 deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].successState;
244             }
245             else if (status == kStatus_USB_Retry) /* need retry */
246             {
247                 deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].retryState;
248             }
249             else if (status == kStatus_USB_NotSupported) /* device don't suport by the application */
250             {
251                 return; /* unrecoverable fail */
252             }
253             else /* process error, next retry */
254             {
255                 /* kStatus_USB_Error or kStatus_USB_AllocFail */
256                 failReason = status;
257                 nextStep   = 2U;
258             }
259         }
260     }
261 
262     if (nextStep == 2U)
263     {
264         if (deviceInstance->enumRetries > 0U) /* next whole retry */
265         {
266             deviceInstance->enumRetries--;
267             deviceInstance->stallRetries       = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
268             deviceInstance->configurationValue = 0U;
269             deviceInstance->state              = (uint8_t)kStatus_DEV_GetDes8;
270         }
271         else
272         {
273 #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
274             usb_echo("Device No Response\r\n");
275 #endif
276             nextStep = 3U;
277         }
278     }
279 
280     /* process the state */
281     if (nextStep != 3U)
282     {
283         if (USB_HostProcessState(deviceInstance) != kStatus_USB_Success)
284         {
285 #ifdef HOST_ECHO
286             usb_echo("enumation setup error\r\n");
287 #endif
288             failReason = kStatus_USB_Error;
289             nextStep   = 3U;
290         }
291     }
292 
293     if (nextStep == 3U)
294     {
295         (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventEnumerationFail,
296                                    (uint32_t)failReason);
297     }
298 }
299 
USB_HostProcessState(usb_host_device_instance_t * deviceInstance)300 static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance)
301 {
302     usb_status_t status = kStatus_USB_Success;
303     usb_host_process_descriptor_param_t getDescriptorParam;
304     usb_host_transfer_t *transfer;
305     usb_host_device_enumeration_status_t state;
306 
307     /* malloc transfer */
308     state = (usb_host_device_enumeration_status_t)deviceInstance->state;
309     if (state != kStatus_DEV_EnumDone)
310     {
311         if (USB_HostMallocTransfer(deviceInstance->hostHandle, &transfer) != kStatus_USB_Success)
312         {
313 #ifdef HOST_ECHO
314             usb_echo("error to get transfer\r\n");
315 #endif
316             return kStatus_USB_Error;
317         }
318         transfer->callbackFn    = USB_HostEnumerationTransferCallback;
319         transfer->callbackParam = deviceInstance;
320 
321         /* reset transfer fields */
322         transfer->setupPacket->bmRequestType = 0x00U;
323         transfer->setupPacket->wIndex        = 0U;
324         transfer->setupPacket->wLength       = 0U;
325         transfer->setupPacket->wValue        = 0U;
326     }
327 
328     switch (state)
329     {
330         case kStatus_DEV_GetDes8:
331         case kStatus_DEV_GetDes: /* get descriptor state */
332             getDescriptorParam.descriptorLength = (uint16_t)sizeof(usb_descriptor_device_t);
333             if (deviceInstance->state == (uint8_t)kStatus_DEV_GetDes8)
334             {
335                 getDescriptorParam.descriptorLength = 8U;
336             }
337             getDescriptorParam.descriptorBuffer = (uint8_t *)deviceInstance->deviceDescriptor;
338             getDescriptorParam.descriptorType   = USB_DESCRIPTOR_TYPE_DEVICE;
339             getDescriptorParam.descriptorIndex  = 0U;
340             getDescriptorParam.languageId       = 0U;
341 
342             transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
343             transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
344             status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
345             break;
346         case kStatus_DEV_SetAddress: /* set address state */
347             transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_ADDRESS;
348             status = USB_HostStandardSetAddress(deviceInstance, transfer, &deviceInstance->allocatedAddress);
349             break;
350 
351         case kStatus_DEV_GetCfg9: /* get 9 bytes configuration state */
352             getDescriptorParam.descriptorBuffer = deviceInstance->enumBuffer;
353             getDescriptorParam.descriptorType   = USB_DESCRIPTOR_TYPE_CONFIGURE;
354             getDescriptorParam.descriptorIndex  = deviceInstance->configurationValue;
355             getDescriptorParam.descriptorLength = 9;
356             getDescriptorParam.languageId       = 0;
357 
358             transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
359             transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
360             status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
361             break;
362 
363         case kStatus_DEV_GetCfg: /* get configuration state */
364             getDescriptorParam.descriptorBuffer = deviceInstance->configurationDesc;
365             getDescriptorParam.descriptorType   = USB_DESCRIPTOR_TYPE_CONFIGURE;
366             getDescriptorParam.descriptorIndex  = deviceInstance->configurationValue;
367             getDescriptorParam.descriptorLength = deviceInstance->configurationLen;
368             getDescriptorParam.languageId       = 0;
369 
370             transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
371             transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
372             status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
373             break;
374 
375         case kStatus_DEV_SetCfg: /* set configuration state */
376             transfer->setupPacket->wValue =
377                 USB_SHORT_TO_LITTLE_ENDIAN(deviceInstance->configuration.configurationDesc->bConfigurationValue);
378             transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_CONFIGURATION;
379             status                          = USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
380             break;
381 
382         case kStatus_DEV_EnumDone: /* enumeration done state */
383             /* notify device enumeration done */
384             status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
385                                           (uint32_t)kUSB_HostEventEnumerationDone, (uint32_t)kStatus_USB_Success);
386             if (status == kStatus_USB_Success)
387             {
388                 deviceInstance->state = (uint8_t)kStatus_DEV_AppUsed;
389             }
390             break;
391 
392         default:
393             /*no action*/
394             break;
395     }
396 
397     return status;
398 }
399 
USB_HostProcessCallback(usb_host_device_instance_t * deviceInstance,uint32_t dataLength)400 static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance, uint32_t dataLength)
401 {
402     usb_host_pipe_t *pipe = (usb_host_pipe_t *)deviceInstance->controlPipe;
403     usb_status_t status   = kStatus_USB_Success;
404     usb_descriptor_configuration_t *configureDesc;
405     usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
406     void *temp;
407     usb_host_device_enumeration_status_t state;
408 #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
409 #if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
410     usb_host_hub_instance_t *hubInstance4Device = NULL;
411 #endif
412 #endif
413 
414     state = (usb_host_device_enumeration_status_t)deviceInstance->state;
415     switch (state)
416     {
417         case kStatus_DEV_GetDes8: /* process get 8 bytes descriptor result */
418             if (dataLength != 8u)
419             {
420                 return kStatus_USB_Error;
421             }
422             pipe->maxPacketSize = deviceInstance->deviceDescriptor->bMaxPacketSize0;
423             /* the callbackFn is initialized in USB_HostGetControllerInterface */
424             (void)hostInstance->controllerTable->controllerIoctl(
425                 hostInstance->controllerHandle, kUSB_HostUpdateControlPacketSize, deviceInstance->controlPipe);
426             break;
427 
428         case kStatus_DEV_SetAddress: /* process set address result */
429             deviceInstance->setAddress = deviceInstance->allocatedAddress;
430             /* the callbackFn is initialized in USB_HostGetControllerInterface */
431             (void)hostInstance->controllerTable->controllerIoctl(
432                 hostInstance->controllerHandle, kUSB_HostUpdateControlEndpointAddress, deviceInstance->controlPipe);
433             break;
434 
435         case kStatus_DEV_GetDes: /* process get full device descriptor result */
436             if (dataLength != sizeof(usb_descriptor_device_t))
437             {
438                 return kStatus_USB_Error;
439             }
440             break;
441 
442         case kStatus_DEV_GetCfg9: /* process get 9 bytes configuration result */
443             if (dataLength != 9u)
444             {
445                 return kStatus_USB_Error;
446             }
447             temp          = (void *)&deviceInstance->enumBuffer[0];
448             configureDesc = (usb_descriptor_configuration_t *)temp;
449 
450             /* clear the potential configuration information that is got for the previous configuration */
451             (void)memset(&deviceInstance->configuration, 0, sizeof(deviceInstance->configuration));
452             deviceInstance->configurationLen = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(configureDesc->wTotalLength);
453             if (deviceInstance->configurationDesc != NULL)
454             {
455 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
456                 SDK_Free(deviceInstance->configurationDesc);
457 #else
458                 OSA_MemoryFree(deviceInstance->configurationDesc);
459 #endif
460                 deviceInstance->configurationDesc = NULL;
461             }
462 
463             /* the only configuration descriptor is at least 9 bytes length */
464             if (deviceInstance->configurationLen < 9U)
465             {
466                 return kStatus_USB_Error;
467             }
468             /* fix misra 4.14 */
469             if (deviceInstance->configurationLen > USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH)
470             {
471                 return kStatus_USB_Error;
472             }
473             /* for KHCI, the start address and the length should be 4 byte align */
474             if ((deviceInstance->configurationLen & 0x03U) != 0U)
475             {
476 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
477                 deviceInstance->configurationDesc =
478                     (uint8_t *)SDK_Malloc((deviceInstance->configurationLen & 0xFFFCu) + 4, USB_CACHE_LINESIZE);
479 #else
480                 deviceInstance->configurationDesc =
481                     (uint8_t *)OSA_MemoryAllocate((((uint32_t)deviceInstance->configurationLen) & 0xFFFCU) + 4UL);
482 #endif
483             }
484             else
485             {
486 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
487                 deviceInstance->configurationDesc =
488                     (uint8_t *)SDK_Malloc(deviceInstance->configurationLen, USB_CACHE_LINESIZE);
489 #else
490                 deviceInstance->configurationDesc = (uint8_t *)OSA_MemoryAllocate(deviceInstance->configurationLen);
491 #endif
492             }
493             if (deviceInstance->configurationDesc == NULL)
494             {
495                 return kStatus_USB_AllocFail;
496             }
497             break;
498 
499         case kStatus_DEV_GetCfg: /* process get configuration result */
500             if (dataLength != deviceInstance->configurationLen)
501             {
502 #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
503                 usb_echo("Host can only provide a maximum of 500mA current\r\n");
504 #endif
505                 return kStatus_USB_Error;
506             }
507 
508 #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
509 #if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
510             hubInstance4Device = USB_HostHubGetHubDeviceHandle(hostInstance, deviceInstance->hubNumber);
511             if ((!(((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bmAttributes &
512                    USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK)) &&
513                 (((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bMaxPower > 50) &&
514                 (hubInstance4Device != NULL) &&
515                 (!(((usb_descriptor_configuration_t *)((usb_host_device_instance_t *)hubInstance4Device->deviceHandle)
516                         ->configurationDesc)
517                        ->bmAttributes &
518                    USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK)))
519             {
520                 usb_echo("The device power exceeded\r\n");
521                 return kStatus_USB_Error;
522             }
523 #endif
524 #endif
525             temp = (void *)deviceInstance->configurationDesc;
526             if (((usb_descriptor_configuration_t *)temp)->bMaxPower > USB_HOST_CONFIG_MAX_POWER)
527             {
528                 return kStatus_USB_Error;
529             }
530             deviceInstance->configurationValue++;
531             if (USB_HostParseDeviceConfigurationDescriptor(deviceInstance) !=
532                 kStatus_USB_Success) /* parse configuration descriptor */
533             {
534                 return kStatus_USB_Error;
535             }
536 
537             status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventAttach,
538                                           (uint32_t)kStatus_USB_Success);
539 
540             if (status != kStatus_USB_Success)
541             {
542                 /* next configuration */
543                 if (deviceInstance->configurationValue < deviceInstance->deviceDescriptor->bNumConfigurations)
544                 {
545                     return kStatus_USB_Retry;
546                 }
547                 else
548                 {
549                     /* notify application device is not supported */
550                     (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
551                                                (uint32_t)kUSB_HostEventNotSupported, (uint32_t)kStatus_USB_Success);
552                     return kStatus_USB_NotSupported;
553                 }
554             }
555             break;
556 
557         case kStatus_DEV_SetCfg:
558             /* NULL */
559             break;
560 
561         default:
562             /*no action*/
563             break;
564     }
565 
566     return status;
567 }
568 
USB_HostNotifyDevice(usb_host_handle hostHandle,usb_host_device_instance_t * deviceInstance,uint32_t eventCode,uint32_t eventParameter)569 static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
570                                          usb_host_device_instance_t *deviceInstance,
571                                          uint32_t eventCode,
572                                          uint32_t eventParameter)
573 {
574     usb_host_instance_t *hostInstance;
575     usb_status_t status1 = kStatus_USB_Error;
576 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
577     usb_status_t status2 = kStatus_USB_Error;
578     uint8_t haveHub;
579     uint8_t haveNoHub;
580     uint8_t interfaceIndex;
581 #endif /* USB_HOST_CONFIG_HUB */
582 
583     eventCode    = (((uint32_t)eventParameter << 16U) | (uint32_t)eventCode);
584     hostInstance = (usb_host_instance_t *)hostHandle;
585     if (deviceInstance == NULL)
586     {
587         (void)hostInstance->deviceCallback(NULL, NULL, eventCode);
588         return kStatus_USB_InvalidHandle;
589     }
590 
591 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
592     haveHub   = 0U;
593     haveNoHub = 0U;
594     for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
595     {
596         if (((usb_descriptor_interface_t *)deviceInstance->configuration.interfaceList[interfaceIndex].interfaceDesc)
597                 ->bInterfaceClass == USB_HOST_HUB_CLASS_CODE)
598         {
599             haveHub = 1U;
600         }
601         else
602         {
603             haveNoHub = 1U;
604         }
605     }
606 
607     if ((hostInstance->deviceCallback != NULL) &&
608         ((haveNoHub == 1U) || (deviceInstance->configuration.interfaceCount == 0U)))
609     {
610         /* call host callback function, function is initialized in USB_HostInit */
611         status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
612     }
613     if (0U != haveHub)
614     {
615         status2 = USB_HostHubDeviceEvent(hostInstance, deviceInstance, &deviceInstance->configuration,
616                                          eventCode); /* notify hub event */
617     }
618 
619     if ((status1 == kStatus_USB_Success) || (status2 == kStatus_USB_Success)) /* the device is supported */
620     {
621         return kStatus_USB_Success;
622     }
623     else if (eventCode == (uint32_t)kUSB_HostEventAttach) /* attach event */
624     {
625         status1 = kStatus_USB_NotSupported;
626     }
627     else
628     {
629         status1 = kStatus_USB_Error;
630     }
631 #else
632     if (hostInstance->deviceCallback != NULL)
633     {
634         /* call host callback function, function is initialized in USB_HostInit */
635         status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
636     }
637 #endif
638     return status1;
639 }
640 
USB_HostAllocateDeviceAddress(usb_host_instance_t * hostInstance)641 static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance)
642 {
643     uint8_t address = 0U;
644     uint8_t addressIndex;
645     uint8_t addressBitIndex;
646     for (addressIndex = 0U; addressIndex < 8U; ++addressIndex) /* find the idle address position byte */
647     {
648         if (hostInstance->addressBitMap[addressIndex] != 0xFFU)
649         {
650             break;
651         }
652     }
653     if (addressIndex < 8U)
654     {
655         for (addressBitIndex = 0U; addressBitIndex < 8U; ++addressBitIndex) /* find the idle address position bit */
656         {
657             if (0U == (hostInstance->addressBitMap[addressIndex] & (0x01U << addressBitIndex)))
658             {
659                 hostInstance->addressBitMap[addressIndex] |= (0x01U << addressBitIndex); /* set the allocated bit */
660                 address = addressIndex * 8U + addressBitIndex + 1U;                      /* the address minimum is 1 */
661                 break;
662             }
663         }
664     }
665     return address;
666 }
667 
USB_HostReleaseDeviceAddress(usb_host_instance_t * hostInstance,uint8_t address)668 static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address)
669 {
670     (void)USB_HostLock();
671     hostInstance->addressBitMap[((uint32_t)address - 1U) >> 3U] &=
672         (~(0x01U << (((uint32_t)address - 1U) & 0x07U))); /* reset the allocated bit */
673     (void)USB_HostUnlock();
674 }
675 
USB_HostRemoveDeviceInstance(usb_host_handle hostHandle,usb_device_handle deviceHandle)676 static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle)
677 {
678     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
679     usb_host_device_instance_t *currentInstance;
680     usb_host_device_instance_t *prevInstance;
681     if ((hostHandle == NULL) || (deviceHandle == NULL))
682     {
683         return kStatus_USB_InvalidHandle;
684     }
685 
686     /* search and remove device instance */
687     prevInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
688     if (prevInstance == deviceHandle)
689     {
690         hostInstance->deviceList = prevInstance->next;
691         return kStatus_USB_Success;
692     }
693     else
694     {
695         currentInstance = prevInstance->next;
696     }
697 
698     while (currentInstance != NULL)
699     {
700         if (currentInstance == deviceHandle)
701         {
702             prevInstance->next = currentInstance->next;
703             return kStatus_USB_Success;
704         }
705         prevInstance    = currentInstance;
706         currentInstance = currentInstance->next;
707     }
708 
709     return kStatus_USB_Success;
710 }
711 
USB_HostReleaseDeviceResource(usb_host_instance_t * hostInstance,usb_host_device_instance_t * deviceInstance)712 static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance, usb_host_device_instance_t *deviceInstance)
713 {
714 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
715     uint8_t level = 0;
716 #endif
717 
718 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
719     if (deviceInstance == hostInstance->suspendedDevice)
720     {
721         hostInstance->suspendedDevice = NULL;
722     }
723 #endif
724     /* release device's address */
725     if (deviceInstance->setAddress != 0U)
726     {
727         USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->setAddress);
728     }
729     else
730     {
731         if (deviceInstance->allocatedAddress != 0U)
732         {
733             USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->allocatedAddress);
734         }
735     }
736 
737     /* close control pipe */
738     if (deviceInstance->controlPipe != NULL)
739     {
740         (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
741         if (USB_HostClosePipe(hostInstance, deviceInstance->controlPipe) != kStatus_USB_Success)
742         {
743 #ifdef HOST_ECHO
744             usb_echo("error when close pipe\r\n");
745 #endif
746         }
747         deviceInstance->controlPipe = NULL;
748     }
749 
750     /* free configuration buffer */
751     if (deviceInstance->configurationDesc != NULL)
752     {
753 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
754         SDK_Free(deviceInstance->configurationDesc);
755 #else
756         OSA_MemoryFree(deviceInstance->configurationDesc);
757 #endif
758     }
759 
760 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
761     level = deviceInstance->level;
762 #endif
763 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
764     SDK_Free(deviceInstance->deviceDescriptor);
765 #else
766     OSA_MemoryFree(deviceInstance->deviceDescriptor);
767 #endif
768     /* free device instance buffer */
769     OSA_MemoryFree(deviceInstance);
770 
771 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
772     /* enable controller attach if root hub */
773     if (level == 1U)
774     {
775         (void)USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
776     }
777 #else
778     /* enable controller attach */
779     USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
780 #endif
781 }
782 
USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle)783 static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle)
784 {
785     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
786     uint32_t endPos;
787     usb_descriptor_union_t *unionDes;
788     usb_host_interface_t *interfaceParse = NULL;
789     usb_host_ep_t *epParse;
790     uint8_t *buffer;
791     void *temp;
792 
793     if (deviceHandle == NULL)
794     {
795         return kStatus_USB_InvalidParameter;
796     }
797 
798     temp   = (void *)&deviceInstance->configuration;
799     buffer = (uint8_t *)temp;
800     /* clear the previous parse result, note: end_pos means buffer index here*/
801     for (endPos = 0U; endPos < sizeof(usb_host_configuration_t); endPos++)
802     {
803         buffer[endPos] = 0U;
804     }
805     for (endPos = 0U; endPos < USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE; ++endPos)
806     {
807         deviceInstance->interfaceStatus[endPos] = 0U;
808     }
809 
810     /* parse configuration descriptor */
811     temp     = (void *)deviceInstance->configurationDesc;
812     unionDes = (usb_descriptor_union_t *)temp;
813     endPos   = (uint32_t)(deviceInstance->configurationDesc + deviceInstance->configurationLen);
814 
815     if (((((uint32_t)unionDes) + 1U) < endPos) && (unionDes->common.bLength == USB_DESCRIPTOR_LENGTH_CONFIGURE) &&
816         (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURE))
817     {
818         /* configuration descriptor */
819         temp                                                       = (void *)unionDes;
820         deviceInstance->configuration.configurationDesc            = (usb_descriptor_configuration_t *)temp;
821         deviceInstance->configuration.configurationExtensionLength = 0;
822         deviceInstance->configuration.configurationExtension       = NULL;
823         deviceInstance->configuration.interfaceCount               = 0;
824         unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
825         while ((uint32_t)unionDes < endPos)
826         {
827             if (((((uint32_t)unionDes) + 1U) < endPos) &&
828                 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
829             {
830                 if (deviceInstance->configuration.configurationExtension == NULL)
831                 {
832                     deviceInstance->configuration.configurationExtension = (uint8_t *)unionDes;
833                 }
834                 if ((unionDes->common.bDescriptorType == 0x00U) ||
835                     (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
836                 {
837                     return kStatus_USB_Error;
838                 }
839                 deviceInstance->configuration.configurationExtensionLength += unionDes->common.bLength;
840                 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
841             }
842             else
843             {
844                 break;
845             }
846         }
847 
848         /* interface descriptor */
849         deviceInstance->configuration.interfaceCount = 0U;
850         while ((uint32_t)unionDes < endPos)
851         {
852             if (((((uint32_t)unionDes) + 1U) < endPos) &&
853                 (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE))
854             {
855                 /* the interface descriptor length is 9 bytes */
856                 if ((((uint32_t)unionDes) + 9U) > endPos)
857                 {
858                     return kStatus_USB_Error;
859                 }
860                 if (unionDes->interface.bAlternateSetting == 0x00U)
861                 {
862                     if (deviceInstance->configuration.interfaceCount >= USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE)
863                     {
864 #if (((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) || defined(HOST_ECHO))
865                         (void)usb_echo(
866                             "Unsupported Device attached\r\n too many interfaces in one configuration, please increase "
867                             "the USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE value\n");
868 #endif
869                         return kStatus_USB_Error;
870                     }
871                     interfaceParse =
872                         &deviceInstance->configuration.interfaceList[deviceInstance->configuration.interfaceCount];
873                     deviceInstance->configuration.interfaceCount++;
874                     interfaceParse->alternateSettingNumber   = 0;
875                     interfaceParse->epCount                  = 0;
876                     interfaceParse->interfaceDesc            = &unionDes->interface;
877                     interfaceParse->interfaceExtensionLength = 0;
878                     interfaceParse->interfaceExtension       = NULL;
879                     interfaceParse->interfaceIndex           = unionDes->interface.bInterfaceNumber;
880                     if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
881                     {
882                         return kStatus_USB_Error;
883                     }
884                     unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
885                     while ((uint32_t)unionDes < endPos)
886                     {
887                         if (((((uint32_t)unionDes) + 1U) < endPos) &&
888                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
889                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
890                         {
891                             if (interfaceParse->interfaceExtension == NULL)
892                             {
893                                 interfaceParse->interfaceExtension = (uint8_t *)unionDes;
894                             }
895                             if ((unionDes->common.bDescriptorType == 0x00U) ||
896                                 (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
897                             {
898                                 return kStatus_USB_Error;
899                             }
900                             interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
901                             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
902                         }
903                         else
904                         {
905                             break;
906                         }
907                     }
908 
909                     /* endpoint descriptor */
910                     if (interfaceParse->interfaceDesc->bNumEndpoints != 0U)
911                     {
912                         if (((((uint32_t)unionDes) + 1U) >= endPos) ||
913                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
914                             (interfaceParse->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
915                         {
916 #ifdef HOST_ECHO
917                             usb_echo("interface descriptor error\n");
918 #endif
919                             return kStatus_USB_Error;
920                         }
921                         for (; interfaceParse->epCount < interfaceParse->interfaceDesc->bNumEndpoints;
922                              (interfaceParse->epCount)++)
923                         {
924                             if (((((uint32_t)unionDes) + 1U) >= endPos) ||
925                                 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
926                             {
927 #ifdef HOST_ECHO
928                                 usb_echo("endpoint descriptor error\n");
929 #endif
930                                 return kStatus_USB_Error;
931                             }
932                             temp                       = (void *)&interfaceParse->epList[interfaceParse->epCount];
933                             epParse                    = (usb_host_ep_t *)temp;
934                             temp                       = (void *)unionDes;
935                             epParse->epDesc            = (usb_descriptor_endpoint_t *)temp;
936                             epParse->epExtensionLength = 0U;
937                             epParse->epExtension       = NULL;
938                             if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
939                             {
940                                 return kStatus_USB_Error;
941                             }
942                             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
943                             while ((uint32_t)unionDes < endPos)
944                             {
945                                 if (((((uint32_t)unionDes) + 1U) < endPos) &&
946                                     (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
947                                     (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
948                                 {
949                                     if (epParse->epExtension == NULL)
950                                     {
951                                         epParse->epExtension = (uint8_t *)unionDes;
952                                     }
953                                     if ((unionDes->common.bDescriptorType == 0x00U) ||
954                                         (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
955                                     {
956                                         return kStatus_USB_Error;
957                                     }
958                                     epParse->epExtensionLength += unionDes->common.bLength;
959                                     unionDes =
960                                         (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
961                                 }
962                                 else
963                                 {
964                                     break;
965                                 }
966                             }
967                         }
968                     }
969                 }
970                 else
971                 {
972                     if (interfaceParse == NULL)
973                     {
974                         return kStatus_USB_Error; /* in normal situation this cannot reach */
975                     }
976                     interfaceParse->alternateSettingNumber++;
977                     if (interfaceParse->interfaceExtension == NULL)
978                     {
979                         interfaceParse->interfaceExtension = (uint8_t *)unionDes;
980                     }
981                     if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
982                     {
983                         return kStatus_USB_Error;
984                     }
985                     interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
986                     unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
987                     while ((uint32_t)unionDes < endPos)
988                     {
989                         if (((((uint32_t)unionDes) + 1U) < endPos) &&
990                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
991                         {
992                             if ((unionDes->common.bDescriptorType == 0x00U) ||
993                                 (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
994                             {
995                                 return kStatus_USB_Error;
996                             }
997                             interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
998                             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
999                         }
1000                         else
1001                         {
1002                             break;
1003                         }
1004                     }
1005                 }
1006             }
1007             else
1008             {
1009                 return kStatus_USB_Error;
1010             }
1011         }
1012     }
1013     else
1014     {
1015         return kStatus_USB_Error;
1016     }
1017 
1018     for (endPos = 0U; endPos < deviceInstance->configuration.interfaceCount; ++endPos)
1019     {
1020         deviceInstance->interfaceStatus[endPos] = (uint8_t)kStatus_interface_Attached;
1021     }
1022 
1023     return kStatus_USB_Success;
1024 }
1025 
USB_HostAttachDevice(usb_host_handle hostHandle,uint8_t speed,uint8_t hubNumber,uint8_t portNumber,uint8_t level,usb_device_handle * deviceHandle)1026 usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle,
1027                                   uint8_t speed,
1028                                   uint8_t hubNumber,
1029                                   uint8_t portNumber,
1030                                   uint8_t level,
1031                                   usb_device_handle *deviceHandle)
1032 {
1033     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
1034     usb_host_device_instance_t *newInstance;
1035 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1036     usb_host_device_instance_t *currentInstance;
1037 #endif
1038     uint8_t address;
1039     usb_host_pipe_init_t pipeInit;
1040 
1041     if (hostHandle == NULL)
1042     {
1043         return kStatus_USB_InvalidHandle;
1044     }
1045 
1046 /* check whether is the device attached? */
1047 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1048     currentInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
1049     while (currentInstance != NULL)
1050     {
1051         if ((currentInstance->hubNumber == hubNumber) && (currentInstance->portNumber == portNumber))
1052         {
1053             *deviceHandle = NULL;
1054 #ifdef HOST_ECHO
1055             usb_echo("device has attached\r\n");
1056 #endif
1057             return kStatus_USB_Busy;
1058         }
1059         else
1060         {
1061             currentInstance = currentInstance->next;
1062         }
1063     }
1064 #else
1065     if (hostInstance->deviceList != NULL)
1066     {
1067         *deviceHandle = NULL;
1068         usb_echo("device has attached\r\n");
1069         return kStatus_USB_Busy;
1070     }
1071 #endif
1072 
1073     /* Allocate new device instance */
1074     newInstance = (usb_host_device_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_device_instance_t));
1075     if (newInstance == NULL)
1076     {
1077 #ifdef HOST_ECHO
1078         usb_echo("allocate dev instance fail\r\n");
1079 #endif
1080         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1081                                    (uint32_t)kStatus_USB_AllocFail);
1082         return kStatus_USB_AllocFail;
1083     }
1084 
1085     /* new instance fields init */
1086     newInstance->hostHandle        = hostHandle;
1087     newInstance->speed             = speed;
1088     newInstance->stallRetries      = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
1089     newInstance->enumRetries       = USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES;
1090     newInstance->setAddress        = 0;
1091     newInstance->deviceAttachState = (uint8_t)kStatus_device_Attached;
1092 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1093     newInstance->deviceDescriptor =
1094         (usb_descriptor_device_t *)SDK_Malloc(sizeof(usb_descriptor_device_t) + 9, USB_CACHE_LINESIZE);
1095 #else
1096     newInstance->deviceDescriptor = (usb_descriptor_device_t *)OSA_MemoryAllocate(sizeof(usb_descriptor_device_t) + 9U);
1097 #endif
1098     if (newInstance->deviceDescriptor == NULL)
1099     {
1100 #ifdef HOST_ECHO
1101         usb_echo("allocate newInstance->deviceDescriptor fail\r\n");
1102 #endif
1103 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1104         SDK_Free(newInstance->deviceDescriptor);
1105 #else
1106         OSA_MemoryFree(newInstance->deviceDescriptor);
1107 #endif
1108         OSA_MemoryFree(newInstance);
1109         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1110                                    (uint32_t)kStatus_USB_AllocFail);
1111         return kStatus_USB_AllocFail;
1112     }
1113     newInstance->enumBuffer = (uint8_t *)((uint8_t *)newInstance->deviceDescriptor + sizeof(usb_descriptor_device_t));
1114 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1115     newInstance->hubNumber  = hubNumber;
1116     newInstance->portNumber = portNumber;
1117     newInstance->level      = level;
1118 
1119     if ((speed != USB_SPEED_HIGH) && (level > 1U))
1120     {
1121         newInstance->hsHubNumber = (uint8_t)USB_HostHubGetHsHubNumber(hostHandle, hubNumber);
1122         newInstance->hsHubPort   = (uint8_t)USB_HostHubGetHsHubPort(hostHandle, hubNumber, portNumber);
1123     }
1124     else
1125     {
1126         newInstance->hsHubNumber = hubNumber;
1127         newInstance->hsHubPort   = portNumber;
1128     }
1129 #endif /* USB_HOST_CONFIG_HUB */
1130 
1131     (void)USB_HostLock();
1132     /* allocate address && insert to the dev list */
1133     address = USB_HostAllocateDeviceAddress(hostInstance);
1134     if (address == 0U)
1135     {
1136 #ifdef HOST_ECHO
1137         usb_echo("allocate address fail\r\n");
1138 #endif
1139         (void)USB_HostUnlock();
1140 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1141         SDK_Free(newInstance->deviceDescriptor);
1142 #else
1143         OSA_MemoryFree(newInstance->deviceDescriptor);
1144 #endif
1145         OSA_MemoryFree(newInstance);
1146         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1147                                    (uint32_t)kStatus_USB_Error);
1148         return kStatus_USB_Error;
1149     }
1150     newInstance->allocatedAddress = address;
1151 
1152     newInstance->next        = (usb_host_device_instance_t *)hostInstance->deviceList;
1153     hostInstance->deviceList = newInstance;
1154     newInstance->state       = (uint8_t)kStatus_DEV_Initial;
1155     (void)USB_HostUnlock();
1156 
1157     /* open control pipe */
1158     pipeInit.devInstance     = newInstance;
1159     pipeInit.pipeType        = USB_ENDPOINT_CONTROL;
1160     pipeInit.direction       = 0;
1161     pipeInit.endpointAddress = 0;
1162     pipeInit.interval        = 0;
1163     pipeInit.maxPacketSize   = 8;
1164     pipeInit.numberPerUframe = 0;
1165     pipeInit.nakCount        = USB_HOST_CONFIG_MAX_NAK;
1166     if (USB_HostOpenPipe(hostHandle, &newInstance->controlPipe, &pipeInit) != kStatus_USB_Success)
1167     {
1168         /* don't need release resource, resource is released when detach */
1169         *deviceHandle = newInstance;
1170 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1171         SDK_Free(newInstance->deviceDescriptor);
1172 #else
1173         OSA_MemoryFree(newInstance->deviceDescriptor);
1174 #endif
1175         OSA_MemoryFree(newInstance);
1176         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1177                                    (uint32_t)kStatus_USB_Error);
1178         return kStatus_USB_Error;
1179     }
1180 
1181     /* start enumeration */
1182     newInstance->state = (uint8_t)kStatus_DEV_GetDes8;
1183     /* process enumeration state machine */
1184     if (USB_HostProcessState(newInstance) != kStatus_USB_Success)
1185     {
1186         (void)USB_HostNotifyDevice(hostInstance, newInstance, (uint32_t)kUSB_HostEventEnumerationFail,
1187                                    (uint32_t)kStatus_USB_Error);
1188     }
1189 
1190     *deviceHandle = newInstance;
1191     return kStatus_USB_Success;
1192 }
1193 
USB_HostDetachDevice(usb_host_handle hostHandle,uint8_t hubNumber,uint8_t portNumber)1194 usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber)
1195 {
1196     usb_host_device_instance_t *deviceInstance;
1197     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
1198 
1199     if (hostHandle == NULL)
1200     {
1201         return kStatus_USB_InvalidHandle;
1202     }
1203 
1204     (void)USB_HostLock();
1205 /* search for device instance handle */
1206 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1207     deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
1208     while (deviceInstance != NULL)
1209     {
1210         if ((deviceInstance->hubNumber == hubNumber) && (deviceInstance->portNumber == portNumber))
1211         {
1212             break;
1213         }
1214         deviceInstance = deviceInstance->next;
1215     }
1216 #else
1217     deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
1218 #endif
1219     (void)USB_HostUnlock();
1220     if (deviceInstance != NULL)
1221     {
1222         return USB_HostDetachDeviceInternal(hostHandle, deviceInstance); /* device instance detach */
1223     }
1224     return kStatus_USB_Success;
1225 }
1226 
USB_HostDetachDeviceInternal(usb_host_handle hostHandle,usb_device_handle deviceHandle)1227 usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle)
1228 {
1229     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1230     usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
1231     if ((hostHandle == NULL) || (deviceHandle == NULL))
1232     {
1233         return kStatus_USB_InvalidHandle;
1234     }
1235 
1236     deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached; /* mark the device is detached from host */
1237 
1238     if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device instance is valid */
1239     {
1240         /* detach internally */
1241         if (deviceInstance->state < (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done */
1242         {
1243             if (deviceInstance->controlPipe != NULL)
1244             {
1245                 (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
1246             }
1247 
1248             /* remove device instance from host */
1249             (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
1250             USB_HostReleaseDeviceResource(hostInstance, deviceInstance);
1251         }
1252         else /* enumeration has be done and notified application */
1253         {
1254             /* notify application device detach */
1255             (void)USB_HostNotifyDevice(hostInstance, deviceInstance, (uint32_t)kUSB_HostEventDetach,
1256                                        (uint32_t)kStatus_USB_Success);
1257         }
1258     }
1259 
1260     return kStatus_USB_Success;
1261 }
1262 
USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)1263 uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)
1264 {
1265     return (NULL != deviceHandle) ? ((usb_host_device_instance_t *)deviceHandle)->deviceAttachState : 0x0U;
1266 }
1267 
USB_HostValidateDevice(usb_host_handle hostHandle,usb_device_handle deviceHandle)1268 usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
1269 {
1270     usb_host_device_instance_t *searchDev;
1271 
1272     if (deviceHandle == NULL)
1273     {
1274         return kStatus_USB_InvalidParameter;
1275     }
1276     /* search for the device */
1277     searchDev = (usb_host_device_instance_t *)((usb_host_instance_t *)hostHandle)->deviceList;
1278     while ((searchDev != NULL) && ((usb_device_handle)searchDev != deviceHandle))
1279     {
1280         searchDev = searchDev->next;
1281     }
1282 
1283     if (NULL != searchDev)
1284     {
1285         return kStatus_USB_Success;
1286     }
1287     return kStatus_USB_Error;
1288 }
1289 
USB_HostControlBus(usb_host_handle hostHandle,uint8_t controlType)1290 static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType)
1291 {
1292     usb_status_t status               = kStatus_USB_Success;
1293     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
1294 
1295     if (hostHandle == NULL)
1296     {
1297         return kStatus_USB_InvalidHandle;
1298     }
1299     /* the callbackFn is initialized in USB_HostGetControllerInterface */
1300     status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
1301                                                             &controlType);
1302 
1303     return status;
1304 }
1305 
USB_HostOpenDeviceInterface(usb_device_handle deviceHandle,usb_host_interface_handle interfaceHandle)1306 usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
1307 {
1308     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1309     usb_host_instance_t *hostInstance          = NULL;
1310     uint8_t interfaceIndex;
1311     uint8_t index = 0;
1312 
1313     if ((deviceHandle == NULL) || (interfaceHandle == NULL))
1314     {
1315         return kStatus_USB_InvalidHandle;
1316     }
1317 
1318     hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
1319     (void)USB_HostLock();
1320     /* check host_instance valid? */
1321     for (; index < (uint8_t)USB_HOST_CONFIG_MAX_HOST; ++index)
1322     {
1323         if ((g_UsbHostInstance[index].occupied == 1U) &&
1324             ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
1325         {
1326             break;
1327         }
1328     }
1329     if (index >= (uint8_t)USB_HOST_CONFIG_MAX_HOST)
1330     {
1331         (void)USB_HostUnlock();
1332         return kStatus_USB_Error;
1333     }
1334 
1335     /* check deviceHandle valid? */
1336     if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
1337     {
1338         (void)USB_HostUnlock();
1339         return kStatus_USB_Error;
1340     }
1341 
1342     /* search interface and set the interface as opened */
1343     for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
1344     {
1345         if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
1346         {
1347             deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Opened;
1348             break;
1349         }
1350     }
1351     (void)USB_HostUnlock();
1352 
1353     return kStatus_USB_Success;
1354 }
1355 
USB_HostCloseDeviceInterface(usb_device_handle deviceHandle,usb_host_interface_handle interfaceHandle)1356 usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
1357 {
1358     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1359     usb_host_instance_t *hostInstance          = NULL;
1360     uint8_t interfaceIndex;
1361     uint8_t removeLabel = 1;
1362     uint8_t index       = 0;
1363 
1364     if (deviceHandle == NULL)
1365     {
1366         return kStatus_USB_InvalidHandle;
1367     }
1368 
1369     hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
1370     (void)USB_HostLock();
1371     /* check host_instance valid? */
1372     for (; index < (uint8_t)USB_HOST_CONFIG_MAX_HOST; ++index)
1373     {
1374         if ((g_UsbHostInstance[index].occupied == 1U) &&
1375             ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
1376         {
1377             break;
1378         }
1379     }
1380     if (index >= (uint8_t)USB_HOST_CONFIG_MAX_HOST)
1381     {
1382         (void)USB_HostUnlock();
1383         return kStatus_USB_Error;
1384     }
1385 
1386     /* check deviceHandle valid? */
1387     if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
1388     {
1389         (void)USB_HostUnlock();
1390         return kStatus_USB_Error;
1391     }
1392 
1393     if (interfaceHandle != NULL)
1394     {
1395         /* search interface and set the interface as detached */
1396         for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
1397         {
1398             if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
1399             {
1400                 deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Detached;
1401                 break;
1402             }
1403         }
1404     }
1405 
1406     if (deviceInstance->deviceAttachState == (uint8_t)kStatus_device_Detached) /* device is removed from host */
1407     {
1408         removeLabel = 1;
1409         /* check all the interfaces of the device are not opened */
1410         for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
1411         {
1412             if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
1413             {
1414                 removeLabel = 0U;
1415                 break;
1416             }
1417         }
1418         if (removeLabel == 1U)
1419         {
1420             /* remove device instance from host */
1421             (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
1422         }
1423         (void)USB_HostUnlock();
1424 
1425         if (removeLabel == 1U)
1426         {
1427             USB_HostReleaseDeviceResource((usb_host_instance_t *)deviceInstance->hostHandle,
1428                                           deviceInstance); /* release device resource */
1429         }
1430     }
1431     else
1432     {
1433         (void)USB_HostUnlock();
1434     }
1435 
1436     return kStatus_USB_Success;
1437 }
1438 
USB_HostRemoveDevice(usb_host_handle hostHandle,usb_device_handle deviceHandle)1439 usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
1440 {
1441     usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
1442     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1443     uint8_t interfaceIndex                     = 0;
1444 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1445     uint8_t level = 0;
1446     uint8_t devHubNo;
1447     uint8_t devPortNo;
1448 #endif
1449 
1450     if ((hostHandle == NULL) || (deviceHandle == NULL))
1451     {
1452         return kStatus_USB_InvalidHandle;
1453     }
1454     if (deviceInstance->hostHandle != hostHandle)
1455     {
1456         return kStatus_USB_InvalidParameter;
1457     }
1458 
1459     if (USB_HostValidateDevice(hostInstance, deviceInstance) == kStatus_USB_Success) /* device is valid */
1460     {
1461 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1462         devHubNo  = deviceInstance->hubNumber;
1463         devPortNo = deviceInstance->portNumber;
1464         level     = deviceInstance->level;
1465 #endif
1466 
1467         deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached;
1468         if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device is valid */
1469         {
1470             if (deviceInstance->state <
1471                 (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done or application don't use */
1472             {
1473                 /* detach internally */
1474                 (void)USB_HostDetachDeviceInternal(hostHandle, deviceHandle);
1475             }
1476             else /* application use the device */
1477             {
1478                 for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount;
1479                      ++interfaceIndex)
1480                 {
1481                     if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
1482                     {
1483 #ifdef HOST_ECHO
1484                         usb_echo("error: there is class instance that is not deinited\r\n");
1485 #endif
1486                         break;
1487                     }
1488                 }
1489                 /* remove device instance from host */
1490                 (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
1491                 USB_HostReleaseDeviceResource(hostInstance, deviceInstance); /* release resource */
1492             }
1493         }
1494 
1495 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1496         if (level == 1U)
1497         {
1498             (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusReset);   /* reset controller port */
1499             (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusRestart); /* restart controller port */
1500         }
1501         else
1502         {
1503             (void)USB_HostHubRemovePort(hostHandle, devHubNo, devPortNo); /* reset hub port */
1504         }
1505 #else
1506         USB_HostControlBus(hostHandle, kUSB_HostBusReset);   /* reset controller port */
1507         USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */
1508 #endif /* USB_HOST_CONFIG_HUB */
1509     }
1510 
1511     return kStatus_USB_Success;
1512 }
1513