⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncdevice.c

📁 CE下 NET2778 NDIS Drivers, 在每个平台上都可以使用
💻 C
📖 第 1 页 / 共 5 页
字号:
            //  - Advanced devices supporting more than configurations zero and one must
            //    trap and handle standard requests for: Get Descriptor (Configuration) 
            //    and Set Configuration
            PrivDeviceObject->EventCode = NC_DEVICE_EVENT_SET_CONFIGURATION;
            *NcStatus = PrivDeviceObject->DeviceEventHandler(PrivDeviceObject);
            if ((*NcStatus == NCSTATUS_SUCCESS) || (*NcStatus == NCSTATUS_MORE_PROCESSING_REQUIRED))
            {   // Requested configuration is acceptable
                *NcStatus = NCSTATUS_SUCCESS;
                return;
            }
            // Requested configuration is NOT acceptable
            //  - Artificially deconfigure the device
            WVALUE_LO = 0;
            NcApi_SetConfiguration(PrivDeviceObject);
        default:
            break;
        }
        break;
    case HOST_TO_DEVICE | STANDARD | RECIPIENT_INTERFACE:
        switch (BREQUEST)
        {
        case CLEAR_FEATURE:
            // Feature not supported - add code if desired
            break;
        case SET_FEATURE:
            // Feature not supported - add code if desired
            break;
        case SET_INTERFACE:
            // Default Set Interface handler
            //  - Simple devices supporting a single interface can let this section 
            //    handle Set Interface requests.
            //  - See USB 2.0: 9.4.10
            //  - See also GET_INTERFACE
            NCDEBUG(sprintf(SetupPacket_Msg, "SET_INTERFACE: %d AltSetting:%d", WINDEX, WVALUE);)

            // Assert: This default Set Interface handler is restricted to configurations 
            // with a single interface. Clients supporting multiple interfaces should 
            // trap and parse Set (and Get) Interface requests. See USB 9.4.10
            ASSERT(UsbConfiguration->bNumInterfaces == 1);

            if ((WVALUE == 0x0000) && (WINDEX == 0x0000))
            {   // Alternate setting zero on interface zero
                //  - Request accepted
                //  - Nothing else to do!
                return;
            }
            // Request failed
            //  - Requested interface does not exist in this simple (single interface) configuration
            break;
        default:
            break;
        }
        break;
    case HOST_TO_DEVICE | STANDARD | RECIPIENT_ENDPOINT:
        Endpoint = NcApi_FindUsbEp(WINDEX_LO);
        if (Endpoint == NULL)
        {   // No logical endpoint matching USB endpoint found!
            break;
        }

        switch (BREQUEST)
        {
        case CLEAR_FEATURE:
        case SET_FEATURE:
            // Clear Endpoint Feature
            if (WVALUE != ENDPOINT_STALL)
            {   // Expected wValue to be ENDPOINT_STALL
                break;
            }
            // Set or clear the Endpoint Stall on endpoint specified by wIndex
            // Tip: This call may change Page Select
            Endpoint->Stall = (BREQUEST == SET_FEATURE)? TRUE: FALSE;
            NcApi_EpStall(Endpoint);

            Endpoint->EventCode = NC_ENDPOINT_EVENT_SET_CLEAR_STALL;
            ASSERT(Endpoint->EndpointEventHandler != NULL);
            Endpoint->EndpointEventHandler(Endpoint);
            NCDEBUG(sprintf(SetupPacket_Msg, "SET/CLR_FEATURE(STALL): USB Ep:%2.2x)", WINDEX_LO);)
            return;
        case SYNCH_FRAME:
            // Feature not supported - add code if desired
            break;
        default:
            break;
        }
        break;
    case DEVICE_TO_HOST | STANDARD | RECIPIENT_DEVICE:
        switch (BREQUEST)
        {
        case GET_STATUS: 
            // Get Status (DEVICE) 
            //  - Bit 1: Remote Wakeup enable
            //  - Bit 0: Currently Self Powered (Important: USB 9.4.5 and Table 9-10 (bmAttributes)
            //  - See USB 2.0: 9.2.5.2, 9.4.5, table 9-4
            if (PrivDeviceObject->HostWakeupEnable)
            {   // This device has its remote host wakeup capability enabled
                //   - Tip: A device with remote wakeup capability may NOT actually 
                //     apply remote wakeup unless specifically enabled by the host
                //   - Notify host that the device's remote wakeup capability is enabled
                lewStatus.Byte[LITTLEEND_LO] = 0x02;
                // Assert: A device that does not report Remote Wakeup capability in its
                // configuration cannot have have its wakeup capability enabled!
                ASSERT(UsbConfiguration->bmAttributes & (1<<5));
            }
            else 
            {   // Device does NOT have its host wakeup capability enabled
                lewStatus.Byte[LITTLEEND_LO] = 0x00;
            }

            if (UsbConfiguration->bmAttributes & (1<<6))
            {   // The current configuration indicates device is self-powered:
                //  - A self-powered device does not draw any power from USB, so bMaxPower in 
                //    the Configuration should be zero UNLESS the device can *dynamically* 
                //    switch power sources...

                // Assert: This implementation assumes fixed power source policy. Devices that 
                // can dynamically change power source between bus and self-powered should:
                //  - Set the Self Powered bit (bit 6) in bmAttributes TRUE (See USB 2.0: Table 9-10)
                //  - Set bMaxPower to an appropriate non-zero value (See USB 2.0: Table 9-10)
                //  - Install a Setup Request handler to handle this Get Status (DEVICE) request,
                //    correctly reporting its power source (self or bus powered)
                ASSERT(UsbConfiguration->bMaxPower == 0);

                // Indicate device is currently self-powered
                lewStatus.Byte[LITTLEEND_LO] |= 0x01;
            }
            NC_EP0_TRANSFER(&lewStatus, sizeof(lewStatus));
            NCDEBUG(sprintf(SetupPacket_Msg, "GET_STATUS [DEVICE]: %4.4x", lewStatus.Word);)
            return;
        case GET_CONFIGURATION:
            // Return the current configuration number
            //  - USB 2.0: 9.4.2: Length of the data phase for Get Configuration is one
            NC_EP0_TRANSFER(&PrivDeviceObject->UsbConfigurationNumber, 1);
            NCDEBUG(sprintf(SetupPacket_Msg, SetupPacket_LengthFormat, "GET_CONFIGURATION", 1);)
            return;
        case GET_DESCRIPTOR:
            switch (WVALUE_HI)
            {   // High byte of wValue specifies the descriptor type (RECIPIENT_DEVICE, CONFIGURATION, STRING, etc.)
            case DEVICE_DESC:
                // "Get Device Descriptor" request
                ASSERT(PrivDeviceObject->DeviceDescriptor != NULL);
                ASSERT(PrivDeviceObject->DeviceDescriptor->bLength == sizeof(USB_DEVICE_DESCRIPTOR));
                Length = min(WLENGTH, sizeof(USB_DEVICE_DESCRIPTOR));
                NC_EP0_TRANSFER(PrivDeviceObject->DeviceDescriptor, Length)
                NCDEBUG(sprintf(SetupPacket_Msg, SetupPacket_LengthFormat, "GET_DESCRIPTOR [DEVICE]", Length);)
                return;
            case DEVICE_QUALIFIER_DESC:
                // "Get Device Qualifier Descriptor" request
                ASSERT(PrivDeviceObject->DeviceQualifierDescriptor != NULL);
                ASSERT(PrivDeviceObject->DeviceQualifierDescriptor->bLength == sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR));
                Length = min(WLENGTH, sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR));
                NC_EP0_TRANSFER(PrivDeviceObject->DeviceQualifierDescriptor, Length);
                NCDEBUG(sprintf(SetupPacket_Msg, SetupPacket_LengthFormat, "GET_DESCRIPTOR [DEVICE_QUALIFIER]", Length);)
                return;
            case CONFIGURATION_DESC:
                // "Get Configuration" request
                //  - The Get Configuration request returns the entire configuration: the Configuration 
                //    descriptor, all its Interface descriptors and all its Endpoint desciptors
                NcApi_UpdateHsFsConfigurations(PrivDeviceObject);
                ASSERT(UsbConfiguration != NULL);
                ASSERT(UsbConfiguration->bDescriptorType == CONFIGURATION_DESC);
                Length = min(WLENGTH, Sizeof_UsbConfiguration.Word);
                NC_EP0_TRANSFER(UsbConfiguration, Length);
                NCDEBUG(sprintf(SetupPacket_Msg, SetupPacket_LengthFormat, "GET_DESCRIPTOR [CONFIGURATION]", Length);)
                return;
            case OTHER_SPEED_CONFIGURATION_DESC:
                // "Get Other Speed Configuration Descriptor" request
                //  - The Get Other Speed Configuration request returns the entire configuration: the Configuration 
                //    descriptor, all its Interface descriptors and all its Endpoint desciptors
                NcApi_UpdateHsFsConfigurations(PrivDeviceObject);
                ASSERT(UsbConfiguration_OtherSpeed != NULL);
                ASSERT(UsbConfiguration_OtherSpeed->bDescriptorType == OTHER_SPEED_CONFIGURATION_DESC);
                Length = min(WLENGTH, Sizeof_UsbConfiguration_OtherSpeed.Word);
                NC_EP0_TRANSFER(UsbConfiguration_OtherSpeed, Length);
                NCDEBUG(sprintf(SetupPacket_Msg, SetupPacket_LengthFormat, "GET_DESCRIPTOR [OTHER_SPEED_CONFIGURATION]", Length);)
                return;
            case STRING_DESC:
                // "Get String Descriptor" request
                if ((WVALUE_LO < NCAPI_MAX_USB_STRINGS) && (UsbStrings[WVALUE_LO] != NULL))
                {   // 
                    Length = min(UsbStrings[WVALUE_LO]->bLength, WLENGTH);
                    NC_EP0_TRANSFER(UsbStrings[WVALUE_LO], Length);
                    NCDEBUG(sprintf(SetupPacket_Msg, SetupPacket_LengthFormat, "GET_DESCRIPTOR [STRING]", Length);)
                    return;
                }
                break;
            default:
                break;
            }
            break;
        default:
            break;
        }
        break;
    case DEVICE_TO_HOST | STANDARD | RECIPIENT_INTERFACE:
        switch (BREQUEST)
        {
        case GET_STATUS:
            // Return interface status 
            //  - Always zero. See USB 2.0: 9.4.5 (fig 9-5)
            NC_EP0_TRANSFER(&lewStatus, WLENGTH);
            NCDEBUG(sprintf(SetupPacket_Msg, "GET_STATUS: [INTERFACE]: %4.4x", lewStatus.Word);)
            return;
        case GET_INTERFACE:
            // NetChip's firmware model allows for projects with different interface requirements:
            //  - The API default Get Interface handler can handle simple devices with a single interface
            //  - Client's with complex interfaces should specify their own interface handler
            //  - See USB 2.0: 9.4.4
            //  - See also SET_INTERFACE
            NCPRINTFCOND(VOLUME_MINIMUM, WLENGTH != 1, ("GET_INTERFACE: Warning: Unexpected wLength value\n"));
            // Assert: This default Get Interface handler is restricted to configurations 
            // with a single interface. Clients supporting multiple interfaces should 
            // install their own Get (and Set) Interface request handler. See USB 9.4.4
            ASSERT(UsbConfiguration->bNumInterfaces == 1);

            if (WINDEX == 0x0000)
            {   // Host requested alternate setting for interface zero
                //  - Alternate setting for simple device is zero
                ASSERT(lewStatus.Word == 0)
                NC_EP0_TRANSFER(&lewStatus, 1);
                return;
            }
            // Request failed
            //  - Requested interface does not exist in this simple (single interface) configuration
            break;

        default:
            break;
        }
        break;
    case DEVICE_TO_HOST | STANDARD | RECIPIENT_ENDPOINT:
        switch (BREQUEST)
        {
        case GET_STATUS:
            // Return status of endpoint specified in wIndex
            Endpoint = NcApi_FindUsbEp(WINDEX_LO);
            if (Endpoint == NULL)
            {   // No logical endpoint matching USB endpoint found!
                break;
            }
#if _NCVIRTUALIZEENDPOINTS
            lewStatus.Byte[LITTLEEND_LO] = (BYTE)(Endpoint->Priv.EpRsp & (1<<ENDPOINT_HALT));
#else
            NETCHIP_WRITE(PAGESEL, Endpoint->Priv.PhysEp);
            lewStatus.Byte[LITTLEEND_LO] = (BYTE)(NETCHIP_READ(EP_RSPSET) & (1<<ENDPOINT_HALT));
#endif
            NC_EP0_TRANSFER(&lewStatus, sizeof(lewStatus));
            NCDEBUG(sprintf(SetupPacket_Msg, "GET_STATUS: USB Ep:%2.2x: %4.4x", WINDEX_LO, lewStatus.Word);)
            return;
        default:
            break;
        }
        break;
    default:
        break;
    }

    // Parse failed
    //  - The host's setup request is not known
    *NcStatus = NCSTATUS_UNSUCCESSFUL;
}

///////////////////////////////////////////////////////////////////////////////
STATIC void
EpZero_SetupPhase(
    void
    )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -