windows-nt/Source/XPSP1/NT/drivers/storage/ide/atapi/atapi.h

1231 lines
35 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#if !defined (___atapi_h___)
#define ___atapi_h___
/*++
Copyright (C) Microsoft Corporation, 1993 - 1999
Module Name:
atapi.h
Abstract:
This module contains the structures and definitions for the ATAPI
IDE miniport driver.
Author:
Mike Glass
Revision History:
--*/
#include "scsi.h"
#include "stdio.h"
#include "string.h"
ULONG
AtapiParseArgumentString(
IN PCHAR String,
IN PCHAR KeyWord
);
//
// IDE register definition
//
typedef struct _IDE_REGISTERS_3 {
ULONG Data;
UCHAR Others[4];
} IDE_REGISTERS_3, *PIDE_REGISTERS_3;
typedef struct _ATA_COMMAND_BLOCK_READ_REGISTERS {
union {
struct {
PUSHORT Data16;
} w;
struct {
PUCHAR Data8;
PUCHAR Error;
PUCHAR SectorCount;
PUCHAR SectorNumber;
PUCHAR CylinderLow;
PUCHAR CylinderHigh;
PUCHAR DriveSelect;
PUCHAR Status;
} b;
} size;
} ATA_COMMAND_BLOCK_READ_REGISTERS, *PATA_COMMAND_BLOCK_READ_REGISTERS;
typedef struct _ATA_COMMAND_BLOCK_WRITE_REGISTERS {
union {
struct {
PUSHORT Data16;
} w;
struct {
PUCHAR Data8;
PUCHAR Feature;
PUCHAR SectorCount;
PUCHAR SectorNumber;
PUCHAR CylinderLow;
PUCHAR CylinderHigh;
PUCHAR DriveSelect;
PUCHAR Command;
} b;
} size;
} ATA_COMMAND_BLOCK_WRITE_REGISTERS, *PATA_COMMAND_BLOCK_WRITE_REGISTERS;
typedef struct _ATAPI_COMMAND_BLOCK_READ_REGISTERS {
union {
struct {
PUSHORT Data16;
} w;
struct {
PUCHAR Data8;
PUCHAR Error;
PUCHAR InterruptReason;
PUCHAR Reserved;
PUCHAR ByteCountLow;
PUCHAR ByteCountHigh;
PUCHAR DriveSelect;
PUCHAR Status;
} b;
} size;
} ATAPI_COMMAND_BLOCK_READ_REGISTERS, *PATAPI_COMMAND_BLOCK_READ_REGISTERS;
typedef struct _ATAPI_COMMAND_BLOCK_WRITE_REGISTERS {
union {
struct {
PUSHORT Data16;
} w;
struct {
PUCHAR Data8;
PUCHAR Feature;
PUCHAR Resereved0;
PUCHAR Resereved1;
PUCHAR ByteCountLow;
PUCHAR ByteCountHigh;
PUCHAR DriveSelect;
PUCHAR Command;
} b;
} size;
} ATAPI_COMMAND_BLOCK_WRITE_REGISTERS, *PATAPI_COMMAND_BLOCK_WRITE_REGISTERS;
typedef struct _IDE_COMMAND_BLOCK_WRITE_REGISTERS {
PUCHAR RegistersBaseAddress;
union {
union {
ATA_COMMAND_BLOCK_READ_REGISTERS r;
ATA_COMMAND_BLOCK_WRITE_REGISTERS w;
} ata;
union {
ATAPI_COMMAND_BLOCK_READ_REGISTERS r;
ATAPI_COMMAND_BLOCK_WRITE_REGISTERS w;
} atapi;
} type;
} IDE_COMMAND_BLOCK_WRITE_REGISTERS, *PIDE_COMMAND_BLOCK_WRITE_REGISTERS;
//
// handy ata macros
//
#define ATA_DATA16_REG(baseAddress) (baseAddress)->type.ata.r.size.w.Data16
#define ATA_ERROR_REG(baseAddress) (baseAddress)->type.ata.r.size.b.Error
#define ATA_SECTOR_COUNT_REG(baseAddress) (baseAddress)->type.ata.r.size.b.SectorCount
#define ATA_SECTOR_NUMBER_REG(baseAddress) (baseAddress)->type.ata.r.size.b.SectorNumber
#define ATA_CYLINDER_LOW_REG(baseAddress) (baseAddress)->type.ata.r.size.b.CylinderLow
#define ATA_CYLINDER_HIGH_REG(baseAddress) (baseAddress)->type.ata.r.size.b.CylinderHigh
#define ATA_DRIVE_SELECT_REG(baseAddress) (baseAddress)->type.ata.r.size.b.DriveSelect
#define ATA_STATUS_REG(baseAddress) (baseAddress)->type.ata.r.size.b.Status
#define ATA_FEATURE_REG(baseAddress) (baseAddress)->type.ata.w.size.b.Feature
#define ATA_COMMAND_REG(baseAddress) (baseAddress)->type.ata.w.size.b.Command
//
// handy atapi macros
//
#define ATAPI_DATA16_REG(baseAddress) (baseAddress)->type.atapi.r.size.w.Data16
#define ATAPI_ERROR_REG(baseAddress) (baseAddress)->type.atapi.r.size.b.Error
#define ATAPI_INTERRUPT_REASON_REG(baseAddress) (baseAddress)->type.atapi.r.size.b.InterruptReason
#define ATAPI_BYTECOUNT_LOW_REG(baseAddress) (baseAddress)->type.atapi.r.size.b.ByteCountLow
#define ATAPI_BYTECOUNT_HIGH_REG(baseAddress) (baseAddress)->type.atapi.r.size.b.ByteCountHigh
#define ATAPI_DRIVE_SELECT_REG(baseAddress) (baseAddress)->type.atapi.r.size.b.DriveSelect
#define ATAPI_STATUS_REG(baseAddress) (baseAddress)->type.atapi.r.size.b.Status
#define ATAPI_FEATURE_REG(baseAddress) (baseAddress)->type.atapi.w.size.b.Feature
#define ATAPI_COMMAND_REG(baseAddress) (baseAddress)->type.atapi.w.size.b.Command
//
// Device Extension Device Flags
//
#define DFLAGS_DEVICE_PRESENT (1 << 0) // Indicates that some device is present.
#define DFLAGS_ATAPI_DEVICE (1 << 1) // Indicates whether Atapi commands can be used.
#define DFLAGS_TAPE_DEVICE (1 << 2) // Indicates whether this is a tape device.
#define DFLAGS_INT_DRQ (1 << 3) // Indicates whether device interrupts as DRQ is set after
// receiving Atapi Packet Command
#define DFLAGS_REMOVABLE_DRIVE (1 << 4) // Indicates that the drive has the 'removable' bit set in
// identify data (offset 128)
#define DFLAGS_MEDIA_STATUS_ENABLED (1 << 5) // Media status notification enabled
#define DFLAGS_USE_DMA (1 << 9) // Indicates whether device can use DMA
#define DFLAGS_LBA (1 << 10) // support LBA addressing
#define DFLAGS_MULTI_LUN_INITED (1 << 11) // Indicates that the init path for multi-lun has already been done.
#define DFLAGS_MSN_SUPPORT (1 << 12) // Device support media status notification
#define DFLAGS_AUTO_EJECT_ZIP (1 << 13) // bootup default enables auto eject
#define DFLAGS_WD_MODE (1 << 14) // Indicates that unit is WD-Mode(not SFF-Mode).
#define DFLAGS_LS120_FORMAT (1 << 15) // Indicates that unit uses ATAPI_LS120_FORMAT_UNIT to format
#define DFLAGS_USE_UDMA (1 << 16) // Indicates whether device can use UDMA
#define DFLAGS_IDENTIFY_VALID (1 << 17) // Indicates whether the Identify data is valid or not
#define DFLAGS_IDENTIFY_INVALID (1 << 18) // Indicates whether the Identify data is valid or not
#define DFLAGS_RDP_SET (1 << 19) // If the srb is for RDP
#define DFLAGS_SONY_MEMORYSTICK (1 << 20) // If the device is a Sony Memorystick
#define DFLAGS_48BIT_LBA (1 << 21) // If the device supports 48-bit LBA
#define DFLAGS_DEVICE_ERASED (1 << 22) // Indicates that some device is temporarily blocked for access.
//
// Used to disable 'advanced' features.
//
#define MAX_ERRORS 4
//
// ATAPI command definitions
//
#define ATAPI_MODE_SENSE 0x5A
#define ATAPI_MODE_SELECT 0x55
#define ATAPI_LS120_FORMAT_UNIT 0x24
//
// ATAPI mode page page code
//
#define ATAPI_NON_CD_DRIVE_OPERATION_MODE_PAGE_PAGECODE (0x00)
#define ATAPI_REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGECODE (0x1b)
//
// ATAPI Command Descriptor Block
//
typedef struct _MODE_PARAMETER_HEADER_10 {
UCHAR ModeDataLengthMsb;
UCHAR ModeDataLengthLsb;
UCHAR MediumType;
UCHAR Reserved[5];
}MODE_PARAMETER_HEADER_10, *PMODE_PARAMETER_HEADER_10;
typedef struct _ATAPI_REMOVABLE_BLOCK_ACCESS_CAPABILITIES {
UCHAR PageCode : 6;
UCHAR Reserved0 : 1;
UCHAR PSBit : 1;
UCHAR PageLength;
UCHAR Reserved2:6;
UCHAR SRFP:1;
UCHAR SFLP:1;
UCHAR TotalLun:3;
UCHAR Reserved3:3;
UCHAR SML:1;
UCHAR NCD:1;
UCHAR Reserved[8];
} ATAPI_REMOVABLE_BLOCK_ACCESS_CAPABILITIES, *PATAPI_REMOVABLE_BLOCK_ACCESS_CAPABILITIES;
typedef struct _ATAPI_NON_CD_DRIVE_OPERATION_MODE_PAGE {
UCHAR PageCode : 6;
UCHAR Reserved0 : 1;
UCHAR PSBit : 1;
UCHAR PageLength;
UCHAR Reserved2:5;
UCHAR DVW:1;
UCHAR SLR:1;
UCHAR SLM:1;
UCHAR Reserved3:4;
UCHAR DDE:1;
UCHAR Reserved4:3;
} ATAPI_NON_CD_DRIVE_OPERATION_MODE_PAGE, *PATAPI_NON_CD_DRIVE_OPERATION_MODE_PAGE;
//
// IDE command definitions
//
#define IDE_COMMAND_NOP 0x00
#define IDE_COMMAND_ATAPI_RESET 0x08
#define IDE_COMMAND_RECALIBRATE 0x10
#define IDE_COMMAND_READ 0x20
#define IDE_COMMAND_READ_EXT 0x24
#define IDE_COMMAND_READ_DMA_EXT 0x25
#define IDE_COMMAND_READ_DMA_QUEUED_EXT 0x26
#define IDE_COMMAND_READ_MULTIPLE_EXT 0x29
#define IDE_COMMAND_WRITE 0x30
#define IDE_COMMAND_WRITE_EXT 0x34
#define IDE_COMMAND_WRITE_DMA_EXT 0x35
#define IDE_COMMAND_WRITE_DMA_QUEUED_EXT 0x36
#define IDE_COMMAND_WRITE_MULTIPLE_EXT 0x39
#define IDE_COMMAND_VERIFY 0x40
#define IDE_COMMAND_VERIFY_EXT 0x42
#define IDE_COMMAND_SEEK 0x70
#define IDE_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC 0x90
#define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91
#define IDE_COMMAND_ATAPI_PACKET 0xA0
#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1
#define IDE_COMMAND_READ_MULTIPLE 0xC4
#define IDE_COMMAND_WRITE_MULTIPLE 0xC5
#define IDE_COMMAND_SET_MULTIPLE 0xC6
#define IDE_COMMAND_READ_DMA 0xC8
#define IDE_COMMAND_WRITE_DMA 0xCA
#define IDE_COMMAND_GET_MEDIA_STATUS 0xDA
#define IDE_COMMAND_STANDBY_IMMEDIATE 0xE0
#define IDE_COMMAND_IDLE_IMMEDIATE 0xE1
#define IDE_COMMAND_CHECK_POWER 0xE5
#define IDE_COMMAND_SLEEP 0xE6
#define IDE_COMMAND_FLUSH_CACHE 0xE7
#define IDE_COMMAND_FLUSH_CACHE_EXT 0xEA
#define IDE_COMMAND_IDENTIFY 0xEC
#define IDE_COMMAND_MEDIA_EJECT 0xED
#define IDE_COMMAND_SET_FEATURE 0xEF
#define IDE_COMMAND_DOOR_LOCK 0xDE
#define IDE_COMMAND_DOOR_UNLOCK 0xDF
#define IDE_COMMAND_NO_FLUSH 0xFF // Commmand value to indicate the target device can't handle any flush command
//
// IDE Set Transfer Mode
//
#define IDE_SET_DEFAULT_PIO_MODE(mode) ((UCHAR) 1) // disable I/O Ready
#define IDE_SET_ADVANCE_PIO_MODE(mode) ((UCHAR) ((1 << 3) | (mode)))
#define IDE_SET_SWDMA_MODE(mode) ((UCHAR) ((1 << 4) | (mode)))
#define IDE_SET_MWDMA_MODE(mode) ((UCHAR) ((1 << 5) | (mode)))
#define IDE_SET_UDMA_MODE(mode) ((UCHAR) ((1 << 6) | (mode)))
#define IDE_SET_FEATURE_SET_TRANSFER_MODE 0x3
#define IDE_SET_FEATURE_ENABLE_WRITE_CACHE 0x2
#define IDE_SET_FEATURE_DISABLE_WRITE_CACHE 0x82
//
// Media Status Set Feature
//
#define IDE_SET_FEATURE_ENABLE_MSN 0x95
#define IDE_SET_FEATURE_DISABLE_MSN 0x31
#define IDE_SET_FEATURE_DISABLE_REVERT_TO_POWER_ON 0x66
//
// IDE drive select/head definitions
//
#define IDE_DRIVE_SELECT_1 0xA0
#define IDE_DRIVE_SELECT_2 0x10
//
// IDE error definitions
//
#define IDE_ERROR_BAD_BLOCK 0x80
#define IDE_ERROR_CRC_ERROR IDE_ERROR_BAD_BLOCK
#define IDE_ERROR_DATA_ERROR 0x40
#define IDE_ERROR_MEDIA_CHANGE 0x20
#define IDE_ERROR_ID_NOT_FOUND 0x10
#define IDE_ERROR_MEDIA_CHANGE_REQ 0x08
#define IDE_ERROR_COMMAND_ABORTED 0x04
#define IDE_ERROR_END_OF_MEDIA 0x02
#define IDE_ERROR_ILLEGAL_LENGTH 0x01
//
// ATAPI register definition
//
typedef struct _ATAPI_REGISTERS_1 {
PUCHAR RegistersBaseAddress;
PUSHORT Data;
PUCHAR Error;
PUCHAR InterruptReason;
PUCHAR Unused1;
PUCHAR ByteCountLow;
PUCHAR ByteCountHigh;
PUCHAR DriveSelect;
PUCHAR Command;
} ATAPI_REGISTERS_1, *PATAPI_REGISTERS_1;
typedef struct _ATAPI_REGISTERS_2 {
PUCHAR RegistersBaseAddress;
PUCHAR DeviceControl;
PUCHAR DriveAddress;
} ATAPI_REGISTERS_2, *PATAPI_REGISTERS_2;
//
// ATAPI interrupt reasons
//
#define ATAPI_IR_COD 0x01
#define ATAPI_IR_IO 0x02
//
// IDENTIFY data
//
/**************** Moved to ide.h *************
#pragma pack (1)
typedef struct _IDENTIFY_DATA {
USHORT GeneralConfiguration; // 00 00
USHORT NumCylinders; // 02 1
USHORT Reserved1; // 04 2
USHORT NumHeads; // 06 3
USHORT UnformattedBytesPerTrack; // 08 4
USHORT UnformattedBytesPerSector; // 0A 5
USHORT NumSectorsPerTrack; // 0C 6
USHORT VendorUnique1[3]; // 0E 7-9
UCHAR SerialNumber[20]; // 14 10-19
USHORT BufferType; // 28 20
USHORT BufferSectorSize; // 2A 21
USHORT NumberOfEccBytes; // 2C 22
UCHAR FirmwareRevision[8]; // 2E 23-26
UCHAR ModelNumber[40]; // 36 27-46
UCHAR MaximumBlockTransfer; // 5E 47
UCHAR VendorUnique2; // 5F
USHORT DoubleWordIo; // 60 48
USHORT Capabilities; // 62 49
USHORT Reserved2; // 64 50
UCHAR VendorUnique3; // 66 51
UCHAR PioCycleTimingMode; // 67
UCHAR VendorUnique4; // 68 52
UCHAR DmaCycleTimingMode; // 69
USHORT TranslationFieldsValid:3; // 6A 53
USHORT Reserved3:13;
USHORT NumberOfCurrentCylinders; // 6C 54
USHORT NumberOfCurrentHeads; // 6E 55
USHORT CurrentSectorsPerTrack; // 70 56
ULONG CurrentSectorCapacity; // 72 57-58
USHORT CurrentMultiSectorSetting; // 59
ULONG UserAddressableSectors; // 60-61
USHORT SingleWordDMASupport : 8; // 62
USHORT SingleWordDMAActive : 8;
USHORT MultiWordDMASupport : 8; // 63
USHORT MultiWordDMAActive : 8;
USHORT AdvancedPIOModes : 8; // 64
USHORT Reserved4 : 8;
USHORT MinimumMWXferCycleTime; // 65
USHORT RecommendedMWXferCycleTime; // 66
USHORT MinimumPIOCycleTime; // 67
USHORT MinimumPIOCycleTimeIORDY; // 68
USHORT Reserved5[11]; // 69-79
USHORT MajorRevision; // 80
USHORT MinorRevision; // 81
USHORT Reserved6[6]; // 82-87
USHORT UltraDMASupport : 8; // 88
USHORT UltraDMAActive : 8; //
USHORT Reserved7[37]; // 89-125
USHORT LastLun:3; // 126
USHORT Reserved8:13;
USHORT MediaStatusNotification:2; // 127
USHORT Reserved9:6;
USHORT DeviceWriteProtect:1;
USHORT Reserved10:7;
USHORT Reserved11[128]; // 128-255
} IDENTIFY_DATA, *PIDENTIFY_DATA;
//
// Identify data without the Reserved4.
//
//typedef struct _IDENTIFY_DATA2 {
// USHORT GeneralConfiguration; // 00 00
// USHORT NumCylinders; // 02 1
// USHORT Reserved1; // 04 2
// USHORT NumHeads; // 06 3
// USHORT UnformattedBytesPerTrack; // 08 4
// USHORT UnformattedBytesPerSector; // 0A 5
// USHORT NumSectorsPerTrack; // 0C 6
// USHORT VendorUnique1[3]; // 0E 7-9
// UCHAR SerialNumber[20]; // 14 10-19
// USHORT BufferType; // 28 20
// USHORT BufferSectorSize; // 2A 21
// USHORT NumberOfEccBytes; // 2C 22
// UCHAR FirmwareRevision[8]; // 2E 23-26
// UCHAR ModelNumber[40]; // 36 27-46
// UCHAR MaximumBlockTransfer; // 5E 47
// UCHAR VendorUnique2; // 5F
// USHORT DoubleWordIo; // 60 48
// USHORT Capabilities; // 62 49
// USHORT Reserved2; // 64 50
// UCHAR VendorUnique3; // 66 51
// UCHAR PioCycleTimingMode; // 67
// UCHAR VendorUnique4; // 68 52
// UCHAR DmaCycleTimingMode; // 69
// USHORT TranslationFieldsValid:3; // 6A 53
// USHORT Reserved3:13;
// USHORT NumberOfCurrentCylinders; // 6C 54
// USHORT NumberOfCurrentHeads; // 6E 55
// USHORT CurrentSectorsPerTrack; // 70 56
// ULONG CurrentSectorCapacity; // 72 57-58
// USHORT CurrentMultiSectorSetting; // 59
// ULONG UserAddressableSectors; // 60-61
// USHORT SingleWordDMASupport : 8; // 62
// USHORT SingleWordDMAActive : 8;
// USHORT MultiWordDMASupport : 8; // 63
// USHORT MultiWordDMAActive : 8;
// USHORT AdvancedPIOModes : 8; // 64
// USHORT Reserved4 : 8;
// USHORT MinimumMWXferCycleTime; // 65
// USHORT RecommendedMWXferCycleTime; // 66
// USHORT MinimumPIOCycleTime; // 67
// USHORT MinimumPIOCycleTimeIORDY; // 68
// USHORT Reserved5[11]; // 69-79
// USHORT MajorRevision; // 80
// USHORT MinorRevision; // 81
// USHORT Reserved6[6]; // 82-87
// USHORT UltraDMASupport : 8; // 88
// USHORT UltraDMAActive : 8; //
// USHORT Reserved7[37]; // 89-125
// USHORT LastLun:3; // 126
// USHORT Reserved8:13;
// USHORT MediaStatusNotification:2; // 127
// USHORT Reserved9:6;
// USHORT DeviceWriteProtect:1;
// USHORT Reserved10:7;
//} IDENTIFY_DATA2, *PIDENTIFY_DATA2;
#pragma pack ()
#define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA)
******************************************************/
//
// Identify Data General Configuration Bit Definition
//
#define IDE_IDDATA_DEVICE_TYPE_MASK ((1 << 15) | (1 << 14))
#define IDE_IDDATA_ATAPI_DEVICE ((1 << 15 | (0 << 14))
#define IDE_IDDATA_ATAPI_DEVICE_MASK ((1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8))
#define IDE_IDDATA_REMOVABLE (1 << 7)
#define IDE_IDDATA_DRQ_TYPE_MASK ((1 << 6) | (1 << 5))
#define IDE_IDDATA_INTERRUPT_DRQ ((1 << 6) | (0 << 5))
//
// Identify Data 48 bit lba support
//
#define IDE_IDDATA_48BIT_LBA_SUPPORT (1<<10)
//
// IDENTIFY capability bit definitions.
//
#define IDENTIFY_CAPABILITIES_DMA_SUPPORTED (1 << 8)
#define IDENTIFY_CAPABILITIES_LBA_SUPPORTED (1 << 9)
#define IDENTIFY_CAPABILITIES_IOREADY_CAN_BE_DISABLED (1 << 10)
#define IDENTIFY_CAPABILITIES_IOREADY_SUPPORTED (1 << 11)
//
// Identify MediaStatusNotification
//
#define IDENTIFY_MEDIA_STATUS_NOTIFICATION_SUPPORTED (0x1)
//
// Select LBA mode when progran IDE device
//
#define IDE_LBA_MODE (1 << 6)
//
// ID DATA
//
/********** Not needed ****************
#define IDD_UDMA_MODE0_ACTIVE (1 << 0)
#define IDD_UDMA_MODE1_ACTIVE (1 << 1)
#define IDD_UDMA_MODE2_ACTIVE (1 << 2)
#define IDD_UDMA_MODE3_ACTIVE (1 << 3)
#define IDD_UDMA_MODE4_ACTIVE (1 << 4)
#define IDD_UDMA_MODE5_ACTIVE (1 << 5)
#define IDD_MWDMA_MODE0_ACTIVE (1 << 0)
#define IDD_MWDMA_MODE1_ACTIVE (1 << 1)
#define IDD_MWDMA_MODE2_ACTIVE (1 << 2)
#define IDD_SWDMA_MODE0_ACTIVE (1 << 0)
#define IDD_SWDMA_MODE1_ACTIVE (1 << 1)
#define IDD_SWDMA_MODE2_ACTIVE (1 << 2)
#define IDD_UDMA_MODE0_SUPPORTED (1 << 0)
#define IDD_UDMA_MODE1_SUPPORTED (1 << 1)
#define IDD_UDMA_MODE2_SUPPORTED (1 << 2)
#define IDD_MWDMA_MODE0_SUPPORTED (1 << 0)
#define IDD_MWDMA_MODE1_SUPPORTED (1 << 1)
#define IDD_MWDMA_MODE2_SUPPORTED (1 << 2)
#define IDD_SWDMA_MODE0_SUPPORTED (1 << 0)
#define IDD_SWDMA_MODE1_SUPPORTED (1 << 1)
#define IDD_SWDMA_MODE2_SUPPORTED (1 << 2)
************/
//
// Beautification macros
//
#define HasSlaveDevice(HwExt, Target) (HwExt->DeviceFlags[(Target+1)%MAX_IDE_DEVICE] & DFLAGS_DEVICE_PRESENT)
#ifdef ENABLE_ATAPI_VERIFIER
#define GetBaseStatus(BaseIoAddress, Status) \
Status = ViIdeGetBaseStatus((PIDE_REGISTERS_1)BaseIoAddress);
#define GetErrorByte(BaseIoAddress, ErrorByte) \
ErrorByte = ViIdeGetErrorByte((PIDE_REGISTERS_1)BaseIoAddress);
#else
#define GetBaseStatus(BaseIoAddress, Status) \
Status = IdePortInPortByte((BaseIoAddress)->Command);
#define GetErrorByte(BaseIoAddress, ErrorByte) \
ErrorByte = IdePortInPortByte((BaseIoAddress)->Error);
#endif
#define WriteCommand(BaseIoAddress, Command) \
IdePortOutPortByte((BaseIoAddress)->Command, Command);
#define ReadBuffer(BaseIoAddress, Buffer, Count) \
IdePortInPortWordBuffer((PUSHORT)(BaseIoAddress)->Data, Buffer, Count);
#define WriteBuffer(BaseIoAddress, Buffer, Count) \
IdePortOutPortWordBuffer((PUSHORT)(BaseIoAddress)->Data, Buffer, Count);
#define WaitOnBusy(BaseIoAddress, Status) \
{ \
ULONG sec; \
ULONG i; \
for (sec=0; sec<10; sec++) { \
/**/ \
/* one second loop */ \
/**/ \
for (i=0; i<2500; i++) { \
GetStatus(BaseIoAddress, Status); \
if (Status & IDE_STATUS_BUSY) { \
KeStallExecutionProcessor(400); \
continue; \
} else { \
break; \
} \
} \
if (Status & IDE_STATUS_BUSY) { \
DebugPrint ((1, "ATAPI: after 1 sec wait, device is still busy with 0x%x status = 0x%x\n", (BaseIoAddress)->RegistersBaseAddress, (ULONG) (Status))); \
} else { \
break; \
} \
} \
if (Status & IDE_STATUS_BUSY) { \
DebugPrint ((0, "WaitOnBusy failed in %s line %u. 0x%x status = 0x%x\n", __FILE__, __LINE__, (BaseIoAddress)->RegistersBaseAddress, (ULONG) (Status))); \
} \
}
#define WaitForDRDY(BaseIoAddress, Status) \
{ \
ULONG i; \
WaitOnBusy(BaseIoAddress, Status);\
for (i=0; i<20000; i++) { \
GetStatus(BaseIoAddress, Status); \
if (!(Status & IDE_STATUS_IDLE)) { \
KeStallExecutionProcessor(150); \
continue; \
} else { \
break; \
} \
} \
if (i == 20000) \
DebugPrint ((0, "WaitForDRDY failed in %s line %u. 0x%x status = 0x%x\n", __FILE__, __LINE__, (BaseIoAddress)->RegistersBaseAddress, (ULONG) (Status))); \
}
#define WaitOnBusyUntil(BaseIoAddress, Status, Millisec) \
{ \
ULONG i; \
ULONG maxCount = Millisec * 10;\
for (i=0; i<maxCount; i++) { \
GetStatus(BaseIoAddress, Status); \
if (Status & IDE_STATUS_BUSY) { \
KeStallExecutionProcessor(100); \
continue; \
} else { \
break; \
} \
} \
if (i == maxCount) \
DebugPrint ((0, "WaitOnBusyUntil failed in %s line %u. status = 0x%x\n", __FILE__, __LINE__, (ULONG) (Status))); \
}
#define WaitOnBaseBusy(BaseIoAddress, Status) \
{ \
ULONG i; \
for (i=0; i<20000; i++) { \
GetBaseStatus(BaseIoAddress, Status); \
if (Status & IDE_STATUS_BUSY) { \
KeStallExecutionProcessor(150); \
continue; \
} else { \
break; \
} \
} \
}
#define WaitForDrq(BaseIoAddress, Status) \
{ \
ULONG i; \
for (i=0; i<1000; i++) { \
GetStatus(BaseIoAddress, Status); \
if (Status & IDE_STATUS_BUSY) { \
KeStallExecutionProcessor(100); \
} else if (Status & IDE_STATUS_DRQ) { \
break; \
} else { \
KeStallExecutionProcessor(200); \
} \
} \
}
#define WaitShortForDrq(BaseIoAddress, Status) \
{ \
ULONG i; \
for (i=0; i<2; i++) { \
GetStatus(BaseIoAddress, Status); \
if (Status & IDE_STATUS_BUSY) { \
KeStallExecutionProcessor(100); \
} else if (Status & IDE_STATUS_DRQ) { \
break; \
} else { \
KeStallExecutionProcessor(100); \
} \
} \
}
#define AtapiSoftReset(BaseIoAddress1, BaseIoAddress2, DeviceNumber, interruptOff) \
{\
ULONG __i;\
UCHAR statusByte; \
SelectIdeDevice(BaseIoAddress1, DeviceNumber, 0); \
KeStallExecutionProcessor(500);\
IdePortOutPortByte((BaseIoAddress1)->Command, IDE_COMMAND_ATAPI_RESET); \
KeStallExecutionProcessor(500);\
SelectIdeDevice(BaseIoAddress1, DeviceNumber, 0); \
WaitOnBusy(BaseIoAddress1, statusByte); \
if ( !Is98LegacyIde(BaseIoAddress1) ) { \
KeStallExecutionProcessor(500); \
} else { \
for (__i = 0; __i < 20; __i++) { \
KeStallExecutionProcessor(500); \
} \
} \
if (interruptOff) { \
IdePortOutPortByte(BaseIoAddress2->DeviceControl, IDE_DC_DISABLE_INTERRUPTS); \
} \
}
#define SAVE_ORIGINAL_CDB(DeviceExtension, Srb) \
RtlCopyMemory(DeviceExtension->OriginalCdb, Srb->Cdb, sizeof(CDB));
#define RESTORE_ORIGINAL_CDB(DeviceExtension, Srb) \
RtlCopyMemory(Srb->Cdb, DeviceExtension->OriginalCdb, sizeof(CDB));
//
// NEC 98: Buffer size of mode sense data.
//
#define MODE_DATA_SIZE 192
typedef enum {
IdeResetBegin = 0,
ideResetBusResetInProgress,
ideResetAtapiReset,
ideResetAtapiResetInProgress,
ideResetAtapiIdentifyData,
ideResetAtaIDP,
ideResetAtaIDPInProgress,
ideResetAtaMSN,
ideResetFinal
} IDE_RESET_STATE;
//
// Definition in ide.h
//
struct IDENTIFY_DATA;
//
// Device extension
//
typedef struct _HW_DEVICE_EXTENSION {
//
// Current request on controller.
//
PSCSI_REQUEST_BLOCK CurrentSrb;
//
// Base register locations
//
IDE_REGISTERS_1 BaseIoAddress1;
IDE_REGISTERS_2 BaseIoAddress2;
//
// Register length.
//
ULONG BaseIoAddress1Length;
ULONG BaseIoAddress2Length;
//
// Max ide device/target-id
//
ULONG MaxIdeDevice;
ULONG MaxIdeTargetId;
//
// Variables to check empty channel
//
#ifdef DPC_FOR_EMPTY_CHANNEL
ULONG CurrentIdeDevice;
ULONG MoreWait;
ULONG NoRetry;
#endif
//
// Drive Geometry
//
ULONG NumberOfCylinders[MAX_IDE_DEVICE * MAX_IDE_LINE];
ULONG NumberOfHeads[MAX_IDE_DEVICE * MAX_IDE_LINE];
ULONG SectorsPerTrack[MAX_IDE_DEVICE * MAX_IDE_LINE];
//
// Interrupt Mode (Level or Edge)
//
ULONG InterruptMode;
//
// Data buffer pointer.
//
PUCHAR DataBuffer;
//
// Data words left.
//
ULONG BytesLeft;
//
// Count of errors. Used to turn off features.
//
ULONG ErrorCount;
//
// Count of timeouts. Used to turn off features.
//
ULONG TimeoutCount[MAX_IDE_DEVICE * MAX_IDE_LINE];
//
// Indicates number of platters on changer-ish devices.
//
ULONG LastLun[MAX_IDE_DEVICE * MAX_IDE_LINE];
//
// Flags word for each possible device.
//
ULONG DeviceFlags[MAX_IDE_DEVICE * MAX_IDE_LINE];
//
// Indicates the number of blocks transferred per int. according to the
// identify data.
//
UCHAR MaximumBlockXfer[MAX_IDE_DEVICE * MAX_IDE_LINE];
//
// Indicates expecting an interrupt
//
BOOLEAN ExpectingInterrupt;
//
// Indicates DMA is in progress
//
BOOLEAN DMAInProgress;
//
// Keep track of whether we convert a SCSI command to ATAPI on the fly
//
BOOLEAN scsi2atapi;
//
// Indicate last tape command was DSC Restrictive.
//
BOOLEAN RDP;
//
// Driver is being used by the crash dump utility or ntldr.
//
BOOLEAN DriverMustPoll;
//
// Indicates whether '0x1f0' is the base address. Used
// in SMART Ioctl calls.
//
BOOLEAN PrimaryAddress;
BOOLEAN SecondaryAddress;
//
// No IDE_SET_FEATURE_SET_TRANSFER_MODE
//
BOOLEAN NoPioSetTransferMode;
//
// Placeholder for the original cdb
//
UCHAR OriginalCdb[16];
//
// Placeholder for the sub-command value of the last
// SMART command.
//
UCHAR SmartCommand;
//
// Placeholder for status register after a GET_MEDIA_STATUS command
//
UCHAR ReturningMediaStatus;
//
// Identify data for device
//
IDENTIFY_DATA IdentifyData[MAX_IDE_DEVICE * MAX_IDE_LINE];
//
// PCI IDE Parent bus master interface
//
PCIIDE_BUSMASTER_INTERFACE BusMasterInterface;
//
// Device Specific Info.
//
struct _DEVICE_PARAMETERS {
ULONG MaxBytePerPioInterrupt;
UCHAR IdePioReadCommand;
UCHAR IdePioWriteCommand;
UCHAR IdeFlushCommand;
UCHAR IdePioReadCommandExt;
UCHAR IdePioWriteCommandExt;
UCHAR IdeFlushCommandExt;
//
// Timing Stuff
//
BOOLEAN IoReadyEnabled;
ULONG BestPioCycleTime;
ULONG BestSwDmaCycleTime;
ULONG BestMwDmaCycleTime;
ULONG BestUDmaCycleTime;
ULONG TransferModeSupported;
ULONG BestPioMode;
ULONG BestSwDmaMode;
ULONG BestMwDmaMode;
ULONG BestUDmaMode;
ULONG TransferModeCurrent;
ULONG TransferModeSelected;
ULONG TransferModeMask;
} DeviceParameters[MAX_IDE_DEVICE * MAX_IDE_LINE];
#define RESET_STATE_TABLE_LEN (((2 + 3 * MAX_IDE_DEVICE) * MAX_IDE_LINE) + 1)
struct RESET_STATE {
ULONG WaitBusyCount;
IDE_RESET_STATE State[RESET_STATE_TABLE_LEN];
IDE_RESET_STATE DeviceNumber[RESET_STATE_TABLE_LEN];
} ResetState;
} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
//
// max number of CHS addressable sectors
//
//#define MAX_NUM_CHS_ADDRESSABLE_SECTORS ((ULONG) (16515072 - 1))
#define MAX_NUM_CHS_ADDRESSABLE_SECTORS ((ULONG) (16514064))
#define MAX_28BIT_LBA ((ULONG) (1<<28))
//
// IDE Cycle Timing
//
/****************************Moved to idep.h****************
#define PIO_MODE0_CYCLE_TIME 600
#define PIO_MODE1_CYCLE_TIME 383
#define PIO_MODE2_CYCLE_TIME 240
#define PIO_MODE3_CYCLE_TIME 180
#define PIO_MODE4_CYCLE_TIME 120
#define SWDMA_MODE0_CYCLE_TIME 960
#define SWDMA_MODE1_CYCLE_TIME 480
#define SWDMA_MODE2_CYCLE_TIME 240
#define MWDMA_MODE0_CYCLE_TIME 480
#define MWDMA_MODE1_CYCLE_TIME 150
#define MWDMA_MODE2_CYCLE_TIME 120
#define UDMA_MODE0_CYCLE_TIME 120
#define UDMA_MODE1_CYCLE_TIME 80
#define UDMA_MODE2_CYCLE_TIME 60
#define UDMA_MODE3_CYCLE_TIME 45
#define UDMA_MODE4_CYCLE_TIME 30
#define UDMA_MODE5_CYCLE_TIME 15
#define UNINITIALIZED_CYCLE_TIME 0xffffffff
#define UNINITIALIZED_TRANSFER_MODE 0xffffffff
*/
BOOLEAN
AtapiInterrupt(
IN PVOID HwDeviceExtension
);
BOOLEAN
AtapiHwInitialize(
IN PVOID HwDeviceExtension,
IN UCHAR FlushCommand[MAX_IDE_DEVICE * MAX_IDE_LINE]
);
BOOLEAN
AtapiStartIo(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
BOOLEAN
AtapiResetController(
IN PVOID HwDeviceExtension,
IN ULONG PathId,
IN PULONG CallAgain
);
VOID
InitDeviceParameters (
IN PVOID HwDeviceExtension,
IN UCHAR FlushCommand[MAX_IDE_DEVICE * MAX_IDE_LINE]
);
VOID
AtapiProgramTransferMode (
PHW_DEVICE_EXTENSION DeviceExtension
);
VOID
AtapiHwInitializeMultiLun (
IN PVOID HwDeviceExtension,
IN ULONG TargetId,
IN ULONG numSlot
);
ULONG
AtapiSendCommand(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
ULONG
IdeBuildSenseBuffer(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
VOID
IdeMediaStatus(
IN BOOLEAN EnableMSN,
IN PVOID HwDeviceExtension,
IN ULONG DeviceNumber
);
VOID
DeviceSpecificInitialize(
IN PVOID HwDeviceExtension
);
BOOLEAN
EnableBusMasterController (
IN PVOID HwDeviceExtension,
IN PCHAR userArgumentString
);
BOOLEAN
AtapiDeviceDMACapable (
IN PVOID HwDeviceExtension,
IN ULONG deviceNumber
);
BOOLEAN
GetAtapiIdentifyQuick (
PIDE_REGISTERS_1 BaseIoAddress1,
PIDE_REGISTERS_2 BaseIoAddress2,
IN ULONG DeviceNumber,
OUT PIDENTIFY_DATA IdentifyData
);
BOOLEAN
IssueIdentify(
PIDE_REGISTERS_1 CmdBaseAddr,
PIDE_REGISTERS_2 CtrlBaseAddr,
IN ULONG DeviceNumber,
IN UCHAR Command,
IN BOOLEAN InterruptOff,
OUT PIDENTIFY_DATA IdentifyData
);
VOID
InitDeviceGeometry(
PHW_DEVICE_EXTENSION HwDeviceExtension,
ULONG Device,
ULONG NumberOfCylinders,
ULONG NumberOfHeads,
ULONG SectorsPerTrack
);
VOID
InitHwExtWithIdentify(
IN PVOID HwDeviceExtension,
IN ULONG DeviceNumber,
IN UCHAR Command,
IN PIDENTIFY_DATA IdentifyData,
IN BOOLEAN RemovableMedia
);
BOOLEAN
SetDriveParameters(
IN PVOID HwDeviceExtension,
IN ULONG DeviceNumber,
IN BOOLEAN Sync
);
BOOLEAN
FindDevices(
IN PVOID HwDeviceExtension,
IN BOOLEAN AtapiOnly
);
ULONG
IdeSendPassThroughCommand(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
BOOLEAN
AtapiSyncResetController(
IN PVOID HwDeviceExtension,
IN ULONG PathId
);
NTSTATUS
IdeHardReset (
PIDE_REGISTERS_1 BaseIoAddress1,
PIDE_REGISTERS_2 BaseIoAddress2,
BOOLEAN InterruptOff,
BOOLEAN Sync
);
ULONG
IdeReadWrite(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
VOID
AtapiTaskRegisterSnapshot (
IN PIDE_REGISTERS_1 CmdRegBase,
IN OUT PIDEREGS IdeReg
);
NTSTATUS
AtapiSetTransferMode (
PHW_DEVICE_EXTENSION DeviceExtension,
ULONG DeviceNumber,
UCHAR ModeValue
);
#define ATA_VERSION_MASK (0xfffe)
#define ATA1_COMPLIANCE (1 << 1)
#define ATA2_COMPLIANCE (1 << 2)
#define ATA3_COMPLIANCE (1 << 3)
#define ATA4_COMPLIANCE (1 << 4)
#endif // ___atapi_h___