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

📄 scsi2.h

📁 s3c2440在wince4.2下的SDK,实时操作系统用
💻 H
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: 

    scsi2.h

Abstract:

    USB Disk Class for
    bInterfaceSubClass = 0x06 : SCSI Passthrough
    bInterfaceSubClass = 0x04 : USB Floppy Interface (UFI), which is a SCSI2 subset
    bInterfaceSubClass = 0x02 : SFF8020i CD-ROM Data Only; Digital Audio requires CD-DA work

Functions:

Notes: 

--*/

#if !defined( _SCSI2_ )
#define _SCSI2_


//*****************************************************************************
// I N C L U D E S
//*****************************************************************************
#include <windows.h>
#include <winioctl.h>
#include <diskio.h>

#include "warning.h"
#include "remlock.h"
#include "utils.h"
#include "cdioctl.h"

//*****************************************************************************
// D E F I N E S
//*****************************************************************************

#define DRIVER_NAME_SZ  TEXT("USBDISK6.DLL")

#define USBSCSI_SIG 'SCSI'

//
// Default Timeout/repeat values in msec
//
#define MEDIA_POLL_SZ TEXT("MediaPollInterval")
#define SCSI_MEDIA_POLL_INTERVAL    1250

// timeout in msec per sector
#define READ_SECTOR_SZ TEXT("ReadSectorTimeout")
#define SCSI_READ_SECTOR_TIMEOUT    10000

// timeout in msec per sector
#define WRITE_SECTOR_SZ TEXT("WriteSectorTimeout")
#define SCSI_WRITE_SECTOR_TIMEOUT   10000

#define SCSI_COMMAND_SZ TEXT("ScsiCommandTimeout")
#define SCSI_COMMAND_TIMEOUT        5000

#define UNIT_ATTENTION_SZ TEXT("UnitAttnRepeat")
#define UNIT_ATTENTION_REPEAT       10

//
// Size in bytes
//
#define FAT_SECTOR_SIZE     512
#define CDSECTOR_SIZE       2048
#define MAX_SECTOR_SIZE     CDSECTOR_SIZE

#define SG_BUFF_SIZE        max((MAX_SG_BUF*FAT_SECTOR_SIZE),(3*CDSECTOR_SIZE))


//
// Is the context pointer valid
//
#define VALID_CONTEXT( p ) \
   ( p != NULL && USBSCSI_SIG == p->Sig )

//
// Can the device accept I/O requests
//
#define ACCEPT_IO( p ) \
   ( VALID_CONTEXT( p ) && \
     p->Flags.Open && \
    !p->Flags.DeviceRemoved  && \
    !p->Flags.PoweredDown )

//
// SCSI-2 DEVICE TYPES
//
#define SCSI_DEVICE_DIRECT_ACCESS       0x00    // e.g. disk
#define SCSI_DEVICE_SEQUENTIAL_ACCESS   0x01
#define SCSI_DEVICE_PRINTER             0x02
#define SCSI_DEVICE_PROCESSOR           0x03
#define SCSI_DEVICE_WRITE_ONCE          0x04
#define SCSI_DEVICE_CDROM               0x05
#define SCSI_DEVICE_SCANNER             0x06
#define SCSI_DEVICE_OPTICAL             0x07
#define SCSI_DEVICE_MEDIUM_CHANGER      0x08
#define SCSI_DEVICE_COMM                0x09
#define SCSI_DEVICE_UNKNOWN             0x1F

//
// SCSI-2 MEDIUM TYPES
//
#define SCSI_MEDIUM_UNKNOWN             0xFF

//
// CD-ROM MEDIUM TYPES
//
#define MEDIUM_CD_ROM_UNKNOWN   0x00
#define MEDIUM_CD_ROM_120       0x01
#define MEDIUM_CD_DA_120        0x02
#define MEDIUM_CD_MIXED_120     0x03
#define MEDIUM_CD_HYBRID_120    0x04
#define MEDIUM_CD_ROM_80        0x05
#define MEDIUM_CD_DA_80         0x06
#define MEDIUM_CD_MIXED_80      0x07
#define MEDIUM_CD_HYBRID_80     0x08
#define MEDIUM_CDR_ROM_UNKNOWN  0x10
#define MEDIUM_CDR_ROM_120      0x11
#define MEDIUM_CDR_DA_120       0x12
#define MEDIUM_CDR_MIXED_120    0x13
#define MEDIUM_CDR_HYBRID_120   0x14
#define MEDIUM_CDR_ROM_80       0x15
#define MEDIUM_CDR_DA_80        0x16
#define MEDIUM_CDR_MIXED_80     0x17

//
// MANDATORY SCSI-2 COMMANDS
//
#define SCSI_TEST_UNIT_READY    0x00
#define SCSI_REQUEST_SENSE      0x03
#define SCSI_INQUIRY            0x12
#define SCSI_SEND_DIAGNOSTIC    0x1D

//
// MANDATORY DEVICE SPECIFIC COMMANDS
//
#define SCSI_READ10             0x28
#define SCSI_READ_CAPACITY      0x25

//
// OPTIONAL DEVICE SPECIFIC COMMANDS
//
#define SCSI_MODE_SELECT6       0x15
#define SCSI_MODE_SENSE6        0x1A
#define SCSI_START_STOP         0x1B
#define SCSI_WRITE10            0x2A
#define SCSI_MODE_SELECT10      0x55
#define SCSI_MODE_SENSE10       0x5A

//
// (ATAPI) CD-ROM Commamds
//
#define SCSI_CD_READ_TOC        0x43
#define SCSI_CD_PLAY10          0x45
#define SCSI_CD_PLAY_MSF        0x47
#define SCSI_CD_PAUSE_RESUME    0x4B
#define SCSI_CD_STOP            0x4E

//
// Mode Pages
//
#define MODE_PAGE_FLEXIBLE_DISK 0x05
#define MODE_PAGE_CDROM         0x0D
#define MODE_PAGE_CDROM_AUDIO   0x0E
#define MODE_PAGE_CDROM_CAPS    0x2A

//
// SCSI-2 SENSE KEYS
//
#define SENSE_NONE              0x00
#define SENSE_RECOVERED_ERROR   0x01
#define SENSE_NOT_READY         0x02
#define SENSE_MEDIUM_ERROR      0x03
#define SENSE_HARDWARE_ERROR    0x04
#define SENSE_ILLEGAL_REQUEST   0x05
#define SENSE_UNIT_ATTENTION    0x06
#define SENSE_DATA_PROTECT      0x07
#define SENSE_BLANK_CHECK       0x08
//...

//
// SCSI-2 ASC (of interest)
//
#define ASC_LUN                     0x04
#define ASC_INVALID_COMMAND_FIELD   0x24
#define ASC_MEDIA_CHANGED           0x28
#define ASC_RESET                   0x29
#define ASC_COMMANDS_CLEARED        0x2F
#define ASC_MEDIUM_NOT_PRESENT      0x3A

//
// Max LUN index
//
#define MAX_LUN     0x7


#define SCSI_CDB_6    6
#define SCSI_CDB_10  10
#define UFI_CDB      12
#define ATAPI_CDB    12
#define MAX_CDB      UFI_CDB

#define START   TRUE
#define STOP    FALSE

#define FAILURE (-1)


//
// SCSI Passthrough IOCTLs
//
#define IOCTL_SCSI_BASE FILE_DEVICE_MASS_STORAGE

#define IOCTL_SCSI_PASSTHROUGH                \
    CTL_CODE(IOCTL_SCSI_BASE, 0x700, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_CDROM_PLAY_AUDIO                \
    CTL_CODE(IOCTL_SCSI_BASE, 0x701, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_CDROM_PLAY_AUDIO_TRACK_INDEX    \
    CTL_CODE(IOCTL_SCSI_BASE, 0x702, METHOD_BUFFERED, FILE_ANY_ACCESS)


//*****************************************************************************
// T Y P E D E F S
//*****************************************************************************

//
// Reg configurable Timeout/repeat values
//
typedef struct _TIMEOUTS {

    ULONG MediaPollInterval;

    ULONG ReadSector;

    ULONG WriteSector;

    ULONG ScsiCommandTimeout;

    ULONG UnitAttnRepeat;

} TIMEOUTS, *PTIMEOUTS;


//
// Device Flags
//
typedef struct _DEVICE_FLAGS {
    //
    // Removal Media Bit (RMB)
    //
    ULONG RMB : 1;

    //
    // MediumPresent
    //
    ULONG MediumPresent : 1;

    //
    // Is the FSD Mounted?
    //
    ULONG FSDMounted : 1;

    //
    // WriteProtect
    //
    ULONG WriteProtect : 1;
    
    //
    // Is the device currently open/closed
    // Set via DSK_Xxx
    //
    ULONG   Open : 1;

    //
    // The device has been flagged for removed.
    // This flag should only be set by the 
    // UsbDiskAttach, or UsbDiskDetach routines
    //
    ULONG   DeviceRemoved : 1;

    // The device has been flagged for Power Down.
    // This flag should only be set by DSK_PowerDown 
    //
    ULONG   PoweredDown : 1;

    // 
    // Currently used to signal CD-ROM is busy
    //
    ULONG   Busy : 1;
    //
    // MediumChanged
    //
    ULONG   MediumChanged:1;
    // 
    // preMediumStatus;
    //
    ULONG   prevMediumStatus:1;
    // Reserved
    // ...
    
} DEVICE_FLAGS, *PDEVICE_FLAGS;


typedef struct _SCSI_DEVICE {
    //
    // device context Signature
    //
    ULONG Sig;

    //
    // bInterfaceSubClass as reported in the device descriptor;
    // received in UsbDiskAttach.
    //
    UCHAR DiskSubClass;

    //
    // HKEY as enumerated by USB Mass Storage Class; received in UsbDiskAttach.
    // Used as Active registry path.
    //
    LPWSTR ActivePath;

    //
    // Handle to the USB Mass Storage Class Transport; 
    // received in UsbDiskAttach
    //
    HANDLE hUsbTransport;

    //
    // global sync object for this instance
    //
    CRITICAL_SECTION Lock;

    //
    // Handle to Media Polling Thread
    //
    HANDLE  hMediaPollThread;

    //
    // Handle to Media Changed Event
    //
    HANDLE  hMediaChangedEvent;

    //
    // Handle to Stream interface.
    //
    HANDLE   hStreamDevice;

    //
    // Our process handle
    //
    HANDLE   hProc;

    //
    // Device Type
    //
    UCHAR DeviceType;

    //
    // Logical Unit Number
    //
    UCHAR Lun;
    UCHAR MaxLun;

    //
    // Medium Type
    //
    UCHAR MediumType;

    //
    // FLAGS
    //
    DEVICE_FLAGS Flags;

    //
    // DSK_Open reference count
    //
    LONG OpenCount;

    //
    // Timeout values
    //
    TIMEOUTS Timeouts;

    //
    // Disk Information
    //
    DISK_INFO DiskInfo;

    //
    // Device Remove Lock
    //
    REMOVE_LOCK RemoveLock;

    //
    // To support odd Scatter Gather buffer combinations (DDTK)
    // we need to use double buffering. We R/W to/from our own S/G buffer then 
    // copy to/from the callers buffer. Our S/G Buffer needs to accommodate at 
    // least 8 full FAT sectors, or 3 UDFS sectors.
    // TODO: alloc buffer based on disk type.
    // A double buffering scheme is required, else don't support all the odd
    // sized combinations. However, you will still need at least 1 full sector 
    // buffer handy for transfers < sector because the disks only take full sector 
    // sized transfers. Sector aligned transfers do not use double buffering.
    //
    UCHAR   SgBuff[SG_BUFF_SIZE];

} SCSI_DEVICE, *PSCSI_DEVICE;


//*****************************************************************************
// P R O T O S
//*****************************************************************************

//
// scsi2.c
//
DWORD 
ScsiGetSenseData(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    );

DWORD 
ScsiInquiry(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    );

DWORD 
ScsiModeSense10(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    );

DWORD
ScsiPassthrough(
    PSCSI_DEVICE        pDevice,
    PTRANSPORT_COMMAND  Command,
    PTRANSPORT_DATA     Data
    );

DWORD 
ScsiReadCapacity(
    PSCSI_DEVICE pDevice,
    PDISK_INFO   pDiskInfo,
    UCHAR        Lun
    );

DWORD
ScsiReadWrite(
    IN PSCSI_DEVICE pDevice,
    IN DWORD        dwStartSector,
    IN DWORD        dwNumSectors,
    IN OUT PVOID    pvBuffer,        // pointer to transfer buffer
    IN OUT PDWORD   pdwTransferSize, // IN: sizeof input buffer, OUT: number of bytes transferred
    IN UCHAR        Lun,
    IN BOOL         bRead
    );

DWORD 
ScsiRWSG(
    PSCSI_DEVICE pDevice,
    PSG_REQ      pSgReq,
    UCHAR        Lun,
    BOOL         bRead
    );

DWORD
ScsiRequestSense(
    PSCSI_DEVICE    pDevice,
    PTRANSPORT_DATA pTData,
    UCHAR           Lun
    );

DWORD
ScsiSendDiagnostic(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    );

DWORD
ScsiStartStopUnit(
    PSCSI_DEVICE    pDevice,
    BOOL            Start,
    BOOL            LoEj,
    UCHAR           Lun
    );

DWORD
ScsiTestUnitReady(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    );

DWORD
ScsiUnitAttention(
    PSCSI_DEVICE    pDevice,
    UCHAR           Lun
    );

//
// cd.c
//
DWORD
ScsiCDRead(
    PSCSI_DEVICE    pDevice,
    PCDROM_READ     pSgReq,
    PULONG          pdwBytesTransferred
    );

DWORD 
ScsiCDAudio(
    PSCSI_DEVICE pDevice,
    DWORD        Ioctl,
    PUCHAR       pInBuf,
    DWORD        InBufLen,
    PUCHAR       pOutBuf,
    DWORD        OutBufLen,
    PDWORD       pdwBytesTransferred
    );


//*****************************************************************************
// D E B U G
//*****************************************************************************
#if DEBUG
#define ZONE_ERR            DEBUGZONE(0)
#define ZONE_WARN           DEBUGZONE(1)
#define ZONE_INIT           DEBUGZONE(2)
#define ZONE_TRACE          DEBUGZONE(3)

#define ZONE_SCSI           DEBUGZONE(4)
#define ZONE_CDROM          DEBUGZONE(5)
#define ZONE_CDDA           DEBUGZONE(6)
#define ZONE_DSK_IOCTL      DEBUGZONE(7)

#define ZONE_READ           DEBUGZONE(8)
#define ZONE_WRITE          DEBUGZONE(9)
#define ZONE_THREAD         DEBUGZONE(10)
#define ZONE_EVENTS         DEBUGZONE(11)
//...

//
// these should be removed in the code if you can 'g' past these successfully
//
#define TEST_TRAP() { \
   NKDbgPrintfW( TEXT("%s: Code Coverage Trap in: %s, Line: %d\n"), DRIVER_NAME_SZ, TEXT(__FILE__), __LINE__); \
   DebugBreak();  \
}

#define DUMP_DISK_INFO( pDI ) { \
    if (pDI) {   \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("DISK_INFO:\n"))); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("---------------------\n"))); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("di_total_sectors: %u\n"), pDI->di_total_sectors )); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("di_bytes_per_sect: %u\n"), pDI->di_bytes_per_sect )); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("di_cylinders: %u\n"), pDI->di_cylinders )); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("di_heads: %u\n"), pDI->di_heads )); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("di_sectors: %u\n"), pDI->di_sectors )); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("di_flags: 0x%x\n"), pDI->di_flags )); \
        DEBUGMSG( ZONE_DSK_IOCTL, (TEXT("\n"))); \
   } \
}

#else
#define TEST_TRAP()
#define DUMP_DISK_INFO( pDI )
#endif // DEBUG

#endif // _SCSI2_

// EOF

⌨️ 快捷键说明

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