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

📄 bot.c

📁 Windows CE 5.0下的U盘驱动源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
        DEBUGMSG( ZONE_ERR,(TEXT("BOT_DataTransfer error:%d\n"), dwErr));
        SetLastError(dwErr);
        return dwErr;
    }

    //
    // We require exclusive entry into the transport.
    // we could implement command queuing.
    //
    EnterCriticalSection(&pUsbDevice->Lock);

    if ( !BOT_ResetAllPipes(pUsbDevice) ) {
        DEBUGMSG( ZONE_ERR, (TEXT("BOT_ResetAllPipes failed!\n")));
        dwErr = ERROR_GEN_FAILURE;
        goto BOT_SendCommandDone;
    }

    ucStallCount = 0;

    pUsbDevice->dwCurTag++;

    memset( &Cbw, 0, dwCbwSize );
    memset( &Csw, 0, dwCswSize );

    //
    // build the active CBW
    //        
    Cbw.dCBWSignature = CBW_SIGNATURE;
    Cbw.dCBWTag = pUsbDevice->dwCurTag;    
    Cbw.dCBWDataTransferLength = pData ? pData->RequestLength : 0;

    if (Direction) {
        Cbw.bmCBWFlags |= 0x80;
    }
    
    Cbw.bCBWLUN = (BYTE)(pCommand->dwLun & 0xf); // TBD
    Cbw.bCBWCBLength = (UCHAR)pCommand->Length;
    memcpy( &Cbw.CBWCB, pCommand->CommandBlock, pCommand->Length);

    //
    // 5.3.1 Command Block Transport
    //
    DEBUGMSG(ZONE_BOT,(TEXT("5.3.1 CBW\n")));
    
    START_DT;

    dwErr = IssueBulkTransfer( pUsbDevice->UsbFuncs,
                               pUsbDevice->BulkOut.hPipe,
                               DefaultTransferComplete,               // Callback
                               pUsbDevice->BulkOut.hEvent,    // Callback Context
                               USB_OUT_TRANSFER|USB_NO_WAIT|USB_SHORT_TRANSFER_OK,// Flags
                              &Cbw, 0,
                               dwCbwSize,
                              &dwBytesTransferred,
                               pUsbDevice->Timeouts.CommandBlock,
                              &dwUsbErr );
    
    STOP_DT( TEXT("CBW"), 10, pUsbDevice->Timeouts.CommandBlock);

    if ( ERROR_SUCCESS != dwErr || USB_NO_ERROR != dwUsbErr || dwBytesTransferred != dwCbwSize ) {

        DEBUGMSG( ZONE_ERR, (TEXT("BOT_DataTransfer error(5.3.1, %d, 0x%x, %d, %d, %d)\n"), 
            dwErr, dwUsbErr, dwBytesTransferred, dwCbwSize, pUsbDevice->Timeouts.CommandBlock));
        
        bRc = BOT_ResetRecovery(pUsbDevice);
        
        goto BOT_SendCommandDone;
    }


    //
    // 5.3.2 Data Transport
    //
    if (pData && pData->DataBlock && pData->RequestLength) 
    {
        PIPE pipeObj = Direction ? pUsbDevice->BulkIn : pUsbDevice->BulkOut;
        DWORD dwFlags = Direction ? (USB_IN_TRANSFER|USB_NO_WAIT|USB_SHORT_TRANSFER_OK) : (USB_OUT_TRANSFER|USB_NO_WAIT|USB_SHORT_TRANSFER_OK);
        BOOL fRet ;
        DWORD dwTimeout = pCommand->Timeout;
        DWORD dwStartTime=0;
        DWORD dwUsbErr = USB_NOT_COMPLETE_ERROR;
        DWORD dwTransferLength = 0 ;
        ResetEvent(pipeObj.hEvent);
        DEBUGMSG(ZONE_BOT,(TEXT("5.3.2 Data%sTransport - dwDataLength:%d, TimeOut:%d \n"), Direction ? TEXT("In") : TEXT("Out"), pData->RequestLength, dwTimeout ));
        
        fRet = BulkTransferMgrTransfer(pipeObj.pAsyncContent, DefaultTransferComplete, pipeObj.hEvent, 
            dwFlags, pData->DataBlock, pData->RequestLength );
        if (fRet ) {
            if (!BulkTransferWait(pipeObj.pAsyncContent,dwTimeout)) {
                fRet = BulkTransferMgrGetStatus(pipeObj.pAsyncContent, &dwTransferLength , &dwUsbErr);
                dwUsbErr = USB_NOT_COMPLETE_ERROR;
            }
            else {
                fRet = BulkTransferMgrGetStatus(pipeObj.pAsyncContent, &dwTransferLength , &dwUsbErr);
            }
            BulkTransferClose(pipeObj.pAsyncContent);
        }
        pData->TransferLength  = dwTransferLength;
        
        if ( USB_NO_ERROR != dwUsbErr ) {

            UCHAR bIndex = Direction ? pUsbDevice->BulkIn.bIndex : pUsbDevice->BulkOut.bIndex;
            
            // 6.7.x.3: the host shall clear the Bulk pipe
            DEBUGMSG( ZONE_ERR, (TEXT("BOT_DataTransfer warning(6.7.x.3, RequestLength:%d TransferLength:%d Err:%d UsbErr:0x%x, dwTimeout:%d)\n"), 
                    pData->RequestLength, dwTransferLength, dwErr, dwUsbErr, dwTimeout ));

            // test/reset Bulk endpoint
            dwResetErr = ResetBulkEndpoint( pUsbDevice->UsbFuncs,
                                            pUsbDevice->hUsbDevice,
                                            pipeObj.hPipe,
                                            DefaultTransferComplete,
                                            pipeObj.hEvent,
                                            bIndex,
                                            pUsbDevice->Timeouts.Reset );

            if (ERROR_SUCCESS != dwResetErr) {
                DEBUGMSG( ZONE_ERR, (TEXT("ResetBulkEndpoint.1 ERROR:%d\n"), dwResetErr));
                
                bRc = BOT_ResetRecovery(pUsbDevice);

                if (ERROR_SUCCESS == dwErr)
                    dwErr = ERROR_GEN_FAILURE;

                goto BOT_SendCommandDone;
            }

        }

    }

    //
    // 5.3.3 Command Status Transport (CSW)
    //
    ucStallCount = 0; // reset Stall count

    DEBUGMSG(ZONE_BOT,(TEXT("5.3.3 CSW\n")));

_RetryCSW:
    START_DT;

    dwCswErr = IssueBulkTransfer( pUsbDevice->UsbFuncs,
                                  pUsbDevice->BulkIn.hPipe,
                                  DefaultTransferComplete,      // Callback
                                  pUsbDevice->BulkIn.hEvent,    // Callback Context
                                  (USB_IN_TRANSFER|USB_NO_WAIT|USB_SHORT_TRANSFER_OK), // Flags
                                 &Csw, 0,
                                  dwCswSize,
                                 &dwBytesTransferred,
                                  pUsbDevice->Timeouts.CommandStatus,
                                 &dwUsbErr );

    STOP_DT( TEXT("CSW"), 100, (Direction ? pUsbDevice->Timeouts.CommandStatus : pCommand->Timeout) );

    // Figure 2 - Status Transport Flow
    if ( ERROR_SUCCESS != dwCswErr || USB_NO_ERROR != dwUsbErr ) {

        DEBUGMSG( ZONE_ERR, (TEXT("BOT_DataTransfer error(5.3.3, dwCswErr:%d, dwUsbErr:0x%x, dwTimeout:%d)\n"), 
                dwCswErr, dwUsbErr, pUsbDevice->Timeouts.CommandStatus ));

        START_DT;

        // reset BulkIn endpoint
        dwResetErr = ResetBulkEndpoint(pUsbDevice->UsbFuncs,
                                       pUsbDevice->hUsbDevice,
                                       pUsbDevice->BulkIn.hPipe,
                                       DefaultTransferComplete,
                                       pUsbDevice->BulkIn.hEvent,
                                       pUsbDevice->BulkIn.bIndex,
                                       pUsbDevice->Timeouts.Reset );

        STOP_DT( TEXT("ResetBulkEndpoint.2"), 10, pUsbDevice->Timeouts.Reset );

        if ( ERROR_SUCCESS == dwResetErr &&
             ++ucStallCount < MAX_BOT_STALL_COUNT ) {

            DEBUGMSG( ZONE_WARN, (TEXT("Retry CSW\n")));
            
            Sleep(ONE_FRAME_PERIOD);

            goto _RetryCSW;

        } else {
            DEBUGMSG( ZONE_ERR, (TEXT("BOT_DataTransfer error(5.3.3, ResetErr:0x%x StallCount:%d)\n"), dwResetErr, ucStallCount));

            bRc = BOT_ResetRecovery(pUsbDevice);

            if (ERROR_SUCCESS == dwErr)
                dwErr = ERROR_GEN_FAILURE;

            goto BOT_SendCommandDone;
        }
    }

    //
    // Validate CSW...
    //

    // 6.3.1 Valid CSW: size
    if ( dwBytesTransferred != dwCswSize ) { 
        DEBUGMSG( ZONE_ERR, (TEXT("Invalid Csw size: %d, %d\n"), dwBytesTransferred, dwCswSize ));

        // 6.5 Host shall perform ResetRecovery for invalid CSW
        bRc = BOT_ResetRecovery(pUsbDevice);

        if (ERROR_SUCCESS == dwErr)
            dwErr = ERROR_GEN_FAILURE;

        goto BOT_SendCommandDone;
    }


    // 6.3.1 Valid CSW: Signature
    if ( CSW_SIGNATURE != Csw.dCSWSignature) { 
        DEBUGMSG( ZONE_ERR, (TEXT("Invalid Csw.dCSWSignature:0x%x\n"), Csw.dCSWSignature ));
        
        // 6.5 Host shall perform ResetRecovery for invalid CSW
        bRc = BOT_ResetRecovery(pUsbDevice);

        if (ERROR_SUCCESS == dwErr)
            dwErr = ERROR_GEN_FAILURE;

        goto BOT_SendCommandDone;
    }

    // 6.3.1 Valid CSW: Tags
    if ( Cbw.dCBWTag != Csw.dCSWTag ) {
        DEBUGMSG( ZONE_ERR, (TEXT("Mismatched Tags Cbw:0x%x Csw:0x%x\n"), Cbw.dCBWTag, Csw.dCSWTag ));

        // 6.5 Host shall perform ResetRecovery for invalid CSW
        bRc = BOT_ResetRecovery(pUsbDevice);

        if (ERROR_SUCCESS == dwErr)
            dwErr = ERROR_GEN_FAILURE;

        goto BOT_SendCommandDone;
    }

    //
    // Command Status?
    //
    if ( 0 == Csw.bCSWStatus || 1 == Csw.bCSWStatus ) {

        if (1 == Csw.bCSWStatus ) {
            DEBUGMSG( ZONE_WARN, (TEXT("Command Block Status: Command Failed\n")));
            dwErr = ERROR_GEN_FAILURE;
        }

        goto BOT_SendCommandDone;
    }

    //
    // Phase Error?
    //
    if ( 2 == Csw.bCSWStatus ) {
        DEBUGMSG( ZONE_ERR, (TEXT("Command Block Status: Phase Error\n")));

        // ignore the dCSWDataResidue
        bRc = BOT_ResetRecovery(pUsbDevice);

        if (ERROR_SUCCESS == dwErr)
            dwErr = ERROR_GEN_FAILURE;
        
        goto BOT_SendCommandDone;
    }


BOT_SendCommandDone:
    //
    // cleanup        
    //
    LeaveCriticalSection(&pUsbDevice->Lock);
   
    DEBUGMSG(ZONE_TRACE,(TEXT("USBMSC<BOT_DataTransfer:%d\n"), dwErr));    

    return dwErr;
}


//
// Set a DWORD Value into an array of chars pointed to by pbArray
// (Little Endian)
//
VOID
SetDWORD(
    IN OUT PUCHAR pbArray,
    IN DWORD dwValue
    ) 
{
    if (pbArray) {
        pbArray[3] = (UCHAR)dwValue;
        dwValue >>= 8;
        pbArray[2] = (UCHAR)dwValue;
        dwValue >>= 8;
        pbArray[1] = (UCHAR)dwValue;
        dwValue >>= 8;
        pbArray[0] = (UCHAR)dwValue;
    }
    return;
}

VOID 
SetWORD(
    PBYTE pBytes,
    WORD wValue 
    )
{
    if (pBytes) {
        pBytes[1] = (BYTE)wValue;
        wValue >>= 8;
        pBytes[0] = (BYTE)wValue;
    }
    return;
}


//
// Gets a USHORT Value from an array of chars pointed to by pbArray.
// The return value is promoted to DWORD.
// (Little Endian)
//
DWORD 
GetDWORD(
    IN PUCHAR pbArray
    )
{
    DWORD dwReturn=0;
    if (pbArray) {
        dwReturn=*(pbArray++);
        dwReturn=dwReturn*0x100 + *(pbArray++);
        dwReturn=dwReturn*0x100 + *(pbArray++);
        dwReturn=dwReturn*0x100 + *(pbArray++);
    }
    return dwReturn;
}

// EOF

⌨️ 快捷键说明

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