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

📄 scsi2.c

📁 Windows CE 5.0下的U盘驱动源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
                        memset(&pDevice->DiskInfo, 0, sizeof(DISK_INFO) );
                        break;

                    case ASC_RESET :
                        DEBUGMSG(ZONE_WARN,(TEXT("SENSE_UNIT_ATTENTION : ASC_RESET\n")));
                        break;

                    case ASC_COMMANDS_CLEARED :
                    default:
                        DEBUGMSG(ZONE_WARN,(TEXT("SENSE_UNIT_ATTENTION : Unhandled ASC:0x%x\n"), 
                            ASC));
                        break;
                }
                dwErr = DISK_REMOVED_ERROR;
                break;

            case SENSE_DATA_PROTECT :
                dwErr = ERROR_WRITE_PROTECT;
                break;

            default:
                dwErr = ERROR_FLOPPY_UNKNOWN_ERROR;
                break;
        }

        LeaveCriticalSection(&pDevice->Lock);
    
    } else {
        DEBUGMSG(ZONE_ERR,(TEXT("ScsiGetSenseData error:%d\n"), dwErr));
    }

    ReleaseRemoveLock(&pDevice->RemoveLock, NULL);

    DEBUGMSG(ZONE_TRACE,(TEXT("USBDISK6<ScsiGetSenseData:%d\n"), dwErr));

    return dwErr;
}


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

    TRANSPORT_DATA    tData = {0};
    UCHAR             bDataBlock[36]; // Standard Inquiry Data
#ifdef DEBUG
    DWORD          dwStatus;
    ANSI_STRING    asString;
    UNICODE_STRING usString = {0, 0, 0};
    WCHAR          wcBuff[128]; // excessively large for the unexcected
#endif    
    DWORD dwErr = ERROR_SUCCESS;;
    
    DEBUGMSG(ZONE_SCSI,(TEXT("USBDISK6>ScsiInquiry:Lun:%d\n"), Lun));

    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;
    tCommand.dwLun=Lun;

    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;
    tCommand.dwLun=Lun;
    
    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;
    tCommand.dwLun=Lun;

    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;

⌨️ 快捷键说明

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