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

📄 rndis_pdd.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 4 页
字号:
                    g_EP2Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
#ifdef USE_1BYTE_TERMINATING_PACKETS
                    g_EP2Transfer.pvBuffer = &g_ucScratch;
                    g_EP2Transfer.cbBuffer = sizeof(UCHAR);
#else
                    g_EP2Transfer.pvBuffer = NULL;
                    g_EP2Transfer.cbBuffer = 0;
#endif
                    // g_EP2Transfer.dwBufferPhysicalAddress; // not used
                    g_EP2Transfer.cbTransferred = 0;
                    g_EP2Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
                    g_EP2Transfer.pvPddData = NULL;
                    g_EP2Transfer.pvPddTransferInfo = NULL;


                    OALMSG(OAL_ETHER&&OAL_FUNC, (
                        L"Sending NULL terminator for the packet...\r\n"
                    ));
                    g_EP2TransferState = TS_SENDING_PACKET_TERMINATOR;
                    g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 2, &g_EP2Transfer );
                }
                else
                {
                    g_EP2TransferState = TS_IDLE;
                    TxComplete();
                }
            }
            else if( g_EP2TransferState == TS_SENDING_PACKET_TERMINATOR )
            {
                ASSERT( g_EP2Transfer.dwUsbError == UFN_NO_ERROR );
                OALMSG(OAL_ETHER&&OAL_FUNC, (L"SendPacket NULL terminator sent!\r\n"));
                g_EP2TransferState = TS_IDLE;

                TxComplete();
            }
            else
            {
                OALMSG(OAL_ERROR, (L"Unexpected EP2 transfer state!"));
            }
        }
        else if( pTransfer == &g_EP3Transfer )
        {
            OALMSG(OAL_ETHER&&OAL_FUNC, (
                L"EP3 Interrupt successfully sent!\r\n"
            ));
            // interrupt succesfully sent
        }
        else
        {
            OALMSG(OAL_ERROR, (L"INVALID TRANSFER!\r\n"));
        }
        break;

    case UFN_MSG_BUS_EVENTS:
        switch( dwParam )
        {
        case UFN_DETACH:
            g_devState = DS_DETACHED;
            break;
        case UFN_ATTACH:
            g_devState = DS_ATTACHED;
            break;
        case UFN_RESET:
            g_devState = DS_DEFAULT;
            g_EP0TransferState = TS_IDLE;
            g_EP2TransferState = TS_IDLE;

#if 0
            OALMSG (OAL_WARN, (TEXT("RNDISFN:: UFN_RESET received.\r\n")));                
            //ClosePipes(pContext);
            
            //AbortAllTransfers(pContext);
            //MddDisconnect();
            // try to AbortTransfer on EP0
            g_pddInterface.pfnAbortTransfer(g_pddInterface.pvPddContext, 0, &g_EP0Transfer);
            g_pddInterface.pfnAbortTransfer(g_pddInterface.pvPddContext, 2, &g_EP2Transfer);
#endif  //  0
            break;
        case UFN_SUSPEND:
            g_devState = DS_ATTACHED;
            break;
        case UFN_RESUME:
            g_devState = DS_ATTACHED;
            break;
        default:
            ASSERT(!"Unexpected bus event!");
        }
        break;

    case UFN_MSG_BUS_SPEED:
        break;

    case UFN_MSG_SET_ADDRESS:
        if( dwParam )
        {
            g_devState = DS_ADDRESSED;
        }
        else
        {
            g_devState = DS_DEFAULT;
        }
        // we should call pfnSetAddress here
        break;

    default:
        ASSERT(!"Unexpected Msg in NotifyHandler!");
    }

    return FALSE;
}

// register the USB device, setup the non zero endpoints
void RegisterUSBDevice()
{

    static USB_DEVICE_DESCRIPTOR deviceDescriptor;
    static UFN_ENDPOINT rgEndPoints[3];
    static UFN_INTERFACE Interface;
    static UFN_CONFIGURATION deviceConfiguration;

#if 1
    static USB_ENDPOINT_DESCRIPTOR EndpointZeroDesc = {
        7,                              //  bLength
        USB_ENDPOINT_DESCRIPTOR_TYPE,   //  DescriptorType;
        0,                              //  bEndpointAddress;
        USB_ENDPOINT_TYPE_CONTROL,      //  bmAttributes;
        EP0MaxSize,                     //  wMaxPacketSize;
        0,                              //  bInterval;
    };
    
    // we also need to apply IsEndpointSupportable to initial endpoint in some USBFN driver
    USB_CONFIGURATION_DESCRIPTOR   *pUsbConfDesc    = (PVOID)&gs_pucUSBDescriptors[iCONF];
    USB_INTERFACE_DESCRIPTOR       *pUsbInfDesc0    = (PVOID)&gs_pucUSBDescriptors[iINF0];
    USB_INTERFACE_DESCRIPTOR       *pUsbInfDesc1    = (PVOID)&gs_pucUSBDescriptors[iINF1];

    USB_ENDPOINT_DESCRIPTOR        *pUsbEP0         = (PVOID)&EndpointZeroDesc;
    USB_ENDPOINT_DESCRIPTOR        *pUsbEP1         = (PVOID)&gs_pucUSBDescriptors[iEP1];
    USB_ENDPOINT_DESCRIPTOR        *pUsbEP2         = (PVOID)&gs_pucUSBDescriptors[iEP2];
    USB_ENDPOINT_DESCRIPTOR        *pUsbEP3         = (PVOID)&gs_pucUSBDescriptors[iEP3];

    // Enpoint 0, interface 0
    g_pddInterface.pfnIsEndpointSupportable( g_pddInterface.pvPddContext, 
                                        0, BS_FULL_SPEED, pUsbEP0,
                                        0, 0, 0);

    // Enpoint 1, interface 0
    g_pddInterface.pfnIsEndpointSupportable( g_pddInterface.pvPddContext, 
                                        1, BS_FULL_SPEED, pUsbEP1, 
                                        pUsbConfDesc->bConfigurationValue,
                                        pUsbInfDesc0->bInterfaceNumber, pUsbInfDesc0-> bAlternateSetting);

    // Enpoint 2, interface 1
    g_pddInterface.pfnIsEndpointSupportable( g_pddInterface.pvPddContext, 
                                        2, BS_FULL_SPEED, pUsbEP2, 
                                        pUsbConfDesc->bConfigurationValue,
                                        pUsbInfDesc1->bInterfaceNumber, pUsbInfDesc1-> bAlternateSetting);

    // Enpoint 3, interface 1
    g_pddInterface.pfnIsEndpointSupportable( g_pddInterface.pvPddContext, 
                                        3, BS_FULL_SPEED, pUsbEP3, 
                                        pUsbConfDesc->bConfigurationValue,
                                        pUsbInfDesc1->bInterfaceNumber, pUsbInfDesc1-> bAlternateSetting);
#endif  //  1

    deviceConfiguration.pInterfaces = &Interface;
    deviceConfiguration.Descriptor.bNumInterfaces = 1;
    Interface.pEndpoints = rgEndPoints;
    Interface.Descriptor.bNumEndpoints = 3;
    rgEndPoints[0].Descriptor.bEndpointAddress = 0x01; // EP1, OUT (BULK)
    rgEndPoints[0].Descriptor.wMaxPacketSize = EPMaxSize;
    rgEndPoints[0].Descriptor.bmAttributes = 0;
    rgEndPoints[1].Descriptor.bEndpointAddress = 0x82; // EP2, IN (BULK)
    rgEndPoints[1].Descriptor.wMaxPacketSize = EPMaxSize;
    rgEndPoints[1].Descriptor.bmAttributes = 0;
    rgEndPoints[2].Descriptor.bEndpointAddress = 0x83; // EP3, IN (INT)
    rgEndPoints[2].Descriptor.wMaxPacketSize = EPIntMaxSize;
    rgEndPoints[2].Descriptor.bmAttributes = 0;
    deviceDescriptor.bMaxPacketSize0 = EP0MaxSize;

    // We assume knowledge of the RegisterDevice function implementation and pass very simplified arguments
    g_pddInterface.pfnRegisterDevice( g_pddInterface.pvPddContext, 
                                        NULL, NULL, NULL,
                                        &deviceDescriptor, &deviceConfiguration, NULL,
                                        NULL, 0 );
}

// initialize the USB KITL driver
BOOL PDDInit(
  RNDIS_PDD_CHARACTERISTICS* pRndisPddCharacteristics,
  PBYTE pBaseAddress
)
{
    PDDZONE0 = 0;
    PDDZONE = 0;
    MDDZONE0 = 0;
    MDDZONE = 1;
    MDDZONE2 = 1;
    MDDZONE3 = 1;
    MDDZONE4 = 1;
    MDDZONE5 = 0;

    g_mddInterface.dwVersion = 1;
    g_mddInterface.pfnNotify = NotifyHandler;

    memset( &g_pddInterface, 0, sizeof(g_pddInterface) );
    g_pddInterface.dwVersion = 1;

    // configure clock, I2C cotroller, USB OTG transceiver and USB OTG controller
    InitializeHardware();

    // initialize usb function unit
    if( UfnPdd_Init( NULL, 
        (PVOID)0x11223344, //  assigned some dummy value or we'll get hanged.
        &g_mddInterface, &g_pddInterface ) != ERROR_SUCCESS )
    {
        OALMSG(OAL_ERROR, (L"UfnPdd_Init failed!\r\n"));
        return FALSE;
    }

    // register device
    RegisterUSBDevice();

    // attach device to USB bus
    g_pddInterface.pfnStart( g_pddInterface.pvPddContext );

    SetRNDISMACAddress();
    SetRNDISSerialNumber();

    //
    // Everything ok, fill up our characteristics.
    //
    memset(pRndisPddCharacteristics, 0x00, sizeof(RNDIS_PDD_CHARACTERISTICS));

    pRndisPddCharacteristics->SendRndisMessageHandler = PDD_SendRndisMessage;
    pRndisPddCharacteristics->SendRndisPacketHandler = PDD_SendRndisPacket;
    pRndisPddCharacteristics->SetHandler = PDD_Set;
    pRndisPddCharacteristics->GetHandler = PDD_Get;
    pRndisPddCharacteristics->ISRHandler = PDD_ISR;
    pRndisPddCharacteristics->dwIRQ = -1;       // @todo : check this
    pRndisPddCharacteristics->dwMaxRx = MAX_INCOMING_BUFFER;
    pRndisPddCharacteristics->dwBaseAddr = (DWORD)pBaseAddress/*USB_CLIENT_BASE*/;       // TODO: check this 
    pRndisPddCharacteristics->IndicateRndisPacketCompleteHandler = PDD_IndicateRndisPacketComplete;

    // we are not a PCI device
    pRndisPddCharacteristics->bPCIDevice = FALSE;

    //
    // Everything is fine... Proceed!
    //
    InitializeListHead(&g_RndisKitlDev.listTxRndisMessageQueue);

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L" RNDIS_USBFN_PDDInit: initialization completed\r\n"
    ));

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDDInit\r\n"));

    PDDZONE0 = 0;
    PDDZONE = 0;
    MDDZONE0 = 0;
    MDDZONE = 0;
    MDDZONE2 = 0;
    MDDZONE3 = 0; // 1
    MDDZONE4 = 0;
    MDDZONE5 = 0;

    return TRUE;
}

void PDDDeinit(void)
{
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDDDenit\r\n"));
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDDDenit\r\n"));
}

////////////////////////////////////////////////////////////////////////////////
//  PDD_SendRndisMessage()
//  
//  Routine Description:
//
//      This routine is called by MDD to send one buffer through control 
//      channel.
//  
//  Arguments:
//      
//      pDataWrapper :: Structure containing the data..
//
//  Return Value:
//
//      None.
//

void PDD_SendRndisMessage(PDATA_WRAPPER  pDataWrapper)
{
    OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_SendRndisMessage\r\n"));

    //
    // We don't do the actual sending here but queue it up...
    // We then trigger Interrupt endpoint to send interrupt to host which will in turn
    // use EP0 to GET_ENCAPSULATED_RESPONSE
    InsertTailList((&g_RndisKitlDev.listTxRndisMessageQueue), &(pDataWrapper->Link));

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"+RNDIS_USBFN_PDD_SendRndisMessage: message queued.\r\n"
    ));
    // Interrupt (via interrupt endpoint) the host to GET_ENCAPSULATED_RESPONSE

    // g_EP3Transfer.dwCallerPermissions;
    g_EP3Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
    g_EP3Transfer.pvBuffer = &g_InterruptData;
    // g_EP3Transfer.dwBufferPhysicalAddress; // not used
    g_EP3Transfer.cbBuffer = sizeof(g_InterruptData);
    g_EP3Transfer.cbTransferred = 0;
    g_EP3Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
    g_EP3Transfer.pvPddData = NULL;
    g_EP3Transfer.pvPddTransferInfo = NULL;

    OALMSG(OAL_ETHER&&OAL_FUNC, (
        L"+RNDIS_USBFN_PDD_SendRndisMessage: issuing interrupt...\r\n"
    ));
    g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 3, &g_EP3Transfer );

    OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_SendRndisMessage\r\n"));

}

////////////////////////////////////////////////////////////////////////////////
//  PDD_SendRndisPacket()
//
//  Routine Description:
//
//      This routine is called by MDD to send data to host via IN pipe.
//      PDD is guaranteed to have only one outstanding packet to send until
//      the packet is retured to MDD via MddSendRndisPacketComplete()
//  
//  Arguments:
//      

⌨️ 快捷键说明

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