12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511 |
- /*
- * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
- * Copyright 2016,2019 NXP
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <usb/include/usb_host_config.h>
- #include "usb_host.h"
- #include "usb_host_hci.h"
- #include "usb_host_devices.h"
- #include "usb_host_framework.h"
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- #include "usb_host_hub.h"
- #include "usb_host_hub_app.h"
- #endif /* USB_HOST_CONFIG_HUB */
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #ifndef USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH
- #define USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH (5000U)
- #endif
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*!
- * @brief enumeration transfer callback function.
- *
- * @param param callback parameter.
- * @param transfer the transfer.
- * @param status transfer result status.
- */
- static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
- /*!
- * @brief process the new step state.
- *
- * @param deviceInstance device instance pointer.
- *
- * @return kStatus_USB_Success or error codes
- */
- static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance);
- /*!
- * @brief process the previous step transfer result.
- *
- * @param deviceInstance device instance pointer.
- *
- * @return kStatus_USB_Success or error codes
- */
- static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance, uint32_t dataLength);
- /*!
- * @brief notify the application event, the callback is registered when initializing host.
- *
- * @param deviceInstance device instance pointer.
- * @param eventCode event code.
- *
- * @return kStatus_USB_Success or error codes
- */
- static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
- usb_host_device_instance_t *deviceInstance,
- uint32_t eventCode,
- uint32_t eventParameter);
- /*!
- * @brief allocate one address.
- *
- * @param hostInstance host instance pointer.
- *
- * @return address, 0 is invalid.
- */
- static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance);
- /*!
- * @brief release one address.
- *
- * @param hostInstance host instance pointer.
- * @param address releasing address.
- */
- static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address);
- /*!
- * @brief release device resource.
- *
- * @param hostInstance host instance pointer.
- * @param deviceInstance device instance pointer.
- */
- static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance,
- usb_host_device_instance_t *deviceInstance);
- /*!
- * @brief parse device configuration descriptor.
- *
- * @param deviceHandle device handle.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle);
- /*!
- * @brief remove device instance from host device list.
- *
- * @param hostHandle host instance handle.
- * @param deviceHandle device handle.
- *
- * @return kStatus_USB_Success or error codes.
- */
- static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle);
- /*!
- * @brief control the bus.
- *
- * This function control the host bus.
- *
- * @param[in] hostHandle the host handle.
- * @param[in] controlType the control code, please reference to bus_event_t.
- *
- * @retval kStatus_USB_Success control successfully.
- * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer.
- */
- static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType);
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- #endif
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- /*! @brief enumeration step process array */
- static const usb_host_enum_process_entry_t s_EnumEntries[] = {
- /* kStatus_dev_initial */
- {
- kStatus_DEV_Notinit,
- kStatus_DEV_Notinit,
- NULL,
- },
- /* kStatus_DEV_GetDes8 */
- {
- kStatus_DEV_SetAddress,
- kStatus_DEV_GetDes8,
- USB_HostProcessCallback,
- },
- /* kStatus_DEV_SetAddress */
- {
- kStatus_DEV_GetDes,
- kStatus_DEV_SetAddress,
- USB_HostProcessCallback,
- },
- /* kStatus_DEV_GetDes */
- {
- kStatus_DEV_GetCfg9,
- kStatus_DEV_GetDes,
- NULL,
- },
- /* kStatus_DEV_GetCfg9 */
- {
- kStatus_DEV_GetCfg,
- kStatus_DEV_GetCfg9,
- USB_HostProcessCallback,
- },
- /* kStatus_DEV_GetCfg */
- {
- kStatus_DEV_SetCfg,
- kStatus_DEV_GetCfg9,
- USB_HostProcessCallback,
- },
- /* kStatus_DEV_SetCfg */
- {
- kStatus_DEV_EnumDone,
- kStatus_DEV_SetCfg,
- NULL,
- },
- };
- /*******************************************************************************
- * Code
- ******************************************************************************/
- static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
- {
- /* 0 - retry current transfer, 1 - transfer success process,
- * 2 - retry whole process, 3 - fail process
- */
- uint8_t nextStep = 0U;
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)param;
- usb_status_t failReason = kStatus_USB_Success;
- uint32_t dataLength;
- dataLength = transfer->transferSofar;
- (void)USB_HostFreeTransfer(deviceInstance->hostHandle, transfer); /* free transfer */
- if (status == kStatus_USB_Success)
- {
- nextStep = 1U;
- }
- else if (status == kStatus_USB_TransferStall)
- {
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- (void)usb_echo("no response from device\r\n");
- #endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
- if (deviceInstance->stallRetries > 0U) /* retry same transfer when stall */
- {
- nextStep = 0U;
- deviceInstance->stallRetries--;
- }
- else
- {
- failReason = kStatus_USB_TransferFailed;
- nextStep = 2U;
- }
- }
- else if (status == kStatus_USB_TransferCancel)
- {
- failReason = kStatus_USB_TransferCancel;
- nextStep = 3U;
- }
- else
- {
- failReason = kStatus_USB_TransferFailed;
- nextStep = 2U;
- }
- if (nextStep == 1U)
- {
- deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
- if (s_EnumEntries[deviceInstance->state - 1U].process == NULL)
- {
- deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].successState; /* next state */
- }
- else
- {
- status = s_EnumEntries[deviceInstance->state - 1U].process(
- deviceInstance, dataLength); /* process the previous state result */
- if (status == kStatus_USB_Success) /* process success */
- {
- deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].successState;
- }
- else if (status == kStatus_USB_Retry) /* need retry */
- {
- deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].retryState;
- }
- else if (status == kStatus_USB_NotSupported) /* device don't suport by the application */
- {
- return; /* unrecoverable fail */
- }
- else /* process error, next retry */
- {
- /* kStatus_USB_Error or kStatus_USB_AllocFail */
- failReason = status;
- nextStep = 2U;
- }
- }
- }
- if (nextStep == 2U)
- {
- if (deviceInstance->enumRetries > 0U) /* next whole retry */
- {
- deviceInstance->enumRetries--;
- deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
- deviceInstance->configurationValue = 0U;
- deviceInstance->state = (uint8_t)kStatus_DEV_GetDes8;
- }
- else
- {
- #if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- usb_echo("Device No Response\r\n");
- #endif
- nextStep = 3U;
- }
- }
- /* process the state */
- if (nextStep != 3U)
- {
- if (USB_HostProcessState(deviceInstance) != kStatus_USB_Success)
- {
- #ifdef HOST_ECHO
- usb_echo("enumation setup error\r\n");
- #endif
- failReason = kStatus_USB_Error;
- nextStep = 3U;
- }
- }
- if (nextStep == 3U)
- {
- (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventEnumerationFail,
- (uint32_t)failReason);
- }
- }
- static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance)
- {
- usb_status_t status = kStatus_USB_Success;
- usb_host_process_descriptor_param_t getDescriptorParam;
- usb_host_transfer_t *transfer;
- usb_host_device_enumeration_status_t state;
- /* malloc transfer */
- state = (usb_host_device_enumeration_status_t)deviceInstance->state;
- if (state != kStatus_DEV_EnumDone)
- {
- if (USB_HostMallocTransfer(deviceInstance->hostHandle, &transfer) != kStatus_USB_Success)
- {
- #ifdef HOST_ECHO
- usb_echo("error to get transfer\r\n");
- #endif
- return kStatus_USB_Error;
- }
- transfer->callbackFn = USB_HostEnumerationTransferCallback;
- transfer->callbackParam = deviceInstance;
- /* reset transfer fields */
- transfer->setupPacket->bmRequestType = 0x00U;
- transfer->setupPacket->wIndex = 0U;
- transfer->setupPacket->wLength = 0U;
- transfer->setupPacket->wValue = 0U;
- }
- switch (state)
- {
- case kStatus_DEV_GetDes8:
- case kStatus_DEV_GetDes: /* get descriptor state */
- getDescriptorParam.descriptorLength = (uint16_t)sizeof(usb_descriptor_device_t);
- if (deviceInstance->state == (uint8_t)kStatus_DEV_GetDes8)
- {
- getDescriptorParam.descriptorLength = 8U;
- }
- getDescriptorParam.descriptorBuffer = (uint8_t *)deviceInstance->deviceDescriptor;
- getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
- getDescriptorParam.descriptorIndex = 0U;
- getDescriptorParam.languageId = 0U;
- transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
- status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
- break;
- case kStatus_DEV_SetAddress: /* set address state */
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_ADDRESS;
- status = USB_HostStandardSetAddress(deviceInstance, transfer, &deviceInstance->allocatedAddress);
- break;
- case kStatus_DEV_GetCfg9: /* get 9 bytes configuration state */
- getDescriptorParam.descriptorBuffer = deviceInstance->enumBuffer;
- getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE;
- getDescriptorParam.descriptorIndex = deviceInstance->configurationValue;
- getDescriptorParam.descriptorLength = 9;
- getDescriptorParam.languageId = 0;
- transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
- status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
- break;
- case kStatus_DEV_GetCfg: /* get configuration state */
- getDescriptorParam.descriptorBuffer = deviceInstance->configurationDesc;
- getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE;
- getDescriptorParam.descriptorIndex = deviceInstance->configurationValue;
- getDescriptorParam.descriptorLength = deviceInstance->configurationLen;
- getDescriptorParam.languageId = 0;
- transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
- status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
- break;
- case kStatus_DEV_SetCfg: /* set configuration state */
- transfer->setupPacket->wValue =
- USB_SHORT_TO_LITTLE_ENDIAN(deviceInstance->configuration.configurationDesc->bConfigurationValue);
- transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_CONFIGURATION;
- status = USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
- break;
- case kStatus_DEV_EnumDone: /* enumeration done state */
- /* notify device enumeration done */
- status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
- (uint32_t)kUSB_HostEventEnumerationDone, (uint32_t)kStatus_USB_Success);
- if (status == kStatus_USB_Success)
- {
- deviceInstance->state = (uint8_t)kStatus_DEV_AppUsed;
- }
- break;
- default:
- /*no action*/
- break;
- }
- return status;
- }
- static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance, uint32_t dataLength)
- {
- usb_host_pipe_t *pipe = (usb_host_pipe_t *)deviceInstance->controlPipe;
- usb_status_t status = kStatus_USB_Success;
- usb_descriptor_configuration_t *configureDesc;
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
- void *temp;
- usb_host_device_enumeration_status_t state;
- #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- #if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- usb_host_hub_instance_t *hubInstance4Device = NULL;
- #endif
- #endif
- state = (usb_host_device_enumeration_status_t)deviceInstance->state;
- switch (state)
- {
- case kStatus_DEV_GetDes8: /* process get 8 bytes descriptor result */
- if (dataLength != 8u)
- {
- return kStatus_USB_Error;
- }
- pipe->maxPacketSize = deviceInstance->deviceDescriptor->bMaxPacketSize0;
- /* the callbackFn is initialized in USB_HostGetControllerInterface */
- (void)hostInstance->controllerTable->controllerIoctl(
- hostInstance->controllerHandle, kUSB_HostUpdateControlPacketSize, deviceInstance->controlPipe);
- break;
- case kStatus_DEV_SetAddress: /* process set address result */
- deviceInstance->setAddress = deviceInstance->allocatedAddress;
- /* the callbackFn is initialized in USB_HostGetControllerInterface */
- (void)hostInstance->controllerTable->controllerIoctl(
- hostInstance->controllerHandle, kUSB_HostUpdateControlEndpointAddress, deviceInstance->controlPipe);
- break;
- case kStatus_DEV_GetDes: /* process get full device descriptor result */
- if (dataLength != sizeof(usb_descriptor_device_t))
- {
- return kStatus_USB_Error;
- }
- break;
- case kStatus_DEV_GetCfg9: /* process get 9 bytes configuration result */
- if (dataLength != 9u)
- {
- return kStatus_USB_Error;
- }
- temp = (void *)&deviceInstance->enumBuffer[0];
- configureDesc = (usb_descriptor_configuration_t *)temp;
- deviceInstance->configurationLen = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(configureDesc->wTotalLength);
- if (deviceInstance->configurationDesc != NULL)
- {
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- SDK_Free(deviceInstance->configurationDesc);
- #else
- OSA_MemoryFree(deviceInstance->configurationDesc);
- #endif
- deviceInstance->configurationDesc = NULL;
- }
- /* the only configuration descriptor is at least 9 bytes length */
- if (deviceInstance->configurationLen < 9U)
- {
- return kStatus_USB_Error;
- }
- /* fix misra 4.14 */
- if (deviceInstance->configurationLen > USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH)
- {
- return kStatus_USB_Error;
- }
- /* for KHCI, the start address and the length should be 4 byte align */
- if ((deviceInstance->configurationLen & 0x03U) != 0U)
- {
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- deviceInstance->configurationDesc =
- (uint8_t *)SDK_Malloc((deviceInstance->configurationLen & 0xFFFCu) + 4, USB_CACHE_LINESIZE);
- #else
- deviceInstance->configurationDesc =
- (uint8_t *)OSA_MemoryAllocate((((uint32_t)deviceInstance->configurationLen) & 0xFFFCU) + 4UL);
- #endif
- }
- else
- {
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- deviceInstance->configurationDesc =
- (uint8_t *)SDK_Malloc(deviceInstance->configurationLen, USB_CACHE_LINESIZE);
- #else
- deviceInstance->configurationDesc = (uint8_t *)OSA_MemoryAllocate(deviceInstance->configurationLen);
- #endif
- }
- if (deviceInstance->configurationDesc == NULL)
- {
- return kStatus_USB_AllocFail;
- }
- break;
- case kStatus_DEV_GetCfg: /* process get configuration result */
- if (dataLength != deviceInstance->configurationLen)
- {
- #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- usb_echo("Host can only provide a maximum of 500mA current\r\n");
- #endif
- return kStatus_USB_Error;
- }
- #if (defined(USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
- #if (defined(USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- hubInstance4Device = USB_HostHubGetHubDeviceHandle(hostInstance, deviceInstance->hubNumber);
- if ((!(((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bmAttributes &
- USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK)) &&
- (((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bMaxPower > 50) &&
- (hubInstance4Device != NULL) &&
- (!(((usb_descriptor_configuration_t *)((usb_host_device_instance_t *)hubInstance4Device->deviceHandle)
- ->configurationDesc)
- ->bmAttributes &
- USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK)))
- {
- usb_echo("The device power exceeded\r\n");
- return kStatus_USB_Error;
- }
- #endif
- #endif
- temp = (void *)deviceInstance->configurationDesc;
- if (((usb_descriptor_configuration_t *)temp)->bMaxPower > USB_HOST_CONFIG_MAX_POWER)
- {
- return kStatus_USB_Error;
- }
- deviceInstance->configurationValue++;
- if (USB_HostParseDeviceConfigurationDescriptor(deviceInstance) !=
- kStatus_USB_Success) /* parse configuration descriptor */
- {
- return kStatus_USB_Error;
- }
- status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventAttach,
- (uint32_t)kStatus_USB_Success);
- if (status != kStatus_USB_Success)
- {
- /* next configuration */
- if (deviceInstance->configurationValue < deviceInstance->deviceDescriptor->bNumConfigurations)
- {
- return kStatus_USB_Retry;
- }
- else
- {
- /* notify application device is not supported */
- (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
- (uint32_t)kUSB_HostEventNotSupported, (uint32_t)kStatus_USB_Success);
- return kStatus_USB_NotSupported;
- }
- }
- break;
- case kStatus_DEV_SetCfg:
- /* NULL */
- break;
- default:
- /*no action*/
- break;
- }
- return status;
- }
- static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
- usb_host_device_instance_t *deviceInstance,
- uint32_t eventCode,
- uint32_t eventParameter)
- {
- usb_host_instance_t *hostInstance;
- usb_status_t status1 = kStatus_USB_Error;
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- usb_status_t status2 = kStatus_USB_Error;
- uint8_t haveHub;
- uint8_t haveNoHub;
- uint8_t interfaceIndex;
- #endif /* USB_HOST_CONFIG_HUB */
- eventCode = (((uint32_t)eventParameter << 16U) | (uint32_t)eventCode);
- hostInstance = (usb_host_instance_t *)hostHandle;
- if (deviceInstance == NULL)
- {
- (void)hostInstance->deviceCallback(NULL, NULL, eventCode);
- return kStatus_USB_InvalidHandle;
- }
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- haveHub = 0U;
- haveNoHub = 0U;
- for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
- {
- if (((usb_descriptor_interface_t *)deviceInstance->configuration.interfaceList[interfaceIndex].interfaceDesc)
- ->bInterfaceClass == USB_HOST_HUB_CLASS_CODE)
- {
- haveHub = 1U;
- }
- else
- {
- haveNoHub = 1U;
- }
- }
- if ((hostInstance->deviceCallback != NULL) &&
- ((haveNoHub == 1U) || (deviceInstance->configuration.interfaceCount == 0U)))
- {
- /* call host callback function, function is initialized in USB_HostInit */
- status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
- }
- if (0U != haveHub)
- {
- status2 = USB_HostHubDeviceEvent(hostInstance, deviceInstance, &deviceInstance->configuration,
- eventCode); /* notify hub event */
- }
- if ((status1 == kStatus_USB_Success) || (status2 == kStatus_USB_Success)) /* the device is supported */
- {
- return kStatus_USB_Success;
- }
- else if (eventCode == (uint32_t)kUSB_HostEventAttach) /* attach event */
- {
- status1 = kStatus_USB_NotSupported;
- }
- else
- {
- status1 = kStatus_USB_Error;
- }
- #else
- if (hostInstance->deviceCallback != NULL)
- {
- /* call host callback function, function is initialized in USB_HostInit */
- status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
- }
- #endif
- return status1;
- }
- static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance)
- {
- uint8_t address = 0U;
- uint8_t addressIndex;
- uint8_t addressBitIndex;
- for (addressIndex = 0U; addressIndex < 8U; ++addressIndex) /* find the idle address position byte */
- {
- if (hostInstance->addressBitMap[addressIndex] != 0xFFU)
- {
- break;
- }
- }
- if (addressIndex < 8U)
- {
- for (addressBitIndex = 0U; addressBitIndex < 8U; ++addressBitIndex) /* find the idle address position bit */
- {
- if (0U == (hostInstance->addressBitMap[addressIndex] & (0x01U << addressBitIndex)))
- {
- hostInstance->addressBitMap[addressIndex] |= (0x01U << addressBitIndex); /* set the allocated bit */
- address = addressIndex * 8U + addressBitIndex + 1U; /* the address minimum is 1 */
- break;
- }
- }
- }
- return address;
- }
- static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address)
- {
- (void)USB_HostLock();
- hostInstance->addressBitMap[((uint32_t)address - 1U) >> 3U] &=
- (~(0x01U << (((uint32_t)address - 1U) & 0x07U))); /* reset the allocated bit */
- (void)USB_HostUnlock();
- }
- static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle)
- {
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
- usb_host_device_instance_t *currentInstance;
- usb_host_device_instance_t *prevInstance;
- if ((hostHandle == NULL) || (deviceHandle == NULL))
- {
- return kStatus_USB_InvalidHandle;
- }
- /* search and remove device instance */
- prevInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
- if (prevInstance == deviceHandle)
- {
- hostInstance->deviceList = prevInstance->next;
- return kStatus_USB_Success;
- }
- else
- {
- currentInstance = prevInstance->next;
- }
- while (currentInstance != NULL)
- {
- if (currentInstance == deviceHandle)
- {
- prevInstance->next = currentInstance->next;
- return kStatus_USB_Success;
- }
- prevInstance = currentInstance;
- currentInstance = currentInstance->next;
- }
- return kStatus_USB_Success;
- }
- static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance, usb_host_device_instance_t *deviceInstance)
- {
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- uint8_t level = 0;
- #endif
- #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
- if (deviceInstance == hostInstance->suspendedDevice)
- {
- hostInstance->suspendedDevice = NULL;
- }
- #endif
- /* release device's address */
- if (deviceInstance->setAddress != 0U)
- {
- USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->setAddress);
- }
- else
- {
- if (deviceInstance->allocatedAddress != 0U)
- {
- USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->allocatedAddress);
- }
- }
- /* close control pipe */
- if (deviceInstance->controlPipe != NULL)
- {
- (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
- if (USB_HostClosePipe(hostInstance, deviceInstance->controlPipe) != kStatus_USB_Success)
- {
- #ifdef HOST_ECHO
- usb_echo("error when close pipe\r\n");
- #endif
- }
- deviceInstance->controlPipe = NULL;
- }
- /* free configuration buffer */
- if (deviceInstance->configurationDesc != NULL)
- {
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- SDK_Free(deviceInstance->configurationDesc);
- #else
- OSA_MemoryFree(deviceInstance->configurationDesc);
- #endif
- }
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- level = deviceInstance->level;
- #endif
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- SDK_Free(deviceInstance->deviceDescriptor);
- #else
- OSA_MemoryFree(deviceInstance->deviceDescriptor);
- #endif
- /* free device instance buffer */
- OSA_MemoryFree(deviceInstance);
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- /* enable controller attach if root hub */
- if (level == 1U)
- {
- (void)USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
- }
- #else
- /* enable controller attach */
- USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
- #endif
- }
- static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle)
- {
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- uint32_t endPos;
- usb_descriptor_union_t *unionDes;
- usb_host_interface_t *interfaceParse = NULL;
- usb_host_ep_t *epParse;
- uint8_t *buffer;
- void *temp;
- if (deviceHandle == NULL)
- {
- return kStatus_USB_InvalidParameter;
- }
- temp = (void *)&deviceInstance->configuration;
- buffer = (uint8_t *)temp;
- /* clear the previous parse result, note: end_pos means buffer index here*/
- for (endPos = 0U; endPos < sizeof(usb_host_configuration_t); endPos++)
- {
- buffer[endPos] = 0U;
- }
- for (endPos = 0U; endPos < USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE; ++endPos)
- {
- deviceInstance->interfaceStatus[endPos] = 0U;
- }
- /* parse configuration descriptor */
- temp = (void *)deviceInstance->configurationDesc;
- unionDes = (usb_descriptor_union_t *)temp;
- endPos = (uint32_t)(deviceInstance->configurationDesc + deviceInstance->configurationLen);
- if (((((uint32_t)unionDes) + 1U) < endPos) && (unionDes->common.bLength == USB_DESCRIPTOR_LENGTH_CONFIGURE) &&
- (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURE))
- {
- /* configuration descriptor */
- temp = (void *)unionDes;
- deviceInstance->configuration.configurationDesc = (usb_descriptor_configuration_t *)temp;
- deviceInstance->configuration.configurationExtensionLength = 0;
- deviceInstance->configuration.configurationExtension = NULL;
- deviceInstance->configuration.interfaceCount = 0;
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- while ((uint32_t)unionDes < endPos)
- {
- if (((((uint32_t)unionDes) + 1U) < endPos) &&
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
- {
- if (deviceInstance->configuration.configurationExtension == NULL)
- {
- deviceInstance->configuration.configurationExtension = (uint8_t *)unionDes;
- }
- if ((unionDes->common.bDescriptorType == 0x00U) ||
- (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- deviceInstance->configuration.configurationExtensionLength += unionDes->common.bLength;
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- }
- else
- {
- break;
- }
- }
- /* interface descriptor */
- deviceInstance->configuration.interfaceCount = 0U;
- while ((uint32_t)unionDes < endPos)
- {
- if (((((uint32_t)unionDes) + 1U) < endPos) &&
- (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE))
- {
- /* the interface descriptor length is 9 bytes */
- if ((((uint32_t)unionDes) + 9U) > endPos)
- {
- return kStatus_USB_Error;
- }
- if (unionDes->interface.bAlternateSetting == 0x00U)
- {
- if (deviceInstance->configuration.interfaceCount >= USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE)
- {
- #if (((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) || defined(HOST_ECHO))
- (void)usb_echo(
- "Unsupported Device attached\r\n too many interfaces in one configuration, please increase "
- "the USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE value\n");
- #endif
- return kStatus_USB_Error;
- }
- interfaceParse =
- &deviceInstance->configuration.interfaceList[deviceInstance->configuration.interfaceCount];
- deviceInstance->configuration.interfaceCount++;
- interfaceParse->alternateSettingNumber = 0;
- interfaceParse->epCount = 0;
- interfaceParse->interfaceDesc = &unionDes->interface;
- interfaceParse->interfaceExtensionLength = 0;
- interfaceParse->interfaceExtension = NULL;
- interfaceParse->interfaceIndex = unionDes->interface.bInterfaceNumber;
- if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- while ((uint32_t)unionDes < endPos)
- {
- if (((((uint32_t)unionDes) + 1U) < endPos) &&
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
- {
- if (interfaceParse->interfaceExtension == NULL)
- {
- interfaceParse->interfaceExtension = (uint8_t *)unionDes;
- }
- if ((unionDes->common.bDescriptorType == 0x00U) ||
- (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- }
- else
- {
- break;
- }
- }
- /* endpoint descriptor */
- if (interfaceParse->interfaceDesc->bNumEndpoints != 0U)
- {
- if (((((uint32_t)unionDes) + 1U) >= endPos) ||
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
- (interfaceParse->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
- {
- #ifdef HOST_ECHO
- usb_echo("interface descriptor error\n");
- #endif
- return kStatus_USB_Error;
- }
- for (; interfaceParse->epCount < interfaceParse->interfaceDesc->bNumEndpoints;
- (interfaceParse->epCount)++)
- {
- if (((((uint32_t)unionDes) + 1U) >= endPos) ||
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
- {
- #ifdef HOST_ECHO
- usb_echo("endpoint descriptor error\n");
- #endif
- return kStatus_USB_Error;
- }
- temp = (void *)&interfaceParse->epList[interfaceParse->epCount];
- epParse = (usb_host_ep_t *)temp;
- temp = (void *)unionDes;
- epParse->epDesc = (usb_descriptor_endpoint_t *)temp;
- epParse->epExtensionLength = 0U;
- epParse->epExtension = NULL;
- if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- while ((uint32_t)unionDes < endPos)
- {
- if (((((uint32_t)unionDes) + 1U) < endPos) &&
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
- {
- if (epParse->epExtension == NULL)
- {
- epParse->epExtension = (uint8_t *)unionDes;
- }
- if ((unionDes->common.bDescriptorType == 0x00U) ||
- (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- epParse->epExtensionLength += unionDes->common.bLength;
- unionDes =
- (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- }
- else
- {
- break;
- }
- }
- }
- }
- }
- else
- {
- if (interfaceParse == NULL)
- {
- return kStatus_USB_Error; /* in normal situation this cannot reach */
- }
- interfaceParse->alternateSettingNumber++;
- if (interfaceParse->interfaceExtension == NULL)
- {
- interfaceParse->interfaceExtension = (uint8_t *)unionDes;
- }
- if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- while ((uint32_t)unionDes < endPos)
- {
- if (((((uint32_t)unionDes) + 1U) < endPos) &&
- (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
- {
- if ((unionDes->common.bDescriptorType == 0x00U) ||
- (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
- {
- return kStatus_USB_Error;
- }
- interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
- unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
- }
- else
- {
- break;
- }
- }
- }
- }
- else
- {
- return kStatus_USB_Error;
- }
- }
- }
- else
- {
- return kStatus_USB_Error;
- }
- for (endPos = 0U; endPos < deviceInstance->configuration.interfaceCount; ++endPos)
- {
- deviceInstance->interfaceStatus[endPos] = (uint8_t)kStatus_interface_Attached;
- }
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle,
- uint8_t speed,
- uint8_t hubNumber,
- uint8_t portNumber,
- uint8_t level,
- usb_device_handle *deviceHandle)
- {
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
- usb_host_device_instance_t *newInstance;
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- usb_host_device_instance_t *currentInstance;
- #endif
- uint8_t address;
- usb_host_pipe_init_t pipeInit;
- if (hostHandle == NULL)
- {
- return kStatus_USB_InvalidHandle;
- }
- /* check whether is the device attached? */
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- currentInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
- while (currentInstance != NULL)
- {
- if ((currentInstance->hubNumber == hubNumber) && (currentInstance->portNumber == portNumber))
- {
- *deviceHandle = NULL;
- #ifdef HOST_ECHO
- usb_echo("device has attached\r\n");
- #endif
- return kStatus_USB_Busy;
- }
- else
- {
- currentInstance = currentInstance->next;
- }
- }
- #else
- if (hostInstance->deviceList != NULL)
- {
- *deviceHandle = NULL;
- usb_echo("device has attached\r\n");
- return kStatus_USB_Busy;
- }
- #endif
- /* Allocate new device instance */
- newInstance = (usb_host_device_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_device_instance_t));
- if (newInstance == NULL)
- {
- #ifdef HOST_ECHO
- usb_echo("allocate dev instance fail\r\n");
- #endif
- (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
- (uint32_t)kStatus_USB_AllocFail);
- return kStatus_USB_AllocFail;
- }
- /* new instance fields init */
- newInstance->hostHandle = hostHandle;
- newInstance->speed = speed;
- newInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
- newInstance->enumRetries = USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES;
- newInstance->setAddress = 0;
- newInstance->deviceAttachState = (uint8_t)kStatus_device_Attached;
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- newInstance->deviceDescriptor =
- (usb_descriptor_device_t *)SDK_Malloc(sizeof(usb_descriptor_device_t) + 9, USB_CACHE_LINESIZE);
- #else
- newInstance->deviceDescriptor = (usb_descriptor_device_t *)OSA_MemoryAllocate(sizeof(usb_descriptor_device_t) + 9U);
- #endif
- if (newInstance->deviceDescriptor == NULL)
- {
- #ifdef HOST_ECHO
- usb_echo("allocate newInstance->deviceDescriptor fail\r\n");
- #endif
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- SDK_Free(newInstance->deviceDescriptor);
- #else
- OSA_MemoryFree(newInstance->deviceDescriptor);
- #endif
- OSA_MemoryFree(newInstance);
- (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
- (uint32_t)kStatus_USB_AllocFail);
- return kStatus_USB_AllocFail;
- }
- newInstance->enumBuffer = (uint8_t *)((uint8_t *)newInstance->deviceDescriptor + sizeof(usb_descriptor_device_t));
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- newInstance->hubNumber = hubNumber;
- newInstance->portNumber = portNumber;
- newInstance->level = level;
- if ((speed != USB_SPEED_HIGH) && (level > 1U))
- {
- newInstance->hsHubNumber = (uint8_t)USB_HostHubGetHsHubNumber(hostHandle, hubNumber);
- newInstance->hsHubPort = (uint8_t)USB_HostHubGetHsHubPort(hostHandle, hubNumber, portNumber);
- }
- else
- {
- newInstance->hsHubNumber = hubNumber;
- newInstance->hsHubPort = portNumber;
- }
- #endif /* USB_HOST_CONFIG_HUB */
- (void)USB_HostLock();
- /* allocate address && insert to the dev list */
- address = USB_HostAllocateDeviceAddress(hostInstance);
- if (address == 0U)
- {
- #ifdef HOST_ECHO
- usb_echo("allocate address fail\r\n");
- #endif
- (void)USB_HostUnlock();
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- SDK_Free(newInstance->deviceDescriptor);
- #else
- OSA_MemoryFree(newInstance->deviceDescriptor);
- #endif
- OSA_MemoryFree(newInstance);
- (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
- (uint32_t)kStatus_USB_Error);
- return kStatus_USB_Error;
- }
- newInstance->allocatedAddress = address;
- newInstance->next = (usb_host_device_instance_t *)hostInstance->deviceList;
- hostInstance->deviceList = newInstance;
- newInstance->state = (uint8_t)kStatus_DEV_Initial;
- (void)USB_HostUnlock();
- /* open control pipe */
- pipeInit.devInstance = newInstance;
- pipeInit.pipeType = USB_ENDPOINT_CONTROL;
- pipeInit.direction = 0;
- pipeInit.endpointAddress = 0;
- pipeInit.interval = 0;
- pipeInit.maxPacketSize = 8;
- pipeInit.numberPerUframe = 0;
- pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
- if (USB_HostOpenPipe(hostHandle, &newInstance->controlPipe, &pipeInit) != kStatus_USB_Success)
- {
- /* don't need release resource, resource is released when detach */
- *deviceHandle = newInstance;
- #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
- SDK_Free(newInstance->deviceDescriptor);
- #else
- OSA_MemoryFree(newInstance->deviceDescriptor);
- #endif
- OSA_MemoryFree(newInstance);
- (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
- (uint32_t)kStatus_USB_Error);
- return kStatus_USB_Error;
- }
- /* start enumeration */
- newInstance->state = (uint8_t)kStatus_DEV_GetDes8;
- /* process enumeration state machine */
- if (USB_HostProcessState(newInstance) != kStatus_USB_Success)
- {
- (void)USB_HostNotifyDevice(hostInstance, newInstance, (uint32_t)kUSB_HostEventEnumerationFail,
- (uint32_t)kStatus_USB_Error);
- }
- *deviceHandle = newInstance;
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber)
- {
- usb_host_device_instance_t *deviceInstance;
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
- if (hostHandle == NULL)
- {
- return kStatus_USB_InvalidHandle;
- }
- (void)USB_HostLock();
- /* search for device instance handle */
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
- while (deviceInstance != NULL)
- {
- if ((deviceInstance->hubNumber == hubNumber) && (deviceInstance->portNumber == portNumber))
- {
- break;
- }
- deviceInstance = deviceInstance->next;
- }
- #else
- deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
- #endif
- (void)USB_HostUnlock();
- if (deviceInstance != NULL)
- {
- return USB_HostDetachDeviceInternal(hostHandle, deviceInstance); /* device instance detach */
- }
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle)
- {
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
- if ((hostHandle == NULL) || (deviceHandle == NULL))
- {
- return kStatus_USB_InvalidHandle;
- }
- deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached; /* mark the device is detached from host */
- if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device instance is valid */
- {
- /* detach internally */
- if (deviceInstance->state < (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done */
- {
- if (deviceInstance->controlPipe != NULL)
- {
- (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
- }
- /* remove device instance from host */
- (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
- USB_HostReleaseDeviceResource(hostInstance, deviceInstance);
- }
- else /* enumeration has be done and notified application */
- {
- /* notify application device detach */
- (void)USB_HostNotifyDevice(hostInstance, deviceInstance, (uint32_t)kUSB_HostEventDetach,
- (uint32_t)kStatus_USB_Success);
- }
- }
- return kStatus_USB_Success;
- }
- uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)
- {
- return (NULL != deviceHandle) ? ((usb_host_device_instance_t *)deviceHandle)->deviceAttachState : 0x0U;
- }
- usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
- {
- usb_host_device_instance_t *searchDev;
- if (deviceHandle == NULL)
- {
- return kStatus_USB_InvalidParameter;
- }
- /* search for the device */
- searchDev = (usb_host_device_instance_t *)((usb_host_instance_t *)hostHandle)->deviceList;
- while ((searchDev != NULL) && ((usb_device_handle)searchDev != deviceHandle))
- {
- searchDev = searchDev->next;
- }
- if (NULL != searchDev)
- {
- return kStatus_USB_Success;
- }
- return kStatus_USB_Error;
- }
- static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType)
- {
- usb_status_t status = kStatus_USB_Success;
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
- if (hostHandle == NULL)
- {
- return kStatus_USB_InvalidHandle;
- }
- /* the callbackFn is initialized in USB_HostGetControllerInterface */
- status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
- &controlType);
- return status;
- }
- usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
- {
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- usb_host_instance_t *hostInstance = NULL;
- uint8_t interfaceIndex;
- uint8_t index = 0;
- if ((deviceHandle == NULL) || (interfaceHandle == NULL))
- {
- return kStatus_USB_InvalidHandle;
- }
- hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
- (void)USB_HostLock();
- /* check host_instance valid? */
- for (; index < (uint8_t)USB_HOST_CONFIG_MAX_HOST; ++index)
- {
- if ((g_UsbHostInstance[index].occupied == 1U) &&
- ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
- {
- break;
- }
- }
- if (index >= (uint8_t)USB_HOST_CONFIG_MAX_HOST)
- {
- (void)USB_HostUnlock();
- return kStatus_USB_Error;
- }
- /* check deviceHandle valid? */
- if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
- {
- (void)USB_HostUnlock();
- return kStatus_USB_Error;
- }
- /* search interface and set the interface as opened */
- for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
- {
- if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
- {
- deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Opened;
- break;
- }
- }
- (void)USB_HostUnlock();
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
- {
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- usb_host_instance_t *hostInstance = NULL;
- uint8_t interfaceIndex;
- uint8_t removeLabel = 1;
- uint8_t index = 0;
- if (deviceHandle == NULL)
- {
- return kStatus_USB_InvalidHandle;
- }
- hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
- (void)USB_HostLock();
- /* check host_instance valid? */
- for (; index < (uint8_t)USB_HOST_CONFIG_MAX_HOST; ++index)
- {
- if ((g_UsbHostInstance[index].occupied == 1U) &&
- ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
- {
- break;
- }
- }
- if (index >= (uint8_t)USB_HOST_CONFIG_MAX_HOST)
- {
- (void)USB_HostUnlock();
- return kStatus_USB_Error;
- }
- /* check deviceHandle valid? */
- if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
- {
- (void)USB_HostUnlock();
- return kStatus_USB_Error;
- }
- if (interfaceHandle != NULL)
- {
- /* search interface and set the interface as detached */
- for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
- {
- if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
- {
- deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Detached;
- break;
- }
- }
- }
- if (deviceInstance->deviceAttachState == (uint8_t)kStatus_device_Detached) /* device is removed from host */
- {
- removeLabel = 1;
- /* check all the interfaces of the device are not opened */
- for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
- {
- if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
- {
- removeLabel = 0U;
- break;
- }
- }
- if (removeLabel == 1U)
- {
- /* remove device instance from host */
- (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
- }
- (void)USB_HostUnlock();
- if (removeLabel == 1U)
- {
- USB_HostReleaseDeviceResource((usb_host_instance_t *)deviceInstance->hostHandle,
- deviceInstance); /* release device resource */
- }
- }
- else
- {
- (void)USB_HostUnlock();
- }
- return kStatus_USB_Success;
- }
- usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
- {
- usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
- usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
- uint8_t interfaceIndex = 0;
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- uint8_t level = 0;
- uint8_t devHubNo;
- uint8_t devPortNo;
- #endif
- if ((hostHandle == NULL) || (deviceHandle == NULL))
- {
- return kStatus_USB_InvalidHandle;
- }
- if (deviceInstance->hostHandle != hostHandle)
- {
- return kStatus_USB_InvalidParameter;
- }
- if (USB_HostValidateDevice(hostInstance, deviceInstance) == kStatus_USB_Success) /* device is valid */
- {
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- devHubNo = deviceInstance->hubNumber;
- devPortNo = deviceInstance->portNumber;
- level = deviceInstance->level;
- #endif
- deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached;
- if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device is valid */
- {
- if (deviceInstance->state <
- (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done or application don't use */
- {
- /* detach internally */
- (void)USB_HostDetachDeviceInternal(hostHandle, deviceHandle);
- }
- else /* application use the device */
- {
- for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount;
- ++interfaceIndex)
- {
- if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
- {
- #ifdef HOST_ECHO
- usb_echo("error: there is class instance that is not deinited\r\n");
- #endif
- break;
- }
- }
- /* remove device instance from host */
- (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
- USB_HostReleaseDeviceResource(hostInstance, deviceInstance); /* release resource */
- }
- }
- #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
- if (level == 1U)
- {
- (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusReset); /* reset controller port */
- (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusRestart); /* restart controller port */
- }
- else
- {
- (void)USB_HostHubRemovePort(hostHandle, devHubNo, devPortNo); /* reset hub port */
- }
- #else
- USB_HostControlBus(hostHandle, kUSB_HostBusReset); /* reset controller port */
- USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */
- #endif /* USB_HOST_CONFIG_HUB */
- }
- return kStatus_USB_Success;
- }
|