|
|
#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 stallTime; \ ULONG sec; \ ULONG i; \ for (sec=0; sec<10; sec++) { \ /**/ \ /* one second loop */ \ /**/ \ for (i=0; i<25000; i++) { \ GetStatus(BaseIoAddress, Status); \ if (Status & IDE_STATUS_BUSY) { \ stallTime = 40; \ KeStallExecutionProcessor(stallTime); \ 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 );
ULONG IdeSendAtaPassThroughExCommand( 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 IdeReadWriteExt( IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb );
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___
|