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             deviceInstance->configurationLen = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(configureDesc->wTotalLength);
451             if (deviceInstance->configurationDesc != NULL)
452             {
453 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
454                 SDK_Free(deviceInstance->configurationDesc);
455 #else
456                 OSA_MemoryFree(deviceInstance->configurationDesc);
457 #endif
458                 deviceInstance->configurationDesc = NULL;
459             }
460 
461             /* the only configuration descriptor is at least 9 bytes length */
462             if (deviceInstance->configurationLen < 9U)
463             {
464                 return kStatus_USB_Error;
465             }
466             /* fix misra 4.14 */
467             if (deviceInstance->configurationLen > USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH)
468             {
469                 return kStatus_USB_Error;
470             }
471             /* for KHCI, the start address and the length should be 4 byte align */
472             if ((deviceInstance->configurationLen & 0x03U) != 0U)
473             {
474 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
475                 deviceInstance->configurationDesc =
476                     (uint8_t *)SDK_Malloc((deviceInstance->configurationLen & 0xFFFCu) + 4, USB_CACHE_LINESIZE);
477 #else
478                 deviceInstance->configurationDesc =
479                     (uint8_t *)OSA_MemoryAllocate((((uint32_t)deviceInstance->configurationLen) & 0xFFFCU) + 4UL);
480 #endif
481             }
482             else
483             {
484 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
485                 deviceInstance->configurationDesc =
486                     (uint8_t *)SDK_Malloc(deviceInstance->configurationLen, USB_CACHE_LINESIZE);
487 #else
488                 deviceInstance->configurationDesc = (uint8_t *)OSA_MemoryAllocate(deviceInstance->configurationLen);
489 #endif
490             }
491             if (deviceInstance->configurationDesc == NULL)
492             {
493                 return kStatus_USB_AllocFail;
494             }
495             break;
496 
497         case kStatus_DEV_GetCfg: /* process get configuration result */
498             if (dataLength != deviceInstance->configurationLen)
499             {
500 #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
501                 usb_echo("Host can only provide a maximum of 500mA current\r\n");
502 #endif
503                 return kStatus_USB_Error;
504             }
505 
506 #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
507 #if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
508             hubInstance4Device = USB_HostHubGetHubDeviceHandle(hostInstance, deviceInstance->hubNumber);
509             if ((!(((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bmAttributes &
510                    USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK)) &&
511                 (((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bMaxPower > 50) &&
512                 (hubInstance4Device != NULL) &&
513                 (!(((usb_descriptor_configuration_t *)((usb_host_device_instance_t *)hubInstance4Device->deviceHandle)
514                         ->configurationDesc)
515                        ->bmAttributes &
516                    USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK)))
517             {
518                 usb_echo("The device power exceeded\r\n");
519                 return kStatus_USB_Error;
520             }
521 #endif
522 #endif
523             temp = (void *)deviceInstance->configurationDesc;
524             if (((usb_descriptor_configuration_t *)temp)->bMaxPower > USB_HOST_CONFIG_MAX_POWER)
525             {
526                 return kStatus_USB_Error;
527             }
528             deviceInstance->configurationValue++;
529             if (USB_HostParseDeviceConfigurationDescriptor(deviceInstance) !=
530                 kStatus_USB_Success) /* parse configuration descriptor */
531             {
532                 return kStatus_USB_Error;
533             }
534 
535             status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventAttach,
536                                           (uint32_t)kStatus_USB_Success);
537 
538             if (status != kStatus_USB_Success)
539             {
540                 /* next configuration */
541                 if (deviceInstance->configurationValue < deviceInstance->deviceDescriptor->bNumConfigurations)
542                 {
543                     return kStatus_USB_Retry;
544                 }
545                 else
546                 {
547                     /* notify application device is not supported */
548                     (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
549                                                (uint32_t)kUSB_HostEventNotSupported, (uint32_t)kStatus_USB_Success);
550                     return kStatus_USB_NotSupported;
551                 }
552             }
553             break;
554 
555         case kStatus_DEV_SetCfg:
556             /* NULL */
557             break;
558 
559         default:
560             /*no action*/
561             break;
562     }
563 
564     return status;
565 }
566 
USB_HostNotifyDevice(usb_host_handle hostHandle,usb_host_device_instance_t * deviceInstance,uint32_t eventCode,uint32_t eventParameter)567 static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
568                                          usb_host_device_instance_t *deviceInstance,
569                                          uint32_t eventCode,
570                                          uint32_t eventParameter)
571 {
572     usb_host_instance_t *hostInstance;
573     usb_status_t status1 = kStatus_USB_Error;
574 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
575     usb_status_t status2 = kStatus_USB_Error;
576     uint8_t haveHub;
577     uint8_t haveNoHub;
578     uint8_t interfaceIndex;
579 #endif /* USB_HOST_CONFIG_HUB */
580 
581     eventCode    = (((uint32_t)eventParameter << 16U) | (uint32_t)eventCode);
582     hostInstance = (usb_host_instance_t *)hostHandle;
583     if (deviceInstance == NULL)
584     {
585         (void)hostInstance->deviceCallback(NULL, NULL, eventCode);
586         return kStatus_USB_InvalidHandle;
587     }
588 
589 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
590     haveHub   = 0U;
591     haveNoHub = 0U;
592     for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
593     {
594         if (((usb_descriptor_interface_t *)deviceInstance->configuration.interfaceList[interfaceIndex].interfaceDesc)
595                 ->bInterfaceClass == USB_HOST_HUB_CLASS_CODE)
596         {
597             haveHub = 1U;
598         }
599         else
600         {
601             haveNoHub = 1U;
602         }
603     }
604 
605     if ((hostInstance->deviceCallback != NULL) &&
606         ((haveNoHub == 1U) || (deviceInstance->configuration.interfaceCount == 0U)))
607     {
608         /* call host callback function, function is initialized in USB_HostInit */
609         status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
610     }
611     if (0U != haveHub)
612     {
613         status2 = USB_HostHubDeviceEvent(hostInstance, deviceInstance, &deviceInstance->configuration,
614                                          eventCode); /* notify hub event */
615     }
616 
617     if ((status1 == kStatus_USB_Success) || (status2 == kStatus_USB_Success)) /* the device is supported */
618     {
619         return kStatus_USB_Success;
620     }
621     else if (eventCode == (uint32_t)kUSB_HostEventAttach) /* attach event */
622     {
623         status1 = kStatus_USB_NotSupported;
624     }
625     else
626     {
627         status1 = kStatus_USB_Error;
628     }
629 #else
630     if (hostInstance->deviceCallback != NULL)
631     {
632         /* call host callback function, function is initialized in USB_HostInit */
633         status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
634     }
635 #endif
636     return status1;
637 }
638 
USB_HostAllocateDeviceAddress(usb_host_instance_t * hostInstance)639 static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance)
640 {
641     uint8_t address = 0U;
642     uint8_t addressIndex;
643     uint8_t addressBitIndex;
644     for (addressIndex = 0U; addressIndex < 8U; ++addressIndex) /* find the idle address position byte */
645     {
646         if (hostInstance->addressBitMap[addressIndex] != 0xFFU)
647         {
648             break;
649         }
650     }
651     if (addressIndex < 8U)
652     {
653         for (addressBitIndex = 0U; addressBitIndex < 8U; ++addressBitIndex) /* find the idle address position bit */
654         {
655             if (0U == (hostInstance->addressBitMap[addressIndex] & (0x01U << addressBitIndex)))
656             {
657                 hostInstance->addressBitMap[addressIndex] |= (0x01U << addressBitIndex); /* set the allocated bit */
658                 address = addressIndex * 8U + addressBitIndex + 1U;                      /* the address minimum is 1 */
659                 break;
660             }
661         }
662     }
663     return address;
664 }
665 
USB_HostReleaseDeviceAddress(usb_host_instance_t * hostInstance,uint8_t address)666 static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address)
667 {
668     (void)USB_HostLock();
669     hostInstance->addressBitMap[((uint32_t)address - 1U) >> 3U] &=
670         (~(0x01U << (((uint32_t)address - 1U) & 0x07U))); /* reset the allocated bit */
671     (void)USB_HostUnlock();
672 }
673 
USB_HostRemoveDeviceInstance(usb_host_handle hostHandle,usb_device_handle deviceHandle)674 static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle)
675 {
676     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
677     usb_host_device_instance_t *currentInstance;
678     usb_host_device_instance_t *prevInstance;
679     if ((hostHandle == NULL) || (deviceHandle == NULL))
680     {
681         return kStatus_USB_InvalidHandle;
682     }
683 
684     /* search and remove device instance */
685     prevInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
686     if (prevInstance == deviceHandle)
687     {
688         hostInstance->deviceList = prevInstance->next;
689         return kStatus_USB_Success;
690     }
691     else
692     {
693         currentInstance = prevInstance->next;
694     }
695 
696     while (currentInstance != NULL)
697     {
698         if (currentInstance == deviceHandle)
699         {
700             prevInstance->next = currentInstance->next;
701             return kStatus_USB_Success;
702         }
703         prevInstance    = currentInstance;
704         currentInstance = currentInstance->next;
705     }
706 
707     return kStatus_USB_Success;
708 }
709 
USB_HostReleaseDeviceResource(usb_host_instance_t * hostInstance,usb_host_device_instance_t * deviceInstance)710 static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance, usb_host_device_instance_t *deviceInstance)
711 {
712 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
713     uint8_t level = 0;
714 #endif
715 
716 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
717     if (deviceInstance == hostInstance->suspendedDevice)
718     {
719         hostInstance->suspendedDevice = NULL;
720     }
721 #endif
722     /* release device's address */
723     if (deviceInstance->setAddress != 0U)
724     {
725         USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->setAddress);
726     }
727     else
728     {
729         if (deviceInstance->allocatedAddress != 0U)
730         {
731             USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->allocatedAddress);
732         }
733     }
734 
735     /* close control pipe */
736     if (deviceInstance->controlPipe != NULL)
737     {
738         (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
739         if (USB_HostClosePipe(hostInstance, deviceInstance->controlPipe) != kStatus_USB_Success)
740         {
741 #ifdef HOST_ECHO
742             usb_echo("error when close pipe\r\n");
743 #endif
744         }
745         deviceInstance->controlPipe = NULL;
746     }
747 
748     /* free configuration buffer */
749     if (deviceInstance->configurationDesc != NULL)
750     {
751 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
752         SDK_Free(deviceInstance->configurationDesc);
753 #else
754         OSA_MemoryFree(deviceInstance->configurationDesc);
755 #endif
756     }
757 
758 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
759     level = deviceInstance->level;
760 #endif
761 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
762     SDK_Free(deviceInstance->deviceDescriptor);
763 #else
764     OSA_MemoryFree(deviceInstance->deviceDescriptor);
765 #endif
766     /* free device instance buffer */
767     OSA_MemoryFree(deviceInstance);
768 
769 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
770     /* enable controller attach if root hub */
771     if (level == 1U)
772     {
773         (void)USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
774     }
775 #else
776     /* enable controller attach */
777     USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
778 #endif
779 }
780 
USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle)781 static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle)
782 {
783     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
784     uint32_t endPos;
785     usb_descriptor_union_t *unionDes;
786     usb_host_interface_t *interfaceParse = NULL;
787     usb_host_ep_t *epParse;
788     uint8_t *buffer;
789     void *temp;
790 
791     if (deviceHandle == NULL)
792     {
793         return kStatus_USB_InvalidParameter;
794     }
795 
796     temp   = (void *)&deviceInstance->configuration;
797     buffer = (uint8_t *)temp;
798     /* clear the previous parse result, note: end_pos means buffer index here*/
799     for (endPos = 0U; endPos < sizeof(usb_host_configuration_t); endPos++)
800     {
801         buffer[endPos] = 0U;
802     }
803     for (endPos = 0U; endPos < USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE; ++endPos)
804     {
805         deviceInstance->interfaceStatus[endPos] = 0U;
806     }
807 
808     /* parse configuration descriptor */
809     temp     = (void *)deviceInstance->configurationDesc;
810     unionDes = (usb_descriptor_union_t *)temp;
811     endPos   = (uint32_t)(deviceInstance->configurationDesc + deviceInstance->configurationLen);
812 
813     if (((((uint32_t)unionDes) + 1U) < endPos) && (unionDes->common.bLength == USB_DESCRIPTOR_LENGTH_CONFIGURE) &&
814         (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURE))
815     {
816         /* configuration descriptor */
817         temp                                                       = (void *)unionDes;
818         deviceInstance->configuration.configurationDesc            = (usb_descriptor_configuration_t *)temp;
819         deviceInstance->configuration.configurationExtensionLength = 0;
820         deviceInstance->configuration.configurationExtension       = NULL;
821         deviceInstance->configuration.interfaceCount               = 0;
822         unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
823         while ((uint32_t)unionDes < endPos)
824         {
825             if (((((uint32_t)unionDes) + 1U) < endPos) &&
826                 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
827             {
828                 if (deviceInstance->configuration.configurationExtension == NULL)
829                 {
830                     deviceInstance->configuration.configurationExtension = (uint8_t *)unionDes;
831                 }
832                 if ((unionDes->common.bDescriptorType == 0x00U) ||
833                     (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
834                 {
835                     return kStatus_USB_Error;
836                 }
837                 deviceInstance->configuration.configurationExtensionLength += unionDes->common.bLength;
838                 unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
839             }
840             else
841             {
842                 break;
843             }
844         }
845 
846         /* interface descriptor */
847         deviceInstance->configuration.interfaceCount = 0U;
848         while ((uint32_t)unionDes < endPos)
849         {
850             if (((((uint32_t)unionDes) + 1U) < endPos) &&
851                 (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE))
852             {
853                 /* the interface descriptor length is 9 bytes */
854                 if ((((uint32_t)unionDes) + 9U) > endPos)
855                 {
856                     return kStatus_USB_Error;
857                 }
858                 if (unionDes->interface.bAlternateSetting == 0x00U)
859                 {
860                     if (deviceInstance->configuration.interfaceCount >= USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE)
861                     {
862 #if (((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) || defined(HOST_ECHO))
863                         (void)usb_echo(
864                             "Unsupported Device attached\r\n too many interfaces in one configuration, please increase "
865                             "the USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE value\n");
866 #endif
867                         return kStatus_USB_Error;
868                     }
869                     interfaceParse =
870                         &deviceInstance->configuration.interfaceList[deviceInstance->configuration.interfaceCount];
871                     deviceInstance->configuration.interfaceCount++;
872                     interfaceParse->alternateSettingNumber   = 0;
873                     interfaceParse->epCount                  = 0;
874                     interfaceParse->interfaceDesc            = &unionDes->interface;
875                     interfaceParse->interfaceExtensionLength = 0;
876                     interfaceParse->interfaceExtension       = NULL;
877                     interfaceParse->interfaceIndex           = unionDes->interface.bInterfaceNumber;
878                     if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
879                     {
880                         return kStatus_USB_Error;
881                     }
882                     unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
883                     while ((uint32_t)unionDes < endPos)
884                     {
885                         if (((((uint32_t)unionDes) + 1U) < endPos) &&
886                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
887                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
888                         {
889                             if (interfaceParse->interfaceExtension == NULL)
890                             {
891                                 interfaceParse->interfaceExtension = (uint8_t *)unionDes;
892                             }
893                             if ((unionDes->common.bDescriptorType == 0x00U) ||
894                                 (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
895                             {
896                                 return kStatus_USB_Error;
897                             }
898                             interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
899                             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
900                         }
901                         else
902                         {
903                             break;
904                         }
905                     }
906 
907                     /* endpoint descriptor */
908                     if (interfaceParse->interfaceDesc->bNumEndpoints != 0U)
909                     {
910                         if (((((uint32_t)unionDes) + 1U) >= endPos) ||
911                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
912                             (interfaceParse->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
913                         {
914 #ifdef HOST_ECHO
915                             usb_echo("interface descriptor error\n");
916 #endif
917                             return kStatus_USB_Error;
918                         }
919                         for (; interfaceParse->epCount < interfaceParse->interfaceDesc->bNumEndpoints;
920                              (interfaceParse->epCount)++)
921                         {
922                             if (((((uint32_t)unionDes) + 1U) >= endPos) ||
923                                 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
924                             {
925 #ifdef HOST_ECHO
926                                 usb_echo("endpoint descriptor error\n");
927 #endif
928                                 return kStatus_USB_Error;
929                             }
930                             temp                       = (void *)&interfaceParse->epList[interfaceParse->epCount];
931                             epParse                    = (usb_host_ep_t *)temp;
932                             temp                       = (void *)unionDes;
933                             epParse->epDesc            = (usb_descriptor_endpoint_t *)temp;
934                             epParse->epExtensionLength = 0U;
935                             epParse->epExtension       = NULL;
936                             if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
937                             {
938                                 return kStatus_USB_Error;
939                             }
940                             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
941                             while ((uint32_t)unionDes < endPos)
942                             {
943                                 if (((((uint32_t)unionDes) + 1U) < endPos) &&
944                                     (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
945                                     (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
946                                 {
947                                     if (epParse->epExtension == NULL)
948                                     {
949                                         epParse->epExtension = (uint8_t *)unionDes;
950                                     }
951                                     if ((unionDes->common.bDescriptorType == 0x00U) ||
952                                         (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
953                                     {
954                                         return kStatus_USB_Error;
955                                     }
956                                     epParse->epExtensionLength += unionDes->common.bLength;
957                                     unionDes =
958                                         (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
959                                 }
960                                 else
961                                 {
962                                     break;
963                                 }
964                             }
965                         }
966                     }
967                 }
968                 else
969                 {
970                     if (interfaceParse == NULL)
971                     {
972                         return kStatus_USB_Error; /* in normal situation this cannot reach */
973                     }
974                     interfaceParse->alternateSettingNumber++;
975                     if (interfaceParse->interfaceExtension == NULL)
976                     {
977                         interfaceParse->interfaceExtension = (uint8_t *)unionDes;
978                     }
979                     if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
980                     {
981                         return kStatus_USB_Error;
982                     }
983                     interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
984                     unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
985                     while ((uint32_t)unionDes < endPos)
986                     {
987                         if (((((uint32_t)unionDes) + 1U) < endPos) &&
988                             (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
989                         {
990                             if ((unionDes->common.bDescriptorType == 0x00U) ||
991                                 (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
992                             {
993                                 return kStatus_USB_Error;
994                             }
995                             interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
996                             unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
997                         }
998                         else
999                         {
1000                             break;
1001                         }
1002                     }
1003                 }
1004             }
1005             else
1006             {
1007                 return kStatus_USB_Error;
1008             }
1009         }
1010     }
1011     else
1012     {
1013         return kStatus_USB_Error;
1014     }
1015 
1016     for (endPos = 0U; endPos < deviceInstance->configuration.interfaceCount; ++endPos)
1017     {
1018         deviceInstance->interfaceStatus[endPos] = (uint8_t)kStatus_interface_Attached;
1019     }
1020 
1021     return kStatus_USB_Success;
1022 }
1023 
USB_HostAttachDevice(usb_host_handle hostHandle,uint8_t speed,uint8_t hubNumber,uint8_t portNumber,uint8_t level,usb_device_handle * deviceHandle)1024 usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle,
1025                                   uint8_t speed,
1026                                   uint8_t hubNumber,
1027                                   uint8_t portNumber,
1028                                   uint8_t level,
1029                                   usb_device_handle *deviceHandle)
1030 {
1031     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
1032     usb_host_device_instance_t *newInstance;
1033 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1034     usb_host_device_instance_t *currentInstance;
1035 #endif
1036     uint8_t address;
1037     usb_host_pipe_init_t pipeInit;
1038 
1039     if (hostHandle == NULL)
1040     {
1041         return kStatus_USB_InvalidHandle;
1042     }
1043 
1044 /* check whether is the device attached? */
1045 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1046     currentInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
1047     while (currentInstance != NULL)
1048     {
1049         if ((currentInstance->hubNumber == hubNumber) && (currentInstance->portNumber == portNumber))
1050         {
1051             *deviceHandle = NULL;
1052 #ifdef HOST_ECHO
1053             usb_echo("device has attached\r\n");
1054 #endif
1055             return kStatus_USB_Busy;
1056         }
1057         else
1058         {
1059             currentInstance = currentInstance->next;
1060         }
1061     }
1062 #else
1063     if (hostInstance->deviceList != NULL)
1064     {
1065         *deviceHandle = NULL;
1066         usb_echo("device has attached\r\n");
1067         return kStatus_USB_Busy;
1068     }
1069 #endif
1070 
1071     /* Allocate new device instance */
1072     newInstance = (usb_host_device_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_device_instance_t));
1073     if (newInstance == NULL)
1074     {
1075 #ifdef HOST_ECHO
1076         usb_echo("allocate dev instance fail\r\n");
1077 #endif
1078         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1079                                    (uint32_t)kStatus_USB_AllocFail);
1080         return kStatus_USB_AllocFail;
1081     }
1082 
1083     /* new instance fields init */
1084     newInstance->hostHandle        = hostHandle;
1085     newInstance->speed             = speed;
1086     newInstance->stallRetries      = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
1087     newInstance->enumRetries       = USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES;
1088     newInstance->setAddress        = 0;
1089     newInstance->deviceAttachState = (uint8_t)kStatus_device_Attached;
1090 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1091     newInstance->deviceDescriptor =
1092         (usb_descriptor_device_t *)SDK_Malloc(sizeof(usb_descriptor_device_t) + 9, USB_CACHE_LINESIZE);
1093 #else
1094     newInstance->deviceDescriptor = (usb_descriptor_device_t *)OSA_MemoryAllocate(sizeof(usb_descriptor_device_t) + 9U);
1095 #endif
1096     if (newInstance->deviceDescriptor == NULL)
1097     {
1098 #ifdef HOST_ECHO
1099         usb_echo("allocate newInstance->deviceDescriptor fail\r\n");
1100 #endif
1101 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1102         SDK_Free(newInstance->deviceDescriptor);
1103 #else
1104         OSA_MemoryFree(newInstance->deviceDescriptor);
1105 #endif
1106         OSA_MemoryFree(newInstance);
1107         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1108                                    (uint32_t)kStatus_USB_AllocFail);
1109         return kStatus_USB_AllocFail;
1110     }
1111     newInstance->enumBuffer = (uint8_t *)((uint8_t *)newInstance->deviceDescriptor + sizeof(usb_descriptor_device_t));
1112 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1113     newInstance->hubNumber  = hubNumber;
1114     newInstance->portNumber = portNumber;
1115     newInstance->level      = level;
1116 
1117     if ((speed != USB_SPEED_HIGH) && (level > 1U))
1118     {
1119         newInstance->hsHubNumber = (uint8_t)USB_HostHubGetHsHubNumber(hostHandle, hubNumber);
1120         newInstance->hsHubPort   = (uint8_t)USB_HostHubGetHsHubPort(hostHandle, hubNumber, portNumber);
1121     }
1122     else
1123     {
1124         newInstance->hsHubNumber = hubNumber;
1125         newInstance->hsHubPort   = portNumber;
1126     }
1127 #endif /* USB_HOST_CONFIG_HUB */
1128 
1129     (void)USB_HostLock();
1130     /* allocate address && insert to the dev list */
1131     address = USB_HostAllocateDeviceAddress(hostInstance);
1132     if (address == 0U)
1133     {
1134 #ifdef HOST_ECHO
1135         usb_echo("allocate address fail\r\n");
1136 #endif
1137         (void)USB_HostUnlock();
1138 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1139         SDK_Free(newInstance->deviceDescriptor);
1140 #else
1141         OSA_MemoryFree(newInstance->deviceDescriptor);
1142 #endif
1143         OSA_MemoryFree(newInstance);
1144         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1145                                    (uint32_t)kStatus_USB_Error);
1146         return kStatus_USB_Error;
1147     }
1148     newInstance->allocatedAddress = address;
1149 
1150     newInstance->next        = (usb_host_device_instance_t *)hostInstance->deviceList;
1151     hostInstance->deviceList = newInstance;
1152     newInstance->state       = (uint8_t)kStatus_DEV_Initial;
1153     (void)USB_HostUnlock();
1154 
1155     /* open control pipe */
1156     pipeInit.devInstance     = newInstance;
1157     pipeInit.pipeType        = USB_ENDPOINT_CONTROL;
1158     pipeInit.direction       = 0;
1159     pipeInit.endpointAddress = 0;
1160     pipeInit.interval        = 0;
1161     pipeInit.maxPacketSize   = 8;
1162     pipeInit.numberPerUframe = 0;
1163     pipeInit.nakCount        = USB_HOST_CONFIG_MAX_NAK;
1164     if (USB_HostOpenPipe(hostHandle, &newInstance->controlPipe, &pipeInit) != kStatus_USB_Success)
1165     {
1166         /* don't need release resource, resource is released when detach */
1167         *deviceHandle = newInstance;
1168 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
1169         SDK_Free(newInstance->deviceDescriptor);
1170 #else
1171         OSA_MemoryFree(newInstance->deviceDescriptor);
1172 #endif
1173         OSA_MemoryFree(newInstance);
1174         (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
1175                                    (uint32_t)kStatus_USB_Error);
1176         return kStatus_USB_Error;
1177     }
1178 
1179     /* start enumeration */
1180     newInstance->state = (uint8_t)kStatus_DEV_GetDes8;
1181     /* process enumeration state machine */
1182     if (USB_HostProcessState(newInstance) != kStatus_USB_Success)
1183     {
1184         (void)USB_HostNotifyDevice(hostInstance, newInstance, (uint32_t)kUSB_HostEventEnumerationFail,
1185                                    (uint32_t)kStatus_USB_Error);
1186     }
1187 
1188     *deviceHandle = newInstance;
1189     return kStatus_USB_Success;
1190 }
1191 
USB_HostDetachDevice(usb_host_handle hostHandle,uint8_t hubNumber,uint8_t portNumber)1192 usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber)
1193 {
1194     usb_host_device_instance_t *deviceInstance;
1195     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
1196 
1197     if (hostHandle == NULL)
1198     {
1199         return kStatus_USB_InvalidHandle;
1200     }
1201 
1202     (void)USB_HostLock();
1203 /* search for device instance handle */
1204 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1205     deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
1206     while (deviceInstance != NULL)
1207     {
1208         if ((deviceInstance->hubNumber == hubNumber) && (deviceInstance->portNumber == portNumber))
1209         {
1210             break;
1211         }
1212         deviceInstance = deviceInstance->next;
1213     }
1214 #else
1215     deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
1216 #endif
1217     (void)USB_HostUnlock();
1218     if (deviceInstance != NULL)
1219     {
1220         return USB_HostDetachDeviceInternal(hostHandle, deviceInstance); /* device instance detach */
1221     }
1222     return kStatus_USB_Success;
1223 }
1224 
USB_HostDetachDeviceInternal(usb_host_handle hostHandle,usb_device_handle deviceHandle)1225 usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle)
1226 {
1227     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1228     usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
1229     if ((hostHandle == NULL) || (deviceHandle == NULL))
1230     {
1231         return kStatus_USB_InvalidHandle;
1232     }
1233 
1234     deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached; /* mark the device is detached from host */
1235 
1236     if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device instance is valid */
1237     {
1238         /* detach internally */
1239         if (deviceInstance->state < (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done */
1240         {
1241             if (deviceInstance->controlPipe != NULL)
1242             {
1243                 (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
1244             }
1245 
1246             /* remove device instance from host */
1247             (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
1248             USB_HostReleaseDeviceResource(hostInstance, deviceInstance);
1249         }
1250         else /* enumeration has be done and notified application */
1251         {
1252             /* notify application device detach */
1253             (void)USB_HostNotifyDevice(hostInstance, deviceInstance, (uint32_t)kUSB_HostEventDetach,
1254                                        (uint32_t)kStatus_USB_Success);
1255         }
1256     }
1257 
1258     return kStatus_USB_Success;
1259 }
1260 
USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)1261 uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)
1262 {
1263     return (NULL != deviceHandle) ? ((usb_host_device_instance_t *)deviceHandle)->deviceAttachState : 0x0U;
1264 }
1265 
USB_HostValidateDevice(usb_host_handle hostHandle,usb_device_handle deviceHandle)1266 usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
1267 {
1268     usb_host_device_instance_t *searchDev;
1269 
1270     if (deviceHandle == NULL)
1271     {
1272         return kStatus_USB_InvalidParameter;
1273     }
1274     /* search for the device */
1275     searchDev = (usb_host_device_instance_t *)((usb_host_instance_t *)hostHandle)->deviceList;
1276     while ((searchDev != NULL) && ((usb_device_handle)searchDev != deviceHandle))
1277     {
1278         searchDev = searchDev->next;
1279     }
1280 
1281     if (NULL != searchDev)
1282     {
1283         return kStatus_USB_Success;
1284     }
1285     return kStatus_USB_Error;
1286 }
1287 
USB_HostControlBus(usb_host_handle hostHandle,uint8_t controlType)1288 static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType)
1289 {
1290     usb_status_t status               = kStatus_USB_Success;
1291     usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
1292 
1293     if (hostHandle == NULL)
1294     {
1295         return kStatus_USB_InvalidHandle;
1296     }
1297     /* the callbackFn is initialized in USB_HostGetControllerInterface */
1298     status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
1299                                                             &controlType);
1300 
1301     return status;
1302 }
1303 
USB_HostOpenDeviceInterface(usb_device_handle deviceHandle,usb_host_interface_handle interfaceHandle)1304 usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
1305 {
1306     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1307     usb_host_instance_t *hostInstance          = NULL;
1308     uint8_t interfaceIndex;
1309     uint8_t index = 0;
1310 
1311     if ((deviceHandle == NULL) || (interfaceHandle == NULL))
1312     {
1313         return kStatus_USB_InvalidHandle;
1314     }
1315 
1316     hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
1317     (void)USB_HostLock();
1318     /* check host_instance valid? */
1319     for (; index < (uint8_t)USB_HOST_CONFIG_MAX_HOST; ++index)
1320     {
1321         if ((g_UsbHostInstance[index].occupied == 1U) &&
1322             ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
1323         {
1324             break;
1325         }
1326     }
1327     if (index >= (uint8_t)USB_HOST_CONFIG_MAX_HOST)
1328     {
1329         (void)USB_HostUnlock();
1330         return kStatus_USB_Error;
1331     }
1332 
1333     /* check deviceHandle valid? */
1334     if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
1335     {
1336         (void)USB_HostUnlock();
1337         return kStatus_USB_Error;
1338     }
1339 
1340     /* search interface and set the interface as opened */
1341     for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
1342     {
1343         if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
1344         {
1345             deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Opened;
1346             break;
1347         }
1348     }
1349     (void)USB_HostUnlock();
1350 
1351     return kStatus_USB_Success;
1352 }
1353 
USB_HostCloseDeviceInterface(usb_device_handle deviceHandle,usb_host_interface_handle interfaceHandle)1354 usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
1355 {
1356     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1357     usb_host_instance_t *hostInstance          = NULL;
1358     uint8_t interfaceIndex;
1359     uint8_t removeLabel = 1;
1360     uint8_t index       = 0;
1361 
1362     if (deviceHandle == NULL)
1363     {
1364         return kStatus_USB_InvalidHandle;
1365     }
1366 
1367     hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
1368     (void)USB_HostLock();
1369     /* check host_instance valid? */
1370     for (; index < (uint8_t)USB_HOST_CONFIG_MAX_HOST; ++index)
1371     {
1372         if ((g_UsbHostInstance[index].occupied == 1U) &&
1373             ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
1374         {
1375             break;
1376         }
1377     }
1378     if (index >= (uint8_t)USB_HOST_CONFIG_MAX_HOST)
1379     {
1380         (void)USB_HostUnlock();
1381         return kStatus_USB_Error;
1382     }
1383 
1384     /* check deviceHandle valid? */
1385     if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
1386     {
1387         (void)USB_HostUnlock();
1388         return kStatus_USB_Error;
1389     }
1390 
1391     if (interfaceHandle != NULL)
1392     {
1393         /* search interface and set the interface as detached */
1394         for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
1395         {
1396             if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
1397             {
1398                 deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Detached;
1399                 break;
1400             }
1401         }
1402     }
1403 
1404     if (deviceInstance->deviceAttachState == (uint8_t)kStatus_device_Detached) /* device is removed from host */
1405     {
1406         removeLabel = 1;
1407         /* check all the interfaces of the device are not opened */
1408         for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
1409         {
1410             if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
1411             {
1412                 removeLabel = 0U;
1413                 break;
1414             }
1415         }
1416         if (removeLabel == 1U)
1417         {
1418             /* remove device instance from host */
1419             (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
1420         }
1421         (void)USB_HostUnlock();
1422 
1423         if (removeLabel == 1U)
1424         {
1425             USB_HostReleaseDeviceResource((usb_host_instance_t *)deviceInstance->hostHandle,
1426                                           deviceInstance); /* release device resource */
1427         }
1428     }
1429     else
1430     {
1431         (void)USB_HostUnlock();
1432     }
1433 
1434     return kStatus_USB_Success;
1435 }
1436 
USB_HostRemoveDevice(usb_host_handle hostHandle,usb_device_handle deviceHandle)1437 usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
1438 {
1439     usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
1440     usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1441     uint8_t interfaceIndex                     = 0;
1442 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1443     uint8_t level = 0;
1444     uint8_t devHubNo;
1445     uint8_t devPortNo;
1446 #endif
1447 
1448     if ((hostHandle == NULL) || (deviceHandle == NULL))
1449     {
1450         return kStatus_USB_InvalidHandle;
1451     }
1452     if (deviceInstance->hostHandle != hostHandle)
1453     {
1454         return kStatus_USB_InvalidParameter;
1455     }
1456 
1457     if (USB_HostValidateDevice(hostInstance, deviceInstance) == kStatus_USB_Success) /* device is valid */
1458     {
1459 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1460         devHubNo  = deviceInstance->hubNumber;
1461         devPortNo = deviceInstance->portNumber;
1462         level     = deviceInstance->level;
1463 #endif
1464 
1465         deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached;
1466         if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device is valid */
1467         {
1468             if (deviceInstance->state <
1469                 (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done or application don't use */
1470             {
1471                 /* detach internally */
1472                 (void)USB_HostDetachDeviceInternal(hostHandle, deviceHandle);
1473             }
1474             else /* application use the device */
1475             {
1476                 for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount;
1477                      ++interfaceIndex)
1478                 {
1479                     if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
1480                     {
1481 #ifdef HOST_ECHO
1482                         usb_echo("error: there is class instance that is not deinited\r\n");
1483 #endif
1484                         break;
1485                     }
1486                 }
1487                 /* remove device instance from host */
1488                 (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
1489                 USB_HostReleaseDeviceResource(hostInstance, deviceInstance); /* release resource */
1490             }
1491         }
1492 
1493 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1494         if (level == 1U)
1495         {
1496             (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusReset);   /* reset controller port */
1497             (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusRestart); /* restart controller port */
1498         }
1499         else
1500         {
1501             (void)USB_HostHubRemovePort(hostHandle, devHubNo, devPortNo); /* reset hub port */
1502         }
1503 #else
1504         USB_HostControlBus(hostHandle, kUSB_HostBusReset);   /* reset controller port */
1505         USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */
1506 #endif /* USB_HOST_CONFIG_HUB */
1507     }
1508 
1509     return kStatus_USB_Success;
1510 }
1511