mirror of
https://github.com/reactos/reactos.git
synced 2024-08-26 13:18:51 +00:00
1726 lines
52 KiB
C
1726 lines
52 KiB
C
/*++
|
|
|
|
Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
|
|
|
|
Module Name:
|
|
atapi.h
|
|
|
|
Abstract:
|
|
This file contains IDE, ATA, ATAPI and SCSI Miniport definitions
|
|
and function prototypes.
|
|
|
|
Author:
|
|
Alexander A. Telyatnikov (Alter)
|
|
|
|
Environment:
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
Revision History:
|
|
|
|
Some definitions were taken from standard ATAPI.SYS sources from NT4 DDK by
|
|
Mike Glass (MGlass)
|
|
|
|
Some definitions were taken from FreeBSD 4.3-4.6 ATA driver by
|
|
Søren Schmidt, Copyright (c) 1998,1999,2000,2001
|
|
|
|
Code was changed/updated by
|
|
Alter, Copyright (c) 2002-20016
|
|
|
|
Licence:
|
|
GPLv2
|
|
|
|
|
|
--*/
|
|
#ifndef __GLOBAL_H__
|
|
#define __GLOBAL_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif //__cplusplus
|
|
|
|
#ifndef USER_MODE
|
|
#include "config.h"
|
|
#endif //USER_MODE
|
|
|
|
#include "scsi.h"
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifndef _DBGNT_
|
|
|
|
#ifdef KdPrint
|
|
#undef KdPrint
|
|
#endif
|
|
|
|
#ifdef USE_DBGPRINT_LOGGER
|
|
#include "inc/PostDbgMesg.h"
|
|
#define DbgPrint DbgDump_Printf
|
|
#define Connect_DbgPrint() {DbgDump_SetAutoReconnect(TRUE); DbgDump_Reconnect();}
|
|
#else // USE_DBGPRINT_LOGGER
|
|
#define Connect_DbgPrint() {;}
|
|
#endif // USE_DBGPRINT_LOGGER
|
|
|
|
#ifdef SCSI_PORT_DBG_PRINT
|
|
|
|
SCSIPORT_API
|
|
VOID
|
|
__cdecl
|
|
ScsiDebugPrint(
|
|
ULONG DebugPrintLevel,
|
|
PCCHAR DebugMessage,
|
|
...
|
|
);
|
|
|
|
#define PRINT_PREFIX 0,
|
|
|
|
#define KdPrint3(_x_) ScsiDebugPrint _x_ {;}
|
|
#define KdPrint2(_x_) {ScsiDebugPrint("%x: ", PsGetCurrentThread()) ; ScsiDebugPrint _x_ ; }
|
|
#define KdPrint(_x_) ScsiDebugPrint _x_ {;}
|
|
|
|
#else // SCSI_PORT_DBG_PRINT
|
|
|
|
#ifndef USE_DBGPRINT_LOGGER
|
|
/*
|
|
ULONG
|
|
_cdecl
|
|
DbgPrint(
|
|
PCH Format,
|
|
...
|
|
);
|
|
*/
|
|
#endif // USE_DBGPRINT_LOGGER
|
|
|
|
#define PRINT_PREFIX
|
|
|
|
// Note, that using DbgPrint on raised IRQL will crash w2k
|
|
// ttis will not happen immediately, so we shall see some logs
|
|
//#define LOG_ON_RAISED_IRQL_W2K TRUE
|
|
//#define LOG_ON_RAISED_IRQL_W2K FALSE
|
|
|
|
#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
|
|
#define KdPrint2(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
|
|
#define KdPrint(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
|
|
/*
|
|
#define PRINT_PREFIX_PTR ((PCHAR)&__tmp__kdprint__buff__)
|
|
#define PRINT_UPREFIX_PTR ((PWCHAR)&__tmp__kdprint__ubuff__)
|
|
#define PRINT_PREFIX PRINT_PREFIX_PTR,
|
|
#define KdPrint2(_x_) \
|
|
{ \
|
|
WCHAR __tmp__kdprint__ubuff__[256]; \
|
|
CHAR __tmp__kdprint__buff__[256]; \
|
|
UNICODE_STRING __tmp__usrt__buff__; \
|
|
sprintf _x_; \
|
|
swprintf (PRINT_UPREFIX_PTR, L"%hs", PRINT_PREFIX_PTR); \
|
|
__tmp__usrt__buff__.Buffer = PRINT_UPREFIX_PTR; \
|
|
__tmp__usrt__buff__.Length = \
|
|
__tmp__usrt__buff__.MaximumLength = strlen(PRINT_PREFIX_PTR); \
|
|
NtDisplayString(&__tmp__usrt__buff__); \
|
|
};
|
|
#define KdPrint(_x_) DbgPrint _x_
|
|
*/
|
|
#endif // SCSI_PORT_DBG_PRINT
|
|
|
|
//#define AtapiStallExecution(dt) { KdPrint2((" AtapiStallExecution(%d)\n", dt)); ScsiPortStallExecution(dt); }
|
|
#define AtapiStallExecution(dt) { ScsiPortStallExecution(dt); }
|
|
|
|
#endif // _DBGNT_
|
|
|
|
#else // _DEBUG
|
|
|
|
#ifdef KdPrint
|
|
#undef KdPrint
|
|
#endif
|
|
|
|
#define PRINT_PREFIX "UniATA: "
|
|
|
|
//#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
|
|
#define KdPrint3(_x_) {;}
|
|
#define KdPrint2(_x_) {;}
|
|
#define KdPrint(_x_) {;}
|
|
#define Connect_DbgPrint() {;}
|
|
|
|
#define AtapiStallExecution(dt) ScsiPortStallExecution(dt)
|
|
|
|
#endif // _DEBUG
|
|
|
|
// IDE register definition
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
typedef union _IDE_REGISTERS_1 {
|
|
struct _o {
|
|
UCHAR Data;
|
|
UCHAR Feature;
|
|
UCHAR BlockCount;
|
|
UCHAR BlockNumber;
|
|
UCHAR CylinderLow;
|
|
UCHAR CylinderHigh;
|
|
UCHAR DriveSelect;
|
|
UCHAR Command;
|
|
} o;
|
|
|
|
struct _i {
|
|
UCHAR Data;
|
|
UCHAR Error;
|
|
UCHAR BlockCount;
|
|
UCHAR BlockNumber;
|
|
UCHAR CylinderLow;
|
|
UCHAR CylinderHigh;
|
|
UCHAR DriveSelect;
|
|
UCHAR Status;
|
|
} i;
|
|
|
|
} IDE_REGISTERS_1, *PIDE_REGISTERS_1;
|
|
|
|
#define IDX_IO1 0
|
|
#define IDX_IO1_SZ sizeof(IDE_REGISTERS_1)
|
|
|
|
#define IDX_IO1 0
|
|
#define IDX_IO1_SZ sizeof(IDE_REGISTERS_1)
|
|
#define IDX_IO1_i_Data (FIELD_OFFSET(IDE_REGISTERS_1, i.Data )+IDX_IO1)
|
|
#define IDX_IO1_i_Error (FIELD_OFFSET(IDE_REGISTERS_1, i.Error )+IDX_IO1)
|
|
#define IDX_IO1_i_BlockCount (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockCount )+IDX_IO1)
|
|
#define IDX_IO1_i_BlockNumber (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockNumber )+IDX_IO1)
|
|
#define IDX_IO1_i_CylinderLow (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderLow )+IDX_IO1)
|
|
#define IDX_IO1_i_CylinderHigh (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderHigh)+IDX_IO1)
|
|
#define IDX_IO1_i_DriveSelect (FIELD_OFFSET(IDE_REGISTERS_1, i.DriveSelect )+IDX_IO1)
|
|
#define IDX_IO1_i_Status (FIELD_OFFSET(IDE_REGISTERS_1, i.Status )+IDX_IO1)
|
|
|
|
#define IDX_IO1_o IDX_IO1_SZ
|
|
#define IDX_IO1_o_SZ sizeof(IDE_REGISTERS_1)
|
|
|
|
#define IDX_IO1_o_Data (FIELD_OFFSET(IDE_REGISTERS_1, o.Data )+IDX_IO1_o)
|
|
#define IDX_IO1_o_Feature (FIELD_OFFSET(IDE_REGISTERS_1, o.Feature )+IDX_IO1_o)
|
|
#define IDX_IO1_o_BlockCount (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockCount )+IDX_IO1_o)
|
|
#define IDX_IO1_o_BlockNumber (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockNumber )+IDX_IO1_o)
|
|
#define IDX_IO1_o_CylinderLow (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderLow )+IDX_IO1_o)
|
|
#define IDX_IO1_o_CylinderHigh (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderHigh)+IDX_IO1_o)
|
|
#define IDX_IO1_o_DriveSelect (FIELD_OFFSET(IDE_REGISTERS_1, o.DriveSelect )+IDX_IO1_o)
|
|
#define IDX_IO1_o_Command (FIELD_OFFSET(IDE_REGISTERS_1, o.Command )+IDX_IO1_o)
|
|
|
|
typedef union _IDE_REGISTERS_2 {
|
|
UCHAR AltStatus;
|
|
UCHAR Control;
|
|
} IDE_REGISTERS_2, *PIDE_REGISTERS_2;
|
|
|
|
#define IDX_IO2 (IDX_IO1_o+IDX_IO1_o_SZ)
|
|
#define IDX_IO2_SZ sizeof(IDE_REGISTERS_2)
|
|
|
|
#define IDX_IO2_AltStatus (FIELD_OFFSET(IDE_REGISTERS_2, AltStatus )+IDX_IO2)
|
|
//#define IDX_IO2_DriveAddress (FIELD_OFFSET(IDE_REGISTERS_2, DriveAddress)+IDX_IO2)
|
|
|
|
#define IDX_IO2_o (IDX_IO2+IDX_IO2_SZ)
|
|
#define IDX_IO2_o_SZ sizeof(IDE_REGISTERS_2)
|
|
|
|
#define IDX_IO2_o_Control (FIELD_OFFSET(IDE_REGISTERS_2, Control)+IDX_IO2_o)
|
|
//
|
|
// Device Extension Device Flags
|
|
//
|
|
|
|
#define DFLAGS_DEVICE_PRESENT 0x0001 // Indicates that some device is present.
|
|
#define DFLAGS_ATAPI_DEVICE 0x0002 // Indicates whether ATAPI commands can be used.
|
|
#define DFLAGS_TAPE_DEVICE 0x0004 // Indicates whether this is a tape device.
|
|
#define DFLAGS_INT_DRQ 0x0008 // Indicates whether device interrupts as DRQ is set after
|
|
// receiving ATAPI Packet Command
|
|
#define DFLAGS_REMOVABLE_DRIVE 0x0010 // Indicates that the drive has the 'removable' bit set in
|
|
// identify data (offset 128)
|
|
#define DFLAGS_MEDIA_STATUS_ENABLED 0x0020 // Media status notification enabled
|
|
#define DFLAGS_ATAPI_CHANGER 0x0040 // Indicates atapi 2.5 changer present.
|
|
#define DFLAGS_SANYO_ATAPI_CHANGER 0x0080 // Indicates multi-platter device, not conforming to the 2.5 spec.
|
|
#define DFLAGS_CHANGER_INITED 0x0100 // Indicates that the init path for changers has already been done.
|
|
#define DFLAGS_LBA_ENABLED 0x0200 // Indicates that we should use LBA addressing rather than CHS
|
|
#define DFLAGS_DWORDIO_ENABLED 0x0400 // Indicates that we should use 32-bit IO
|
|
#define DFLAGS_WCACHE_ENABLED 0x0800 // Indicates that we use write cache
|
|
#define DFLAGS_RCACHE_ENABLED 0x1000 // Indicates that we use read cache
|
|
#define DFLAGS_ORIG_GEOMETRY 0x2000 //
|
|
#define DFLAGS_REINIT_DMA 0x4000 //
|
|
#define DFLAGS_HIDDEN 0x8000 // Hidden device, available only with special IOCTLs
|
|
// via communication virtual device
|
|
#define DFLAGS_MANUAL_CHS 0x10000 // For devices those have no IDENTIFY commands
|
|
#define DFLAGS_LBA32plus 0x20000 // Device is larger than LBA32
|
|
//#define DFLAGS_ 0x10000 //
|
|
//
|
|
// Used to disable 'advanced' features.
|
|
//
|
|
|
|
#define MAX_ERRORS 4
|
|
|
|
//
|
|
// ATAPI command definitions
|
|
//
|
|
|
|
#define ATAPI_MODE_SENSE 0x5A
|
|
#define ATAPI_MODE_SELECT 0x55
|
|
#define ATAPI_FORMAT_UNIT 0x24
|
|
|
|
// ATAPI Command Descriptor Block
|
|
|
|
typedef struct _MODE_SENSE_10 {
|
|
UCHAR OperationCode;
|
|
UCHAR Reserved1;
|
|
UCHAR PageCode : 6;
|
|
UCHAR Pc : 2;
|
|
UCHAR Reserved2[4];
|
|
UCHAR ParameterListLengthMsb;
|
|
UCHAR ParameterListLengthLsb;
|
|
UCHAR Reserved3[3];
|
|
} MODE_SENSE_10, *PMODE_SENSE_10;
|
|
|
|
typedef struct _MODE_SELECT_10 {
|
|
UCHAR OperationCode;
|
|
UCHAR Reserved1 : 4;
|
|
UCHAR PFBit : 1;
|
|
UCHAR Reserved2 : 3;
|
|
UCHAR Reserved3[5];
|
|
UCHAR ParameterListLengthMsb;
|
|
UCHAR ParameterListLengthLsb;
|
|
UCHAR Reserved4[3];
|
|
} MODE_SELECT_10, *PMODE_SELECT_10;
|
|
|
|
typedef struct _MODE_PARAMETER_HEADER_10 {
|
|
UCHAR ModeDataLengthMsb;
|
|
UCHAR ModeDataLengthLsb;
|
|
UCHAR MediumType;
|
|
UCHAR Reserved[5];
|
|
}MODE_PARAMETER_HEADER_10, *PMODE_PARAMETER_HEADER_10;
|
|
|
|
//
|
|
// values for TransferMode
|
|
//
|
|
#define ATA_PIO 0x00
|
|
#define ATA_PIO_NRDY 0x01
|
|
|
|
#define ATA_PIO0 0x08
|
|
#define ATA_PIO1 0x09
|
|
#define ATA_PIO2 0x0a
|
|
#define ATA_PIO3 0x0b
|
|
#define ATA_PIO4 0x0c
|
|
#define ATA_PIO5 0x0d
|
|
|
|
#define ATA_DMA 0x10
|
|
#define ATA_SDMA 0x10
|
|
#define ATA_SDMA0 0x10
|
|
#define ATA_SDMA1 0x11
|
|
#define ATA_SDMA2 0x12
|
|
|
|
#define ATA_WDMA 0x20
|
|
#define ATA_WDMA0 0x20
|
|
#define ATA_WDMA1 0x21
|
|
#define ATA_WDMA2 0x22
|
|
|
|
#define ATA_UDMA 0x40
|
|
#define ATA_UDMA0 0x40 // ATA-16
|
|
#define ATA_UDMA1 0x41 // ATA-25
|
|
#define ATA_UDMA2 0x42 // ATA-33
|
|
#define ATA_UDMA3 0x43 // ATA-44
|
|
#define ATA_UDMA4 0x44 // ATA-66
|
|
#define ATA_UDMA5 0x45 // ATA-100
|
|
#define ATA_UDMA6 0x46 // ATA-133
|
|
//#define ATA_UDMA7 0x47 // ATA-166
|
|
|
|
#define ATA_SA150 0x47 /*0x80*/
|
|
#define ATA_SA300 0x48 /*0x81*/
|
|
#define ATA_SA600 0x49 /*0x82*/
|
|
|
|
#define ATA_MODE_NOT_SPEC ((ULONG)(-1)) /*0x82*/
|
|
|
|
//
|
|
// IDE command definitions
|
|
//
|
|
|
|
#define IDE_COMMAND_DATA_SET_MGMT 0x06 // TRIM
|
|
#define IDE_COMMAND_ATAPI_RESET 0x08
|
|
#define IDE_COMMAND_RECALIBRATE 0x10
|
|
#define IDE_COMMAND_READ 0x20
|
|
#define IDE_COMMAND_READ_NO_RETR 0x21
|
|
#define IDE_COMMAND_READ48 0x24
|
|
#define IDE_COMMAND_READ_DMA48 0x25
|
|
#define IDE_COMMAND_READ_DMA_Q48 0x26
|
|
#define IDE_COMMAND_READ_NATIVE_SIZE48 0x27
|
|
#define IDE_COMMAND_READ_MUL48 0x29
|
|
#define IDE_COMMAND_READ_STREAM_DMA48 0x2A
|
|
#define IDE_COMMAND_READ_STREAM48 0x2B
|
|
#define IDE_COMMAND_READ_LOG48 0x2f
|
|
#define IDE_COMMAND_WRITE 0x30
|
|
#define IDE_COMMAND_WRITE_NO_RETR 0x31
|
|
#define IDE_COMMAND_WRITE48 0x34
|
|
#define IDE_COMMAND_WRITE_DMA48 0x35
|
|
#define IDE_COMMAND_WRITE_DMA_Q48 0x36
|
|
#define IDE_COMMAND_SET_NATIVE_SIZE48 0x37
|
|
#define IDE_COMMAND_WRITE_MUL48 0x39
|
|
#define IDE_COMMAND_WRITE_STREAM_DMA48 0x3a
|
|
#define IDE_COMMAND_WRITE_STREAM48 0x3b
|
|
#define IDE_COMMAND_WRITE_FUA_DMA48 0x3d
|
|
#define IDE_COMMAND_WRITE_FUA_DMA_Q48 0x3e
|
|
#define IDE_COMMAND_WRITE_LOG48 0x3f
|
|
#define IDE_COMMAND_VERIFY 0x40
|
|
#define IDE_COMMAND_VERIFY48 0x42
|
|
#define IDE_COMMAND_READ_LOG_DMA48 0x47
|
|
#define IDE_COMMAND_WRITE_LOG_DMA48 0x57
|
|
#define IDE_COMMAND_TRUSTED_RCV 0x5c
|
|
#define IDE_COMMAND_TRUSTED_RCV_DMA 0x5d
|
|
#define IDE_COMMAND_TRUSTED_SEND 0x5e
|
|
#define IDE_COMMAND_TRUSTED_SEND_DMA 0x5f
|
|
#define IDE_COMMAND_SEEK 0x70
|
|
#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_Q 0xC7
|
|
#define IDE_COMMAND_READ_DMA 0xC8
|
|
#define IDE_COMMAND_WRITE_DMA 0xCA
|
|
#define IDE_COMMAND_WRITE_DMA_Q 0xCC
|
|
#define IDE_COMMAND_WRITE_MUL_FUA48 0xCE
|
|
#define IDE_COMMAND_GET_MEDIA_STATUS 0xDA
|
|
#define IDE_COMMAND_DOOR_LOCK 0xDE
|
|
#define IDE_COMMAND_DOOR_UNLOCK 0xDF
|
|
#define IDE_COMMAND_STANDBY_IMMED 0xE0 // flush and spin down
|
|
#define IDE_COMMAND_IDLE_IMMED 0xE1
|
|
#define IDE_COMMAND_STANDBY 0xE2 // flush and spin down and enable autopowerdown timer
|
|
#define IDE_COMMAND_IDLE 0xE3
|
|
#define IDE_COMMAND_READ_PM 0xE4 // SATA PM
|
|
#define IDE_COMMAND_SLEEP 0xE6 // flush, spin down and deactivate interface
|
|
#define IDE_COMMAND_FLUSH_CACHE 0xE7
|
|
#define IDE_COMMAND_WRITE_PM 0xE8 // SATA PM
|
|
#define IDE_COMMAND_IDENTIFY 0xEC
|
|
#define IDE_COMMAND_MEDIA_EJECT 0xED
|
|
#define IDE_COMMAND_FLUSH_CACHE48 0xEA
|
|
#define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF
|
|
#define IDE_COMMAND_SET_FEATURES 0xEF /* features command,
|
|
IDE_COMMAND_ENABLE_MEDIA_STATUS */
|
|
#define IDE_COMMAND_READ_NATIVE_SIZE 0xF8
|
|
#define IDE_COMMAND_SET_NATIVE_SIZE 0xF9
|
|
|
|
#define SCSIOP_ATA_PASSTHROUGH 0xCC //
|
|
|
|
//
|
|
// IDE status definitions
|
|
//
|
|
|
|
#define IDE_STATUS_SUCCESS 0x00
|
|
#define IDE_STATUS_ERROR 0x01
|
|
#define IDE_STATUS_INDEX 0x02
|
|
#define IDE_STATUS_CORRECTED_ERROR 0x04
|
|
#define IDE_STATUS_DRQ 0x08
|
|
#define IDE_STATUS_DSC 0x10
|
|
//#define IDE_STATUS_DWF 0x10 /* drive write fault */
|
|
#define IDE_STATUS_DMA 0x20 /* DMA ready */
|
|
#define IDE_STATUS_DWF 0x20 /* drive write fault */
|
|
#define IDE_STATUS_DRDY 0x40
|
|
#define IDE_STATUS_IDLE 0x50
|
|
#define IDE_STATUS_BUSY 0x80
|
|
|
|
#define IDE_STATUS_WRONG 0xff
|
|
#define IDE_STATUS_MASK 0xff
|
|
|
|
|
|
//
|
|
// IDE drive select/head definitions
|
|
//
|
|
|
|
#define IDE_DRIVE_SELECT 0xA0
|
|
#define IDE_DRIVE_1 0x00
|
|
#define IDE_DRIVE_2 0x10
|
|
#define IDE_DRIVE_SELECT_1 (IDE_DRIVE_SELECT | IDE_DRIVE_1)
|
|
#define IDE_DRIVE_SELECT_2 (IDE_DRIVE_SELECT | IDE_DRIVE_2)
|
|
#define IDE_DRIVE_MASK (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)
|
|
|
|
#define IDE_USE_LBA 0x40
|
|
|
|
//
|
|
// IDE drive control definitions
|
|
//
|
|
|
|
#define IDE_DC_DISABLE_INTERRUPTS 0x02
|
|
#define IDE_DC_RESET_CONTROLLER 0x04
|
|
#define IDE_DC_A_4BIT 0x80
|
|
#define IDE_DC_USE_HOB 0x80 // use high-order byte(s)
|
|
#define IDE_DC_REENABLE_CONTROLLER 0x00
|
|
|
|
// IDE error definitions
|
|
//
|
|
|
|
#define IDE_ERROR_ICRC 0x80
|
|
#define IDE_ERROR_BAD_BLOCK 0x80
|
|
#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_NO_MEDIA 0x02
|
|
#define IDE_ERROR_ILLEGAL_LENGTH 0x01
|
|
|
|
//
|
|
// ATAPI register definition
|
|
//
|
|
|
|
typedef union _ATAPI_REGISTERS_1 {
|
|
struct _o {
|
|
UCHAR Data;
|
|
UCHAR Feature;
|
|
UCHAR Unused0;
|
|
UCHAR Unused1;
|
|
UCHAR ByteCountLow;
|
|
UCHAR ByteCountHigh;
|
|
UCHAR DriveSelect;
|
|
UCHAR Command;
|
|
} o;
|
|
|
|
struct _i {
|
|
UCHAR Data;
|
|
UCHAR Error;
|
|
UCHAR InterruptReason;
|
|
UCHAR Unused1;
|
|
UCHAR ByteCountLow;
|
|
UCHAR ByteCountHigh;
|
|
UCHAR DriveSelect;
|
|
UCHAR Status;
|
|
} i;
|
|
|
|
//IDE_REGISTERS_1 ide;
|
|
|
|
} ATAPI_REGISTERS_1, *PATAPI_REGISTERS_1;
|
|
|
|
#define IDX_ATAPI_IO1 IDX_IO1
|
|
#define IDX_ATAPI_IO1_SZ sizeof(ATAPI_REGISTERS_1)
|
|
|
|
#define IDX_ATAPI_IO1_i_Data (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Data )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_Error (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Error )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_InterruptReason (FIELD_OFFSET(ATAPI_REGISTERS_1, i.InterruptReason)+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_Unused1 (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Unused1 )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_ByteCountLow (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountLow )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_ByteCountHigh (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountHigh )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_DriveSelect (FIELD_OFFSET(ATAPI_REGISTERS_1, i.DriveSelect )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_i_Status (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Status )+IDX_ATAPI_IO1)
|
|
|
|
#define IDX_ATAPI_IO1_o_Data (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Data )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_Feature (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Feature )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_Unused0 (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused0 )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_Unused1 (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused1 )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_ByteCountLow (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountLow )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_ByteCountHigh (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountHigh)+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_DriveSelect (FIELD_OFFSET(ATAPI_REGISTERS_1, o.DriveSelect )+IDX_ATAPI_IO1)
|
|
#define IDX_ATAPI_IO1_o_Command (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Command )+IDX_ATAPI_IO1)
|
|
|
|
/*
|
|
typedef union _ATAPI_REGISTERS_2 {
|
|
struct {
|
|
UCHAR AltStatus;
|
|
UCHAR DriveAddress;
|
|
};
|
|
|
|
//IDE_REGISTERS_2 ide;
|
|
|
|
} ATAPI_REGISTERS_2, *PATAPI_REGISTERS_2;
|
|
|
|
#define IDX_ATAPI_IO2 IDX_ATAPI_IO2_SZ
|
|
#define IDX_ATAPI_IO2_SZ sizeof(ATAPI_REGISTERS_2)
|
|
*/
|
|
|
|
//
|
|
// ATAPI interrupt reasons
|
|
//
|
|
|
|
// for IDX_ATAPI_IO1_i_InterruptReason
|
|
#define ATAPI_IR_COD 0x01
|
|
#define ATAPI_IR_COD_Data 0x0
|
|
#define ATAPI_IR_COD_Cmd 0x1
|
|
|
|
#define ATAPI_IR_IO 0x02
|
|
#define ATAPI_IR_IO_toDev 0x00
|
|
#define ATAPI_IR_IO_toHost 0x02
|
|
|
|
#define ATAPI_IR_Mask 0x03
|
|
|
|
//
|
|
// ATA Features
|
|
//
|
|
|
|
#define ATA_F_DMA 0x01 /* enable DMA */
|
|
#define ATA_F_OVL 0x02 /* enable overlap */
|
|
#define ATA_F_DMAREAD 0x04 /* DMA Packet (ATAPI) read */
|
|
|
|
#define ATA_C_F_SETXFER 0x03 /* set transfer mode */
|
|
|
|
#define ATA_C_F_ENAB_WCACHE 0x02 /* enable write cache */
|
|
#define ATA_C_F_DIS_WCACHE 0x82 /* disable write cache */
|
|
|
|
#define ATA_C_F_ENAB_RCACHE 0xaa /* enable readahead cache */
|
|
#define ATA_C_F_DIS_RCACHE 0x55 /* disable readahead cache */
|
|
|
|
#define ATA_C_F_ENAB_RELIRQ 0x5d /* enable release interrupt */
|
|
#define ATA_C_F_DIS_RELIRQ 0xdd /* disable release interrupt */
|
|
|
|
#define ATA_C_F_ENAB_SRVIRQ 0x5e /* enable service interrupt */
|
|
#define ATA_C_F_DIS_SRVIRQ 0xde /* disable service interrupt */
|
|
|
|
#define ATA_C_F_ENAB_MEDIASTAT 0x95 /* enable media status */
|
|
#define ATA_C_F_DIS_MEDIASTAT 0x31 /* disable media status */
|
|
|
|
#define ATA_C_F_ENAB_APM 0x05 /* enable advanced power management */
|
|
#define ATA_C_F_DIS_APM 0x85 /* disable advanced power management */
|
|
#define ATA_C_F_APM_CNT_MAX_PERF 0xfe /* maximum performance */
|
|
#define ATA_C_F_APM_CNT_MIN_NO_STANDBY 0x80 /* min. power w/o standby */
|
|
#define ATA_C_F_APM_CNT_MIN_STANDBY 0x01 /* min. power with standby */
|
|
|
|
#define ATA_C_F_ENAB_ACOUSTIC 0x42 /* enable acoustic management */
|
|
#define ATA_C_F_DIS_ACOUSTIC 0xc2 /* disable acoustic management */
|
|
#define ATA_C_F_AAM_CNT_MAX_PERF 0xfe /* maximum performance */
|
|
#define ATA_C_F_AAM_CNT_MAX_POWER_SAVE 0x80 /* min. power */
|
|
|
|
// New SMART Feature definitions
|
|
#ifndef READ_LOG_SECTOR
|
|
#define READ_LOG_SECTOR 0xD5
|
|
#define WRITE_LOG_SECTOR 0xD6
|
|
#define WRITE_THRESHOLDS 0xD7
|
|
#define AUTO_OFFLINE 0xDB
|
|
#endif // READ_LOG_SECTOR
|
|
|
|
//
|
|
// ATAPI interrupt reasons
|
|
//
|
|
|
|
#define ATA_I_CMD 0x01 /* cmd (1) | data (0) */
|
|
#define ATA_I_IN 0x02 /* read (1) | write (0) */
|
|
#define ATA_I_RELEASE 0x04 /* released bus (1) */
|
|
#define ATA_I_TAGMASK 0xf8 /* tag mask */
|
|
|
|
// IDENTIFY data
|
|
//
|
|
|
|
typedef struct _IDENTIFY_DATA {
|
|
UCHAR AtapiCmdSize:2; // 00 00
|
|
#define ATAPI_PSIZE_12 0 /* 12 bytes */
|
|
#define ATAPI_PSIZE_16 1 /* 16 bytes */
|
|
UCHAR :3;
|
|
UCHAR DrqType:2; // 00 00
|
|
#define ATAPI_DRQT_MPROC 0 /* cpu 3 ms delay */
|
|
#define ATAPI_DRQT_INTR 1 /* intr 10 ms delay */
|
|
#define ATAPI_DRQT_ACCEL 2 /* accel 50 us delay */
|
|
UCHAR Removable:1;
|
|
|
|
UCHAR DeviceType:5;
|
|
#define ATAPI_TYPE_DIRECT 0 /* disk/floppy */
|
|
#define ATAPI_TYPE_TAPE 1 /* streaming tape */
|
|
#define ATAPI_TYPE_CDROM 5 /* CD-ROM device */
|
|
#define ATAPI_TYPE_OPTICAL 7 /* optical disk */
|
|
UCHAR :1;
|
|
UCHAR CmdProtocol:2; // 00 00
|
|
#define ATAPI_PROTO_ATAPI 2
|
|
// USHORT GeneralConfiguration; // 00 00
|
|
|
|
USHORT NumberOfCylinders; // 02 1
|
|
USHORT Reserved1; // 04 2
|
|
USHORT NumberOfHeads; // 06 3
|
|
USHORT UnformattedBytesPerTrack; // 08 4 // Now obsolete
|
|
USHORT UnformattedBytesPerSector; // 0A 5 // Now obsolete
|
|
USHORT SectorsPerTrack; // 0C 6
|
|
|
|
USHORT VendorUnique1[3]; // 0E 7-9
|
|
UCHAR SerialNumber[20]; // 14 10-19
|
|
|
|
USHORT BufferType; // 28 20
|
|
#define ATA_BT_SINGLEPORTSECTOR 1 /* 1 port, 1 sector buffer */
|
|
#define ATA_BT_DUALPORTMULTI 2 /* 2 port, mult sector buffer */
|
|
#define ATA_BT_DUALPORTMULTICACHE 3 /* above plus track cache */
|
|
|
|
USHORT BufferSectorSize; // 2A 21
|
|
USHORT NumberOfEccBytes; // 2C 22
|
|
USHORT FirmwareRevision[4]; // 2E 23-26
|
|
USHORT ModelNumber[20]; // 36 27-46
|
|
UCHAR MaximumBlockTransfer; // 5E 47
|
|
UCHAR VendorUnique2; // 5F
|
|
|
|
USHORT DoubleWordIo; // 60 48
|
|
|
|
USHORT Reserved62_0:8; // 62 49
|
|
USHORT SupportDma:1;
|
|
USHORT SupportLba:1;
|
|
USHORT DisableIordy:1;
|
|
USHORT SupportIordy:1;
|
|
USHORT SoftReset:1;
|
|
USHORT StandbyOverlap:1;
|
|
USHORT SupportQTag:1; /* supports queuing overlap */
|
|
USHORT SupportIDma:1; /* interleaved DMA supported */
|
|
|
|
/* USHORT Capabilities; // 62 49
|
|
#define IDENTIFY_CAPABILITIES_SUPPORT_DMA 0x0100
|
|
#define IDENTIFY_CAPABILITIES_SUPPORT_LBA 0x0200
|
|
#define IDENTIFY_CAPABILITIES_DISABLE_IORDY 0x0400
|
|
#define IDENTIFY_CAPABILITIES_SUPPORT_IORDY 0x0800
|
|
#define IDENTIFY_CAPABILITIES_SOFT_RESET 0x1000
|
|
#define IDENTIFY_CAPABILITIES_STDBY_OVLP 0x2000
|
|
#define IDENTIFY_CAPABILITIES_SUPPORT_QTAG 0x4000
|
|
#define IDENTIFY_CAPABILITIES_SUPPORT_IDMA 0x8000*/
|
|
|
|
USHORT DeviceStandbyMin:1; // 64 50
|
|
USHORT Reserved50_1:13;
|
|
USHORT DeviceCapability1:1;
|
|
USHORT DeviceCapability0:1;
|
|
// USHORT Reserved2;
|
|
|
|
UCHAR Vendor51; // 66 51
|
|
UCHAR PioCycleTimingMode; // 67
|
|
|
|
UCHAR Vendor52; // 68 52
|
|
UCHAR DmaCycleTimingMode; // 69
|
|
|
|
USHORT TranslationFieldsValid:1; // 6A 53 /* 54-58 */
|
|
USHORT PioTimingsValid:1; /* 64-70 */
|
|
USHORT UdmaModesValid:1; /* 88 */
|
|
USHORT Reserved3:13;
|
|
|
|
USHORT NumberOfCurrentCylinders; // 6C 54 \-
|
|
USHORT NumberOfCurrentHeads; // 6E 55 \-
|
|
USHORT CurrentSectorsPerTrack; // 70 56 /- obsolete USHORT[5]
|
|
ULONG CurrentSectorCapacity; // 72 57-58 /-
|
|
|
|
USHORT CurrentMultiSector:8; // 59
|
|
USHORT CurrentMultiSectorValid:1;
|
|
USHORT Reserved59_9_11:3;
|
|
USHORT SanitizeSupported:1;
|
|
USHORT CryptoScrambleExtSupported:1;
|
|
USHORT OverwriteExtSupported:1;
|
|
USHORT BlockEraseExtSupported:1;
|
|
|
|
ULONG UserAddressableSectors; // 60-61
|
|
|
|
union {
|
|
struct {
|
|
USHORT SingleWordDMASupport : 8; // 62 ATA, obsolete
|
|
USHORT SingleWordDMAActive : 8; //
|
|
};
|
|
struct {
|
|
USHORT UDMASupport : 7; // 62 ATAPI
|
|
USHORT MultiWordDMASupport : 3;
|
|
USHORT DMASupport : 1;
|
|
USHORT Reseved62_11_14 : 4;
|
|
USHORT DMADirRequired : 1;
|
|
} AtapiDMA;
|
|
};
|
|
|
|
USHORT MultiWordDMASupport : 8; // 63
|
|
USHORT MultiWordDMAActive : 8;
|
|
|
|
USHORT AdvancedPIOModes : 8; // 64
|
|
USHORT Reserved4 : 8;
|
|
|
|
#define AdvancedPIOModes_3 1
|
|
#define AdvancedPIOModes_4 2
|
|
#define AdvancedPIOModes_5 4 // non-standard
|
|
|
|
USHORT MinimumMWXferCycleTime; // 65
|
|
USHORT RecommendedMWXferCycleTime; // 66
|
|
USHORT MinimumPIOCycleTime; // 67
|
|
USHORT MinimumPIOCycleTimeIORDY; // 68
|
|
|
|
USHORT Reserved69_0_4:5; // 69
|
|
USHORT ReadZeroAfterTrim:1;
|
|
USHORT Lba28Support:1;
|
|
USHORT Reserved69_7_IEEE1667:1;
|
|
USHORT MicrocodeDownloadDMA:1;
|
|
USHORT MaxPwdDMA:1;
|
|
USHORT WriteBufferDMA:1;
|
|
USHORT ReadBufferDMA:1;
|
|
USHORT DevConfigDMA:1;
|
|
USHORT LongSectorErrorReporting:1;
|
|
USHORT DeterministicReadAfterTrim:1;
|
|
USHORT CFastSupport:1;
|
|
|
|
USHORT Reserved70; // 70
|
|
USHORT ReleaseTimeOverlapped; // 71
|
|
USHORT ReleaseTimeServiceCommand; // 72
|
|
USHORT Reserved73_74[2]; // 73-74
|
|
|
|
USHORT QueueLength : 5; // 75
|
|
USHORT Reserved75_6 : 11;
|
|
|
|
USHORT SataCapabilities; // 76
|
|
#define ATA_SATA_GEN1 0x0002
|
|
#define ATA_SATA_GEN2 0x0004
|
|
#define ATA_SATA_GEN3 0x0008
|
|
#define ATA_SUPPORT_NCQ 0x0100
|
|
#define ATA_SUPPORT_IFPWRMNGTRCV 0x0200
|
|
#define ATA_SUPPORT_PHY_EVENT_COUNTER 0x0400
|
|
#define ATA_SUPPORT_NCQ_UNLOAD 0x0800
|
|
#define ATA_SUPPORT_NCQ_PRI_INFO 0x1000
|
|
|
|
USHORT Reserved77; // 77
|
|
|
|
USHORT SataSupport; // 78
|
|
#define ATA_SUPPORT_NONZERO 0x0002
|
|
#define ATA_SUPPORT_AUTOACTIVATE 0x0004
|
|
#define ATA_SUPPORT_IFPWRMNGT 0x0008
|
|
#define ATA_SUPPORT_INORDERDATA 0x0010
|
|
|
|
USHORT SataEnable; // 79
|
|
USHORT MajorRevision; // 80
|
|
USHORT MinorRevision; // 81
|
|
|
|
#define ATA_VER_MJ_ATA4 0x0010
|
|
#define ATA_VER_MJ_ATA5 0x0020
|
|
#define ATA_VER_MJ_ATA6 0x0040
|
|
#define ATA_VER_MJ_ATA7 0x0080
|
|
#define ATA_VER_MJ_ATA8_ASC 0x0100
|
|
|
|
struct {
|
|
USHORT Smart:1; // 82/85
|
|
USHORT Security:1;
|
|
USHORT Removable:1;
|
|
USHORT PowerMngt:1;
|
|
USHORT Packet:1;
|
|
USHORT WriteCache:1;
|
|
USHORT LookAhead:1;
|
|
USHORT ReleaseDRQ:1;
|
|
USHORT ServiceDRQ:1;
|
|
USHORT Reset:1;
|
|
USHORT Protected:1;
|
|
USHORT Reserved_82_11:1;
|
|
USHORT WriteBuffer:1;
|
|
USHORT ReadBuffer:1;
|
|
USHORT Nop:1;
|
|
USHORT Reserved_82_15:1;
|
|
|
|
USHORT Microcode:1; // 83/86
|
|
USHORT Queued:1; //
|
|
USHORT CFA:1; //
|
|
USHORT APM:1; //
|
|
USHORT Notify:1; //
|
|
USHORT Standby:1; //
|
|
USHORT Spinup:1; //
|
|
USHORT Reserver_83_7:1;
|
|
USHORT MaxSecurity:1; //
|
|
USHORT AutoAcoustic:1; //
|
|
USHORT Address48:1; //
|
|
USHORT ConfigOverlay:1; //
|
|
USHORT FlushCache:1; //
|
|
USHORT FlushCache48:1; //
|
|
USHORT SupportOne:1; //
|
|
USHORT SupportZero:1; //
|
|
|
|
USHORT SmartErrorLog:1; // 84/87
|
|
USHORT SmartSelfTest:1;
|
|
USHORT MediaSerialNo:1;
|
|
USHORT MediaCardPass:1;
|
|
USHORT Streaming:1;
|
|
USHORT Logging:1;
|
|
USHORT Reserver_84_6:8;
|
|
USHORT ExtendedOne:1; //
|
|
USHORT ExtendedZero:1; //
|
|
} FeaturesSupport, FeaturesEnabled;
|
|
|
|
USHORT UltraDMASupport : 8; // 88
|
|
USHORT UltraDMAActive : 8;
|
|
|
|
USHORT EraseTime; // 89
|
|
USHORT EnhancedEraseTime; // 90
|
|
USHORT CurentAPMLevel; // 91
|
|
|
|
USHORT MasterPasswdRevision; // 92
|
|
|
|
USHORT HwResMaster : 8; // 93
|
|
USHORT HwResSlave : 5;
|
|
USHORT HwResCableId : 1;
|
|
USHORT HwResValid : 2;
|
|
|
|
#define IDENTIFY_CABLE_ID_VALID 0x01
|
|
|
|
USHORT CurrentAcoustic : 8; // 94
|
|
USHORT VendorAcoustic : 8;
|
|
|
|
USHORT StreamMinReqSize; // 95
|
|
USHORT StreamTransferTime; // 96
|
|
USHORT StreamAccessLatency; // 97
|
|
ULONG StreamGranularity; // 98-99
|
|
|
|
ULONGLONG UserAddressableSectors48; // 100-103
|
|
|
|
USHORT StreamingTransferTimePIO; // 104
|
|
USHORT MaxLBARangeDescBlockCount; // 105 // in 512b blocks
|
|
union {
|
|
USHORT PhysLogSectorSize; // 106
|
|
struct {
|
|
USHORT PLSS_Size:4;
|
|
USHORT PLSS_Reserved:8;
|
|
USHORT PLSS_LargeL:1; // =1 if 117-118 are valid
|
|
USHORT PLSS_LargeP:1;
|
|
USHORT PLSS_Signature:2; // = 0x01 = 01b
|
|
};
|
|
};
|
|
USHORT InterSeekDelay; // 107
|
|
USHORT WorldWideName[4]; // 108-111
|
|
USHORT Reserved112[5]; // 112-116
|
|
|
|
ULONG LargeSectorSize; // 117-118
|
|
|
|
struct {
|
|
USHORT Reserved;
|
|
} CommandFeatureSetSupport, CommandFeatureSetEnabled; // 119-120
|
|
USHORT Reserved121[4]; // 121-124
|
|
USHORT AtapiByteCount0; // 125
|
|
USHORT Reserved126; // 126
|
|
|
|
USHORT RemovableStatus; // 127
|
|
union {
|
|
USHORT SecurityStatus; // 128
|
|
struct {
|
|
USHORT Support:1;
|
|
USHORT Enabled:1;
|
|
USHORT Locked:1;
|
|
USHORT Frozen:1;
|
|
USHORT CountExpired:1;
|
|
USHORT EnhancedEraseSupport:1;
|
|
USHORT Reserved7_8:2;
|
|
USHORT MasterPasswdCap:1; // 0 - high, 1 - max
|
|
USHORT Reserved9_15:7;
|
|
} SecurityStatusOpt;
|
|
};
|
|
|
|
USHORT Reserved129[31]; // 129-159
|
|
USHORT CfAdvPowerMode; // 160
|
|
USHORT Reserved161[7]; // 161-167
|
|
USHORT DeviceNominalFormFactor:4; // 168
|
|
USHORT Reserved168_4_15:12;
|
|
USHORT DataSetManagementSupported:1; // 169
|
|
USHORT Reserved169_1_15:15;
|
|
USHORT AdditionalProdNum[4]; // 170-173
|
|
USHORT Reserved174[2]; // 174-175
|
|
USHORT MediaSerial[30]; // 176-205
|
|
union {
|
|
USHORT SCT; // 206
|
|
struct {
|
|
USHORT SCT_Supported:1;
|
|
USHORT Reserved:1;
|
|
USHORT SCT_WriteSame:1;
|
|
USHORT SCT_ErrorRecovery:1;
|
|
USHORT SCT_Feature:1;
|
|
USHORT SCT_DataTables:1;
|
|
USHORT Reserved_6_15:10;
|
|
};
|
|
};
|
|
USHORT Reserved_CE_ATA[2]; // 207-208
|
|
USHORT LogicalSectorOffset:14; // 209
|
|
USHORT Reserved209_14_One:1;
|
|
USHORT Reserved209_15_Zero:1;
|
|
|
|
USHORT WriteReadVerify_CountMode2[2]; // 210-211
|
|
USHORT WriteReadVerify_CountMode3[2]; // 212-213
|
|
|
|
USHORT NVCache_PM_Supported:1; // 214
|
|
USHORT NVCache_PM_Enabled:1;
|
|
USHORT NVCache_Reserved_2_3:2;
|
|
USHORT NVCache_Enabled:1;
|
|
USHORT NVCache_Reserved_5_7:3;
|
|
USHORT NVCache_PM_Version:4;
|
|
USHORT NVCache_Version:4;
|
|
|
|
USHORT NVCache_Size_LogicalBlocks[2]; // 215-216
|
|
USHORT NominalMediaRotationRate; // 217
|
|
USHORT Reserved218; // 218
|
|
USHORT NVCache_DeviceSpinUpTime:8; // 219
|
|
USHORT NVCache_Reserved219_8_15:8;
|
|
|
|
USHORT WriteReadVerify_CurrentMode:8; // 220
|
|
USHORT WriteReadVerify_Reserved220_8_15:8;
|
|
|
|
USHORT Reserved221; // 221
|
|
union {
|
|
struct {
|
|
USHORT VersionFlags:12;
|
|
USHORT TransportType:4;
|
|
};
|
|
struct {
|
|
USHORT ATA8_APT:1;
|
|
USHORT ATA_ATAPI7:1;
|
|
USHORT Reserved:14;
|
|
} PATA;
|
|
struct {
|
|
USHORT ATA8_AST:1;
|
|
USHORT v10a:1;
|
|
USHORT II_Ext:1;
|
|
USHORT v25:1;
|
|
USHORT v26:1;
|
|
USHORT v30:1;
|
|
USHORT Reserved:10;
|
|
} SATA;
|
|
USHORT Flags;
|
|
} TransportMajor;
|
|
USHORT TransportMinor; // 223
|
|
|
|
USHORT Reserved224[10]; // 224-233
|
|
|
|
USHORT MinBlocks_MicrocodeDownload_Mode3; // 234
|
|
USHORT MaxBlocks_MicrocodeDownload_Mode3; // 235
|
|
|
|
USHORT Reserved236[19]; // 236-254
|
|
|
|
union {
|
|
USHORT Integrity; // 255
|
|
struct {
|
|
#define ATA_ChecksumValid 0xA5
|
|
USHORT ChecksumValid:8;
|
|
USHORT Checksum:8;
|
|
};
|
|
};
|
|
} IDENTIFY_DATA, *PIDENTIFY_DATA;
|
|
|
|
//
|
|
// Identify data without the Reserved4.
|
|
//
|
|
|
|
#define IDENTIFY_DATA2 IDENTIFY_DATA
|
|
#define PIDENTIFY_DATA2 PIDENTIFY_DATA
|
|
|
|
/*typedef struct _IDENTIFY_DATA2 {
|
|
UCHAR AtapiCmdSize:2; // 00 00
|
|
UCHAR :3;
|
|
UCHAR DrqType:2; // 00 00
|
|
UCHAR Removable:1;
|
|
|
|
UCHAR DeviceType:5;
|
|
UCHAR :1;
|
|
UCHAR CmdProtocol:2; // 00 00
|
|
// USHORT GeneralConfiguration; // 00
|
|
|
|
USHORT NumberOfCylinders; // 02
|
|
USHORT Reserved1; // 04
|
|
USHORT NumberOfHeads; // 06
|
|
USHORT UnformattedBytesPerTrack; // 08
|
|
USHORT UnformattedBytesPerSector; // 0A
|
|
USHORT SectorsPerTrack; // 0C
|
|
USHORT VendorUnique1[3]; // 0E
|
|
UCHAR SerialNumber[20]; // 14
|
|
USHORT BufferType; // 28
|
|
USHORT BufferSectorSize; // 2A
|
|
USHORT NumberOfEccBytes; // 2C
|
|
USHORT FirmwareRevision[4]; // 2E
|
|
USHORT ModelNumber[20]; // 36
|
|
UCHAR MaximumBlockTransfer; // 5E
|
|
UCHAR VendorUnique2; // 5F
|
|
USHORT DoubleWordIo; // 60
|
|
USHORT Capabilities; // 62
|
|
USHORT Reserved2; // 64
|
|
UCHAR VendorUnique3; // 66
|
|
UCHAR PioCycleTimingMode; // 67
|
|
UCHAR VendorUnique4; // 68
|
|
UCHAR DmaCycleTimingMode; // 69
|
|
USHORT TranslationFieldsValid:1; // 6A
|
|
USHORT Reserved3:15;
|
|
USHORT NumberOfCurrentCylinders; // 6C
|
|
USHORT NumberOfCurrentHeads; // 6E
|
|
USHORT CurrentSectorsPerTrack; // 70
|
|
ULONG CurrentSectorCapacity; // 72
|
|
} IDENTIFY_DATA2, *PIDENTIFY_DATA2;*/
|
|
|
|
#define IDENTIFY_DATA_SIZE sizeof(IDENTIFY_DATA)
|
|
|
|
|
|
// IDENTIFY DMA timing cycle modes.
|
|
#define IDENTIFY_DMA_CYCLES_MODE_0 0x00
|
|
#define IDENTIFY_DMA_CYCLES_MODE_1 0x01
|
|
#define IDENTIFY_DMA_CYCLES_MODE_2 0x02
|
|
|
|
// for IDE_COMMAND_DATA_SET_MGMT
|
|
typedef struct _TRIM_DATA {
|
|
ULONGLONG Lba:48;
|
|
ULONGLONG BlockCount:16;
|
|
} TRIM_DATA, *PTRIM_DATA;
|
|
|
|
/*
|
|
#define PCI_DEV_HW_SPEC(idhi, idlo) \
|
|
{ #idlo, 4, #idhi, 4}
|
|
|
|
typedef struct _BROKEN_CONTROLLER_INFORMATION {
|
|
PCHAR VendorId;
|
|
ULONG VendorIdLength;
|
|
PCHAR DeviceId;
|
|
ULONG DeviceIdLength;
|
|
}BROKEN_CONTROLLER_INFORMATION, *PBROKEN_CONTROLLER_INFORMATION;
|
|
|
|
BROKEN_CONTROLLER_INFORMATION const BrokenAdapters[] = {
|
|
// CMD 640 ATA controller !WARNING! buggy chip data loss possible
|
|
PCI_DEV_HW_SPEC( 0640, 1095 ), //{ "1095", 4, "0640", 4},
|
|
// ??
|
|
PCI_DEV_HW_SPEC( 0601, 1039 ), //{ "1039", 4, "0601", 4}
|
|
// RZ 100? ATA controller !WARNING! buggy chip data loss possible
|
|
PCI_DEV_HW_SPEC( 1000, 1042 ),
|
|
PCI_DEV_HW_SPEC( 1001, 1042 )
|
|
};
|
|
|
|
#define BROKEN_ADAPTERS (sizeof(BrokenAdapters) / sizeof(BROKEN_CONTROLLER_INFORMATION))
|
|
|
|
typedef struct _NATIVE_MODE_CONTROLLER_INFORMATION {
|
|
PCHAR VendorId;
|
|
ULONG VendorIdLength;
|
|
PCHAR DeviceId;
|
|
ULONG DeviceIdLength;
|
|
}NATIVE_MODE_CONTROLLER_INFORMATION, *PNATIVE_MODE_CONTROLLER_INFORMATION;
|
|
|
|
NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = {
|
|
PCI_DEV_HW_SPEC( 0105, 10ad ) //{ "10ad", 4, "0105", 4}
|
|
};
|
|
|
|
#define NUM_NATIVE_MODE_ADAPTERS (sizeof(NativeModeAdapters) / sizeof(NATIVE_MODE_CONTROLLER_INFORMATION))
|
|
*/
|
|
//
|
|
// Beautification macros
|
|
//
|
|
|
|
#ifndef USER_MODE
|
|
|
|
#define GetStatus(chan, Status) \
|
|
Status = AtapiReadPort1(chan, IDX_IO2_AltStatus);
|
|
|
|
#define GetBaseStatus(chan, pStatus) \
|
|
pStatus = AtapiReadPort1(chan, IDX_IO1_i_Status);
|
|
|
|
#define WriteCommand(chan, _Command) \
|
|
AtapiWritePort1(chan, IDX_IO1_o_Command, _Command);
|
|
|
|
/*
|
|
#define SelectDrive(chan, unit) { \
|
|
if(chan && chan->lun[unit] && chan->lun[unit]->DeviceFlags & DFLAGS_ATAPI_CHANGER) KdPrint3((" Select %d\n", unit)); \
|
|
AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (unit) ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); \
|
|
}
|
|
*/
|
|
|
|
#define ReadBuffer(chan, Buffer, Count, timing) \
|
|
AtapiReadBuffer2(chan, IDX_IO1_i_Data, \
|
|
Buffer, \
|
|
Count, \
|
|
timing);
|
|
|
|
#define WriteBuffer(chan, Buffer, Count, timing) \
|
|
AtapiWriteBuffer2(chan, IDX_IO1_o_Data, \
|
|
Buffer, \
|
|
Count, \
|
|
timing);
|
|
|
|
#define ReadBuffer2(chan, Buffer, Count, timing) \
|
|
AtapiReadBuffer4(chan, IDX_IO1_i_Data, \
|
|
Buffer, \
|
|
Count, \
|
|
timing);
|
|
|
|
#define WriteBuffer2(chan, Buffer, Count, timing) \
|
|
AtapiWriteBuffer4(chan, IDX_IO1_o_Data, \
|
|
Buffer, \
|
|
Count, \
|
|
timing);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
SelectDrive(
|
|
IN struct _HW_CHANNEL* chan,
|
|
IN ULONG DeviceNumber
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
WaitOnBusy(
|
|
IN struct _HW_CHANNEL* chan/*,
|
|
PIDE_REGISTERS_2 BaseIoAddress*/
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
WaitOnBusyLong(
|
|
IN struct _HW_CHANNEL* chan/*,
|
|
PIDE_REGISTERS_2 BaseIoAddress*/
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
WaitOnBaseBusy(
|
|
IN struct _HW_CHANNEL* chan/*,
|
|
PIDE_REGISTERS_1 BaseIoAddress*/
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
WaitOnBaseBusyLong(
|
|
IN struct _HW_CHANNEL* chan/*,
|
|
PIDE_REGISTERS_1 BaseIoAddress*/
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
WaitForDrq(
|
|
IN struct _HW_CHANNEL* chan/*,
|
|
PIDE_REGISTERS_2 BaseIoAddress*/
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
WaitShortForDrq(
|
|
IN struct _HW_CHANNEL* chan/*,
|
|
PIDE_REGISTERS_2 BaseIoAddress*/
|
|
);
|
|
|
|
VOID
|
|
DDKFASTAPI
|
|
AtapiSoftReset(
|
|
IN struct _HW_CHANNEL* chan,/*
|
|
PIDE_REGISTERS_1 BaseIoAddress*/
|
|
IN ULONG DeviceNumber
|
|
);
|
|
|
|
VOID
|
|
DDKFASTAPI
|
|
AtapiHardReset(
|
|
IN struct _HW_CHANNEL* chan,
|
|
IN BOOLEAN DisableInterrupts,
|
|
IN ULONG Delay
|
|
);
|
|
|
|
|
|
#endif //USER_MODE
|
|
|
|
#define IS_RDP(OperationCode)\
|
|
((OperationCode == SCSIOP_ERASE)||\
|
|
(OperationCode == SCSIOP_LOAD_UNLOAD)||\
|
|
(OperationCode == SCSIOP_LOCATE)||\
|
|
(OperationCode == SCSIOP_REWIND) ||\
|
|
(OperationCode == SCSIOP_SPACE)||\
|
|
(OperationCode == SCSIOP_SEEK)||\
|
|
/* (OperationCode == SCSIOP_FORMAT_UNIT)||\
|
|
(OperationCode == SCSIOP_BLANK)||*/ \
|
|
(OperationCode == SCSIOP_WRITE_FILEMARKS))
|
|
|
|
#ifndef USER_MODE
|
|
|
|
PSCSI_REQUEST_BLOCK
|
|
NTAPI
|
|
BuildMechanismStatusSrb (
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb
|
|
);
|
|
|
|
PSCSI_REQUEST_BLOCK
|
|
NTAPI
|
|
BuildRequestSenseSrb (
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb
|
|
);
|
|
|
|
VOID
|
|
NTAPI
|
|
AtapiHwInitializeChanger (
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG TargetId,
|
|
IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
AtapiSendCommand(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb,
|
|
IN ULONG CmdAction
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
IdeSendCommand(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb,
|
|
IN ULONG CmdAction
|
|
);
|
|
|
|
#define AtapiCopyMemory RtlCopyMemory
|
|
|
|
VOID
|
|
NTAPI
|
|
AtapiHexToString (
|
|
ULONG Value,
|
|
PCHAR *Buffer
|
|
);
|
|
|
|
#define AtapiStringCmp(s1, s2, n) _strnicmp(s1, s2, n)
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
AtapiInterrupt(
|
|
IN PVOID HwDeviceExtension
|
|
);
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
AtapiInterrupt__(
|
|
IN PVOID HwDeviceExtension,
|
|
IN UCHAR c
|
|
);
|
|
|
|
UCHAR
|
|
NTAPI
|
|
AtapiCheckInterrupt__(
|
|
IN PVOID HwDeviceExtension,
|
|
IN UCHAR c
|
|
);
|
|
|
|
#define INTERRUPT_REASON_IGNORE 0
|
|
#define INTERRUPT_REASON_OUR 1
|
|
#define INTERRUPT_REASON_UNEXPECTED 2
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
AtapiHwInitialize(
|
|
IN PVOID HwDeviceExtension
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
IdeBuildSenseBuffer(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb
|
|
);
|
|
|
|
VOID
|
|
NTAPI
|
|
IdeMediaStatus(
|
|
BOOLEAN EnableMSN,
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG lChannel,
|
|
IN ULONG DeviceNumber
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
AtapiFindIsaController(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PVOID Context,
|
|
IN PVOID BusInformation,
|
|
IN PCHAR ArgumentString,
|
|
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
|
OUT PBOOLEAN Again
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
AtapiReadArgumentString(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PVOID Context,
|
|
IN PVOID BusInformation,
|
|
IN PCHAR ArgumentString,
|
|
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
|
OUT PBOOLEAN Again
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
AtapiParseArgumentString(
|
|
IN PCCH String,
|
|
IN PCCH KeyWord
|
|
);
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
IssueIdentify(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG DeviceNumber,
|
|
IN ULONG Channel,
|
|
IN UCHAR Command,
|
|
IN BOOLEAN NoSetup
|
|
);
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
SetDriveParameters(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG DeviceNumber,
|
|
IN ULONG Channel
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
CheckDevice(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG Channel,
|
|
IN ULONG deviceNumber,
|
|
IN BOOLEAN ResetBus
|
|
);
|
|
|
|
#define UNIATA_FIND_DEV_UNHIDE 0x01
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
FindDevices(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG Flags,
|
|
IN ULONG Channel
|
|
);
|
|
|
|
#endif //USER_MODE
|
|
|
|
#ifdef __cplusplus
|
|
};
|
|
#endif //__cplusplus
|
|
|
|
#ifndef USER_MODE
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
AtapiResetController(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG PathId
|
|
);
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
AtapiStartIo(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb
|
|
);
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
AtapiStartIo__(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PSCSI_REQUEST_BLOCK Srb,
|
|
IN BOOLEAN TopLevel
|
|
);
|
|
|
|
extern UCHAR
|
|
NTAPI
|
|
AtaCommand48(
|
|
// IN PVOID HwDeviceExtension,
|
|
IN struct _HW_DEVICE_EXTENSION* deviceExtension,
|
|
IN ULONG DeviceNumber,
|
|
IN ULONG Channel,
|
|
IN UCHAR command,
|
|
IN ULONGLONG lba,
|
|
IN USHORT count,
|
|
IN USHORT feature,
|
|
IN ULONG flags
|
|
);
|
|
|
|
extern UCHAR
|
|
NTAPI
|
|
AtaCommand(
|
|
// IN PVOID HwDeviceExtension,
|
|
IN struct _HW_DEVICE_EXTENSION* deviceExtension,
|
|
IN ULONG DeviceNumber,
|
|
IN ULONG Channel,
|
|
IN UCHAR command,
|
|
IN USHORT cylinder,
|
|
IN UCHAR head,
|
|
IN UCHAR sector,
|
|
IN UCHAR count,
|
|
IN UCHAR feature,
|
|
IN ULONG flags
|
|
);
|
|
|
|
extern LONG
|
|
NTAPI
|
|
AtaPioMode(PIDENTIFY_DATA2 ident);
|
|
|
|
extern LONG
|
|
NTAPI
|
|
AtaWmode(PIDENTIFY_DATA2 ident);
|
|
|
|
extern LONG
|
|
NTAPI
|
|
AtaUmode(PIDENTIFY_DATA2 ident);
|
|
|
|
extern VOID
|
|
NTAPI
|
|
AtapiDpcDispatch(
|
|
IN PKDPC Dpc,
|
|
IN PVOID DeferredContext,
|
|
IN PVOID SystemArgument1,
|
|
IN PVOID SystemArgument2
|
|
);
|
|
|
|
//#define AtaCommand(de, devn, chan, cmd, cyl, hd, sec, cnt, feat, flg)
|
|
|
|
extern LONG
|
|
NTAPI
|
|
AtaPio2Mode(LONG pio);
|
|
|
|
extern LONG
|
|
NTAPI
|
|
AtaPioMode(PIDENTIFY_DATA2 ident);
|
|
|
|
extern VOID
|
|
NTAPI
|
|
AtapiEnableInterrupts(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG c
|
|
);
|
|
|
|
extern VOID
|
|
NTAPI
|
|
AtapiDisableInterrupts(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG c
|
|
);
|
|
|
|
extern VOID
|
|
UniataExpectChannelInterrupt(
|
|
IN struct _HW_CHANNEL* chan,
|
|
IN BOOLEAN Expecting
|
|
);
|
|
|
|
#define CHAN_NOT_SPECIFIED (0xffffffffL)
|
|
#define CHAN_NOT_SPECIFIED_CHECK_CABLE (0xfffffffeL)
|
|
#define DEVNUM_NOT_SPECIFIED (0xffffffffL)
|
|
#define IOMODE_NOT_SPECIFIED (0xffffffffL)
|
|
|
|
extern ULONG
|
|
NTAPI
|
|
AtapiRegCheckDevValue(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG chan,
|
|
IN ULONG dev,
|
|
IN PCWSTR Name,
|
|
IN ULONG Default
|
|
);
|
|
|
|
extern ULONG
|
|
NTAPI
|
|
AtapiRegCheckParameterValue(
|
|
IN PVOID HwDeviceExtension,
|
|
IN PCWSTR PathSuffix,
|
|
IN PCWSTR Name,
|
|
IN ULONG Default
|
|
);
|
|
|
|
extern ULONG g_LogToDisplay;
|
|
|
|
extern "C"
|
|
VOID
|
|
_cdecl
|
|
_PrintNtConsole(
|
|
PCCH DebugMessage,
|
|
...
|
|
);
|
|
|
|
VOID
|
|
NTAPI
|
|
UniataInitMapBM(
|
|
IN struct _HW_DEVICE_EXTENSION* deviceExtension,
|
|
IN struct _IDE_BUSMASTER_REGISTERS* BaseIoAddressBM_0,
|
|
IN BOOLEAN MemIo
|
|
);
|
|
|
|
VOID
|
|
NTAPI
|
|
UniataInitMapBase(
|
|
IN struct _HW_CHANNEL* chan,
|
|
IN PIDE_REGISTERS_1 BaseIoAddress1,
|
|
IN PIDE_REGISTERS_2 BaseIoAddress2
|
|
);
|
|
|
|
VOID
|
|
NTAPI
|
|
UniataInitSyncBaseIO(
|
|
IN struct _HW_CHANNEL* chan
|
|
);
|
|
|
|
VOID
|
|
UniataInitIoRes(
|
|
IN struct _HW_CHANNEL* chan,
|
|
IN ULONG idx,
|
|
IN ULONG addr,
|
|
IN BOOLEAN MemIo,
|
|
IN BOOLEAN Proc
|
|
);
|
|
|
|
VOID
|
|
UniataInitIoResEx(
|
|
IN struct _IORES* IoRes,
|
|
IN ULONG addr,
|
|
IN BOOLEAN MemIo,
|
|
IN BOOLEAN Proc
|
|
);
|
|
|
|
UCHAR
|
|
DDKFASTAPI
|
|
UniataIsIdle(
|
|
IN struct _HW_DEVICE_EXTENSION* deviceExtension,
|
|
IN UCHAR Status
|
|
);
|
|
|
|
VOID
|
|
NTAPI
|
|
UniataDumpATARegs(
|
|
IN struct _HW_CHANNEL* chan
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
EncodeVendorStr(
|
|
OUT PWCHAR Buffer,
|
|
IN PUCHAR Str,
|
|
IN ULONG Length
|
|
);
|
|
|
|
ULONGLONG
|
|
NTAPI
|
|
UniAtaCalculateLBARegsBack(
|
|
struct _HW_LU_EXTENSION* LunExt,
|
|
ULONGLONG lba
|
|
);
|
|
|
|
ULONG
|
|
NTAPI
|
|
UniataAnybodyHome(
|
|
IN PVOID HwDeviceExtension,
|
|
IN ULONG Channel,
|
|
IN ULONG deviceNumber
|
|
);
|
|
|
|
#endif //USER_MODE
|
|
|
|
#define ATA_AT_HOME_HDD 0x01
|
|
#define ATA_AT_HOME_ATAPI 0x02
|
|
#define ATA_AT_HOME_XXX 0x04
|
|
#define ATA_AT_HOME_NOBODY 0x00
|
|
|
|
#define ATA_CMD_FLAG_LBAIOsupp 0x01
|
|
#define ATA_CMD_FLAG_48supp 0x02
|
|
#define ATA_CMD_FLAG_48 0x04
|
|
#define ATA_CMD_FLAG_DMA 0x08
|
|
#define ATA_CMD_FLAG_FUA 0x10
|
|
#define ATA_CMD_FLAG_In 0x40
|
|
#define ATA_CMD_FLAG_Out 0x80
|
|
|
|
/*
|
|
We need LBA48 when requested LBA or BlockCount are too large.
|
|
But for LBA-based commands we have *special* limitation
|
|
*/
|
|
#define UniAta_need_lba48(command, lba, count, supp48) \
|
|
( ((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) && (supp48) && (((lba+count) >= ATA_MAX_IOLBA28) || (count > 256)) ) || \
|
|
(lba > ATA_MAX_LBA28) || (count > 255) )
|
|
|
|
#ifndef USER_MODE
|
|
|
|
#define UniAtaClearAtaReq(AtaReq) \
|
|
{ \
|
|
RtlZeroMemory((PCHAR)(AtaReq), FIELD_OFFSET(ATA_REQ, ata)); \
|
|
}
|
|
|
|
extern UCHAR const AtaCommands48[256];
|
|
extern UCHAR const AtaCommandFlags[256];
|
|
|
|
//#define ATAPI_DEVICE(de, ldev) (de->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE)
|
|
#define ATAPI_DEVICE(chan, dev) ((chan->lun[dev]->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE)
|
|
|
|
#ifdef _DEBUG
|
|
#define PrintNtConsole _PrintNtConsole
|
|
#else //_DEBUG
|
|
#define PrintNtConsole(x) {;}
|
|
#endif //_DEBUG
|
|
|
|
#endif //USER_MODE
|
|
|
|
__inline
|
|
BOOLEAN
|
|
ata_is_sata(
|
|
PIDENTIFY_DATA ident
|
|
)
|
|
{
|
|
return (ident->SataCapabilities && ident->SataCapabilities != 0xffff);
|
|
} // end ata_is_sata()
|
|
|
|
#define IDENT_MODE_MAX FALSE
|
|
#define IDENT_MODE_ACTIVE TRUE
|
|
|
|
__inline
|
|
LONG
|
|
ata_cur_mode_from_ident(
|
|
PIDENTIFY_DATA ident,
|
|
BOOLEAN Active
|
|
)
|
|
{
|
|
USHORT mode;
|
|
if(ata_is_sata(ident)) {
|
|
if(ident->SataCapabilities & ATA_SATA_GEN3) {
|
|
return ATA_SA600;
|
|
} else
|
|
if(ident->SataCapabilities & ATA_SATA_GEN2) {
|
|
return ATA_SA300;
|
|
} else
|
|
if(ident->SataCapabilities & ATA_SATA_GEN1) {
|
|
return ATA_SA150;
|
|
}
|
|
return ATA_SA150;
|
|
}
|
|
|
|
if (ident->UdmaModesValid) {
|
|
mode = Active ? ident->UltraDMAActive : ident->UltraDMASupport;
|
|
if (mode & 0x40)
|
|
return ATA_UDMA0+6;
|
|
if (mode & 0x20)
|
|
return ATA_UDMA0+5;
|
|
if (mode & 0x10)
|
|
return ATA_UDMA0+4;
|
|
if (mode & 0x08)
|
|
return ATA_UDMA0+3;
|
|
if (mode & 0x04)
|
|
return ATA_UDMA0+2;
|
|
if (mode & 0x02)
|
|
return ATA_UDMA0+1;
|
|
if (mode & 0x01)
|
|
return ATA_UDMA0+0;
|
|
}
|
|
|
|
mode = Active ? ident->MultiWordDMAActive : ident->MultiWordDMASupport;
|
|
if (ident->MultiWordDMAActive & 0x04)
|
|
return ATA_WDMA0+2;
|
|
if (ident->MultiWordDMAActive & 0x02)
|
|
return ATA_WDMA0+1;
|
|
if (ident->MultiWordDMAActive & 0x01)
|
|
return ATA_WDMA0+0;
|
|
|
|
mode = Active ? ident->SingleWordDMAActive : ident->SingleWordDMASupport;
|
|
if (ident->SingleWordDMAActive & 0x04)
|
|
return ATA_SDMA0+2;
|
|
if (ident->SingleWordDMAActive & 0x02)
|
|
return ATA_SDMA0+1;
|
|
if (ident->SingleWordDMAActive & 0x01)
|
|
return ATA_SDMA0+0;
|
|
|
|
if (ident->PioTimingsValid) {
|
|
mode = ident->AdvancedPIOModes;
|
|
if (mode & AdvancedPIOModes_5)
|
|
return ATA_PIO0+5;
|
|
if (mode & AdvancedPIOModes_4)
|
|
return ATA_PIO0+4;
|
|
if (mode & AdvancedPIOModes_3)
|
|
return ATA_PIO0+3;
|
|
}
|
|
mode = ident->PioCycleTimingMode;
|
|
if (ident->PioCycleTimingMode == 2)
|
|
return ATA_PIO0+2;
|
|
if (ident->PioCycleTimingMode == 1)
|
|
return ATA_PIO0+1;
|
|
if (ident->PioCycleTimingMode == 0)
|
|
return ATA_PIO0+0;
|
|
|
|
return ATA_PIO;
|
|
} // end ata_cur_mode_from_ident()
|
|
|
|
#pragma pack(pop)
|
|
|
|
#endif // __GLOBAL_H__
|