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

📄 scsi2.c

📁 s3c2440在wince4.2下的SDK,实时操作系统用
💻 C
📖 第 1 页 / 共 3 页
字号:
    tCommand.CommandBlock = bCDB;

    memset( bCDB, 0, sizeof(bCDB));
    bCDB[0] = SCSI_INQUIRY;
    
    ASSERT(Lun <= 0x7);
    bCDB[1] = ((Lun & 0x7) << 5);

    // EVPB is tbd
    // PageCode = 0
    bCDB[4] = sizeof(bDataBlock); // Allocation Length

    memset( bDataBlock, 0, sizeof(bDataBlock));
    tData.TransferLength = 0;
    tData.RequestLength = sizeof(bDataBlock);
    tData.DataBlock = bDataBlock;
    
    dwErr = UsbsDataTransfer(pDevice->hUsbTransport,
                             &tCommand,
                             &tData );

    if (dwErr != ERROR_SUCCESS || (tData.TransferLength != tData.RequestLength))
    {
        dwErr = ScsiGetSenseData( pDevice, Lun );

        DEBUGMSG(ZONE_ERR,(TEXT("ScsiInquiry ERROR:%d\n"), dwErr));

        SetLastError(dwErr);

    } else {

        CHAR  asBuff[17] = {0};
        UCHAR perq; // peripherial qualifier
        #define PERQ_LUN_CONNECTED      0x0
        #define PERQ_LUN_DISCONNECTED   0x1
        #define PERQ_LUN_INVALID        0x3

        DEBUGMSG(ZONE_SCSI,(TEXT("InquiryData@Lun:%d = 0x%x\n"), 
            Lun, bDataBlock[0]));

        if (bDataBlock[0] == 0x7F) {
            
            dwErr = ERROR_INVALID_PARAMETER; 
            TEST_TRAP();
        
        } else {

            EnterCriticalSection(&pDevice->Lock);

            pDevice->DeviceType = bDataBlock[0] & SCSI_DEVICE_UNKNOWN;
        
            perq = (bDataBlock[0] & 0xE0) >> 5;
            ASSERT(PERQ_LUN_INVALID != perq);

            // currently developing Direct Access & CD-ROM devices only
            ASSERT(SCSI_DEVICE_DIRECT_ACCESS == pDevice->DeviceType ||
                   SCSI_DEVICE_CDROM == pDevice->DeviceType);

            pDevice->Flags.RMB = (bDataBlock[1] & 0x80) >> 7;

    //        ASSERT(bDataBlock[3] & 0x01);   // Response Data Format

#ifdef DEBUG
            usString.Buffer = wcBuff;
            usString.MaximumLength = sizeof(wcBuff);

            //
            // VID
            //
            memcpy(asBuff, &bDataBlock[8], 8); asBuff[8] = 0;
            RtlInitAnsiString( &asString,  asBuff);
            dwStatus = RtlAnsiStringToUnicodeString(&usString, &asString, FALSE);
            if (STATUS_SUCCESS != dwStatus) { // NT status code
                DEBUGMSG(ZONE_ERR, (TEXT("RtlAnsiStringToUnicodeString error:0x%x\n"),
                    dwStatus));
                TEST_TRAP();
            } else {
                DEBUGMSG(ZONE_SCSI, (TEXT("VID: %s\n"), usString.Buffer ));
            }

            //
            // PID
            //
            memcpy(asBuff, &bDataBlock[16], 16); asBuff[16] = 0;
            RtlInitAnsiString( &asString, asBuff );
            dwStatus = RtlAnsiStringToUnicodeString( &usString, &asString, FALSE );
            if (STATUS_SUCCESS != dwStatus) { // NT status code
                DEBUGMSG(ZONE_ERR, (TEXT("RtlAnsiStringToUnicodeString error:0x%x\n"),
                dwStatus));
                TEST_TRAP();
            } else {
                DEBUGMSG(ZONE_SCSI, (TEXT("PID: %s\n"), usString.Buffer ));
            }

            //
            // PRL
            //
            memcpy(asBuff, &bDataBlock[32], 4); asBuff[4] = 0;
            RtlInitAnsiString( &asString, asBuff );
            dwStatus = RtlAnsiStringToUnicodeString(&usString, &asString, FALSE);
            if (STATUS_SUCCESS != dwStatus) { // NT status code
                DEBUGMSG(ZONE_ERR, (TEXT("RtlAnsiStringToUnicodeString error:0x%x\n"),
                    dwStatus));
                TEST_TRAP();
            } else {
                DEBUGMSG(ZONE_SCSI, (TEXT("PRL: %s\n"), usString.Buffer ));
            }
#endif DEBUG
    
            LeaveCriticalSection(&pDevice->Lock);
        }
    }

    ReleaseRemoveLock(&pDevice->RemoveLock, NULL);
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6<ScsiInquiry:%d\n"), dwErr));
    
    return dwErr;
}


DWORD
ScsiSendDiagnostic(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    )
{
    TRANSPORT_COMMAND tCommand;
    UCHAR             bCDB[MAX_CDB];
    
    DWORD dwErr;
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6>ScsiSendDiagnostic\n")));

    dwErr = AcquireRemoveLock(&pDevice->RemoveLock, NULL) ;
    if ( ERROR_SUCCESS != dwErr) {
        return dwErr;
    }

    tCommand.Flags   = DATA_IN;
    tCommand.Timeout = pDevice->Timeouts.ScsiCommandTimeout;
    tCommand.Length  = USBMSC_SUBCLASS_SCSI == pDevice->DiskSubClass ?
                       SCSI_CDB_6 : UFI_CDB;
    tCommand.CommandBlock = bCDB;
    
    memset( bCDB, 0, sizeof(bCDB));
    bCDB[0] = SCSI_SEND_DIAGNOSTIC;

    ASSERT(Lun <= 0x7);
    bCDB[1] = ((Lun & 0x7) << 5);

    bCDB[1] |= 0x4; // SelfTest

    dwErr = UsbsDataTransfer(pDevice->hUsbTransport,
                             &tCommand,
                             NULL );

    if ( dwErr != ERROR_SUCCESS ) {

        dwErr = ScsiGetSenseData( pDevice, Lun );

        DEBUGMSG(ZONE_ERR,(TEXT("ScsiSendDiagnostic ERROR:%d\n"), dwErr));

        SetLastError(dwErr);

    }

    ReleaseRemoveLock(&pDevice->RemoveLock, NULL);
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6<ScsiSendDiagnostic:%d\n"), dwErr));

    return dwErr;
}


// returns Win32 error
DWORD 
ScsiReadCapacity(
    PSCSI_DEVICE pDevice,
    PDISK_INFO   pDiskInfo,
    UCHAR        Lun
    )
{
    TRANSPORT_COMMAND tCommand;
    UCHAR             bCDB[MAX_CDB];

    TRANSPORT_DATA tData;
    UCHAR          bDataBlock[8];
    DWORD dwSizeDB = sizeof(bDataBlock);

    DWORD dwSizeDI = sizeof(DISK_INFO);
    DWORD dwErr    = ERROR_SUCCESS;
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6>ScsiReadCapacity\n")));

    dwErr = AcquireRemoveLock(&pDevice->RemoveLock, NULL) ;
    if ( ERROR_SUCCESS != dwErr) {
        return dwErr;
    }

    memset(pDiskInfo, 0, dwSizeDI);

    tCommand.Flags   = DATA_IN;
    tCommand.Timeout = pDevice->Timeouts.ScsiCommandTimeout;
    tCommand.Length  = USBMSC_SUBCLASS_SCSI == pDevice->DiskSubClass ?
                       SCSI_CDB_10 : UFI_CDB;
    tCommand.CommandBlock = bCDB;

    memset( bCDB, 0, sizeof(bCDB));
    bCDB[0] = SCSI_READ_CAPACITY;

    ASSERT(Lun <= 0x7);
    bCDB[1] = ((Lun & 0x7) << 5);

    // PMI & LBA support is TBD
    // It's useful in determining where longer access times occur

    memset( bDataBlock, 0, dwSizeDB);
    tData.TransferLength = 0;
    tData.RequestLength = dwSizeDB;
    tData.DataBlock = bDataBlock;

    dwErr = UsbsDataTransfer(pDevice->hUsbTransport,
                             &tCommand,
                             &tData );

    if ( dwErr != ERROR_SUCCESS ||
        (tData.TransferLength != tData.RequestLength) ) {

        dwErr = ScsiGetSenseData( pDevice, Lun );

        DEBUGMSG(ZONE_ERR,(TEXT("ScsiReadCapacity ERROR:%d\n"), dwErr));

        SetLastError(dwErr);

    } else {

        EnterCriticalSection(&pDevice->Lock);
        // Get total sectors from Last Logical Block Address
        pDiskInfo->di_total_sectors  = GetDWORD(&bDataBlock[0])+1; 
        // Block Length in bytes
        pDiskInfo->di_bytes_per_sect = GetDWORD(&bDataBlock[4]);
        pDiskInfo->di_flags         |= DISK_INFO_FLAG_PAGEABLE | DISK_INFO_FLAG_CHS_UNCERTAIN;

        if ( pDiskInfo->di_bytes_per_sect && pDiskInfo->di_total_sectors) {
            //
            // update our media info & flags
            //
            pDevice->Flags.MediumPresent = TRUE;

            if ( 0 != memcmp(&pDevice->DiskInfo, pDiskInfo, dwSizeDI) ) {

                memcpy(&pDevice->DiskInfo, pDiskInfo, dwSizeDI);

            }
        }

        LeaveCriticalSection(&pDevice->Lock);

        DUMP_DISK_INFO(pDiskInfo);
    }
    
    ReleaseRemoveLock(&pDevice->RemoveLock, NULL);

    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6<ScsiReadCapacity:%d\n"), dwErr));
    
    return dwErr;
}


//
// Mode sense is dependant on Device Type.
// returns Win32 error. 
//
DWORD 
ScsiModeSense10(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    )
{
    TRANSPORT_DATA    tData;
    TRANSPORT_COMMAND tCommand;
    UCHAR             bCDB[MAX_CDB];
    #define MAX_LIST_LENGTH     512
    UCHAR   bDataBlock[MAX_LIST_LENGTH] = {0};  // Standard Header + mode pages
    USHORT  usPageLength = 8;                   // Standard Header size

    DWORD dwErr = ERROR_SUCCESS;

    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6>ScsiModeSense\n")));

    dwErr = AcquireRemoveLock(&pDevice->RemoveLock, NULL) ;
    if ( ERROR_SUCCESS != dwErr) {
        return dwErr;
    }

    ASSERT( SCSI_DEVICE_DIRECT_ACCESS == pDevice->DeviceType || 
            SCSI_DEVICE_CDROM == pDevice->DeviceType );

    memset( bCDB, 0, sizeof(bCDB));

    tCommand.Flags   = DATA_IN;
    tCommand.Timeout = pDevice->Timeouts.ScsiCommandTimeout;
    tCommand.Length  = USBMSC_SUBCLASS_SCSI == pDevice->DiskSubClass ?
                        SCSI_CDB_10 : UFI_CDB;
    tCommand.CommandBlock = bCDB;

    bCDB[0] = SCSI_MODE_SENSE10;

    ASSERT(Lun <= 0x7);
    bCDB[1] = ((Lun & 0x7) << 5);
    bCDB[1] |= 0x8;      // DBD

    // PC = current
    // Page Code
    bCDB[2] = 0;
    switch (pDevice->DeviceType) 
    {
        case SCSI_DEVICE_DIRECT_ACCESS:
            if (pDevice->DiskSubClass == USBMSC_SUBCLASS_UFI) {
                bCDB[2] = MODE_PAGE_FLEXIBLE_DISK;
                usPageLength += 32;
            } else {
                usPageLength = sizeof(bDataBlock);
            }
            break;

        case SCSI_DEVICE_CDROM:
            bCDB[2] = MODE_PAGE_CDROM;
            usPageLength += 8;
            break;

        default:
            DEBUGMSG(ZONE_ERR,(TEXT("ScsiModeSense10: Unknown DeviceType:0x%x\n"),
                    pDevice->DeviceType));
            TEST_TRAP();
            usPageLength = sizeof(bDataBlock);
            break;
    }

    bCDB[7] = (sizeof(bDataBlock) & 0xFF00) >> 8; // MSB
    bCDB[8] =  sizeof(bDataBlock) & 0x00FF;       // LSB

    memset( bDataBlock, 0, sizeof(bDataBlock));
    ASSERT( usPageLength <= sizeof(bDataBlock));

    tData.TransferLength = 0;
    // Note: some devices fail with only 8 byte header request length, 
    // but all should recover with extra buffer space.
    tData.RequestLength = usPageLength;
    tData.DataBlock = bDataBlock;

    dwErr = UsbsDataTransfer( pDevice->hUsbTransport,
                             &tCommand,
                             &tData );

    if ( dwErr != ERROR_SUCCESS || tData.TransferLength < 8 ) { // want at least the header

        dwErr = ScsiGetSenseData( pDevice, Lun );
        
        SetLastError(dwErr);

        DEBUGMSG(ZONE_ERR,(TEXT("ScsiModeSense ERROR:%d\n"), dwErr));

    } else {
        
        EnterCriticalSection(&pDevice->Lock);

        // look at the Header
        DEBUGMSG(ZONE_SCSI,(TEXT("Medium Type:0x%x\n"), bDataBlock[2]));

        pDevice->MediumType = bDataBlock[2];

        // bit7 is WP bit
        DEBUGMSG(ZONE_SCSI,(TEXT("Device Specific:0x%x\n"), bDataBlock[3] ));
        pDevice->Flags.WriteProtect = bDataBlock[3] & 0x80;
        
        LeaveCriticalSection(&pDevice->Lock);
        
        //
        // TBD: look at the the requested page ...
        //
    }

    ReleaseRemoveLock(&pDevice->RemoveLock, NULL);
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6<ScsiModeSense:%d\n"), dwErr));
    
    return dwErr;
}


DWORD
ScsiStartStopUnit(
    PSCSI_DEVICE    pDevice,
    BOOL            Start,  // TRUE = START, else STOP
    BOOL            LoEj,
    UCHAR           Lun
    )
{
    TRANSPORT_COMMAND tCommand;
    UCHAR             bCDB[MAX_CDB];
    
    DWORD dwErr;
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6>ScsiStartStopUnit\n")));

    dwErr = AcquireRemoveLock(&pDevice->RemoveLock, NULL);
    if ( ERROR_SUCCESS != dwErr) {
        return dwErr;
    }

    tCommand.Flags   = DATA_OUT;
    tCommand.Timeout = pDevice->Timeouts.ScsiCommandTimeout;
    tCommand.Length  = USBMSC_SUBCLASS_SCSI == pDevice->DiskSubClass ?
                       SCSI_CDB_6 : UFI_CDB;
    tCommand.CommandBlock = bCDB;

    memset( bCDB, 0, sizeof(bCDB));
    bCDB[0] = SCSI_START_STOP;

    ASSERT(Lun <= 0x7);
    bCDB[1] = ((Lun & 0x7) << 5);

    bCDB[4] = (LoEj & 0x1) << 1;
    bCDB[4] |= Start & 0x1;

    dwErr = UsbsDataTransfer(pDevice->hUsbTransport,
                             &tCommand,
                             NULL );

⌨️ 快捷键说明

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