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