usb_host_devices.c 54.7 KB
Newer Older
T
tyustli 已提交
1 2
/*
 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3
 * Copyright 2016,2019 NXP
T
tyustli 已提交
4
 *
5
 * SPDX-License-Identifier: BSD-3-Clause
T
tyustli 已提交
6 7
 */

8
#include <usb/include/usb_host_config.h>
T
tyustli 已提交
9 10 11
#include "usb_host.h"
#include "usb_host_hci.h"
#include "usb_host_devices.h"
12
#include "usb_host_framework.h"
T
tyustli 已提交
13 14
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
#include "usb_host_hub.h"
15
#include "usb_host_hub_app.h"
T
tyustli 已提交
16 17 18 19 20 21
#endif /* USB_HOST_CONFIG_HUB */

/*******************************************************************************
 * Definitions
 ******************************************************************************/

22 23 24 25
#ifndef USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH
#define USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH (5000U)
#endif

T
tyustli 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*******************************************************************************
 * 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
 */
55
static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance, uint32_t dataLength);
T
tyustli 已提交
56 57 58 59 60 61 62 63 64

/*!
 * @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
 */
65 66 67 68
static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
                                         usb_host_device_instance_t *deviceInstance,
                                         uint32_t eventCode,
                                         uint32_t eventParameter);
T
tyustli 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

/*!
 * @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 */
137
static const usb_host_enum_process_entry_t s_EnumEntries[] = {
T
tyustli 已提交
138 139
    /* kStatus_dev_initial */
    {
140 141 142
        kStatus_DEV_Notinit,
        kStatus_DEV_Notinit,
        NULL,
T
tyustli 已提交
143 144 145
    },
    /* kStatus_DEV_GetDes8 */
    {
146 147 148
        kStatus_DEV_SetAddress,
        kStatus_DEV_GetDes8,
        USB_HostProcessCallback,
T
tyustli 已提交
149 150 151
    },
    /* kStatus_DEV_SetAddress */
    {
152 153 154
        kStatus_DEV_GetDes,
        kStatus_DEV_SetAddress,
        USB_HostProcessCallback,
T
tyustli 已提交
155 156 157
    },
    /* kStatus_DEV_GetDes */
    {
158 159 160
        kStatus_DEV_GetCfg9,
        kStatus_DEV_GetDes,
        NULL,
T
tyustli 已提交
161 162 163
    },
    /* kStatus_DEV_GetCfg9 */
    {
164 165 166
        kStatus_DEV_GetCfg,
        kStatus_DEV_GetCfg9,
        USB_HostProcessCallback,
T
tyustli 已提交
167 168 169
    },
    /* kStatus_DEV_GetCfg */
    {
170 171 172
        kStatus_DEV_SetCfg,
        kStatus_DEV_GetCfg9,
        USB_HostProcessCallback,
T
tyustli 已提交
173 174 175
    },
    /* kStatus_DEV_SetCfg */
    {
176 177 178
        kStatus_DEV_EnumDone,
        kStatus_DEV_SetCfg,
        NULL,
T
tyustli 已提交
179 180 181 182 183 184 185 186 187
    },
};

/*******************************************************************************
 * Code
 ******************************************************************************/

static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
188 189 190 191
    /* 0 - retry current transfer, 1 - transfer success process,
     * 2 - retry whole process, 3 - fail process
     */
    uint8_t nextStep                           = 0U;
T
tyustli 已提交
192
    usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)param;
193 194
    usb_status_t failReason                    = kStatus_USB_Success;
    uint32_t dataLength;
T
tyustli 已提交
195

196 197
    dataLength = transfer->transferSofar;
    (void)USB_HostFreeTransfer(deviceInstance->hostHandle, transfer); /* free transfer */
T
tyustli 已提交
198 199 200

    if (status == kStatus_USB_Success)
    {
201
        nextStep = 1U;
T
tyustli 已提交
202 203 204 205
    }
    else if (status == kStatus_USB_TransferStall)
    {
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
206 207 208
        (void)usb_echo("no response from device\r\n");
#endif                                         /* USB_HOST_CONFIG_COMPLIANCE_TEST */
        if (deviceInstance->stallRetries > 0U) /* retry same transfer when stall */
T
tyustli 已提交
209
        {
210
            nextStep = 0U;
T
tyustli 已提交
211 212
            deviceInstance->stallRetries--;
        }
213
        else
T
tyustli 已提交
214
        {
215 216
            failReason = kStatus_USB_TransferFailed;
            nextStep   = 2U;
T
tyustli 已提交
217 218 219 220
        }
    }
    else if (status == kStatus_USB_TransferCancel)
    {
221 222
        failReason = kStatus_USB_TransferCancel;
        nextStep   = 3U;
T
tyustli 已提交
223 224 225
    }
    else
    {
226 227
        failReason = kStatus_USB_TransferFailed;
        nextStep   = 2U;
T
tyustli 已提交
228 229
    }

230
    if (nextStep == 1U)
T
tyustli 已提交
231 232
    {
        deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
233
        if (s_EnumEntries[deviceInstance->state - 1U].process == NULL)
T
tyustli 已提交
234
        {
235
            deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].successState; /* next state */
T
tyustli 已提交
236 237 238
        }
        else
        {
239 240
            status = s_EnumEntries[deviceInstance->state - 1U].process(
                deviceInstance, dataLength);   /* process the previous state result */
T
tyustli 已提交
241 242
            if (status == kStatus_USB_Success) /* process success */
            {
243
                deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].successState;
T
tyustli 已提交
244 245 246
            }
            else if (status == kStatus_USB_Retry) /* need retry */
            {
247
                deviceInstance->state = (uint8_t)s_EnumEntries[deviceInstance->state - 1U].retryState;
T
tyustli 已提交
248 249 250 251 252 253 254
            }
            else if (status == kStatus_USB_NotSupported) /* device don't suport by the application */
            {
                return; /* unrecoverable fail */
            }
            else /* process error, next retry */
            {
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
                /* 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
        {
T
tyustli 已提交
273
#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
274
            usb_echo("Device No Response\r\n");
T
tyustli 已提交
275
#endif
276
            nextStep = 3U;
T
tyustli 已提交
277 278 279
        }
    }

280 281
    /* process the state */
    if (nextStep != 3U)
T
tyustli 已提交
282
    {
283 284
        if (USB_HostProcessState(deviceInstance) != kStatus_USB_Success)
        {
T
tyustli 已提交
285
#ifdef HOST_ECHO
286
            usb_echo("enumation setup error\r\n");
T
tyustli 已提交
287
#endif
288 289 290 291 292 293 294 295 296
            failReason = kStatus_USB_Error;
            nextStep   = 3U;
        }
    }

    if (nextStep == 3U)
    {
        (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventEnumerationFail,
                                   (uint32_t)failReason);
T
tyustli 已提交
297 298 299 300 301 302 303 304
    }
}

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;
305
    usb_host_device_enumeration_status_t state;
T
tyustli 已提交
306 307

    /* malloc transfer */
308 309
    state = (usb_host_device_enumeration_status_t)deviceInstance->state;
    if (state != kStatus_DEV_EnumDone)
T
tyustli 已提交
310 311 312 313 314 315 316 317
    {
        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;
        }
318
        transfer->callbackFn    = USB_HostEnumerationTransferCallback;
T
tyustli 已提交
319 320 321
        transfer->callbackParam = deviceInstance;

        /* reset transfer fields */
322 323 324 325
        transfer->setupPacket->bmRequestType = 0x00U;
        transfer->setupPacket->wIndex        = 0U;
        transfer->setupPacket->wLength       = 0U;
        transfer->setupPacket->wValue        = 0U;
T
tyustli 已提交
326 327
    }

328
    switch (state)
T
tyustli 已提交
329 330 331 332
    {
        case kStatus_DEV_GetDes8:
        case kStatus_DEV_GetDes: /* get descriptor state */
            getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
333
            if (deviceInstance->state == (uint8_t)kStatus_DEV_GetDes8)
T
tyustli 已提交
334
            {
335
                getDescriptorParam.descriptorLength = 8U;
T
tyustli 已提交
336 337
            }
            getDescriptorParam.descriptorBuffer = (uint8_t *)deviceInstance->deviceDescriptor;
338 339 340
            getDescriptorParam.descriptorType   = USB_DESCRIPTOR_TYPE_DEVICE;
            getDescriptorParam.descriptorIndex  = 0U;
            getDescriptorParam.languageId       = 0U;
T
tyustli 已提交
341 342 343 344 345 346 347 348 349 350 351 352

            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;
353 354
            getDescriptorParam.descriptorType   = USB_DESCRIPTOR_TYPE_CONFIGURE;
            getDescriptorParam.descriptorIndex  = deviceInstance->configurationValue;
T
tyustli 已提交
355
            getDescriptorParam.descriptorLength = 9;
356
            getDescriptorParam.languageId       = 0;
T
tyustli 已提交
357 358 359 360 361 362 363 364

            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;
365 366
            getDescriptorParam.descriptorType   = USB_DESCRIPTOR_TYPE_CONFIGURE;
            getDescriptorParam.descriptorIndex  = deviceInstance->configurationValue;
T
tyustli 已提交
367
            getDescriptorParam.descriptorLength = deviceInstance->configurationLen;
368
            getDescriptorParam.languageId       = 0;
T
tyustli 已提交
369 370 371 372 373 374 375 376 377 378

            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;
379
            status                          = USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
T
tyustli 已提交
380 381 382
            break;

        case kStatus_DEV_EnumDone: /* enumeration done state */
383 384 385
            /* notify device enumeration done */
            status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
                                          (uint32_t)kUSB_HostEventEnumerationDone, (uint32_t)kStatus_USB_Success);
T
tyustli 已提交
386 387
            if (status == kStatus_USB_Success)
            {
388
                deviceInstance->state = (uint8_t)kStatus_DEV_AppUsed;
T
tyustli 已提交
389 390 391 392
            }
            break;

        default:
393
            /*no action*/
T
tyustli 已提交
394 395 396 397 398 399
            break;
    }

    return status;
}

400
static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance, uint32_t dataLength)
T
tyustli 已提交
401 402
{
    usb_host_pipe_t *pipe = (usb_host_pipe_t *)deviceInstance->controlPipe;
403
    usb_status_t status   = kStatus_USB_Success;
T
tyustli 已提交
404 405
    usb_descriptor_configuration_t *configureDesc;
    usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
406 407
    void *temp;
    usb_host_device_enumeration_status_t state;
T
tyustli 已提交
408

409 410
    state = (usb_host_device_enumeration_status_t)deviceInstance->state;
    switch (state)
T
tyustli 已提交
411 412
    {
        case kStatus_DEV_GetDes8: /* process get 8 bytes descriptor result */
413 414 415 416
            if (dataLength != 8u)
            {
                return kStatus_USB_Error;
            }
T
tyustli 已提交
417
            pipe->maxPacketSize = deviceInstance->deviceDescriptor->bMaxPacketSize0;
418 419
            /* the callbackFn is initialized in USB_HostGetControllerInterface */
            (void)hostInstance->controllerTable->controllerIoctl(
T
tyustli 已提交
420 421 422 423 424
                hostInstance->controllerHandle, kUSB_HostUpdateControlPacketSize, deviceInstance->controlPipe);
            break;

        case kStatus_DEV_SetAddress: /* process set address result */
            deviceInstance->setAddress = deviceInstance->allocatedAddress;
425 426
            /* the callbackFn is initialized in USB_HostGetControllerInterface */
            (void)hostInstance->controllerTable->controllerIoctl(
T
tyustli 已提交
427 428 429
                hostInstance->controllerHandle, kUSB_HostUpdateControlEndpointAddress, deviceInstance->controlPipe);
            break;

430 431 432 433 434
        case kStatus_DEV_GetDes: /* process get full device descriptor result */
            if (dataLength != sizeof(usb_descriptor_device_t))
            {
                return kStatus_USB_Error;
            }
T
tyustli 已提交
435 436 437
            break;

        case kStatus_DEV_GetCfg9: /* process get 9 bytes configuration result */
438 439 440 441 442 443
            if (dataLength != 9u)
            {
                return kStatus_USB_Error;
            }
            temp          = (void *)&deviceInstance->enumBuffer[0];
            configureDesc = (usb_descriptor_configuration_t *)temp;
T
tyustli 已提交
444 445 446 447 448 449 450

            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
451
                OSA_MemoryFree(deviceInstance->configurationDesc);
T
tyustli 已提交
452 453 454
#endif
                deviceInstance->configurationDesc = NULL;
            }
455 456 457 458 459 460

            /* fix misra 4.14 */
            if (deviceInstance->configurationLen > USB_HOST_CONFIG_MAX_CONFIGURATION_DESCRIPTOR_LENGTH)
            {
                return kStatus_USB_Error;
            }
T
tyustli 已提交
461
            /* for KHCI, the start address and the length should be 4 byte align */
462
            if ((deviceInstance->configurationLen & 0x03U) != 0U)
T
tyustli 已提交
463 464 465
            {
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
                deviceInstance->configurationDesc =
466
                    (uint8_t *)SDK_Malloc((deviceInstance->configurationLen & 0xFFFCu) + 4, USB_CACHE_LINESIZE);
T
tyustli 已提交
467 468
#else
                deviceInstance->configurationDesc =
469
                    (uint8_t *)OSA_MemoryAllocate((((uint32_t)deviceInstance->configurationLen) & 0xFFFCU) + 4UL);
T
tyustli 已提交
470 471 472 473 474 475 476 477
#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
478
                deviceInstance->configurationDesc = (uint8_t *)OSA_MemoryAllocate(deviceInstance->configurationLen);
T
tyustli 已提交
479 480 481 482
#endif
            }
            if (deviceInstance->configurationDesc == NULL)
            {
483
                return kStatus_USB_AllocFail;
T
tyustli 已提交
484 485 486
            }
            break;

487 488 489 490 491 492 493
        case kStatus_DEV_GetCfg: /* process get configuration result */
            if (dataLength != deviceInstance->configurationLen)
            {
                return kStatus_USB_Error;
            }
            temp = (void *)deviceInstance->configurationDesc;
            if (((usb_descriptor_configuration_t *)temp)->bMaxPower > USB_HOST_CONFIG_MAX_POWER)
T
tyustli 已提交
494 495 496 497 498 499 500 501 502 503
            {
                return kStatus_USB_Error;
            }
            deviceInstance->configurationValue++;
            if (USB_HostParseDeviceConfigurationDescriptor(deviceInstance) !=
                kStatus_USB_Success) /* parse configuration descriptor */
            {
                return kStatus_USB_Error;
            }

504 505
            status = USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance, (uint32_t)kUSB_HostEventAttach,
                                          (uint32_t)kStatus_USB_Success);
T
tyustli 已提交
506 507 508 509 510 511 512 513 514 515

            if (status != kStatus_USB_Success)
            {
                /* next configuration */
                if (deviceInstance->configurationValue < deviceInstance->deviceDescriptor->bNumConfigurations)
                {
                    return kStatus_USB_Retry;
                }
                else
                {
516 517 518
                    /* notify application device is not supported */
                    (void)USB_HostNotifyDevice(deviceInstance->hostHandle, deviceInstance,
                                               (uint32_t)kUSB_HostEventNotSupported, (uint32_t)kStatus_USB_Success);
T
tyustli 已提交
519 520 521 522 523 524 525 526 527 528
                    return kStatus_USB_NotSupported;
                }
            }
            break;

        case kStatus_DEV_SetCfg:
            /* NULL */
            break;

        default:
529
            /*no action*/
T
tyustli 已提交
530 531 532 533 534 535
            break;
    }

    return status;
}

536 537 538 539
static usb_status_t USB_HostNotifyDevice(usb_host_handle hostHandle,
                                         usb_host_device_instance_t *deviceInstance,
                                         uint32_t eventCode,
                                         uint32_t eventParameter)
T
tyustli 已提交
540 541 542 543 544 545 546 547 548 549
{
    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 */

550 551
    eventCode    = (((uint32_t)eventParameter << 16U) | (uint32_t)eventCode);
    hostInstance = (usb_host_instance_t *)hostHandle;
T
tyustli 已提交
552 553
    if (deviceInstance == NULL)
    {
554
        (void)hostInstance->deviceCallback(NULL, NULL, eventCode);
T
tyustli 已提交
555 556 557 558
        return kStatus_USB_InvalidHandle;
    }

#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
559 560 561
    haveHub   = 0U;
    haveNoHub = 0U;
    for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
T
tyustli 已提交
562 563 564 565
    {
        if (((usb_descriptor_interface_t *)deviceInstance->configuration.interfaceList[interfaceIndex].interfaceDesc)
                ->bInterfaceClass == USB_HOST_HUB_CLASS_CODE)
        {
566
            haveHub = 1U;
T
tyustli 已提交
567 568 569
        }
        else
        {
570
            haveNoHub = 1U;
T
tyustli 已提交
571 572 573
        }
    }

574 575
    if ((hostInstance->deviceCallback != NULL) &&
        ((haveNoHub == 1U) || (deviceInstance->configuration.interfaceCount == 0U)))
T
tyustli 已提交
576
    {
577 578
        /* call host callback function, function is initialized in USB_HostInit */
        status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
T
tyustli 已提交
579
    }
580
    if (0U != haveHub)
T
tyustli 已提交
581 582 583 584 585 586 587 588 589
    {
        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;
    }
590
    else if (eventCode == (uint32_t)kUSB_HostEventAttach) /* attach event */
T
tyustli 已提交
591 592 593 594 595 596 597 598 599 600
    {
        status1 = kStatus_USB_NotSupported;
    }
    else
    {
        status1 = kStatus_USB_Error;
    }
#else
    if (hostInstance->deviceCallback != NULL)
    {
601 602
        /* call host callback function, function is initialized in USB_HostInit */
        status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, eventCode);
T
tyustli 已提交
603 604 605 606 607 608 609
    }
#endif
    return status1;
}

static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance)
{
610
    uint8_t address = 0U;
T
tyustli 已提交
611 612
    uint8_t addressIndex;
    uint8_t addressBitIndex;
613
    for (addressIndex = 0U; addressIndex < 8U; ++addressIndex) /* find the idle address position byte */
T
tyustli 已提交
614
    {
615
        if (hostInstance->addressBitMap[addressIndex] != 0xFFU)
T
tyustli 已提交
616 617 618 619
        {
            break;
        }
    }
620
    if (addressIndex < 8U)
T
tyustli 已提交
621
    {
622
        for (addressBitIndex = 0U; addressBitIndex < 8U; ++addressBitIndex) /* find the idle address position bit */
T
tyustli 已提交
623
        {
624
            if (0U == (hostInstance->addressBitMap[addressIndex] & (0x01U << addressBitIndex)))
T
tyustli 已提交
625
            {
626 627
                hostInstance->addressBitMap[addressIndex] |= (0x01U << addressBitIndex); /* set the allocated bit */
                address = addressIndex * 8U + addressBitIndex + 1U;                      /* the address minimum is 1 */
T
tyustli 已提交
628 629 630 631 632 633 634 635 636
                break;
            }
        }
    }
    return address;
}

static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address)
{
637 638 639 640
    (void)USB_HostLock();
    hostInstance->addressBitMap[((uint32_t)address - 1U) >> 3U] &=
        (~(0x01U << (((uint32_t)address - 1U) & 0x07U))); /* reset the allocated bit */
    (void)USB_HostUnlock();
T
tyustli 已提交
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
}

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;
        }
672
        prevInstance    = currentInstance;
T
tyustli 已提交
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
        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 */
692
    if (deviceInstance->setAddress != 0U)
T
tyustli 已提交
693 694 695 696 697
    {
        USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->setAddress);
    }
    else
    {
698
        if (deviceInstance->allocatedAddress != 0U)
T
tyustli 已提交
699 700 701 702 703 704 705 706
        {
            USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->allocatedAddress);
        }
    }

    /* close control pipe */
    if (deviceInstance->controlPipe != NULL)
    {
707
        (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
T
tyustli 已提交
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
        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
723
        OSA_MemoryFree(deviceInstance->configurationDesc);
T
tyustli 已提交
724 725 726 727 728 729 730 731 732
#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
733
    OSA_MemoryFree(deviceInstance->deviceDescriptor);
T
tyustli 已提交
734 735
#endif
    /* free device instance buffer */
736
    OSA_MemoryFree(deviceInstance);
T
tyustli 已提交
737 738 739

#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
    /* enable controller attach if root hub */
740
    if (level == 1U)
T
tyustli 已提交
741
    {
742
        (void)USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
T
tyustli 已提交
743 744 745
    }
#else
    /* enable controller attach */
746
    USB_HostControlBus(hostInstance, (uint8_t)kUSB_HostBusEnableAttach);
T
tyustli 已提交
747 748 749 750 751 752 753 754 755 756 757
#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;
758
    void *temp;
T
tyustli 已提交
759 760 761 762 763 764

    if (deviceHandle == NULL)
    {
        return kStatus_USB_InvalidParameter;
    }

765 766
    temp   = (void *)&deviceInstance->configuration;
    buffer = (uint8_t *)temp;
T
tyustli 已提交
767
    /* clear the previous parse result, note: end_pos means buffer index here*/
768
    for (endPos = 0U; endPos < sizeof(usb_host_configuration_t); endPos++)
T
tyustli 已提交
769
    {
770
        buffer[endPos] = 0U;
T
tyustli 已提交
771
    }
772
    for (endPos = 0U; endPos < USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE; ++endPos)
T
tyustli 已提交
773
    {
774
        deviceInstance->interfaceStatus[endPos] = 0U;
T
tyustli 已提交
775 776 777
    }

    /* parse configuration descriptor */
778 779 780
    temp     = (void *)deviceInstance->configurationDesc;
    unionDes = (usb_descriptor_union_t *)temp;
    endPos   = (uint32_t)(deviceInstance->configurationDesc + deviceInstance->configurationLen);
T
tyustli 已提交
781 782 783 784 785

    if ((unionDes->common.bLength == USB_DESCRIPTOR_LENGTH_CONFIGURE) &&
        (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURE))
    {
        /* configuration descriptor */
786 787
        temp                                                       = (void *)unionDes;
        deviceInstance->configuration.configurationDesc            = (usb_descriptor_configuration_t *)temp;
T
tyustli 已提交
788
        deviceInstance->configuration.configurationExtensionLength = 0;
789 790
        deviceInstance->configuration.configurationExtension       = NULL;
        deviceInstance->configuration.interfaceCount               = 0;
T
tyustli 已提交
791 792 793 794 795 796 797 798 799
        unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
        while ((uint32_t)unionDes < endPos)
        {
            if (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE)
            {
                if (deviceInstance->configuration.configurationExtension == NULL)
                {
                    deviceInstance->configuration.configurationExtension = (uint8_t *)unionDes;
                }
800 801
                if ((unionDes->common.bDescriptorType == 0x00U) ||
                    (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
T
tyustli 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814
                {
                    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 */
815
        deviceInstance->configuration.interfaceCount = 0U;
T
tyustli 已提交
816 817 818 819
        while ((uint32_t)unionDes < endPos)
        {
            if (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
            {
820
                if (unionDes->interface.bAlternateSetting == 0x00U)
T
tyustli 已提交
821 822 823
                {
                    if (deviceInstance->configuration.interfaceCount >= USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE)
                    {
824 825
#if (((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) || defined(HOST_ECHO))
                        (void)usb_echo(
T
tyustli 已提交
826 827 828 829 830 831 832 833
                            "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++;
834 835 836
                    interfaceParse->alternateSettingNumber   = 0;
                    interfaceParse->epCount                  = 0;
                    interfaceParse->interfaceDesc            = &unionDes->interface;
T
tyustli 已提交
837
                    interfaceParse->interfaceExtensionLength = 0;
838 839 840
                    interfaceParse->interfaceExtension       = NULL;
                    interfaceParse->interfaceIndex           = unionDes->interface.bInterfaceNumber;
                    if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
T
tyustli 已提交
841 842 843 844 845 846 847 848 849 850 851 852 853
                    {
                        return kStatus_USB_Error;
                    }
                    unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
                    while ((uint32_t)unionDes < endPos)
                    {
                        if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
                            (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
                        {
                            if (interfaceParse->interfaceExtension == NULL)
                            {
                                interfaceParse->interfaceExtension = (uint8_t *)unionDes;
                            }
854 855
                            if ((unionDes->common.bDescriptorType == 0x00U) ||
                                (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
T
tyustli 已提交
856 857 858 859 860 861 862 863 864 865 866 867 868
                            {
                                return kStatus_USB_Error;
                            }
                            interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
                            unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
                        }
                        else
                        {
                            break;
                        }
                    }

                    /* endpoint descriptor */
869
                    if (interfaceParse->interfaceDesc->bNumEndpoints != 0U)
T
tyustli 已提交
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
                    {
                        if ((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 >= endPos) ||
                                (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
                            {
#ifdef HOST_ECHO
                                usb_echo("endpoint descriptor error\n");
#endif
                                return kStatus_USB_Error;
                            }
890 891 892 893 894 895 896
                            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 */
T
tyustli 已提交
897 898 899 900 901 902 903 904 905 906 907 908 909
                            {
                                return kStatus_USB_Error;
                            }
                            unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
                            while ((uint32_t)unionDes < endPos)
                            {
                                if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
                                    (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
                                {
                                    if (epParse->epExtension == NULL)
                                    {
                                        epParse->epExtension = (uint8_t *)unionDes;
                                    }
910 911
                                    if ((unionDes->common.bDescriptorType == 0x00U) ||
                                        (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
T
tyustli 已提交
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937
                                    {
                                        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;
                    }
938
                    if (unionDes->common.bLength == 0x00U) /* the descriptor data is wrong */
T
tyustli 已提交
939 940 941 942 943 944 945 946 947
                    {
                        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 (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE)
                        {
948 949
                            if ((unionDes->common.bDescriptorType == 0x00U) ||
                                (unionDes->common.bLength == 0x00U)) /* the descriptor data is wrong */
T
tyustli 已提交
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969
                            {
                                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;
            }
        }
    }

970
    for (endPos = 0U; endPos < deviceInstance->configuration.interfaceCount; ++endPos)
T
tyustli 已提交
971
    {
972
        deviceInstance->interfaceStatus[endPos] = (uint8_t)kStatus_interface_Attached;
T
tyustli 已提交
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
    }

    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 */
1026
    newInstance = (usb_host_device_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_device_instance_t));
T
tyustli 已提交
1027 1028 1029 1030 1031
    if (newInstance == NULL)
    {
#ifdef HOST_ECHO
        usb_echo("allocate dev instance fail\r\n");
#endif
1032 1033
        (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
                                   (uint32_t)kStatus_USB_AllocFail);
T
tyustli 已提交
1034 1035 1036 1037
        return kStatus_USB_AllocFail;
    }

    /* new instance fields init */
1038 1039 1040 1041 1042 1043
    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;
T
tyustli 已提交
1044 1045 1046 1047
#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
1048
    newInstance->deviceDescriptor = (usb_descriptor_device_t *)OSA_MemoryAllocate(sizeof(usb_descriptor_device_t) + 9U);
T
tyustli 已提交
1049 1050 1051 1052 1053 1054 1055 1056 1057
#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
1058
        OSA_MemoryFree(newInstance->deviceDescriptor);
T
tyustli 已提交
1059
#endif
1060 1061 1062
        OSA_MemoryFree(newInstance);
        (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
                                   (uint32_t)kStatus_USB_AllocFail);
T
tyustli 已提交
1063 1064 1065 1066
        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))
1067
    newInstance->hubNumber  = hubNumber;
T
tyustli 已提交
1068
    newInstance->portNumber = portNumber;
1069
    newInstance->level      = level;
T
tyustli 已提交
1070

1071
    if ((speed != USB_SPEED_HIGH) && (level > 1U))
T
tyustli 已提交
1072
    {
1073 1074
        newInstance->hsHubNumber = (uint8_t)USB_HostHubGetHsHubNumber(hostHandle, hubNumber);
        newInstance->hsHubPort   = (uint8_t)USB_HostHubGetHsHubPort(hostHandle, hubNumber, portNumber);
T
tyustli 已提交
1075 1076 1077 1078
    }
    else
    {
        newInstance->hsHubNumber = hubNumber;
1079
        newInstance->hsHubPort   = portNumber;
T
tyustli 已提交
1080 1081 1082
    }
#endif /* USB_HOST_CONFIG_HUB */

1083
    (void)USB_HostLock();
T
tyustli 已提交
1084 1085
    /* allocate address && insert to the dev list */
    address = USB_HostAllocateDeviceAddress(hostInstance);
1086
    if (address == 0U)
T
tyustli 已提交
1087 1088 1089 1090
    {
#ifdef HOST_ECHO
        usb_echo("allocate address fail\r\n");
#endif
1091
        (void)USB_HostUnlock();
T
tyustli 已提交
1092 1093 1094
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
        SDK_Free(newInstance->deviceDescriptor);
#else
1095
        OSA_MemoryFree(newInstance->deviceDescriptor);
T
tyustli 已提交
1096
#endif
1097 1098 1099
        OSA_MemoryFree(newInstance);
        (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
                                   (uint32_t)kStatus_USB_Error);
T
tyustli 已提交
1100 1101 1102 1103
        return kStatus_USB_Error;
    }
    newInstance->allocatedAddress = address;

1104
    newInstance->next        = (usb_host_device_instance_t *)hostInstance->deviceList;
T
tyustli 已提交
1105
    hostInstance->deviceList = newInstance;
1106 1107
    newInstance->state       = (uint8_t)kStatus_DEV_Initial;
    (void)USB_HostUnlock();
T
tyustli 已提交
1108 1109

    /* open control pipe */
1110 1111 1112
    pipeInit.devInstance     = newInstance;
    pipeInit.pipeType        = USB_ENDPOINT_CONTROL;
    pipeInit.direction       = 0;
T
tyustli 已提交
1113
    pipeInit.endpointAddress = 0;
1114 1115
    pipeInit.interval        = 0;
    pipeInit.maxPacketSize   = 8;
T
tyustli 已提交
1116
    pipeInit.numberPerUframe = 0;
1117
    pipeInit.nakCount        = USB_HOST_CONFIG_MAX_NAK;
T
tyustli 已提交
1118 1119 1120 1121 1122 1123 1124
    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
1125
        OSA_MemoryFree(newInstance->deviceDescriptor);
T
tyustli 已提交
1126
#endif
1127 1128 1129
        OSA_MemoryFree(newInstance);
        (void)USB_HostNotifyDevice(hostInstance, NULL, (uint32_t)kUSB_HostEventEnumerationFail,
                                   (uint32_t)kStatus_USB_Error);
T
tyustli 已提交
1130 1131 1132 1133
        return kStatus_USB_Error;
    }

    /* start enumeration */
1134 1135 1136 1137 1138 1139 1140
    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);
    }
T
tyustli 已提交
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155

    *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;
    }

1156
    (void)USB_HostLock();
T
tyustli 已提交
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
/* 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
1171
    (void)USB_HostUnlock();
T
tyustli 已提交
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
    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;
1182
    usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
T
tyustli 已提交
1183 1184 1185 1186 1187
    if ((hostHandle == NULL) || (deviceHandle == NULL))
    {
        return kStatus_USB_InvalidHandle;
    }

1188
    deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached; /* mark the device is detached from host */
T
tyustli 已提交
1189

1190
    if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device instance is valid */
T
tyustli 已提交
1191 1192
    {
        /* detach internally */
1193
        if (deviceInstance->state < (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done */
T
tyustli 已提交
1194 1195 1196
        {
            if (deviceInstance->controlPipe != NULL)
            {
1197
                (void)USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
T
tyustli 已提交
1198 1199 1200
            }

            /* remove device instance from host */
1201
            (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
T
tyustli 已提交
1202 1203
            USB_HostReleaseDeviceResource(hostInstance, deviceInstance);
        }
1204
        else /* enumeration has be done and notified application */
T
tyustli 已提交
1205
        {
1206 1207 1208
            /* notify application device detach */
            (void)USB_HostNotifyDevice(hostInstance, deviceInstance, (uint32_t)kUSB_HostEventDetach,
                                       (uint32_t)kStatus_USB_Success);
T
tyustli 已提交
1209 1210 1211 1212 1213 1214 1215 1216
        }
    }

    return kStatus_USB_Success;
}

uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)
{
1217
    return (NULL != deviceHandle) ? ((usb_host_device_instance_t *)deviceHandle)->deviceAttachState : 0x0U;
T
tyustli 已提交
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
}

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;
    }

1235
    if (NULL != searchDev)
T
tyustli 已提交
1236 1237 1238 1239 1240 1241 1242 1243
    {
        return kStatus_USB_Success;
    }
    return kStatus_USB_Error;
}

static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType)
{
1244
    usb_status_t status               = kStatus_USB_Success;
T
tyustli 已提交
1245 1246 1247 1248 1249 1250
    usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;

    if (hostHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }
1251
    /* the callbackFn is initialized in USB_HostGetControllerInterface */
T
tyustli 已提交
1252 1253 1254 1255 1256 1257 1258 1259 1260
    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;
1261
    usb_host_instance_t *hostInstance          = NULL;
T
tyustli 已提交
1262 1263 1264 1265 1266 1267 1268 1269 1270
    uint8_t interfaceIndex;
    uint8_t index = 0;

    if ((deviceHandle == NULL) || (interfaceHandle == NULL))
    {
        return kStatus_USB_InvalidHandle;
    }

    hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
1271
    (void)USB_HostLock();
T
tyustli 已提交
1272 1273 1274
    /* check host_instance valid? */
    for (; index < USB_HOST_CONFIG_MAX_HOST; ++index)
    {
1275
        if ((g_UsbHostInstance[index].occupied == 1U) &&
T
tyustli 已提交
1276 1277 1278 1279 1280 1281 1282
            ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
        {
            break;
        }
    }
    if (index >= USB_HOST_CONFIG_MAX_HOST)
    {
1283
        (void)USB_HostUnlock();
T
tyustli 已提交
1284 1285 1286 1287 1288 1289
        return kStatus_USB_Error;
    }

    /* check deviceHandle valid? */
    if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
    {
1290
        (void)USB_HostUnlock();
T
tyustli 已提交
1291 1292 1293 1294 1295 1296 1297 1298
        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)
        {
1299
            deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Opened;
T
tyustli 已提交
1300 1301 1302
            break;
        }
    }
1303
    (void)USB_HostUnlock();
T
tyustli 已提交
1304 1305 1306 1307 1308 1309 1310

    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;
1311
    usb_host_instance_t *hostInstance          = NULL;
T
tyustli 已提交
1312 1313
    uint8_t interfaceIndex;
    uint8_t removeLabel = 1;
1314
    uint8_t index       = 0;
T
tyustli 已提交
1315 1316 1317 1318 1319 1320 1321

    if (deviceHandle == NULL)
    {
        return kStatus_USB_InvalidHandle;
    }

    hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
1322
    (void)USB_HostLock();
T
tyustli 已提交
1323 1324 1325
    /* check host_instance valid? */
    for (; index < USB_HOST_CONFIG_MAX_HOST; ++index)
    {
1326
        if ((g_UsbHostInstance[index].occupied == 1U) &&
T
tyustli 已提交
1327 1328 1329 1330 1331 1332 1333
            ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
        {
            break;
        }
    }
    if (index >= USB_HOST_CONFIG_MAX_HOST)
    {
1334
        (void)USB_HostUnlock();
T
tyustli 已提交
1335 1336 1337 1338 1339 1340
        return kStatus_USB_Error;
    }

    /* check deviceHandle valid? */
    if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
    {
1341
        (void)USB_HostUnlock();
T
tyustli 已提交
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
        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)
            {
1352
                deviceInstance->interfaceStatus[interfaceIndex] = (uint8_t)kStatus_interface_Detached;
T
tyustli 已提交
1353 1354 1355 1356 1357
                break;
            }
        }
    }

1358
    if (deviceInstance->deviceAttachState == (uint8_t)kStatus_device_Detached) /* device is removed from host */
T
tyustli 已提交
1359 1360 1361 1362 1363
    {
        removeLabel = 1;
        /* check all the interfaces of the device are not opened */
        for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
        {
1364
            if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
T
tyustli 已提交
1365
            {
1366
                removeLabel = 0U;
T
tyustli 已提交
1367 1368 1369
                break;
            }
        }
1370
        if (removeLabel == 1U)
T
tyustli 已提交
1371 1372
        {
            /* remove device instance from host */
1373
            (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
T
tyustli 已提交
1374
        }
1375
        (void)USB_HostUnlock();
T
tyustli 已提交
1376

1377
        if (removeLabel == 1U)
T
tyustli 已提交
1378 1379 1380 1381 1382 1383 1384
        {
            USB_HostReleaseDeviceResource((usb_host_instance_t *)deviceInstance->hostHandle,
                                          deviceInstance); /* release device resource */
        }
    }
    else
    {
1385
        (void)USB_HostUnlock();
T
tyustli 已提交
1386 1387 1388 1389 1390 1391 1392
    }

    return kStatus_USB_Success;
}

usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
{
1393
    usb_host_instance_t *hostInstance          = (usb_host_instance_t *)hostHandle;
T
tyustli 已提交
1394
    usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
1395
    uint8_t interfaceIndex                     = 0;
T
tyustli 已提交
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413
#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))
1414
        devHubNo  = deviceInstance->hubNumber;
T
tyustli 已提交
1415
        devPortNo = deviceInstance->portNumber;
1416
        level     = deviceInstance->level;
T
tyustli 已提交
1417 1418
#endif

1419 1420
        deviceInstance->deviceAttachState = (uint8_t)kStatus_device_Detached;
        if (deviceInstance->state >= (uint8_t)kStatus_DEV_Initial) /* device is valid */
T
tyustli 已提交
1421
        {
1422 1423
            if (deviceInstance->state <
                (uint8_t)kStatus_DEV_AppUsed) /* enumeration is not done or application don't use */
T
tyustli 已提交
1424 1425
            {
                /* detach internally */
1426
                (void)USB_HostDetachDeviceInternal(hostHandle, deviceHandle);
T
tyustli 已提交
1427 1428 1429
            }
            else /* application use the device */
            {
1430
                for (interfaceIndex = 0U; interfaceIndex < deviceInstance->configuration.interfaceCount;
T
tyustli 已提交
1431 1432
                     ++interfaceIndex)
                {
1433
                    if (deviceInstance->interfaceStatus[interfaceIndex] == (uint8_t)kStatus_interface_Opened)
T
tyustli 已提交
1434 1435 1436 1437 1438 1439 1440 1441
                    {
#ifdef HOST_ECHO
                        usb_echo("error: there is class instance that is not deinited\r\n");
#endif
                        break;
                    }
                }
                /* remove device instance from host */
1442
                (void)USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
T
tyustli 已提交
1443 1444 1445 1446 1447
                USB_HostReleaseDeviceResource(hostInstance, deviceInstance); /* release resource */
            }
        }

#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
1448
        if (level == 1U)
T
tyustli 已提交
1449
        {
1450 1451
            (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusReset);   /* reset controller port */
            (void)USB_HostControlBus(hostHandle, (uint8_t)kUSB_HostBusRestart); /* restart controller port */
T
tyustli 已提交
1452 1453 1454
        }
        else
        {
1455
            (void)USB_HostHubRemovePort(hostHandle, devHubNo, devPortNo); /* reset hub port */
T
tyustli 已提交
1456 1457 1458 1459 1460 1461 1462 1463
        }
#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;
1464
}