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