mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[UNIATA]
* Sync with UniATA v0.42e2. * Hello AHCI support, you've been missed ! (that's WIP but still) svn path=/trunk/; revision=57018
This commit is contained in:
parent
e1398e05d4
commit
d1f163d021
15 changed files with 2426 additions and 1138 deletions
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2002-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
atapi.h
|
||||
|
@ -106,7 +106,7 @@ DbgPrint(
|
|||
#define PRINT_PREFIX
|
||||
|
||||
// Note, that using DbgPrint on raised IRQL will crash w2k
|
||||
// tis will not happen immediately, so we shall see some logs
|
||||
// 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
|
||||
|
||||
|
@ -249,6 +249,7 @@ typedef struct _IDE_REGISTERS_2 {
|
|||
#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_ 0x10000 //
|
||||
//
|
||||
// Used to disable 'advanced' features.
|
||||
|
@ -299,6 +300,7 @@ typedef struct _MODE_PARAMETER_HEADER_10 {
|
|||
// 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
|
||||
|
@ -380,6 +382,9 @@ typedef struct _MODE_PARAMETER_HEADER_10 {
|
|||
#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
|
||||
|
@ -615,7 +620,11 @@ typedef struct _IDENTIFY_DATA {
|
|||
|
||||
USHORT CurrentMultiSector:8; // 59
|
||||
USHORT CurrentMultiSectorValid:1;
|
||||
USHORT Reserved59_9:7;
|
||||
USHORT Reserved59_9_11:3;
|
||||
USHORT SanitizeSupported:1;
|
||||
USHORT CryptoScrambleExtSupported:1;
|
||||
USHORT OverwriteExtSupported:1;
|
||||
USHORT BlockEraseExtSupported:1;
|
||||
|
||||
ULONG UserAddressableSectors; // 60-61
|
||||
|
||||
|
@ -637,7 +646,20 @@ typedef struct _IDENTIFY_DATA {
|
|||
USHORT MinimumPIOCycleTime; // 67
|
||||
USHORT MinimumPIOCycleTimeIORDY; // 68
|
||||
|
||||
USHORT Reserved69_70[2]; // 69-70
|
||||
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
|
||||
|
@ -651,6 +673,9 @@ typedef struct _IDENTIFY_DATA {
|
|||
#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
|
||||
|
||||
|
@ -664,6 +689,12 @@ typedef struct _IDENTIFY_DATA {
|
|||
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;
|
||||
|
@ -734,7 +765,8 @@ typedef struct _IDENTIFY_DATA {
|
|||
|
||||
ULONGLONG UserAddressableSectors48; // 100-103
|
||||
|
||||
USHORT Reserved104[2]; // 104-105
|
||||
USHORT StreamingTransferTimePIO; // 104
|
||||
USHORT MaxLBARangeDescBlockCount; // 105 // in 512b blocks
|
||||
union {
|
||||
USHORT PhysLogSectorSize; // 106
|
||||
struct {
|
||||
|
@ -745,22 +777,101 @@ typedef struct _IDENTIFY_DATA {
|
|||
USHORT PLSS_Signature:2; // = 0x01 = 01b
|
||||
};
|
||||
};
|
||||
USHORT Reserved107[10]; // 107-116
|
||||
USHORT InterSeekDelay; // 107
|
||||
USHORT WorldWideName[4]; // 108-111
|
||||
USHORT Reserved112[5]; // 112-116
|
||||
|
||||
ULONG LargeSectorSize; // 117-118
|
||||
|
||||
USHORT Reserved117[8]; // 119-126
|
||||
USHORT Reserved119[8]; // 119-126
|
||||
|
||||
USHORT RemovableStatus; // 127
|
||||
USHORT SecurityStatus; // 128
|
||||
|
||||
USHORT FeaturesSupport4; // 129
|
||||
USHORT Reserved130[30]; // 130-159
|
||||
USHORT Reserved129[31]; // 129-159
|
||||
USHORT CfAdvPowerMode; // 160
|
||||
USHORT Reserved161[14]; // 161-175
|
||||
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
|
||||
USHORT Reserved206[49]; // 205-254
|
||||
USHORT Integrity; // 255
|
||||
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;
|
||||
} 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 {
|
||||
USHORT ChecksumValid:8;
|
||||
USHORT Checksum:8;
|
||||
};
|
||||
};
|
||||
} IDENTIFY_DATA, *PIDENTIFY_DATA;
|
||||
|
||||
//
|
||||
|
@ -813,10 +924,18 @@ typedef struct _IDENTIFY_DATA {
|
|||
|
||||
#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}
|
||||
|
@ -1219,6 +1338,12 @@ AtapiDisableInterrupts(
|
|||
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)
|
||||
|
@ -1303,7 +1428,7 @@ UniAtaCalculateLBARegsBack(
|
|||
ULONGLONG lba
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
ULONG
|
||||
NTAPI
|
||||
UniataAnybodyHome(
|
||||
IN PVOID HwDeviceExtension,
|
||||
|
@ -1311,10 +1436,18 @@ UniataAnybodyHome(
|
|||
IN ULONG deviceNumber
|
||||
);
|
||||
|
||||
#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
|
||||
|
||||
extern UCHAR AtaCommands48[256];
|
||||
extern UCHAR AtaCommandFlags[256];
|
||||
|
@ -1327,6 +1460,15 @@ extern UCHAR AtaCommandFlags[256];
|
|||
( ((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) && (supp48) && (((lba+count) >= ATA_MAX_IOLBA28) || (count > 256)) ) || \
|
||||
(lba > ATA_MAX_LBA28) || (count > 255) )
|
||||
|
||||
#define UniAtaClearAtaReq(AtaReq) \
|
||||
{ \
|
||||
RtlZeroMemory((PCHAR)(AtaReq), FIELD_OFFSET(ATA_REQ, ata)); \
|
||||
}
|
||||
|
||||
|
||||
//#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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2002-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
bm_devs.h
|
||||
|
@ -88,11 +88,17 @@ Revision History:
|
|||
#ifndef __IDE_BUSMASTER_DEVICES_H__
|
||||
#define __IDE_BUSMASTER_DEVICES_H__
|
||||
|
||||
#ifdef USER_MODE
|
||||
#define PVEN_STR PCSTR
|
||||
#else // USER_MODE
|
||||
#define PVEN_STR PCHAR
|
||||
#endif // USER_MODE
|
||||
|
||||
typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||
PCHAR VendorId;
|
||||
PVEN_STR VendorId;
|
||||
ULONG VendorIdLength;
|
||||
ULONG nVendorId;
|
||||
PCHAR DeviceId;
|
||||
PVEN_STR DeviceId;
|
||||
ULONG DeviceIdLength;
|
||||
ULONG nDeviceId;
|
||||
ULONG nRevId;
|
||||
|
@ -692,10 +698,10 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
|||
|
||||
#ifdef USER_MODE
|
||||
#define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \
|
||||
{ #idlo, 4, 0x##idlo, #idhi, 4, 0x##idhi, rev, mode, name, flags}
|
||||
{ (PVEN_STR) #idlo, 4, 0x##idlo, (PVEN_STR) #idhi, 4, 0x##idhi, rev, mode, name, flags}
|
||||
#else
|
||||
#define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \
|
||||
{ (PCHAR) #idlo, 4, 0x##idlo, (PCHAR) #idhi, 4, 0x##idhi, rev, mode, NULL, flags}
|
||||
{ (PVEN_STR) #idlo, 4, 0x##idlo, (PVEN_STR) #idhi, 4, 0x##idhi, rev, mode, NULL, flags}
|
||||
#endif
|
||||
|
||||
#define BMLIST_TERMINATOR (0xffffffffL)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2002-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
bsmaster.h
|
||||
|
@ -163,12 +163,14 @@ typedef struct _IDE_AHCI_REGISTERS {
|
|||
// HBA Capabilities
|
||||
struct {
|
||||
ULONG NOP:5; // number of ports
|
||||
ULONG Reserved5_7:1;
|
||||
ULONG SXS:1; // Supports External SATA
|
||||
ULONG EMS:1; // Enclosure Management Supported
|
||||
ULONG CCCS:1; // Command Completion Coalescing Supported
|
||||
ULONG NCS:5; // number of command slots
|
||||
ULONG PSC:1; // partial state capable
|
||||
ULONG SSC:1; // slumber state capable
|
||||
ULONG PMD:1; // PIO multiple DRQ block
|
||||
ULONG Reserved16:1;
|
||||
ULONG FBSS:1; // FIS-based Switching Supported
|
||||
|
||||
ULONG SPM:1; // port multiplier
|
||||
ULONG SAM:1; // AHCI mode only
|
||||
|
@ -179,7 +181,7 @@ typedef struct _IDE_AHCI_REGISTERS {
|
|||
ULONG SALP:1; // aggressive link power management
|
||||
ULONG SSS:1; // staggered spin-up
|
||||
ULONG SIS:1; // interlock switch
|
||||
ULONG Reserved29:1;
|
||||
ULONG SSNTF:1; // Supports SNotification Register
|
||||
ULONG SNCQ:1; // native command queue
|
||||
ULONG S64A:1; // 64bit addr
|
||||
} CAP;
|
||||
|
@ -206,14 +208,40 @@ typedef struct _IDE_AHCI_REGISTERS {
|
|||
#define AHCI_GHC_AE 0x80000000
|
||||
|
||||
// Interrupt status (bit mask)
|
||||
ULONG IS;
|
||||
ULONG IS; // 0x08
|
||||
// Ports implemented (bit mask)
|
||||
ULONG PI;
|
||||
ULONG PI; // 0x0c
|
||||
// AHCI Version
|
||||
ULONG VS;
|
||||
ULONG Reserved[3];
|
||||
ULONG VS; // 0x10
|
||||
|
||||
UCHAR Reserved2[0x80];
|
||||
ULONG CCC_CTL; // 0x14
|
||||
ULONG CCC_PORTS; // 0x18
|
||||
ULONG EM_LOC; // 0x1c
|
||||
ULONG EM_CTL; // 0x20
|
||||
|
||||
// Extended HBA Capabilities
|
||||
struct { // 0x24
|
||||
ULONG BOH:1; // BIOS/OS Handoff
|
||||
ULONG NVMP:1; // NVMHCI Present
|
||||
ULONG APST:1; // Automatic Partial to Slumber Transitions
|
||||
ULONG Reserved:29;
|
||||
} CAP2;
|
||||
|
||||
#define AHCI_CAP2_BOH 0x00000001
|
||||
#define AHCI_CAP2_NVMP 0x00000002
|
||||
#define AHCI_CAP2_APST 0x00000004
|
||||
|
||||
// BIOS/OS Handoff Control and Status
|
||||
struct { // 0x28
|
||||
ULONG BB:1; // BIOS Busy
|
||||
ULONG OOC:1; // OS Ownership Change
|
||||
ULONG SOOE:1; // SMI on OS Ownership Change Enable
|
||||
ULONG OOS:1; // OS Owned Semaphore
|
||||
ULONG BOS:1; // BIOS Owned Semaphore
|
||||
ULONG Reserved:27;
|
||||
} BOHC;
|
||||
|
||||
UCHAR Reserved2[0x74];
|
||||
|
||||
UCHAR VendorSpec[0x60];
|
||||
} IDE_AHCI_REGISTERS, *PIDE_AHCI_REGISTERS;
|
||||
|
@ -223,6 +251,8 @@ typedef struct _IDE_AHCI_REGISTERS {
|
|||
#define IDX_AHCI_IS (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
|
||||
#define IDX_AHCI_VS (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
|
||||
#define IDX_AHCI_PI (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
|
||||
#define IDX_AHCI_CAP2 (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP2))
|
||||
#define IDX_AHCI_BOHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, BOHC))
|
||||
|
||||
|
||||
typedef union _SATA_SSTATUS_REG {
|
||||
|
@ -561,7 +591,22 @@ typedef struct _IDE_AHCI_PORT_REGISTERS {
|
|||
};
|
||||
} SNTF; // 0x100 + 0x80*c + 0x003c
|
||||
|
||||
ULONG FIS_Switching_Reserved[12];
|
||||
// AHCI 1.2
|
||||
union {
|
||||
ULONG Reg;
|
||||
struct {
|
||||
ULONG EN:1; // Enable
|
||||
ULONG DEC:1; // Device Error Clear
|
||||
ULONG SDE:1; // Single Device Error
|
||||
ULONG Reserved_3_7:5; // Reserved
|
||||
ULONG DEV:4; // Device To Issue
|
||||
ULONG ADO:4; // Active Device Optimization (recommended parallelism)
|
||||
ULONG DWE:4; // Device With Error
|
||||
ULONG Reserved_20_31:12; // Reserved
|
||||
};
|
||||
} FBS; // 0x100 + 0x80*c + 0x0040
|
||||
|
||||
ULONG Reserved_44_7f[11];
|
||||
UCHAR VendorSpec[16];
|
||||
|
||||
} IDE_AHCI_PORT_REGISTERS, *PIDE_AHCI_PORT_REGISTERS;
|
||||
|
@ -617,9 +662,14 @@ typedef struct _IDE_AHCI_PRD_ENTRY {
|
|||
};
|
||||
ULONG Reserved1;
|
||||
|
||||
ULONG DBC:22;
|
||||
ULONG Reserved2:9;
|
||||
ULONG I:1;
|
||||
union {
|
||||
struct {
|
||||
ULONG DBC:22;
|
||||
ULONG Reserved2:9;
|
||||
ULONG I:1;
|
||||
};
|
||||
ULONG DBC_ULONG;
|
||||
};
|
||||
|
||||
} IDE_AHCI_PRD_ENTRY, *PIDE_AHCI_PRD_ENTRY;
|
||||
|
||||
|
@ -628,6 +678,50 @@ typedef struct _IDE_AHCI_PRD_ENTRY {
|
|||
|
||||
#define AHCI_FIS_TYPE_ATA_H2D 0x27
|
||||
#define AHCI_FIS_TYPE_ATA_D2H 0x34
|
||||
#define AHCI_FIS_TYPE_DMA_D2H 0x39
|
||||
#define AHCI_FIS_TYPE_DMA_BiDi 0x41
|
||||
#define AHCI_FIS_TYPE_DATA_BiDi 0x46
|
||||
#define AHCI_FIS_TYPE_BIST_BiDi 0x58
|
||||
#define AHCI_FIS_TYPE_PIO_D2H 0x5f
|
||||
#define AHCI_FIS_TYPE_DEV_BITS_D2H 0xA1
|
||||
|
||||
typedef struct _AHCI_ATA_H2D_FIS {
|
||||
UCHAR FIS_Type; // = 0x27
|
||||
UCHAR Reserved1:7;
|
||||
UCHAR Cmd:1; // update Command register
|
||||
UCHAR Command; // [2]
|
||||
UCHAR Feature; // [3]
|
||||
|
||||
UCHAR BlockNumber; // [4]
|
||||
UCHAR CylinderLow; // [5]
|
||||
UCHAR CylinderHigh; // [6]
|
||||
UCHAR DriveSelect; // [7]
|
||||
|
||||
UCHAR BlockNumberExp; // [8]
|
||||
UCHAR CylinderLowExp; // [9]
|
||||
UCHAR CylinderHighExp; // [10]
|
||||
UCHAR FeatureExp; // [11]
|
||||
|
||||
UCHAR BlockCount; // [12]
|
||||
UCHAR BlockCountExp; // [13]
|
||||
UCHAR Reserved14; // [14]
|
||||
UCHAR Control; // [15]
|
||||
|
||||
} AHCI_ATA_H2D_FIS, *PAHCI_ATA_H2D_FIS;
|
||||
|
||||
#define IDX_AHCI_o_Command (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Command))
|
||||
#define IDX_AHCI_o_Feature (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Feature))
|
||||
#define IDX_AHCI_o_BlockNumber (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumber ))
|
||||
#define IDX_AHCI_o_CylinderLow (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLow ))
|
||||
#define IDX_AHCI_o_CylinderHigh (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHigh))
|
||||
#define IDX_AHCI_o_DriveSelect (FIELD_OFFSET(AHCI_ATA_H2D_FIS, DriveSelect ))
|
||||
#define IDX_AHCI_o_BlockCount (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCount))
|
||||
#define IDX_AHCI_o_Control (FIELD_OFFSET(AHCI_ATA_H2D_FIS, Control))
|
||||
#define IDX_AHCI_o_FeatureExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, FeatureExp))
|
||||
#define IDX_AHCI_o_BlockNumberExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockNumberExp ))
|
||||
#define IDX_AHCI_o_CylinderLowExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderLowExp ))
|
||||
#define IDX_AHCI_o_CylinderHighExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, CylinderHighExp))
|
||||
#define IDX_AHCI_o_BlockCountExp (FIELD_OFFSET(AHCI_ATA_H2D_FIS, BlockCountExp))
|
||||
|
||||
#define AHCI_FIS_COMM_PM (0x80 | AHCI_DEV_SEL_PM)
|
||||
|
||||
|
@ -638,8 +732,8 @@ typedef struct _IDE_AHCI_PRD_ENTRY {
|
|||
/* 128-byte aligned */
|
||||
typedef struct _IDE_AHCI_CMD {
|
||||
UCHAR cfis[64];
|
||||
UCHAR acmd[32];
|
||||
UCHAR Reserved[32];
|
||||
UCHAR acmd[16];
|
||||
UCHAR Reserved[48];
|
||||
IDE_AHCI_PRD_ENTRY prd_tab[ATA_AHCI_DMA_ENTRIES]; // also 128-byte aligned
|
||||
} IDE_AHCI_CMD, *PIDE_AHCI_CMD;
|
||||
|
||||
|
@ -665,11 +759,11 @@ typedef struct _IDE_AHCI_CMD_LIST {
|
|||
typedef struct _IDE_AHCI_RCV_FIS {
|
||||
UCHAR dsfis[28];
|
||||
UCHAR Reserved1[4];
|
||||
UCHAR psfis[24];
|
||||
UCHAR Reserved2[8];
|
||||
UCHAR rfis[24];
|
||||
UCHAR psfis[20];
|
||||
UCHAR Reserved2[12];
|
||||
UCHAR rfis[20];
|
||||
UCHAR Reserved3[4];
|
||||
ULONG SDBFIS;
|
||||
UCHAR SDBFIS[8];
|
||||
UCHAR ufis[64];
|
||||
UCHAR Reserved4[96];
|
||||
} IDE_AHCI_RCV_FIS, *PIDE_AHCI_RCV_FIS;
|
||||
|
@ -678,7 +772,7 @@ typedef struct _IDE_AHCI_RCV_FIS {
|
|||
typedef struct _IDE_AHCI_CHANNEL_CTL_BLOCK {
|
||||
IDE_AHCI_CMD_LIST cmd_list[ATA_AHCI_MAX_TAGS]; // 1K-size (32*32)
|
||||
IDE_AHCI_RCV_FIS rcv_fis;
|
||||
IDE_AHCI_CMD cmd; // for single internal comamnds w/o associated AtaReq
|
||||
IDE_AHCI_CMD cmd; // for single internal commands w/o associated AtaReq
|
||||
} IDE_AHCI_CHANNEL_CTL_BLOCK, *PIDE_AHCI_CHANNEL_CTL_BLOCK;
|
||||
|
||||
|
||||
|
@ -741,7 +835,7 @@ typedef union _ATA_REQ {
|
|||
ULONG in_bcount;
|
||||
ULONG in_status;
|
||||
USHORT io_cmd_flags; // out
|
||||
|
||||
UCHAR in_error;
|
||||
} ahci;
|
||||
};
|
||||
};
|
||||
|
@ -781,7 +875,8 @@ typedef union _ATA_REQ {
|
|||
#define REQ_STATE_EXPECTING_INTR 0x40
|
||||
#define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
|
||||
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
|
||||
#define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x43
|
||||
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2 0x43
|
||||
#define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x44
|
||||
|
||||
#define REQ_STATE_EARLY_INTR 0x48
|
||||
|
||||
|
@ -832,9 +927,12 @@ struct _HW_DEVICE_EXTENSION;
|
|||
struct _HW_LU_EXTENSION;
|
||||
|
||||
typedef struct _IORES {
|
||||
ULONG Addr; /* Base address*/
|
||||
union {
|
||||
ULONG Addr; /* Base address*/
|
||||
PVOID pAddr; /* Base address in pointer form */
|
||||
};
|
||||
ULONG MemIo:1; /* Memory mapping (1) vs IO ports (0) */
|
||||
ULONG Proc:1; /* Need special process via IO_Proc */
|
||||
ULONG Proc:1; /* Need special processing via IO_Proc */
|
||||
ULONG Reserved:30;
|
||||
} IORES, *PIORES;
|
||||
|
||||
|
@ -867,7 +965,7 @@ typedef struct _HW_CHANNEL {
|
|||
//BOOLEAN MemIo;
|
||||
BOOLEAN AltRegMap;
|
||||
|
||||
//UCHAR Reserved[3];
|
||||
UCHAR Reserved[3];
|
||||
|
||||
MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData;
|
||||
SENSE_DATA MechStatusSense;
|
||||
|
@ -923,9 +1021,14 @@ typedef struct _HW_CHANNEL {
|
|||
PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock; // 128-byte aligned
|
||||
ULONGLONG AHCI_CTL_PhAddr;
|
||||
IORES BaseIoAHCI_Port;
|
||||
ULONG AhciPrevCI;
|
||||
ULONG AhciCompleteCI;
|
||||
ULONG AhciLastIS;
|
||||
//PVOID AHCI_FIS; // is not actually used by UniATA now, but is required by AHCI controller
|
||||
//ULONGLONG AHCI_FIS_PhAddr;
|
||||
// Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
|
||||
PATA_REQ AhciInternalAtaReq;
|
||||
PSCSI_REQUEST_BLOCK AhciInternalSrb;
|
||||
|
||||
#ifdef QUEUE_STATISTICS
|
||||
LONGLONG QueueStat[MAX_QUEUE_STAT];
|
||||
|
@ -999,6 +1102,7 @@ typedef struct _HW_LU_EXTENSION {
|
|||
ULONG last_write;
|
||||
|
||||
ULONG LunSelectWaitCount;
|
||||
ULONG AtapiReadyWaitDelay;
|
||||
|
||||
// tuning options
|
||||
ULONG opt_GeomType;
|
||||
|
@ -1072,6 +1176,7 @@ typedef struct _HW_DEVICE_EXTENSION {
|
|||
|
||||
ULONG ActiveDpcChan;
|
||||
ULONG FirstDpcChan;
|
||||
ULONG ExpectingInterrupt; // Indicates entire controller expecting an interrupt
|
||||
/*
|
||||
PHW_TIMER HwScsiTimer1;
|
||||
PHW_TIMER HwScsiTimer2;
|
||||
|
@ -1115,16 +1220,20 @@ typedef struct _HW_DEVICE_EXTENSION {
|
|||
INTERFACE_TYPE AdapterInterfaceType;
|
||||
ULONG MaximumDmaTransferLength;
|
||||
ULONG AlignmentMask;
|
||||
ULONG DmaSegmentLength;
|
||||
ULONG DmaSegmentAlignmentMask; // must be PAGE-aligned
|
||||
|
||||
//ULONG BaseMemAddress;
|
||||
|
||||
//PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
|
||||
IORES BaseIoAddressSATA_0;
|
||||
IORES BaseIoAddressSATA_0;
|
||||
//PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
|
||||
|
||||
IORES BaseIoAHCI_0;
|
||||
IORES BaseIoAHCI_0;
|
||||
//PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
|
||||
ULONG AHCI_CAP;
|
||||
ULONG AHCI_CAP;
|
||||
PATA_REQ AhciInternalAtaReq0;
|
||||
PSCSI_REQUEST_BLOCK AhciInternalSrb0;
|
||||
|
||||
BOOLEAN opt_AtapiDmaZeroTransfer; // default FALSE
|
||||
BOOLEAN opt_AtapiDmaControlCmd; // default FALSE
|
||||
|
@ -1186,13 +1295,17 @@ UniataFindCompatBusMasterController2(
|
|||
|
||||
#define UNIATA_ALLOCATE_NEW_LUNS 0x00
|
||||
|
||||
extern BOOLEAN
|
||||
NTAPI
|
||||
extern BOOLEAN NTAPI
|
||||
UniataAllocateLunExt(
|
||||
PHW_DEVICE_EXTENSION deviceExtension,
|
||||
ULONG NewNumberChannels
|
||||
);
|
||||
|
||||
extern VOID NTAPI
|
||||
UniataFreeLunExt(
|
||||
PHW_DEVICE_EXTENSION deviceExtension
|
||||
);
|
||||
|
||||
extern ULONG NTAPI
|
||||
UniataFindBusMasterController(
|
||||
IN PVOID HwDeviceExtension,
|
||||
|
@ -1476,9 +1589,13 @@ AtapiGetIoRange(
|
|||
SetPciConfig4(offs, a); \
|
||||
}
|
||||
|
||||
#define DMA_MODE_NONE 0x00
|
||||
#define DMA_MODE_BM 0x01
|
||||
#define DMA_MODE_AHCI 0x02
|
||||
|
||||
#ifndef GetDmaStatus
|
||||
#define GetDmaStatus(de, c) \
|
||||
(((de)->BusMaster) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
|
||||
(((de)->BusMaster == DMA_MODE_BM) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
|
||||
#endif //GetDmaStatus
|
||||
|
||||
#ifdef USE_OWN_DMA
|
||||
|
@ -1655,6 +1772,7 @@ UniataForgetDevice(
|
|||
extern ULONG SkipRaids;
|
||||
extern ULONG ForceSimplex;
|
||||
extern BOOLEAN g_opt_AtapiDmaRawRead;
|
||||
extern BOOLEAN hasPCI;
|
||||
|
||||
extern BOOLEAN InDriverEntry;
|
||||
|
||||
|
|
|
@ -110,16 +110,16 @@
|
|||
#define DEF_U64(x) (x##ULL)
|
||||
#define DEF_I64(x) (x##LL)
|
||||
|
||||
/* ReactOS-specific defines */
|
||||
|
||||
#ifndef DDKAPI
|
||||
#define DDKAPI __attribute__((stdcall))
|
||||
#define DDKAPI __attribute__((stdcall))
|
||||
#endif
|
||||
|
||||
#ifndef DDKCDECLAPI
|
||||
#define DDKCDECLAPI __attribute__((cdecl))
|
||||
#define DDKCDECLAPI __attribute__((cdecl))
|
||||
#endif
|
||||
|
||||
#ifndef DDKFASTAPI
|
||||
#define DDKFASTAPI __attribute__((fastcall))
|
||||
#define DDKFASTAPI __attribute__((fastcall))
|
||||
#endif
|
||||
|
||||
#define DECLSPEC_NAKED __attribute__((naked))
|
||||
|
@ -129,16 +129,16 @@
|
|||
#define DEF_U64(x) (x##UI64)
|
||||
#define DEF_I64(x) (x##I64)
|
||||
|
||||
/* ReactOS-specific defines */
|
||||
|
||||
#ifndef DDKAPI
|
||||
#define DDKAPI __stdcall
|
||||
#define DDKAPI __stdcall
|
||||
#endif
|
||||
|
||||
#ifndef DDKCDECLAPI
|
||||
#define DDKCDECLAPI _cdecl
|
||||
#define DDKCDECLAPI _cdecl
|
||||
#endif
|
||||
|
||||
#ifndef DDKFASTAPI
|
||||
#define DDKFASTAPI __fastcall
|
||||
#define DDKFASTAPI __fastcall
|
||||
#endif
|
||||
|
||||
#define DECLSPEC_NAKED __declspec(naked)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -182,6 +182,7 @@ InitBadBlocks(
|
|||
for(i=0; i<Length; i++) {
|
||||
cDevSerial[i] = (UCHAR)(DevSerial[i]);
|
||||
}
|
||||
cDevSerial[i] = 0;
|
||||
KdPrint(( "S/N:%s\n", cDevSerial));
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2002-2011 Alexander A. Telyatnikov (Alter)
|
||||
Copyright (c) 2002-2012 Alexander A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
id_dma.cpp
|
||||
|
@ -91,15 +91,13 @@ hpt_cable80(
|
|||
IN ULONG channel // physical channel number (0-1)
|
||||
);
|
||||
|
||||
#define ATAPI_DEVICE(de, ldev) (de->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE)
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
AtapiVirtToPhysAddr_(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PSCSI_REQUEST_BLOCK Srb,
|
||||
IN PUCHAR data,
|
||||
IN PULONG count,
|
||||
OUT PULONG count, /* bytes */
|
||||
OUT PULONG ph_addru
|
||||
)
|
||||
{
|
||||
|
@ -242,11 +240,12 @@ AtapiDmaSetup(
|
|||
IN ULONG lChannel, // logical channel,
|
||||
IN PSCSI_REQUEST_BLOCK Srb,
|
||||
IN PUCHAR data,
|
||||
IN ULONG count
|
||||
IN ULONG count /* bytes */
|
||||
)
|
||||
{
|
||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
ULONG dma_count, dma_base, dma_baseu;
|
||||
ULONG dma_count0, dma_base0;
|
||||
ULONG i;
|
||||
PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
|
||||
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
|
||||
|
@ -254,7 +253,15 @@ AtapiDmaSetup(
|
|||
BOOLEAN use_AHCI = (deviceExtension->HwFlags & UNIATA_AHCI) ? TRUE : FALSE;
|
||||
ULONG orig_count = count;
|
||||
ULONG max_entries = use_AHCI ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES;
|
||||
//ULONG max_frag = use_AHCI ? (0x3fffff+1) : (4096); // DEBUG, replace 4096 for procer chipset-specific value
|
||||
ULONG max_frag = deviceExtension->DmaSegmentLength;
|
||||
ULONG seg_align = deviceExtension->DmaSegmentAlignmentMask;
|
||||
|
||||
if(AtaReq->dma_entries) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaSetup: already setup, %d entries\n", AtaReq->dma_entries));
|
||||
return TRUE;
|
||||
}
|
||||
AtaReq->ata.dma_base = 0;
|
||||
AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaSetup: mode %#x, data %x, count %x, lCh %x, dev %x\n",
|
||||
|
@ -282,9 +289,9 @@ AtapiDmaSetup(
|
|||
|
||||
//KdPrint2((PRINT_PREFIX " checkpoint 4\n" ));
|
||||
if(use_AHCI) {
|
||||
KdPrint2((PRINT_PREFIX " get Phys(AHCI_CMD=%x)\n", &(AtaReq->ahci.ahci_cmd_ptr->prd_tab) ));
|
||||
dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab), &i, &dma_baseu);
|
||||
AtaReq->ahci.ahci_base64 = NULL; // clear before setup
|
||||
KdPrint2((PRINT_PREFIX " get Phys(AHCI_CMD=%x)\n", AtaReq->ahci.ahci_cmd_ptr ));
|
||||
dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(AtaReq->ahci.ahci_cmd_ptr), &i, &dma_baseu);
|
||||
AtaReq->ahci.ahci_base64 = 0; // clear before setup
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX " get Phys(PRD=%x)\n", &(AtaReq->dma_tab) ));
|
||||
dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)&(AtaReq->dma_tab) /*chan->dma_tab*/, &i, &dma_baseu);
|
||||
|
@ -301,9 +308,9 @@ AtapiDmaSetup(
|
|||
KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No BASE\n" ));
|
||||
return FALSE;
|
||||
}
|
||||
AtaReq->ata.dma_base = dma_base; // aliased to ahci_base64
|
||||
AtaReq->ata.dma_base = dma_base; // aliased to AtaReq->ahci.ahci_base64
|
||||
|
||||
KdPrint2((PRINT_PREFIX " get Phys(data=%x)\n", data ));
|
||||
KdPrint2((PRINT_PREFIX " get Phys(data[0]=%x)\n", data ));
|
||||
dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu);
|
||||
if(dma_baseu) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaSetup: 1st block of buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base));
|
||||
|
@ -328,15 +335,40 @@ retry_DB_IO:
|
|||
count -= dma_count;
|
||||
i = 0;
|
||||
|
||||
dma_count0 = dma_count;
|
||||
dma_base0 = dma_base;
|
||||
|
||||
while (count) {
|
||||
/* KdPrint2((PRINT_PREFIX " segments %#x+%#x == %#x && %#x+%#x <= %#x\n",
|
||||
dma_base0, dma_count0, dma_base,
|
||||
dma_count0, dma_count, max_frag));*/
|
||||
if(dma_base0+dma_count0 == dma_base &&
|
||||
dma_count0+dma_count <= max_frag) {
|
||||
// 'i' should be always > 0 here
|
||||
// for BM we cannot cross 64k boundary
|
||||
if(dma_base & seg_align) {
|
||||
//KdPrint2((PRINT_PREFIX " merge segments\n" ));
|
||||
ASSERT(i);
|
||||
//BrutePoint();
|
||||
i--;
|
||||
dma_base = dma_base0;
|
||||
dma_count += dma_count0;
|
||||
}
|
||||
}
|
||||
if(use_AHCI) {
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].base = dma_base;
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].baseu = dma_baseu;
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC = ((dma_count-1) & 0x3fffff);
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved1 = 0;
|
||||
*((PULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC_ULONG)) = ((dma_count-1) & 0x3fffff);
|
||||
/* AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved2 = 0;
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].I = 0;*/
|
||||
KdPrint2((PRINT_PREFIX " ph data[%d]=%x:%x (%x)\n", i, dma_baseu, dma_base, AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC));
|
||||
} else {
|
||||
AtaReq->dma_tab[i].base = dma_base;
|
||||
AtaReq->dma_tab[i].count = (dma_count & 0xffff);
|
||||
}
|
||||
dma_count0 = dma_count;
|
||||
dma_base0 = dma_base;
|
||||
i++;
|
||||
if (i >= max_entries) {
|
||||
KdPrint2((PRINT_PREFIX "too many segments in DMA table\n" ));
|
||||
|
@ -344,7 +376,7 @@ retry_DB_IO:
|
|||
AtaReq->ahci.ahci_base64 = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX " get Phys(data[n]=%x)\n", data ));
|
||||
KdPrint2((PRINT_PREFIX " get Phys(data[n=%d]=%x)\n", i, data ));
|
||||
dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu);
|
||||
if(dma_baseu) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaSetup: block of buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base));
|
||||
|
@ -369,15 +401,45 @@ retry_DB_IO:
|
|||
count -= min(count, PAGE_SIZE);
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX " set TERM\n" ));
|
||||
/* KdPrint2((PRINT_PREFIX " segments %#x+%#x == %#x && #x+%#x <= %#x\n",
|
||||
dma_base0, dma_count0, dma_base,
|
||||
dma_count0, dma_count, max_frag));*/
|
||||
if(dma_base0+dma_count0 == dma_base &&
|
||||
dma_count0+dma_count <= max_frag) {
|
||||
// 'i' should be always > 0 here
|
||||
if(dma_base & seg_align) {
|
||||
//KdPrint2((PRINT_PREFIX " merge segments\n" ));
|
||||
//BrutePoint();
|
||||
ASSERT(i);
|
||||
i--;
|
||||
dma_base = dma_base0;
|
||||
dma_count += dma_count0;
|
||||
}
|
||||
}
|
||||
if(use_AHCI) {
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].base = dma_base;
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].baseu = dma_baseu;
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC = ((dma_count-1) & 0x3fffff);
|
||||
AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved1 = 0;
|
||||
//AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC = ((dma_count-1) & 0x3fffff);
|
||||
//AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].Reserved2 = 0;
|
||||
*((PULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC_ULONG)) = ((dma_count-1) & 0x3fffff);
|
||||
//AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].I = 1; // interrupt when ready
|
||||
KdPrint2((PRINT_PREFIX " ph data[%d]=%x:%x (%x)\n", i, dma_baseu, dma_base, AtaReq->ahci.ahci_cmd_ptr->prd_tab[i].DBC));
|
||||
if(((ULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab) & ~PAGE_MASK) != ((ULONG)&(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i]) & ~PAGE_MASK)) {
|
||||
KdPrint2((PRINT_PREFIX "PRD table crosses page boundary! %x vs %x\n",
|
||||
&AtaReq->ahci.ahci_cmd_ptr->prd_tab, &(AtaReq->ahci.ahci_cmd_ptr->prd_tab[i]) ));
|
||||
//AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD;
|
||||
}
|
||||
} else {
|
||||
AtaReq->dma_tab[i].base = dma_base;
|
||||
AtaReq->dma_tab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT;
|
||||
if(((ULONG)&(AtaReq->dma_tab) & ~PAGE_MASK) != ((ULONG)&(AtaReq->dma_tab[i]) & ~PAGE_MASK)) {
|
||||
KdPrint2((PRINT_PREFIX "DMA table crosses page boundary! %x vs %x\n",
|
||||
&AtaReq->dma_tab, &(AtaReq->dma_tab[i]) ));
|
||||
//AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD;
|
||||
}
|
||||
}
|
||||
AtaReq->dma_entries = i;
|
||||
AtaReq->dma_entries = i+1;
|
||||
|
||||
if(use_DB_IO) {
|
||||
AtaReq->Flags |= REQ_FLAG_DMA_DBUF;
|
||||
|
@ -589,7 +651,7 @@ AtapiDmaDone(
|
|||
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
KdPrint2((PRINT_PREFIX " ACHTUNG! should not be called for AHCI!\n"));
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
|
||||
switch(VendorID) {
|
||||
|
@ -645,6 +707,13 @@ AtapiDmaReinit(
|
|||
{
|
||||
SCHAR apiomode;
|
||||
|
||||
if((deviceExtension->HwFlags & UNIATA_AHCI) &&
|
||||
!(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
|
||||
// skip unnecessary checks
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaReinit: ahci, nothing to do for HDD\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
apiomode = (CHAR)AtaPioMode(&(LunExt->IdentifyData));
|
||||
|
||||
if(!(AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) {
|
||||
|
@ -655,8 +724,8 @@ AtapiDmaReinit(
|
|||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
if(!AtaReq->ahci.ahci_base64) {
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"AtapiDmaReinit: no AHCI PRD, fall to PIO on Device %d\n", LunExt->Lun));
|
||||
goto limit_pio;
|
||||
"AtapiDmaReinit: no AHCI PRD, fatal on Device %d\n", LunExt->Lun));
|
||||
goto exit;
|
||||
}
|
||||
} else
|
||||
if(!AtaReq->ata.dma_base) {
|
||||
|
@ -722,6 +791,9 @@ limit_pio:
|
|||
"AtapiDmaReinit: restore IO mode on Device %d\n", LunExt->Lun));
|
||||
AtapiDmaInit__(deviceExtension, LunExt);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
} // end AtapiDmaReinit()
|
||||
|
||||
VOID
|
||||
|
@ -773,9 +845,19 @@ AtaSetTransferMode(
|
|||
LONG statusByte = 0;
|
||||
CHAR apiomode;
|
||||
|
||||
statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
|
||||
IDE_COMMAND_SET_FEATURES, 0, 0, 0,
|
||||
(UCHAR)((mode > ATA_UDMA6) ? ATA_UDMA6 : mode), ATA_C_F_SETXFER, ATA_WAIT_BASE_READY);
|
||||
if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
|
||||
statusByte = mode <= ATA_PIO2 ? IDE_STATUS_IDLE : IDE_STATUS_ERROR;
|
||||
} else {
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
AtapiDisableInterrupts(deviceExtension, lChannel);
|
||||
}
|
||||
statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
|
||||
IDE_COMMAND_SET_FEATURES, 0, 0, 0,
|
||||
(UCHAR)((mode > ATA_UDMA6) ? ATA_UDMA6 : mode), ATA_C_F_SETXFER, ATA_WAIT_BASE_READY);
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
AtapiEnableInterrupts(deviceExtension, lChannel);
|
||||
}
|
||||
}
|
||||
if(statusByte & IDE_STATUS_ERROR) {
|
||||
KdPrint3((PRINT_PREFIX " wait ready after error\n"));
|
||||
if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
|
||||
|
@ -819,11 +901,13 @@ AtapiDmaInit(
|
|||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
//LONG statusByte = 0;
|
||||
ULONG dev = Channel*2 + DeviceNumber; // for non-SATA/AHCI only!
|
||||
ULONG ldev = lChannel*2 + DeviceNumber; // for non-SATA/AHCI only!
|
||||
//ULONG ldev = lChannel*2 + DeviceNumber; // for non-SATA/AHCI only!
|
||||
BOOLEAN isAtapi = ATAPI_DEVICE(chan, DeviceNumber);
|
||||
ULONG slotNumber = deviceExtension->slotNumber;
|
||||
ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
|
||||
LONG i;
|
||||
PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
|
||||
UCHAR ModeByte;
|
||||
|
||||
ULONG VendorID = deviceExtension->DevID & 0xffff;
|
||||
//ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
|
||||
|
@ -888,29 +972,27 @@ AtapiDmaInit(
|
|||
apiomode = 0;
|
||||
}
|
||||
|
||||
SelectDrive(chan, DeviceNumber);
|
||||
GetStatus(chan, statusByte);
|
||||
// we can see here IDE_STATUS_ERROR status after previous operation
|
||||
if(statusByte & IDE_STATUS_ERROR) {
|
||||
KdPrint2((PRINT_PREFIX "IDE_STATUS_ERROR detected on entry, statusByte = %#x\n", statusByte));
|
||||
//GetBaseStatus(chan, statusByte);
|
||||
}
|
||||
if(statusByte && UniataIsIdle(deviceExtension, statusByte & ~IDE_STATUS_ERROR) != IDE_STATUS_IDLE) {
|
||||
KdPrint2((PRINT_PREFIX "Can't setup transfer mode: statusByte = %#x\n", statusByte));
|
||||
return;
|
||||
}
|
||||
//if(!(ChipFlags & UNIATA_AHCI)) {
|
||||
|
||||
if(deviceExtension->UnknownDev) {
|
||||
KdPrint2((PRINT_PREFIX "Unknown chip, omit Vendor/Dev checks\n"));
|
||||
goto try_generic_dma;
|
||||
}
|
||||
// this is necessary for future PM support
|
||||
SelectDrive(chan, DeviceNumber);
|
||||
GetStatus(chan, statusByte);
|
||||
// we can see here IDE_STATUS_ERROR status after previous operation
|
||||
if(statusByte & IDE_STATUS_ERROR) {
|
||||
KdPrint2((PRINT_PREFIX "IDE_STATUS_ERROR detected on entry, statusByte = %#x\n", statusByte));
|
||||
//GetBaseStatus(chan, statusByte);
|
||||
}
|
||||
if(statusByte && UniataIsIdle(deviceExtension, statusByte & ~IDE_STATUS_ERROR) != IDE_STATUS_IDLE) {
|
||||
KdPrint2((PRINT_PREFIX "Can't setup transfer mode: statusByte = %#x\n", statusByte));
|
||||
return;
|
||||
}
|
||||
//}
|
||||
|
||||
if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
|
||||
//if(ChipFlags & UNIATA_SATA) {
|
||||
//if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
|
||||
/****************/
|
||||
/* SATA Generic */
|
||||
/****************/
|
||||
UCHAR ModeByte;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "SATA Generic\n"));
|
||||
if(udmamode > 5) {
|
||||
|
@ -922,7 +1004,7 @@ AtapiDmaInit(
|
|||
if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode))) {
|
||||
return;
|
||||
}
|
||||
udmamode = min(udmamode, 5);
|
||||
udmamode = min(udmamode, 6);
|
||||
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX "SATA -> PATA adapter ?\n"));
|
||||
|
@ -931,7 +1013,7 @@ AtapiDmaInit(
|
|||
udmamode = 2;
|
||||
apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0));
|
||||
} else {
|
||||
udmamode = min(udmamode, 5);
|
||||
udmamode = min(udmamode, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -950,10 +1032,21 @@ AtapiDmaInit(
|
|||
AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ModeByte);
|
||||
return;
|
||||
}
|
||||
|
||||
if(deviceExtension->UnknownDev) {
|
||||
KdPrint2((PRINT_PREFIX "Unknown chip, omit Vendor/Dev checks\n"));
|
||||
goto try_generic_dma;
|
||||
}
|
||||
|
||||
if(udmamode > 2 && !LunExt->IdentifyData.HwResCableId) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n"));
|
||||
udmamode = 2;
|
||||
apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO));
|
||||
if(LunExt->IdentifyData.SataCapabilities != 0x0000 &&
|
||||
LunExt->IdentifyData.SataCapabilities != 0xffff) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: SATA beyond adapter or Controller compat mode\n"));
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n"));
|
||||
udmamode = 2;
|
||||
apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO));
|
||||
}
|
||||
}
|
||||
|
||||
KdPrint2((PRINT_PREFIX "Setup chip a:w:u=%d:%d:%d\n",
|
||||
|
@ -1021,8 +1114,8 @@ set_new_acard:
|
|||
/* the older Aladdin doesn't support ATAPI DMA on both master & slave */
|
||||
if ((ChipFlags & ALIOLD) &&
|
||||
(udmamode >= 0 || wdmamode >= 0)) {
|
||||
if(ATAPI_DEVICE(deviceExtension, lChannel*2) &&
|
||||
ATAPI_DEVICE(deviceExtension, lChannel*2 + 1)) {
|
||||
if(ATAPI_DEVICE(chan, 0) &&
|
||||
ATAPI_DEVICE(chan, 1)) {
|
||||
// 2 devices on this channel - NO DMA
|
||||
chan->MaxTransferMode =
|
||||
min(chan->MaxTransferMode, ATA_PIO4);
|
||||
|
@ -1364,7 +1457,7 @@ set_new_acard:
|
|||
SetPciConfig2(0x4a, (reg4a & ~(0x3 << (dev<<2))) |
|
||||
(0x01 + !(i & 0x01)) );
|
||||
}
|
||||
if(i >= 3) {
|
||||
if(i >= 2) {
|
||||
reg54 |= (0x1 << dev);
|
||||
} else {
|
||||
reg54 &= ~(0x1 << dev);
|
||||
|
@ -1412,8 +1505,7 @@ set_new_acard:
|
|||
GetPciConfig1(0x44, reg44);
|
||||
|
||||
/* Allow PIO/WDMA timing controls. */
|
||||
reg40 &= ~0x00ff00ff;
|
||||
reg40 |= ~0x40774077;
|
||||
mask40 = 0x000000ff;
|
||||
/* Set PIO/WDMA timings. */
|
||||
if(!(DeviceNumber & 1)) {
|
||||
mask40 |= 0x00003300;
|
||||
|
@ -1423,6 +1515,7 @@ set_new_acard:
|
|||
new44 = ((intel_timings[idx] & 0x30) >> 2) |
|
||||
(intel_timings[idx] & 0x03);
|
||||
}
|
||||
new40 |= 0x00004077;
|
||||
|
||||
if (Channel) {
|
||||
mask40 <<= 16;
|
||||
|
@ -1441,7 +1534,7 @@ set_new_acard:
|
|||
/* Promise */
|
||||
/***********/
|
||||
if(ChipType < PRTX) {
|
||||
if (ATAPI_DEVICE(deviceExtension, ldev)) {
|
||||
if (isAtapi) {
|
||||
udmamode =
|
||||
wdmamode = -1;
|
||||
}
|
||||
|
@ -1919,12 +2012,12 @@ setup_drive_ite:
|
|||
reg40 &= 0xff00;
|
||||
reg40 |= 0x4033;
|
||||
|
||||
if(!(ldev & 1)) {
|
||||
reg40 |= (ATAPI_DEVICE(deviceExtension, ldev) ? 0x04 : 0x00);
|
||||
if(!(DeviceNumber & 1)) {
|
||||
reg40 |= (isAtapi ? 0x04 : 0x00);
|
||||
mask40 = 0x3300;
|
||||
new40 = timing << 8;
|
||||
} else {
|
||||
reg40 |= (ATAPI_DEVICE(deviceExtension, ldev) ? 0x40 : 0x00);
|
||||
reg40 |= (isAtapi ? 0x40 : 0x00);
|
||||
mask44 = 0x0f;
|
||||
new44 = ((timing & 0x30) >> 2) |
|
||||
(timing & 0x03);
|
||||
|
@ -1980,7 +2073,7 @@ try_generic_dma:
|
|||
/* unknown controller chip */
|
||||
|
||||
/* better not try generic DMA on ATAPI devices it almost never works */
|
||||
if (ATAPI_DEVICE(deviceExtension, ldev)) {
|
||||
if (isAtapi) {
|
||||
KdPrint2((PRINT_PREFIX "ATAPI on unknown controller -> PIO\n"));
|
||||
udmamode =
|
||||
wdmamode = -1;
|
||||
|
@ -1989,9 +2082,9 @@ try_generic_dma:
|
|||
/* if controller says its setup for DMA take the easy way out */
|
||||
/* the downside is we dont know what DMA mode we are in */
|
||||
if ((udmamode >= 0 || /*wdmamode > 1*/ wdmamode >= 0) &&
|
||||
/*deviceExtension->BaseIoAddressBM[lChannel]*/ deviceExtension->BusMaster &&
|
||||
/*deviceExtension->BaseIoAddressBM[lChannel]*/ (deviceExtension->BusMaster==DMA_MODE_BM) &&
|
||||
(GetDmaStatus(deviceExtension, lChannel) &
|
||||
(!(ldev & 1) ?
|
||||
(!(DeviceNumber & 1) ?
|
||||
BM_STATUS_DRIVE_0_DMA : BM_STATUS_DRIVE_1_DMA))) {
|
||||
// LunExt->TransferMode = ATA_DMA;
|
||||
// return;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2004-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2004-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
id_init.cpp
|
||||
|
@ -69,8 +69,8 @@ UniataChipDetectChannels(
|
|||
deviceExtension->NumberChannels = 1;
|
||||
}
|
||||
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhciPM", 1 /* DEBUG */)) {
|
||||
KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1\n"));
|
||||
deviceExtension->NumberLuns = 2;
|
||||
KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1 or 2\n"));
|
||||
deviceExtension->NumberLuns = 2; // we may be in Legacy mode
|
||||
//chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
|
||||
|
@ -133,8 +133,8 @@ UniataChipDetectChannels(
|
|||
|
||||
if(ChipFlags & SIIBUG) {
|
||||
/* work around errata in early chips */
|
||||
ConfigInfo->AlignmentMask = 0x1fff;
|
||||
deviceExtension->MaximumDmaTransferLength = 15 * DEV_BSIZE;
|
||||
deviceExtension->DmaSegmentLength = 15 * DEV_BSIZE;
|
||||
deviceExtension->DmaSegmentAlignmentMask = 8192-1;
|
||||
}
|
||||
if(ChipType != SIIMIO) {
|
||||
break;
|
||||
|
@ -255,11 +255,15 @@ UniataChipDetect(
|
|||
deviceExtension->MaxTransferMode = BaseIoAddressBM ? ATA_DMA : ATA_PIO4;
|
||||
ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
|
||||
deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
|
||||
//deviceExtension->NumberOfPhysicalBreaks = min(deviceExtension->MaximumDmaTransferLength/PAGE_SIZE+1, ATA_DMA_ENTRIES);
|
||||
deviceExtension->DmaSegmentLength = 0x10000;
|
||||
deviceExtension->DmaSegmentAlignmentMask = 0xffff;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "i: %#x\n", i));
|
||||
if(i != BMLIST_TERMINATOR) {
|
||||
DevTypeInfo = (PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[i];
|
||||
} else {
|
||||
unknown_dev:
|
||||
if(Ata_is_ahci_dev(pciData)) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI candidate"));
|
||||
|
||||
|
@ -268,10 +272,9 @@ UniataChipDetect(
|
|||
KdPrint2((PRINT_PREFIX " AHCI init failed - not detected\n"));
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX " unknown AHCI dev, addr %#x", deviceExtension->BaseIoAHCI_0.Addr));
|
||||
KdPrint2((PRINT_PREFIX " unknown AHCI dev, addr %#x ", deviceExtension->BaseIoAHCI_0.Addr));
|
||||
}
|
||||
unknown_dev:
|
||||
KdPrint2((PRINT_PREFIX " unknown dev, BM addr %#I64x", BaseIoAddressBM));
|
||||
KdPrint2((PRINT_PREFIX " unknown dev, BM addr %#x ", BaseIoAddressBM));
|
||||
DevTypeInfo = NULL;
|
||||
KdPrint2((PRINT_PREFIX " MaxTransferMode %#x\n", deviceExtension->MaxTransferMode));
|
||||
|
||||
|
@ -281,8 +284,9 @@ unknown_dev:
|
|||
if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return STATUS_NOT_FOUND;
|
||||
// DEBUG, we shall return success when AHCI is completly supported
|
||||
//return STATUS_NOT_FOUND;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static BUSMASTER_CONTROLLER_INFORMATION const SiSAdapters[] = {
|
||||
|
@ -447,7 +451,7 @@ unknown_dev:
|
|||
deviceExtension->BaseIoAddressBM_0);
|
||||
|
||||
deviceExtension->BaseIoAddressBM_0 = 0;
|
||||
deviceExtension->BusMaster = FALSE;
|
||||
deviceExtension->BusMaster = DMA_MODE_NONE;
|
||||
deviceExtension->MaxTransferMode = ATA_PIO4;
|
||||
break;
|
||||
|
||||
|
@ -1020,10 +1024,10 @@ for_ugly_chips:
|
|||
/* if BAR(5) is IO it should point to SATA interface registers */
|
||||
if(deviceExtension->DevID == 0x28288086 &&
|
||||
pciData->u.type0.SubVendorID == 0x106b) {
|
||||
BaseMemAddress = 0;
|
||||
KdPrint2((PRINT_PREFIX "Ignore BAR5 on ICH8M Apples\n"));
|
||||
} else {
|
||||
/* Skip BAR(5) on ICH8M Apples, system locks up on access. */
|
||||
KdPrint2((PRINT_PREFIX "Ignore BAR5 on ICH8M Apples\n"));
|
||||
BaseMemAddress = 0;
|
||||
} else {
|
||||
BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
|
||||
5, 0, 0x10);
|
||||
if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
|
||||
|
@ -1465,16 +1469,44 @@ UniAtaReadLunConfig(
|
|||
}
|
||||
|
||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"GeomType", 0xffffffff);
|
||||
if(tmp32 > 2) {
|
||||
if(tmp32 > GEOM_MANUAL) {
|
||||
tmp32 = 0xffffffff;
|
||||
}
|
||||
LunExt->opt_GeomType = tmp32;
|
||||
if(tmp32 == GEOM_MANUAL) {
|
||||
LunExt->DeviceFlags |= DFLAGS_MANUAL_CHS;
|
||||
LunExt->opt_GeomType = GEOM_ORIG;
|
||||
// assume IdentifyData is already zero-filled
|
||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"C", 0);
|
||||
LunExt->IdentifyData.NumberOfCurrentCylinders =
|
||||
LunExt->IdentifyData.NumberOfCylinders = (USHORT)tmp32;
|
||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"H", 0);
|
||||
LunExt->IdentifyData.NumberOfCurrentHeads =
|
||||
LunExt->IdentifyData.NumberOfHeads = (USHORT)tmp32;
|
||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"S", 0);
|
||||
LunExt->IdentifyData.CurrentSectorsPerTrack =
|
||||
LunExt->IdentifyData.SectorsPerTrack = (USHORT)tmp32;
|
||||
memcpy(LunExt->IdentifyData.ModelNumber, "SEIDH DD", 8); // ESDI HDD
|
||||
memcpy(LunExt->IdentifyData.SerialNumber, ".10", 4);
|
||||
memcpy(LunExt->IdentifyData.FirmwareRevision, ".10", 4);
|
||||
if(!LunExt->IdentifyData.SectorsPerTrack ||
|
||||
!LunExt->IdentifyData.NumberOfCylinders ||
|
||||
!LunExt->IdentifyData.SectorsPerTrack) {
|
||||
// ERROR
|
||||
KdPrint2((PRINT_PREFIX "Wrong CHS\n"));
|
||||
LunExt->opt_GeomType = GEOM_AUTO;
|
||||
} else {
|
||||
LunExt->DeviceFlags |= DFLAGS_MANUAL_CHS;
|
||||
LunExt->opt_GeomType = GEOM_ORIG;
|
||||
}
|
||||
}
|
||||
|
||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"Hidden", 0);
|
||||
if(tmp32) {
|
||||
LunExt->DeviceFlags |= DFLAGS_HIDDEN;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
} // end UniAtaReadLunConfig()
|
||||
|
||||
|
@ -2284,6 +2316,7 @@ UniataInitMapBM(
|
|||
BaseIoAddressBM_0++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} // end UniataInitMapBM()
|
||||
|
||||
VOID
|
||||
|
@ -2305,6 +2338,7 @@ UniataInitMapBase(
|
|||
chan->RegTranslation[IDX_IO2+i].MemIo = FALSE;
|
||||
}
|
||||
UniataInitSyncBaseIO(chan);
|
||||
return;
|
||||
} // end UniataInitMapBase()
|
||||
|
||||
VOID
|
||||
|
@ -2315,6 +2349,7 @@ UniataInitSyncBaseIO(
|
|||
{
|
||||
RtlCopyMemory(&chan->RegTranslation[IDX_IO1_o], &chan->RegTranslation[IDX_IO1], IDX_IO1_SZ*sizeof(chan->RegTranslation[0]));
|
||||
RtlCopyMemory(&chan->RegTranslation[IDX_IO2_o], &chan->RegTranslation[IDX_IO2], IDX_IO2_SZ*sizeof(chan->RegTranslation[0]));
|
||||
return;
|
||||
} // end UniataInitSyncBaseIO()
|
||||
|
||||
VOID
|
||||
|
@ -2327,7 +2362,10 @@ AtapiSetupLunPtrs(
|
|||
{
|
||||
ULONG i;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "AtapiSetupLunPtrs for channel %d of %d, %d luns \n", c, deviceExtension->NumberChannels, deviceExtension->NumberLuns));
|
||||
|
||||
if(!deviceExtension->NumberLuns) {
|
||||
KdPrint2((PRINT_PREFIX "Achtung !deviceExtension->NumberLuns \n"));
|
||||
deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN;
|
||||
}
|
||||
chan->DeviceExtension = deviceExtension;
|
||||
|
@ -2343,5 +2381,106 @@ AtapiSetupLunPtrs(
|
|||
chan->lun[i]->chan = chan;
|
||||
chan->lun[i]->Lun = i;
|
||||
}
|
||||
if((deviceExtension->HwFlags & UNIATA_AHCI) &&
|
||||
deviceExtension->AhciInternalAtaReq0 &&
|
||||
deviceExtension->AhciInternalSrb0) {
|
||||
chan->AhciInternalAtaReq = &(deviceExtension->AhciInternalAtaReq0[c]);
|
||||
chan->AhciInternalSrb = &(deviceExtension->AhciInternalSrb0[c]);
|
||||
UniataAhciSetupCmdPtr(chan->AhciInternalAtaReq);
|
||||
chan->AhciInternalSrb->SrbExtension = chan->AhciInternalAtaReq;
|
||||
chan->AhciInternalAtaReq->Srb = chan->AhciInternalSrb;
|
||||
}
|
||||
return;
|
||||
} // end AtapiSetupLunPtrs()
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
UniataAllocateLunExt(
|
||||
PHW_DEVICE_EXTENSION deviceExtension,
|
||||
ULONG NewNumberChannels
|
||||
)
|
||||
{
|
||||
PHW_LU_EXTENSION old_luns = NULL;
|
||||
PHW_CHANNEL old_chans = NULL;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "allocate %d Luns for %d channels\n", deviceExtension->lun, deviceExtension->NumberChannels));
|
||||
|
||||
old_luns = deviceExtension->lun;
|
||||
old_chans = deviceExtension->chan;
|
||||
|
||||
if(old_luns || old_chans) {
|
||||
if(NewNumberChannels == UNIATA_ALLOCATE_NEW_LUNS) {
|
||||
KdPrint2((PRINT_PREFIX "already allocated!\n"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!deviceExtension->NumberLuns) {
|
||||
KdPrint2((PRINT_PREFIX "default NumberLuns=2\n"));
|
||||
deviceExtension->NumberLuns = 2;
|
||||
}
|
||||
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
if(!deviceExtension->AhciInternalAtaReq0) {
|
||||
deviceExtension->AhciInternalAtaReq0 = (PATA_REQ)ExAllocatePool(NonPagedPool, sizeof(ATA_REQ)*deviceExtension->NumberChannels);
|
||||
if (!deviceExtension->AhciInternalAtaReq0) {
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension->AhciInternalAtaReq0 => SP_RETURN_ERROR\n"));
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension->AhciInternalAtaReq0, sizeof(ATA_REQ)*deviceExtension->NumberChannels);
|
||||
}
|
||||
if(!deviceExtension->AhciInternalSrb0) {
|
||||
deviceExtension->AhciInternalSrb0 = (PSCSI_REQUEST_BLOCK)ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK)*deviceExtension->NumberChannels);
|
||||
if (!deviceExtension->AhciInternalSrb0) {
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension->AhciInternalSrb0 => SP_RETURN_ERROR\n"));
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension->AhciInternalSrb0, sizeof(SCSI_REQUEST_BLOCK)*deviceExtension->NumberChannels);
|
||||
}
|
||||
}
|
||||
|
||||
deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
|
||||
if (!deviceExtension->lun) {
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
|
||||
|
||||
deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
|
||||
if (!deviceExtension->chan) {
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension->chan => SP_RETURN_ERROR\n"));
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension->chan, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
|
||||
return TRUE;
|
||||
} // end UniataAllocateLunExt()
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
UniataFreeLunExt(
|
||||
PHW_DEVICE_EXTENSION deviceExtension
|
||||
)
|
||||
{
|
||||
if (deviceExtension->lun) {
|
||||
ExFreePool(deviceExtension->lun);
|
||||
deviceExtension->lun = NULL;
|
||||
}
|
||||
if (deviceExtension->chan) {
|
||||
ExFreePool(deviceExtension->chan);
|
||||
deviceExtension->chan = NULL;
|
||||
}
|
||||
if(deviceExtension->AhciInternalAtaReq0) {
|
||||
ExFreePool(deviceExtension->AhciInternalAtaReq0);
|
||||
deviceExtension->AhciInternalAtaReq0 = NULL;
|
||||
}
|
||||
if(deviceExtension->AhciInternalSrb0) {
|
||||
ExFreePool(deviceExtension->AhciInternalSrb0);
|
||||
deviceExtension->AhciInternalSrb0 = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
} // end UniataFreeLunExt()
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2002-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
id_probe.cpp
|
||||
|
@ -112,7 +112,36 @@ AtapiGetIoRange(
|
|||
(*ConfigInfo->AccessRanges)[rid].RangeInMemory
|
||||
));
|
||||
|
||||
if(!(*ConfigInfo->AccessRanges)[rid].RangeInMemory) {
|
||||
io_start = (pciData->u.type0.BaseAddresses[rid] & ~0x07/*PCI_ADDRESS_IOMASK*/) + offset;
|
||||
// if(pciData->u.type0.BaseAddresses[rid] != 0) ;)
|
||||
if(io_start > offset) {
|
||||
if(/*(WinVer_Id() <= WinVer_NT) &&*/ offset && rid == 4) {
|
||||
// MS atapi.sys does so for BusMaster controllers
|
||||
(*ConfigInfo->AccessRanges)[rid+1].RangeStart =
|
||||
ScsiPortConvertUlongToPhysicalAddress(io_start);
|
||||
(*ConfigInfo->AccessRanges)[rid+1].RangeLength = length;
|
||||
} else {
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeStart =
|
||||
ScsiPortConvertUlongToPhysicalAddress(io_start);
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeLength = length;
|
||||
}
|
||||
if((pciData->u.type0.BaseAddresses[rid] & PCI_ADDRESS_IO_SPACE)) {
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeInMemory = FALSE;
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX " AtapiGetIoRange: adjust mem 0 -> 1\n"));
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeInMemory = TRUE;
|
||||
}
|
||||
} else {
|
||||
io_start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((*ConfigInfo->AccessRanges)[rid].RangeInMemory) {
|
||||
if(offset) {
|
||||
KdPrint2((PRINT_PREFIX " AtapiGetIoRange: can't map memory range with offset\n"));
|
||||
return 0;
|
||||
}
|
||||
io_start =
|
||||
// Get the system physical address for this IO range.
|
||||
((ULONG_PTR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
||||
|
@ -132,27 +161,6 @@ AtapiGetIoRange(
|
|||
// }
|
||||
}
|
||||
|
||||
io_start = (pciData->u.type0.BaseAddresses[rid] & ~0x07/*PCI_ADDRESS_IOMASK*/) + offset;
|
||||
// if(pciData->u.type0.BaseAddresses[rid] != 0) ;)
|
||||
if(io_start > offset) {
|
||||
if(/*(WinVer_Id() <= WinVer_NT) &&*/ offset && rid == 4) {
|
||||
// MS atapi.sys does so for BusMaster controllers
|
||||
(*ConfigInfo->AccessRanges)[rid+1].RangeStart =
|
||||
ScsiPortConvertUlongToPhysicalAddress(io_start);
|
||||
(*ConfigInfo->AccessRanges)[rid+1].RangeLength = length;
|
||||
} else {
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeStart =
|
||||
ScsiPortConvertUlongToPhysicalAddress(io_start);
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeLength = length;
|
||||
}
|
||||
if((pciData->u.type0.BaseAddresses[rid] & PCI_ADDRESS_IO_SPACE)) {
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeInMemory = FALSE;
|
||||
} else {
|
||||
(*ConfigInfo->AccessRanges)[rid].RangeInMemory = TRUE;
|
||||
}
|
||||
} else {
|
||||
io_start = 0;
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX " AtapiGetIoRange: (2) %#x\n", io_start));
|
||||
return io_start;
|
||||
|
||||
|
@ -164,7 +172,7 @@ AtapiGetIoRange(
|
|||
Do nothing, but build list of supported IDE controllers
|
||||
It is a hack, ScsiPort architecture assumes, that DriverEntry
|
||||
can support only KNOWN Vendor/Device combinations.
|
||||
Thus, we build list here. Later will pretend that always knew
|
||||
Thus, we build list here. Later we pretend that always knew
|
||||
about found devices.
|
||||
|
||||
We shall initiate ISA device init, but callback will use
|
||||
|
@ -298,6 +306,9 @@ UniataEnumBusMasterController__(
|
|||
maxPciBus = busNumber;
|
||||
break;
|
||||
}
|
||||
// indicate that system has PCI bus(es)
|
||||
hasPCI =TRUE;
|
||||
|
||||
// no device in this slot
|
||||
if(busDataRead == 2) {
|
||||
NeedPciAltInit = TRUE;
|
||||
|
@ -321,12 +332,14 @@ UniataEnumBusMasterController__(
|
|||
|
||||
//KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
||||
|
||||
// check for (g_opt_VirtualMachine == VM_AUTO) is performed inside each
|
||||
// VM check for debug purposes
|
||||
// Do not optimize :)
|
||||
if(VendorID == 0x80ee && DeviceID == 0xcafe) {
|
||||
KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - VirtualBox Guest Service\n",busNumber,slotNumber,funcNumber));
|
||||
if(g_opt_VirtualMachine == VM_AUTO) {
|
||||
g_opt_VirtualMachine = VM_VBOX;
|
||||
}
|
||||
//continue;
|
||||
} else
|
||||
if((VendorID == 0x15ad) ||
|
||||
(SubVendorID == 0x15ad && SubSystemID == 0x1976)) {
|
||||
|
@ -334,7 +347,6 @@ UniataEnumBusMasterController__(
|
|||
if(g_opt_VirtualMachine == VM_AUTO) {
|
||||
g_opt_VirtualMachine = VM_VMWARE;
|
||||
}
|
||||
//g_opt_VirtualBox = TRUE;
|
||||
} else
|
||||
if(SubVendorID == 0x1af4 && SubSystemID == 0x1100) {
|
||||
KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - QEmu\n",busNumber,slotNumber,funcNumber));
|
||||
|
@ -350,7 +362,7 @@ UniataEnumBusMasterController__(
|
|||
|
||||
KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x\n",busNumber,slotNumber,funcNumber));
|
||||
KdPrint2((PRINT_PREFIX "Storage Class\n"));
|
||||
KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
||||
KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X, ProgIf %2.2X\n", dev_id, BaseClass, SubClass, pciData.ProgIf ));
|
||||
// look for known chipsets
|
||||
found = FALSE;
|
||||
known = FALSE;
|
||||
|
@ -837,52 +849,6 @@ UniataFindCompatBusMasterController2(
|
|||
);
|
||||
} // end UniataFindCompatBusMasterController2()
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
UniataAllocateLunExt(
|
||||
PHW_DEVICE_EXTENSION deviceExtension,
|
||||
ULONG NewNumberChannels
|
||||
)
|
||||
{
|
||||
PHW_LU_EXTENSION old_luns = NULL;
|
||||
PHW_CHANNEL old_chans = NULL;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "allocate Luns for %d channels\n", deviceExtension->NumberChannels));
|
||||
|
||||
old_luns = deviceExtension->lun;
|
||||
old_chans = deviceExtension->chan;
|
||||
|
||||
if(old_luns || old_chans) {
|
||||
if(NewNumberChannels == UNIATA_ALLOCATE_NEW_LUNS) {
|
||||
KdPrint2((PRINT_PREFIX "already allocated!\n"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!deviceExtension->NumberLuns) {
|
||||
KdPrint2((PRINT_PREFIX "default NumberLuns=2\n"));
|
||||
deviceExtension->NumberLuns = 2;
|
||||
}
|
||||
|
||||
deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
|
||||
if (!deviceExtension->lun) {
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * deviceExtension->NumberLuns);
|
||||
|
||||
deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
|
||||
if (!deviceExtension->chan) {
|
||||
ExFreePool(deviceExtension->lun);
|
||||
deviceExtension->lun = NULL;
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension->chan => SP_RETURN_ERROR\n"));
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension->chan, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
|
||||
return TRUE;
|
||||
} // end UniataAllocateLunExt()
|
||||
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
@ -1194,14 +1160,19 @@ UniataFindBusMasterController(
|
|||
}
|
||||
}
|
||||
}
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI registers layout\n"));
|
||||
} else
|
||||
if(deviceExtension->AltRegMap) {
|
||||
KdPrint2((PRINT_PREFIX " Non-standard registers layout\n"));
|
||||
if(deviceExtension->HwFlags & UNIATA_SATA) {
|
||||
KdPrint2((PRINT_PREFIX "UNIATA_SATA -> IsBusMaster == TRUE\n"));
|
||||
deviceExtension->BusMaster = TRUE;
|
||||
if(!deviceExtension->BusMaster) {
|
||||
deviceExtension->BusMaster = DMA_MODE_BM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deviceExtension->BusMaster = FALSE;
|
||||
deviceExtension->BusMaster = DMA_MODE_NONE;
|
||||
|
||||
if(WinVer_WDM_Model && !deviceExtension->UnknownDev) {
|
||||
ULONG i;
|
||||
|
@ -1259,7 +1230,7 @@ UniataFindBusMasterController(
|
|||
UniataInitMapBM(deviceExtension,
|
||||
BaseIoAddressBM_0,
|
||||
(*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE);
|
||||
deviceExtension->BusMaster = TRUE;
|
||||
deviceExtension->BusMaster = DMA_MODE_BM;
|
||||
deviceExtension->BaseIoAddressBM_0.Addr = (ULONGIO_PTR)BaseIoAddressBM_0;
|
||||
if((*ConfigInfo->AccessRanges)[4].RangeInMemory) {
|
||||
deviceExtension->BaseIoAddressBM_0.MemIo = TRUE;
|
||||
|
@ -1277,8 +1248,9 @@ UniataFindBusMasterController(
|
|||
KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE && !MasterDev\n"));
|
||||
statusByte = AtapiReadPort1(&(deviceExtension->chan[0]), IDX_BM_Status);
|
||||
KdPrint2((PRINT_PREFIX " BM statusByte = %x\n", statusByte));
|
||||
if(statusByte == 0xff) {
|
||||
if(statusByte == IDE_STATUS_WRONG) {
|
||||
KdPrint2((PRINT_PREFIX " invalid port ?\n"));
|
||||
deviceExtension->BusMaster = DMA_MODE_NONE;
|
||||
/*
|
||||
if(BaseIoAddressBM_0) {
|
||||
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
||||
|
@ -1315,7 +1287,7 @@ UniataFindBusMasterController(
|
|||
|
||||
KdPrint2((PRINT_PREFIX "simplexOnly = %d (2)", simplexOnly));
|
||||
|
||||
//TODO: fix hang with UseDpn=TRUE in Simplex mode
|
||||
//TODO: fix hang with UseDpc=TRUE in Simplex mode
|
||||
//deviceExtension->UseDpc = TRUE;
|
||||
if(simplexOnly) {
|
||||
KdPrint2((PRINT_PREFIX "simplexOnly => UseDpc = FALSE\n"));
|
||||
|
@ -1413,7 +1385,12 @@ UniataFindBusMasterController(
|
|||
KdPrint2((PRINT_PREFIX "update ConfigInfo->nt4\n"));
|
||||
_ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
|
||||
_ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
|
||||
_ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ);
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
_ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ);
|
||||
} else {
|
||||
_ConfigInfo->nt4.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, dma_tab) + sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX "using AtaReq sz %x\n", _ConfigInfo->nt4.SrbExtensionSize));
|
||||
}
|
||||
if((WinVer_Id() > WinVer_2k) ||
|
||||
(ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
|
||||
|
@ -1478,10 +1455,6 @@ UniataFindBusMasterController(
|
|||
ConfigInfo->ScatterGather = TRUE;
|
||||
}
|
||||
|
||||
// Note: now we can support only 4 channels !!!
|
||||
// in order to add support for multichannel controllers we must rewrite
|
||||
// io-range claiming algorithm
|
||||
|
||||
KdPrint2((PRINT_PREFIX "BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList[i].channel, deviceExtension->NumberChannels, channel));
|
||||
|
||||
for (; channel < (BMList[i].channel + deviceExtension->NumberChannels); channel++, c++) {
|
||||
|
@ -1645,7 +1618,9 @@ UniataFindBusMasterController(
|
|||
chan->RegTranslation[IDX_SATA_IO].MemIo ? "mem" : "io"));
|
||||
|
||||
if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
|
||||
#if DBG
|
||||
UniataDumpATARegs(chan);
|
||||
#endif
|
||||
|
||||
#ifndef UNIATA_CORE
|
||||
#ifdef UNIATA_INIT_ON_PROBE
|
||||
|
@ -1744,6 +1719,11 @@ exit_findbm:
|
|||
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
||||
BaseIoAddressBM_0);
|
||||
|
||||
if(deviceExtension->BaseIoAHCI_0.Addr) {
|
||||
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
||||
deviceExtension->BaseIoAHCI_0.pAddr);
|
||||
}
|
||||
|
||||
KdPrint2((PRINT_PREFIX "return SP_RETURN_NOT_FOUND\n"));
|
||||
goto exit_notfound;
|
||||
} else {
|
||||
|
@ -1751,7 +1731,7 @@ exit_findbm:
|
|||
KdPrint2((PRINT_PREFIX "exit: init spinlock\n"));
|
||||
//KeInitializeSpinLock(&(deviceExtension->DpcSpinLock));
|
||||
deviceExtension->ActiveDpcChan =
|
||||
deviceExtension->FirstDpcChan = -1;
|
||||
deviceExtension->FirstDpcChan = CHAN_NOT_SPECIFIED;
|
||||
|
||||
BMList[i].Isr2Enable = FALSE;
|
||||
|
||||
|
@ -1796,13 +1776,11 @@ exit_findbm:
|
|||
return SP_RETURN_FOUND;
|
||||
|
||||
exit_error:
|
||||
if (deviceExtension->lun) ExFreePool(deviceExtension->lun);
|
||||
if (deviceExtension->chan) ExFreePool(deviceExtension->chan);
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return SP_RETURN_ERROR;
|
||||
|
||||
exit_notfound:
|
||||
ExFreePool(deviceExtension->lun);
|
||||
ExFreePool(deviceExtension->chan);
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return SP_RETURN_NOT_FOUND;
|
||||
|
||||
} // end UniataFindBusMasterController()
|
||||
|
@ -2056,7 +2034,7 @@ UniataFindFakeBusMasterController(
|
|||
UniataInitMapBM(deviceExtension,
|
||||
BaseIoAddressBM_0,
|
||||
(*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE);
|
||||
deviceExtension->BusMaster = TRUE;
|
||||
deviceExtension->BusMaster = DMA_MODE_BM;
|
||||
deviceExtension->BaseIoAddressBM_0.Addr = (ULONGIO_PTR)BaseIoAddressBM_0;
|
||||
if((*ConfigInfo->AccessRanges)[4].RangeInMemory) {
|
||||
deviceExtension->BaseIoAddressBM_0.MemIo = TRUE;
|
||||
|
@ -2129,13 +2107,11 @@ exit_findbm:
|
|||
return SP_RETURN_FOUND;
|
||||
|
||||
exit_error:
|
||||
if (deviceExtension->lun) ExFreePool(deviceExtension->lun);
|
||||
if (deviceExtension->chan) ExFreePool(deviceExtension->chan);
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return SP_RETURN_ERROR;
|
||||
|
||||
exit_notfound:
|
||||
ExFreePool(deviceExtension->lun);
|
||||
ExFreePool(deviceExtension->chan);
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return SP_RETURN_NOT_FOUND;
|
||||
|
||||
} // end UniataFindFakeBusMasterController()
|
||||
|
@ -2184,6 +2160,13 @@ UniataConnectIntr2(
|
|||
TRUE) {
|
||||
// Ok, continue...
|
||||
KdPrint2((PRINT_PREFIX "Multichannel native mode, go...\n"));
|
||||
#ifndef UNIATA_USE_XXableInterrupts
|
||||
// If we raise IRQL to TIMER value, other interrupt cannot occure on the same CPU
|
||||
if(KeNumberProcessors < 2) {
|
||||
KdPrint2((PRINT_PREFIX "Unnecessary (?), UP machine\n"));
|
||||
//return STATUS_SUCCESS;
|
||||
}
|
||||
#endif //UNIATA_USE_XXableInterrupts
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX "Unnecessary\n"));
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -2500,6 +2483,42 @@ AtapiFindController(
|
|||
UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
|
||||
UniataInitMapBM(deviceExtension, 0, FALSE);
|
||||
|
||||
#if DBG
|
||||
UniataDumpATARegs(chan);
|
||||
#endif
|
||||
|
||||
// Select master.
|
||||
SelectDrive(chan, 0);
|
||||
|
||||
statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
|
||||
|
||||
if(statusByte != AtapiReadPort1(chan, IDX_IO2_AltStatus)) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiFindController: Status vs AlsStatus missmatch, abort init ?\n"));
|
||||
|
||||
if(BaseIoAddress2) {
|
||||
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
||||
(PCHAR)BaseIoAddress2);
|
||||
BaseIoAddress2 = NULL;
|
||||
}
|
||||
BaseIoAddress2 = (PIDE_REGISTERS_2)((ULONGIO_PTR)BaseIoAddress1 + 0x0E);
|
||||
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
||||
ConfigInfo->AdapterInterfaceType,
|
||||
ConfigInfo->SystemIoBusNumber,
|
||||
ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress2),
|
||||
ATA_ALTIOSIZE,
|
||||
TRUE);
|
||||
if(!ioSpace) {
|
||||
BaseIoAddress2 = NULL;
|
||||
KdPrint2((PRINT_PREFIX " abort (0)\n"));
|
||||
goto not_found;
|
||||
}
|
||||
UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
|
||||
if(statusByte != AtapiReadPort1(chan, IDX_IO2_AltStatus)) {
|
||||
KdPrint2((PRINT_PREFIX " abort\n"));
|
||||
goto not_found;
|
||||
}
|
||||
}
|
||||
|
||||
retryIdentifier:
|
||||
|
||||
// Select master.
|
||||
|
@ -2507,16 +2526,18 @@ retryIdentifier:
|
|||
|
||||
// Check if card at this address.
|
||||
AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, 0xAA);
|
||||
statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
|
||||
|
||||
// Check if indentifier can be read back.
|
||||
if ((statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)) != 0xAA) {
|
||||
if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
|
||||
statusByte == IDE_STATUS_WRONG) {
|
||||
|
||||
KdPrint2((PRINT_PREFIX "AtapiFindController: Identifier read back from Master (%#x)\n",
|
||||
statusByte));
|
||||
|
||||
statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
|
||||
|
||||
if (statusByte & IDE_STATUS_BUSY) {
|
||||
if (statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
|
||||
|
||||
i = 0;
|
||||
|
||||
|
@ -2537,11 +2558,13 @@ retryIdentifier:
|
|||
|
||||
// Select slave.
|
||||
SelectDrive(chan, 1);
|
||||
statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
|
||||
|
||||
// See if slave is present.
|
||||
AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, 0xAA);
|
||||
|
||||
if ((statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)) != 0xAA) {
|
||||
if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
|
||||
statusByte == IDE_STATUS_WRONG) {
|
||||
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"AtapiFindController: Identifier read back from Slave (%#x)\n",
|
||||
|
@ -2578,6 +2601,12 @@ not_found:
|
|||
(*ConfigInfo->AccessRanges)[0].RangeLength = 8;
|
||||
(*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
|
||||
|
||||
if(BaseIoAddress2) {
|
||||
(*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG)BaseIoAddress2);
|
||||
(*ConfigInfo->AccessRanges)[1].RangeLength = 2;
|
||||
(*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE;
|
||||
}
|
||||
|
||||
// Indicate the interrupt level corresponding to this IO range.
|
||||
if (irq) {
|
||||
ConfigInfo->BusInterruptLevel = irq;
|
||||
|
@ -2604,10 +2633,13 @@ not_found:
|
|||
|
||||
KdPrint2((PRINT_PREFIX "chan = %#x\n", chan));
|
||||
//PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
|
||||
/*
|
||||
// should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0);
|
||||
|
||||
chan->DeviceExtension = deviceExtension;
|
||||
chan->lChannel = 0;
|
||||
chan->lun[0] = &(deviceExtension->lun[0]);
|
||||
chan->lun[1] = &(deviceExtension->lun[1]);
|
||||
chan->lun[1] = &(deviceExtension->lun[1]);*/
|
||||
|
||||
/* do extra channel-specific setups */
|
||||
AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
|
||||
|
@ -2661,6 +2693,8 @@ not_found:
|
|||
|
||||
// Save the Interrupe Mode for later use
|
||||
deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
|
||||
deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel;
|
||||
deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector;
|
||||
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"AtapiFindController: look for devices\n"));
|
||||
|
@ -2702,6 +2736,7 @@ not_found:
|
|||
MCACount++;
|
||||
}
|
||||
|
||||
ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"AtapiFindController: return SP_RETURN_FOUND\n"));
|
||||
return(SP_RETURN_FOUND);
|
||||
|
@ -2720,18 +2755,16 @@ not_found:
|
|||
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"AtapiFindController: return SP_RETURN_NOT_FOUND\n"));
|
||||
ExFreePool(deviceExtension->lun);
|
||||
ExFreePool(deviceExtension->chan);
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return(SP_RETURN_NOT_FOUND);
|
||||
|
||||
exit_error:
|
||||
if (deviceExtension->lun) ExFreePool(deviceExtension->lun);
|
||||
if (deviceExtension->chan) ExFreePool(deviceExtension->chan);
|
||||
UniataFreeLunExt(deviceExtension);
|
||||
return SP_RETURN_ERROR;
|
||||
|
||||
} // end AtapiFindController()
|
||||
|
||||
BOOLEAN
|
||||
ULONG
|
||||
NTAPI
|
||||
UniataAnybodyHome(
|
||||
IN PVOID HwDeviceExtension,
|
||||
|
@ -2747,64 +2780,98 @@ UniataAnybodyHome(
|
|||
SATA_SSTATUS_REG SStatus;
|
||||
UCHAR signatureLow;
|
||||
UCHAR signatureHigh;
|
||||
|
||||
|
||||
if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
|
||||
KdPrint2((PRINT_PREFIX " hidden\n"));
|
||||
UniataForgetDevice(LunExt);
|
||||
return FALSE;
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
// Select the device.
|
||||
SelectDrive(chan, deviceNumber);
|
||||
|
||||
signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
|
||||
signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
|
||||
|
||||
if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
|
||||
KdPrint2((PRINT_PREFIX " ATAPI at home\n", signatureLow));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
|
||||
AtapiStallExecution(10);
|
||||
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55);
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55);
|
||||
AtapiStallExecution(5);
|
||||
signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
|
||||
if(signatureLow != 0x55) {
|
||||
KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow));
|
||||
UniataForgetDevice(LunExt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA);
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA);
|
||||
AtapiStallExecution(5);
|
||||
signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
|
||||
if(signatureLow != 0xAA) {
|
||||
KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow));
|
||||
UniataForgetDevice(LunExt);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
|
||||
|
||||
SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, deviceNumber);
|
||||
KdPrint2((PRINT_PREFIX "SStatus %x\n", SStatus.Reg));
|
||||
if(SStatus.DET <= SStatus_DET_Dev_NoPhy) {
|
||||
KdPrint2((PRINT_PREFIX " SATA DET <= SStatus_DET_Dev_NoPhy\n"));
|
||||
return FALSE;
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
if(SStatus.SPD < SStatus_SPD_Gen1) {
|
||||
KdPrint2((PRINT_PREFIX " SATA SPD < SStatus_SPD_Gen1\n"));
|
||||
return FALSE;
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
if(SStatus.IPM == SStatus_IPM_NoDev) {
|
||||
KdPrint2((PRINT_PREFIX " SATA IPN == SStatus_IPM_NoDev\n"));
|
||||
return FALSE;
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
|
||||
// Select the device for legacy.
|
||||
goto legacy_select;
|
||||
}
|
||||
|
||||
} else {
|
||||
legacy_select:
|
||||
// Select the device.
|
||||
SelectDrive(chan, deviceNumber);
|
||||
AtapiStallExecution(5);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if((deviceExtension->HwFlags & UNIATA_AHCI) &&
|
||||
UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI check\n"));
|
||||
ULONG SIG = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
|
||||
signatureLow = (UCHAR)(SIG >> 16);
|
||||
signatureHigh = (UCHAR)(SIG >> 24);
|
||||
} else {
|
||||
signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
|
||||
signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
|
||||
}
|
||||
|
||||
if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
|
||||
KdPrint2((PRINT_PREFIX " ATAPI at home\n"));
|
||||
return ATA_AT_HOME_ATAPI;
|
||||
}
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI HDD at home\n"));
|
||||
return ATA_AT_HOME_HDD;
|
||||
}
|
||||
|
||||
AtapiStallExecution(10);
|
||||
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55);
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55);
|
||||
AtapiStallExecution(5);
|
||||
signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
|
||||
if(signatureLow != 0x55) {
|
||||
if(signatureLow == 0xff || signatureLow == 0) {
|
||||
KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow));
|
||||
UniataForgetDevice(LunExt);
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
// another chance
|
||||
signatureLow = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
|
||||
signatureLow += 2;
|
||||
AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, signatureLow);
|
||||
AtapiStallExecution(5);
|
||||
signatureHigh = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
|
||||
if(signatureLow != signatureHigh) {
|
||||
KdPrint2((PRINT_PREFIX " nobody home! last chance failed %#x != %#x\n", signatureLow, signatureHigh));
|
||||
UniataForgetDevice(LunExt);
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
return ATA_AT_HOME_XXX;
|
||||
}
|
||||
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA);
|
||||
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA);
|
||||
AtapiStallExecution(5);
|
||||
signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
|
||||
if(signatureLow != 0xAA) {
|
||||
KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow));
|
||||
UniataForgetDevice(LunExt);
|
||||
return ATA_AT_HOME_NOBODY;
|
||||
}
|
||||
|
||||
KdPrint2((PRINT_PREFIX " HDD at home\n"));
|
||||
return ATA_AT_HOME_HDD;
|
||||
} // end UniataAnybodyHome()
|
||||
|
||||
ULONG
|
||||
|
@ -2830,10 +2897,14 @@ CheckDevice(
|
|||
KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n",
|
||||
deviceNumber));
|
||||
|
||||
if(deviceNumber > chan->NumberLuns) {
|
||||
if(deviceNumber >= chan->NumberLuns) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
LunExt = chan->lun[deviceNumber];
|
||||
|
||||
if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
|
||||
|
@ -2856,11 +2927,11 @@ CheckDevice(
|
|||
}
|
||||
statusByte = WaitOnBusy(chan);
|
||||
|
||||
if((statusByte | IDE_STATUS_BUSY) == 0xff) {
|
||||
if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"CheckDevice: bad status %x\n", statusByte));
|
||||
} else
|
||||
if(statusByte != 0xff && (statusByte & IDE_STATUS_BUSY)) {
|
||||
if(statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
|
||||
// Perform hard-reset.
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"CheckDevice: BUSY\n"));
|
||||
|
@ -2882,16 +2953,18 @@ CheckDevice(
|
|||
"CheckDevice: status after hard reset %x\n", statusByte));
|
||||
}
|
||||
|
||||
if((statusByte | IDE_STATUS_BUSY) == 0xff) {
|
||||
if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"CheckDevice: no dev ?\n"));
|
||||
UniataForgetDevice(LunExt);
|
||||
return 0;
|
||||
} else
|
||||
if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
|
||||
//if(deviceExtension->HwFlags & UNIATA_SATA) {
|
||||
KdPrint2((PRINT_PREFIX
|
||||
"CheckDevice: try enable SATA Phy\n"));
|
||||
statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel, deviceNumber);
|
||||
if(statusByte == 0xff) {
|
||||
if(statusByte == IDE_STATUS_WRONG) {
|
||||
KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte));
|
||||
UniataForgetDevice(LunExt);
|
||||
return 0;
|
||||
|
@ -2919,7 +2992,7 @@ CheckDevice(
|
|||
}
|
||||
|
||||
KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte));
|
||||
if(((statusByte | IDE_STATUS_BUSY) == 0xff) ||
|
||||
if(((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) ||
|
||||
(statusByte & IDE_STATUS_BUSY)) {
|
||||
KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n"));
|
||||
UniataForgetDevice(LunExt);
|
||||
|
@ -2934,6 +3007,7 @@ CheckDevice(
|
|||
LunExt->RwSwitchCost = REORDER_COST_SWITCH_RW_HDD;
|
||||
LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_HDD;
|
||||
LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_HDD;
|
||||
LunExt->AtapiReadyWaitDelay = 0;
|
||||
|
||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
if(RetVal & DFLAGS_DEVICE_PRESENT) {
|
||||
|
@ -2946,8 +3020,11 @@ CheckDevice(
|
|||
KdPrint2((PRINT_PREFIX "CheckDevice: detected AHCI Device %#x\n",
|
||||
deviceNumber));
|
||||
} else {
|
||||
RetVal &= ~DFLAGS_ATAPI_DEVICE;
|
||||
LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
|
||||
//RetVal &= ~DFLAGS_ATAPI_DEVICE;
|
||||
//LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
|
||||
|
||||
UniataForgetDevice(LunExt);
|
||||
RetVal = 0;
|
||||
}
|
||||
}
|
||||
} else
|
||||
|
@ -3074,7 +3151,7 @@ FindDevices(
|
|||
// AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
|
||||
|
||||
// Clear expecting interrupt flag and current SRB field.
|
||||
chan->ExpectingInterrupt = FALSE;
|
||||
UniataExpectChannelInterrupt(chan, FALSE);
|
||||
// chan->CurrentSrb = NULL;
|
||||
// max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
|
||||
max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : deviceExtension->NumberLuns;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2008-2010 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2008-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
id_probe.cpp
|
||||
|
@ -306,11 +306,13 @@ UniataRemoveRequest(
|
|||
LunExt->last_write = ((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_WRITE);
|
||||
|
||||
// get request from longest queue to balance load
|
||||
if(chan->lun[0]->queue_depth * (chan->lun[0]->LunSelectWaitCount+1) >
|
||||
chan->lun[1]->queue_depth * (chan->lun[1]->LunSelectWaitCount+1)) {
|
||||
cdev = 0;
|
||||
} else {
|
||||
cdev = 1;
|
||||
if(chan->NumberLuns > 1) {
|
||||
if(chan->lun[0]->queue_depth * (chan->lun[0]->LunSelectWaitCount+1) >
|
||||
chan->lun[1]->queue_depth * (chan->lun[1]->LunSelectWaitCount+1)) {
|
||||
cdev = 0;
|
||||
} else {
|
||||
cdev = 1;
|
||||
}
|
||||
}
|
||||
/* // prevent too long wait for actively used device
|
||||
if(chan->lun[cdev ^ 1]->queue_depth &&
|
||||
|
@ -320,10 +322,12 @@ UniataRemoveRequest(
|
|||
// get next request for processing
|
||||
chan->cur_req = chan->lun[cdev]->first_req;
|
||||
chan->cur_cdev = cdev;
|
||||
if(!chan->lun[cdev ^ 1]->queue_depth) {
|
||||
chan->lun[cdev ^ 1]->LunSelectWaitCount=0;
|
||||
} else {
|
||||
chan->lun[cdev ^ 1]->LunSelectWaitCount++;
|
||||
if(chan->NumberLuns > 1) {
|
||||
if(!chan->lun[cdev ^ 1]->queue_depth) {
|
||||
chan->lun[cdev ^ 1]->LunSelectWaitCount=0;
|
||||
} else {
|
||||
chan->lun[cdev ^ 1]->LunSelectWaitCount++;
|
||||
}
|
||||
}
|
||||
chan->lun[cdev]->LunSelectWaitCount=0;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2008-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2008-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
id_probe.cpp
|
||||
|
@ -76,7 +76,7 @@ UniataSataConnect(
|
|||
}
|
||||
if(i >= 100) {
|
||||
KdPrint2((PRINT_PREFIX "UniataSataConnect: SStatus %8.8x\n", SStatus.Reg));
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
/* clear SATA error register */
|
||||
UniataSataWritePort4(chan, IDX_SATA_SError,
|
||||
|
@ -156,7 +156,7 @@ UniataSataPhyEnable(
|
|||
}
|
||||
|
||||
KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: failed\n"));
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
} // end UniataSataPhyEnable()
|
||||
|
||||
BOOLEAN
|
||||
|
@ -200,6 +200,7 @@ UniataSataClearErr(
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
//return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -408,7 +409,7 @@ UniataSataWritePM(
|
|||
if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
|
||||
return UniataAhciWritePM(chan, DeviceNumber, Reg, value);
|
||||
}
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
} // end UniataSataWritePM()
|
||||
|
||||
ULONG
|
||||
|
@ -628,6 +629,10 @@ UniataAhciInit(
|
|||
GHC | AHCI_GHC_AE);
|
||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||
KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
|
||||
if(!(GHC & AHCI_GHC_AE)) {
|
||||
KdPrint2((PRINT_PREFIX " Can't enable AHCI mode\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
deviceExtension->AHCI_CAP =
|
||||
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
||||
|
@ -718,7 +723,9 @@ UniataAhciDetect(
|
|||
ULONG i, n;
|
||||
ULONG PI;
|
||||
ULONG CAP;
|
||||
ULONG CAP2;
|
||||
ULONG GHC;
|
||||
ULONG BOHC;
|
||||
ULONG NumberChannels;
|
||||
ULONG v_Mn, v_Mj;
|
||||
ULONG BaseMemAddress;
|
||||
|
@ -726,7 +733,7 @@ UniataAhciDetect(
|
|||
|
||||
KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
|
||||
|
||||
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhci", 1 /* DEBUG */)) {
|
||||
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhci", 0)) {
|
||||
KdPrint((" AHCI excluded\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -762,11 +769,16 @@ UniataAhciDetect(
|
|||
}
|
||||
|
||||
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
||||
KdPrint2((PRINT_PREFIX " AHCI CAP %#x\n", CAP));
|
||||
CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
|
||||
KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x\n", CAP, CAP2));
|
||||
if(CAP & AHCI_CAP_S64A) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
|
||||
//deviceExtension->Host64 = TRUE;
|
||||
}
|
||||
if(CAP2 & AHCI_CAP2_BOH) {
|
||||
BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
|
||||
KdPrint2((PRINT_PREFIX " AHCI BOHC %#x\n", BOHC));
|
||||
}
|
||||
|
||||
/* get the number of HW channels */
|
||||
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
|
||||
|
@ -807,7 +819,7 @@ UniataAhciDetect(
|
|||
KdPrint2((PRINT_PREFIX " PM supported\n"));
|
||||
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreAhciPM", 1 /* DEBUG */)) {
|
||||
KdPrint2((PRINT_PREFIX "SATA/AHCI w/o PM, max luns 1\n"));
|
||||
deviceExtension->NumberLuns = 2;
|
||||
deviceExtension->NumberLuns = 1;
|
||||
//chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX "SATA/AHCI -> possible PM, max luns %d\n", SATA_MAX_PM_UNITS));
|
||||
|
@ -819,7 +831,14 @@ UniataAhciDetect(
|
|||
deviceExtension->NumberLuns = 1;
|
||||
}
|
||||
|
||||
if((v_Mj != 0x01) || (v_Mn > 0x20)) {
|
||||
switch(version) {
|
||||
case 0x00000905:
|
||||
case 0x00010000:
|
||||
case 0x00010100:
|
||||
case 0x00010200:
|
||||
case 0x00010300:
|
||||
break;
|
||||
default:
|
||||
KdPrint2((PRINT_PREFIX " Unknown AHCI revision\n"));
|
||||
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"CheckAhciRevision", 1)) {
|
||||
KdPrint((" AHCI revision excluded\n"));
|
||||
|
@ -827,11 +846,15 @@ UniataAhciDetect(
|
|||
}
|
||||
}
|
||||
|
||||
deviceExtension->HwFlags |= UNIATA_SATA;
|
||||
deviceExtension->HwFlags |= UNIATA_AHCI;
|
||||
deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
|
||||
if(deviceExtension->NumberChannels < NumberChannels) {
|
||||
deviceExtension->NumberChannels = NumberChannels;
|
||||
}
|
||||
deviceExtension->DmaSegmentLength = 0x3fffff+1; // 4MB
|
||||
deviceExtension->DmaSegmentAlignmentMask = -1; // no restrictions
|
||||
|
||||
deviceExtension->BusMaster = DMA_MODE_AHCI;
|
||||
deviceExtension->MaxTransferMode = max(deviceExtension->MaxTransferMode, ATA_SA150);
|
||||
|
||||
return TRUE;
|
||||
} // end UniataAhciDetect()
|
||||
|
@ -855,7 +878,7 @@ UniataAhciStatus(
|
|||
//ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
|
||||
ULONG tag=0;
|
||||
|
||||
KdPrint(("UniataAhciStatus:\n"));
|
||||
KdPrint(("UniataAhciStatus(%d-%d):\n", lChannel, Channel));
|
||||
|
||||
hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
|
||||
KdPrint((" hIS %#x\n", hIS));
|
||||
|
@ -873,7 +896,7 @@ UniataAhciStatus(
|
|||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg);
|
||||
AtapiWritePort4(chan, IDX_SATA_SError, SError.Reg);
|
||||
|
||||
KdPrint((" AHCI: status=%08x sstatus=%08x error=%08x CI=%08x\n",
|
||||
KdPrint((" AHCI: istatus=%08x sstatus=%08x serror=%08x CI=%08x\n",
|
||||
IS.Reg, SStatus.Reg, SError.Reg, CI));
|
||||
|
||||
/* do we have cold connect surprise */
|
||||
|
@ -887,11 +910,35 @@ UniataAhciStatus(
|
|||
if(IS.PRCS) {
|
||||
UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH);
|
||||
}
|
||||
chan->AhciCompleteCI = (chan->AhciPrevCI ^ CI) & chan->AhciPrevCI; // only 1->0 states
|
||||
chan->AhciPrevCI = CI;
|
||||
KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI));
|
||||
chan->AhciLastIS = IS.Reg;
|
||||
if(CI & (1 << tag)) {
|
||||
return INTERRUPT_REASON_OUR;
|
||||
#ifdef DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
#endif //DBG
|
||||
//deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
|
||||
if(IS.Reg &
|
||||
(ATA_AHCI_P_IX_OF | ATA_AHCI_P_IX_INF | ATA_AHCI_P_IX_IF |
|
||||
ATA_AHCI_P_IX_HBD | ATA_AHCI_P_IX_HBF | ATA_AHCI_P_IX_TFE)) {
|
||||
KdPrint((" AHCI: unexpected, error\n"));
|
||||
} else {
|
||||
KdPrint((" AHCI: unexpected, incomplete command or error ?\n"));
|
||||
/*
|
||||
ULONG TFD;
|
||||
|
||||
TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
|
||||
KdPrint2((" TFD %#x\n", TFD));
|
||||
if(TFD & IDE_STATUS_BUSY) {
|
||||
KdPrint2((" Seems to be interrupt on error\n"));
|
||||
return INTERRUPT_REASON_OUR;
|
||||
}
|
||||
*/
|
||||
return INTERRUPT_REASON_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
KdPrint((" AHCI: unexpected\n"));
|
||||
return INTERRUPT_REASON_UNEXPECTED;
|
||||
return INTERRUPT_REASON_OUR;
|
||||
|
||||
} // end UniataAhciStatus()
|
||||
|
||||
|
@ -905,35 +952,42 @@ UniataAhciSetupFIS_H2D(
|
|||
IN UCHAR command,
|
||||
IN ULONGLONG lba,
|
||||
IN USHORT count,
|
||||
IN USHORT feature,
|
||||
IN ULONG flags
|
||||
IN USHORT feature
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
//ULONG i;
|
||||
PUCHAR plba;
|
||||
BOOLEAN need48;
|
||||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
|
||||
KdPrint2((PRINT_PREFIX " AHCI setup FIS ch %d, dev %d\n", lChannel, DeviceNumber));
|
||||
i = 0;
|
||||
KdPrint2((PRINT_PREFIX " AHCI setup FIS %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
|
||||
//i = 0;
|
||||
plba = (PUCHAR)&lba;
|
||||
|
||||
RtlZeroMemory(fis, 20);
|
||||
|
||||
fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
|
||||
fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
|
||||
fis[7] = IDE_USE_LBA;
|
||||
fis[15] = IDE_DC_A_4BIT;
|
||||
fis[IDX_AHCI_o_DriveSelect] = IDE_DRIVE_SELECT_1 |
|
||||
((AtaCommandFlags[command] & (ATA_CMD_FLAG_LBAIOsupp | ATA_CMD_FLAG_48)) ? IDE_USE_LBA : 0);
|
||||
fis[IDX_AHCI_o_Control] = IDE_DC_A_4BIT;
|
||||
|
||||
if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
|
||||
fis[2] = IDE_COMMAND_ATAPI_PACKET;
|
||||
// IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
|
||||
// the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
|
||||
if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
|
||||
*/
|
||||
command == IDE_COMMAND_ATAPI_PACKET) {
|
||||
fis[IDX_AHCI_o_Command] = IDE_COMMAND_ATAPI_PACKET;
|
||||
if(feature & ATA_F_DMA) {
|
||||
fis[3] = (UCHAR)(feature & 0xff);
|
||||
fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
|
||||
} else {
|
||||
fis[5] = (UCHAR)(count & 0xff);
|
||||
fis[6] = (UCHAR)(count>>8) & 0xff;
|
||||
fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
|
||||
fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
|
||||
}
|
||||
//fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
|
||||
} else {
|
||||
|
||||
if((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) &&
|
||||
if(((AtaCommandFlags[command] & (ATA_CMD_FLAG_LBAIOsupp|ATA_CMD_FLAG_FUA)) == ATA_CMD_FLAG_LBAIOsupp) &&
|
||||
CheckIfBadBlock(chan->lun[DeviceNumber], lba, count)) {
|
||||
KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
|
||||
//return IDE_STATUS_ERROR;
|
||||
|
@ -954,32 +1008,40 @@ UniataAhciSetupFIS_H2D(
|
|||
}
|
||||
}
|
||||
|
||||
fis[2] = command;
|
||||
fis[3] = (UCHAR)feature;
|
||||
fis[IDX_AHCI_o_Command] = command;
|
||||
fis[IDX_AHCI_o_Feature] = (UCHAR)feature;
|
||||
|
||||
fis[IDX_AHCI_o_BlockNumber] = plba[0];
|
||||
fis[IDX_AHCI_o_CylinderLow] = plba[1];
|
||||
fis[IDX_AHCI_o_CylinderHigh] = plba[2];
|
||||
|
||||
fis[IDX_AHCI_o_BlockCount] = (UCHAR)count & 0xff;
|
||||
|
||||
fis[4] = plba[0];
|
||||
fis[5] = plba[1];
|
||||
fis[6] = plba[2];
|
||||
if(need48) {
|
||||
i++;
|
||||
//i++;
|
||||
fis[IDX_AHCI_o_Control] |= IDE_DC_USE_HOB;
|
||||
|
||||
fis[IDX_AHCI_o_BlockNumberExp] = plba[3];
|
||||
fis[IDX_AHCI_o_CylinderLowExp] = plba[4];
|
||||
fis[IDX_AHCI_o_CylinderHighExp] = plba[5];
|
||||
|
||||
fis[IDX_AHCI_o_BlockCountExp] = (UCHAR)(count>>8) & 0xff;
|
||||
|
||||
fis[IDX_AHCI_o_FeatureExp] = (UCHAR)(feature>>8) & 0xff;
|
||||
|
||||
chan->ChannelCtrlFlags |= CTRFLAGS_LBA48;
|
||||
} else {
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4333) // right shift by too large amount, data loss
|
||||
#endif
|
||||
fis[7] |= IDE_DRIVE_1 | ((plba[3] >> 24) & 0x0f);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma warning(push)
|
||||
//#pragma warning(disable:4333) // right shift by too large amount, data loss
|
||||
//#endif
|
||||
fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
|
||||
chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma warning(pop)
|
||||
//#endif
|
||||
}
|
||||
|
||||
fis[8] = plba[3];
|
||||
fis[9] = plba[4];
|
||||
fis[10] = plba[5];
|
||||
fis[11] = (UCHAR)(feature>>8) & 0xff;
|
||||
|
||||
fis[12] = (UCHAR)count & 0xff;
|
||||
fis[13] = (UCHAR)(count>>8) & 0xff;
|
||||
//fis[14] = 0x00;
|
||||
|
||||
}
|
||||
|
@ -991,48 +1053,36 @@ UniataAhciSetupFIS_H2D(
|
|||
|
||||
UCHAR
|
||||
NTAPI
|
||||
UniataAhciSendCommand(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG lChannel,
|
||||
IN ULONG DeviceNumber,
|
||||
IN ULONG flags,
|
||||
UniataAhciWaitCommandReady(
|
||||
IN PHW_CHANNEL chan,
|
||||
IN ULONG timeout
|
||||
)
|
||||
{
|
||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
//ULONG Channel = deviceExtension->Channel + lChannel;
|
||||
//ULONG hIS;
|
||||
ULONG CI = 0;
|
||||
AHCI_IS_REG IS;
|
||||
ULONG SError;
|
||||
//SATA_SSTATUS_REG SStatus;
|
||||
//SATA_SERROR_REG SError;
|
||||
//ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
|
||||
//ULONGIO_PTR base;
|
||||
ULONG tag=0;
|
||||
ULONG CI=0;
|
||||
ULONG i;
|
||||
ULONG SError;
|
||||
ULONG tag=0;
|
||||
|
||||
PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
|
||||
|
||||
KdPrint(("UniataAhciSendCommand: lChan %d\n", chan->lChannel));
|
||||
|
||||
AHCI_CL->prd_length = 0;
|
||||
AHCI_CL->cmd_flags = (20 / sizeof(ULONG)) | flags | (DeviceNumber << 12);
|
||||
AHCI_CL->bytecount = 0;
|
||||
AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
|
||||
if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
|
||||
}
|
||||
|
||||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, ATA_AHCI_P_CMD_ST);
|
||||
timeout *= 5;
|
||||
|
||||
for (i=0; i<timeout; i++) {
|
||||
AtapiStallExecution(1000);
|
||||
CI = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CI);
|
||||
if (!(CI & ATA_AHCI_P_CMD_ST)) {
|
||||
if (!((CI >> tag) & 0x01)) {
|
||||
break;
|
||||
}
|
||||
IS.Reg = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_IS);
|
||||
//KdPrint((" IS %#x\n", IS.Reg));
|
||||
if(IS.Reg) {
|
||||
break;
|
||||
}
|
||||
SError = AtapiReadPort4(chan, IDX_SATA_SError);
|
||||
if(SError) {
|
||||
KdPrint((" AHCI: error %#x\n", SError));
|
||||
i = timeout;
|
||||
break;
|
||||
}
|
||||
AtapiStallExecution(200);
|
||||
}
|
||||
KdPrint((" CI %#x\n", CI));
|
||||
|
||||
|
@ -1045,6 +1095,7 @@ UniataAhciSendCommand(
|
|||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg);
|
||||
|
||||
if (timeout && (i >= timeout)) {
|
||||
#ifdef DBG
|
||||
ULONG TFD;
|
||||
|
||||
SError = AtapiReadPort4(chan, IDX_SATA_SError);
|
||||
|
@ -1052,14 +1103,172 @@ UniataAhciSendCommand(
|
|||
|
||||
TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
|
||||
KdPrint2((" TFD %#x\n", TFD));
|
||||
#endif //DBG
|
||||
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
|
||||
return IDE_STATUS_IDLE;
|
||||
} // end UniataAhciWaitCommandReady()
|
||||
|
||||
UCHAR
|
||||
NTAPI
|
||||
UniataAhciSendCommand(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG lChannel,
|
||||
IN ULONG DeviceNumber,
|
||||
IN USHORT ahci_flags,
|
||||
IN ULONG timeout
|
||||
)
|
||||
{
|
||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
//ULONG Channel = deviceExtension->Channel + lChannel;
|
||||
//ULONG hIS;
|
||||
//ULONG SError;
|
||||
//SATA_SSTATUS_REG SStatus;
|
||||
//SATA_SERROR_REG SError;
|
||||
//ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS);
|
||||
//ULONGIO_PTR base;
|
||||
ULONG tag=0;
|
||||
|
||||
PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
|
||||
|
||||
KdPrint(("UniataAhciSendCommand: lChan %d\n", chan->lChannel));
|
||||
|
||||
AHCI_CL->prd_length = 0;
|
||||
//AHCI_CL->cmd_flags = (20 / sizeof(ULONG)) | ahci_flags | (DeviceNumber << 12);
|
||||
AHCI_CL->cmd_flags = UniAtaAhciAdjustIoFlags(0, ahci_flags, 20, DeviceNumber);
|
||||
|
||||
AHCI_CL->bytecount = 0;
|
||||
AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
|
||||
if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
|
||||
}
|
||||
|
||||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 1 << tag);
|
||||
|
||||
return UniataAhciWaitCommandReady(chan, timeout);
|
||||
|
||||
} // end UniataAhciSendCommand()
|
||||
|
||||
UCHAR
|
||||
NTAPI
|
||||
UniataAhciSendPIOCommand(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG lChannel,
|
||||
IN ULONG DeviceNumber,
|
||||
IN PSCSI_REQUEST_BLOCK Srb,
|
||||
IN PUCHAR data,
|
||||
IN ULONG length, /* bytes */
|
||||
IN UCHAR command,
|
||||
IN ULONGLONG lba,
|
||||
IN USHORT bcount, /* block count, just ATA register */
|
||||
IN USHORT feature,
|
||||
IN USHORT ahci_flags,
|
||||
IN ULONG wait_flags,
|
||||
IN ULONG timeout
|
||||
)
|
||||
{
|
||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
UCHAR statusByte;
|
||||
PATA_REQ AtaReq;
|
||||
ULONG fis_size;
|
||||
ULONG tag=0;
|
||||
//PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
|
||||
PIDE_AHCI_CMD AHCI_CMD = NULL;
|
||||
|
||||
PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
|
||||
|
||||
KdPrint2((PRINT_PREFIX "UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x bcount %#x feature %#x, buff %#x, len %#x, WF %#x \n",
|
||||
deviceExtension->DevIndex, lChannel, DeviceNumber, command, lba, bcount, feature, data, length, wait_flags ));
|
||||
|
||||
if(length/DEV_BSIZE != bcount) {
|
||||
KdPrint((" length/DEV_BSIZE != bcount\n"));
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
//UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
if(!Srb) {
|
||||
Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length);
|
||||
if(!Srb) {
|
||||
KdPrint((" !Srb\n"));
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
//UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
|
||||
//should be already called on init
|
||||
}
|
||||
AtaReq = (PATA_REQ)(Srb->SrbExtension);
|
||||
//KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
|
||||
|
||||
AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
|
||||
|
||||
fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
|
||||
&(AHCI_CMD->cfis[0]),
|
||||
command,
|
||||
lba,
|
||||
bcount,
|
||||
feature
|
||||
);
|
||||
|
||||
if(!fis_size) {
|
||||
KdPrint2(("!fis_size\n"));
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
|
||||
//KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
|
||||
ahci_flags = UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber);
|
||||
KdPrint2(("ahci_flags %#x\n", ahci_flags));
|
||||
|
||||
if(data) {
|
||||
if(ahci_flags & ATA_AHCI_CMD_WRITE) {
|
||||
AtaReq->Flags &= ~REQ_FLAG_READ;
|
||||
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
|
||||
KdPrint((" assume OUT\n"));
|
||||
} else {
|
||||
AtaReq->Flags |= REQ_FLAG_READ;
|
||||
Srb->SrbFlags |= SRB_FLAGS_DATA_IN;
|
||||
KdPrint((" assume IN\n"));
|
||||
}
|
||||
if(!AtapiDmaSetup(HwDeviceExtension,
|
||||
DeviceNumber,
|
||||
lChannel, // logical channel,
|
||||
Srb,
|
||||
data,
|
||||
length)) {
|
||||
KdPrint2((" can't setup buffer\n"));
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
}
|
||||
|
||||
AtaReq->ahci.io_cmd_flags = ahci_flags;
|
||||
|
||||
#ifdef DBG
|
||||
//UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
|
||||
|
||||
#ifdef DBG
|
||||
//UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
if(wait_flags == ATA_IMMEDIATE) {
|
||||
statusByte = 0;
|
||||
KdPrint2((" return imemdiately\n"));
|
||||
} else {
|
||||
statusByte = UniataAhciWaitCommandReady(chan, timeout);
|
||||
UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
|
||||
UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
|
||||
}
|
||||
|
||||
return statusByte;
|
||||
|
||||
} // end UniataAhciSendPIOCommand()
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
UniataAhciSoftReset(
|
||||
|
@ -1082,7 +1291,7 @@ UniataAhciSoftReset(
|
|||
PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
|
||||
|
||||
#ifdef DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
// UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
/* kick controller into sane state */
|
||||
|
@ -1091,7 +1300,7 @@ UniataAhciSoftReset(
|
|||
UniataAhciStart(chan);
|
||||
|
||||
#ifdef DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
// UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
/* pull reset active */
|
||||
|
@ -1101,7 +1310,7 @@ UniataAhciSoftReset(
|
|||
//AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
|
||||
AHCI_CMD->cfis[15] = (IDE_DC_A_4BIT | IDE_DC_RESET_CONTROLLER);
|
||||
|
||||
if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, ATA_AHCI_CMD_RESET | ATA_AHCI_CMD_CLR_BUSY, 100) == 0xff) {
|
||||
if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, ATA_AHCI_CMD_RESET | ATA_AHCI_CMD_CLR_BUSY, 100) == IDE_STATUS_WRONG) {
|
||||
KdPrint2((" timeout\n"));
|
||||
return (ULONG)(-1);
|
||||
}
|
||||
|
@ -1113,7 +1322,7 @@ UniataAhciSoftReset(
|
|||
AHCI_CMD->cfis[1] = (UCHAR)DeviceNumber & 0x0f;
|
||||
//AHCI_CMD->cfis[7] = IDE_USE_LBA | IDE_DRIVE_SELECT;
|
||||
AHCI_CMD->cfis[15] = (IDE_DC_A_4BIT);
|
||||
if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, 0, 3000) == 0xff) {
|
||||
if(UniataAhciSendCommand(HwDeviceExtension, lChannel, DeviceNumber, 0, 3000) == IDE_STATUS_WRONG) {
|
||||
KdPrint2((" timeout (2)\n"));
|
||||
return (ULONG)(-1);
|
||||
}
|
||||
|
@ -1172,9 +1381,9 @@ UniataAhciHardReset(
|
|||
(*signature) = 0xffffffff;
|
||||
|
||||
UniataAhciStop(chan);
|
||||
if(UniataSataPhyEnable(HwDeviceExtension, lChannel, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE) == 0xff) {
|
||||
if(UniataSataPhyEnable(HwDeviceExtension, lChannel, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE) == IDE_STATUS_WRONG) {
|
||||
KdPrint((" no PHY\n"));
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
|
||||
/* Wait for clearing busy status. */
|
||||
|
@ -1467,31 +1676,60 @@ UniataAhciBeginTransaction(
|
|||
|
||||
PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
|
||||
|
||||
KdPrint2(("UniataAhciBeginTransaction: lChan %d\n", chan->lChannel));
|
||||
KdPrint2(("UniataAhciBeginTransaction: lChan %d, AtaReq %#x\n", chan->lChannel, AtaReq));
|
||||
|
||||
if(AtaReq->dma_entries > (USHORT)0xffff) {
|
||||
KdPrint2(("UniataAhciBeginTransaction too long DMA tab\n"));
|
||||
if(Srb->DataTransferLength && (!AtaReq->dma_entries || AtaReq->dma_entries >= (USHORT)0xffff)) {
|
||||
KdPrint2(("UniataAhciBeginTransaction wrong DMA tab len %x\n", AtaReq->dma_entries));
|
||||
return 0;
|
||||
}
|
||||
|
||||
AHCI_CL->prd_length = (USHORT)AtaReq->dma_entries;
|
||||
AHCI_CL->prd_length = (USHORT)(AtaReq->dma_entries);
|
||||
AHCI_CL->cmd_flags = AtaReq->ahci.io_cmd_flags;
|
||||
AHCI_CL->bytecount = 0;
|
||||
AHCI_CL->cmd_table_phys = AtaReq->ahci.ahci_base64;
|
||||
if(AtaReq->ahci.ahci_base64) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI AtaReq CMD %#x (ph %#x)\n", AtaReq->ahci.ahci_cmd_ptr, (ULONG)(AtaReq->ahci.ahci_base64)));
|
||||
AHCI_CL->cmd_table_phys = AtaReq->ahci.ahci_base64;
|
||||
} else
|
||||
if(AtaReq->ahci.ahci_cmd_ptr) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI AtaReq->Chan CMD %#x (ph %#x) -> %#x (ph %#x)\n",
|
||||
AtaReq->ahci.ahci_cmd_ptr, (ULONG)(AtaReq->ahci.ahci_base64),
|
||||
&(chan->AhciCtlBlock->cmd), chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd) ));
|
||||
RtlCopyMemory(&(chan->AhciCtlBlock->cmd), AtaReq->ahci.ahci_cmd_ptr,
|
||||
FIELD_OFFSET(IDE_AHCI_CMD, prd_tab)+AHCI_CL->prd_length*sizeof(IDE_AHCI_PRD_ENTRY));
|
||||
AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX " no AHCI CMD\n"));
|
||||
//AHCI_CL->cmd_table_phys = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
|
||||
return 0;
|
||||
}
|
||||
if(AHCI_CL->cmd_table_phys & AHCI_CMD_ALIGNEMENT_MASK) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags,
|
||||
AHCI_CL->cmd_table_phys));
|
||||
#endif // DBG
|
||||
|
||||
CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
|
||||
KdPrint2((" CMD %#x\n", CMD));
|
||||
CMD &= ~ATA_AHCI_P_CMD_ATAPI;
|
||||
KdPrint2((" send CMD %#x\n", CMD));
|
||||
// switch controller to ATAPI mode for ATA_PACKET commands only
|
||||
if(ATAPI_DEVICE(chan, DeviceNumber) &&
|
||||
AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_PACKET) {
|
||||
KdPrint2((" ATAPI\n"));
|
||||
CMD |= ATA_AHCI_P_CMD_ATAPI;
|
||||
} else {
|
||||
CMD &= ~ATA_AHCI_P_CMD_ATAPI;
|
||||
}
|
||||
KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
|
||||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
|
||||
|
||||
/* issue command to controller */
|
||||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, ATA_AHCI_P_CMD_ST);
|
||||
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 0x01 << tag);
|
||||
chan->AhciPrevCI |= 0x01 << tag;
|
||||
|
||||
if(!(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
|
||||
if(!ATAPI_DEVICE(chan, DeviceNumber)) {
|
||||
// TODO: check if we send ATA_RESET and wait for ready of so.
|
||||
if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) {
|
||||
ULONG TFD;
|
||||
|
@ -1511,7 +1749,7 @@ UniataAhciBeginTransaction(
|
|||
}
|
||||
AtaReq->ahci.in_status = TFD;
|
||||
|
||||
return 0x00;
|
||||
return IDE_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1532,17 +1770,27 @@ UniataAhciEndTransaction(
|
|||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
//ULONG Channel = deviceExtension->Channel + lChannel;
|
||||
//ULONG hIS;
|
||||
ULONG CI;
|
||||
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
|
||||
ULONG TFD;
|
||||
PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
|
||||
ULONG tag=0;
|
||||
//ULONG i;
|
||||
PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
|
||||
PHW_LU_EXTENSION LunExt;
|
||||
|
||||
KdPrint2(("UniataAhciEndTransaction: lChan %d\n", chan->lChannel));
|
||||
|
||||
LunExt = chan->lun[DeviceNumber];
|
||||
|
||||
TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
|
||||
KdPrint2((" TFD %#x\n", TFD));
|
||||
|
||||
if(TFD & IDE_STATUS_ERROR) {
|
||||
KdPrint2((" ERROR %#x\n", (UCHAR)(TFD >> 8)));
|
||||
AtaReq->ahci.in_error = (UCHAR)(TFD >> 8);
|
||||
KdPrint2((" ERROR %#x\n", AtaReq->ahci.in_error));
|
||||
} else {
|
||||
AtaReq->ahci.in_error = 0;
|
||||
}
|
||||
AtaReq->ahci.in_status = TFD;
|
||||
|
||||
|
@ -1560,7 +1808,42 @@ UniataAhciEndTransaction(
|
|||
((ULONGLONG)(RCV_FIS[9]) << 32) |
|
||||
((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
|
||||
}
|
||||
AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
|
||||
|
||||
if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
|
||||
KdPrint2(("RCV:\n"));
|
||||
KdDump(RCV_FIS, 24);
|
||||
KdPrint2(("PIO:\n"));
|
||||
KdDump(&(chan->AhciCtlBlock->rcv_fis.psfis[0]), 24);
|
||||
|
||||
KdPrint2(("len: %d vs %d\n", AHCI_CL->bytecount, (ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8) ));
|
||||
if(!AHCI_CL->bytecount) {
|
||||
AtaReq->WordsTransfered = ((ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8)) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
CI = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CI);
|
||||
if(CI & (1 << tag)) {
|
||||
// clear CI
|
||||
KdPrint2((" Incomplete command, CI %#x\n", CI));
|
||||
KdPrint2((" FIS status %#x, error %#x\n", RCV_FIS[2], RCV_FIS[3]));
|
||||
|
||||
#if DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
#endif
|
||||
UniataAhciStop(chan);
|
||||
UniataAhciStart(chan);
|
||||
#if DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
#endif
|
||||
chan->AhciPrevCI = CI & ~((ULONG)1 << tag);
|
||||
if(chan->AhciPrevCI) {
|
||||
KdPrint2((" Need command list restart, CI %#x\n", chan->AhciPrevCI));
|
||||
}
|
||||
} else {
|
||||
chan->AhciPrevCI &= ~((ULONG)1 << tag);
|
||||
RtlZeroMemory(AHCI_CL, sizeof(IDE_AHCI_CMD_LIST));
|
||||
}
|
||||
//}
|
||||
|
||||
return 0;
|
||||
|
@ -1578,7 +1861,7 @@ UniataAhciResume(
|
|||
KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel));
|
||||
|
||||
#ifdef DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
//UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
/* Disable port interrupts */
|
||||
|
@ -1617,7 +1900,7 @@ UniataAhciResume(
|
|||
);
|
||||
|
||||
#ifdef DBG
|
||||
UniataDumpAhciPortRegs(chan);
|
||||
//UniataDumpAhciPortRegs(chan);
|
||||
#endif // DBG
|
||||
|
||||
UniataAhciStartFR(chan);
|
||||
|
@ -1710,7 +1993,7 @@ UniataAhciReadPM(
|
|||
AHCI_CMD->cfis[7] = (UCHAR)(IDE_USE_LBA | DeviceNumber);
|
||||
AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
|
||||
|
||||
if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 10) == 0xff) {
|
||||
if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 10) == IDE_STATUS_WRONG) {
|
||||
KdPrint2((" PM read failed\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1755,7 +2038,7 @@ UniataAhciWritePM(
|
|||
case IDX_SATA_SControl:
|
||||
Reg = 2; break;
|
||||
default:
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1773,9 +2056,9 @@ UniataAhciWritePM(
|
|||
|
||||
AHCI_CMD->cfis[15] = IDE_DC_A_4BIT;
|
||||
|
||||
if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 100) == 0xff) {
|
||||
if(UniataAhciSendCommand(chan->DeviceExtension, chan->lChannel, DeviceNumber, 0, 100) == IDE_STATUS_WRONG) {
|
||||
KdPrint2((" PM write failed\n"));
|
||||
return 0xff;
|
||||
return IDE_STATUS_WRONG;
|
||||
}
|
||||
|
||||
TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
|
||||
|
@ -1806,11 +2089,82 @@ IN OUT PATA_REQ AtaReq
|
|||
prd_base = (PUCHAR)(&AtaReq->ahci_cmd0);
|
||||
prd_base0 = prd_base;
|
||||
|
||||
prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK)) & ~AHCI_CMD_ALIGNEMENT_MASK;
|
||||
prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK;
|
||||
|
||||
d = (ULONG)(prd_base64 - prd_base64_0);
|
||||
KdPrint2((PRINT_PREFIX " aligned %I64x, d=%x\n", prd_base64, d));
|
||||
KdPrint2((PRINT_PREFIX " AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d));
|
||||
|
||||
AtaReq->ahci.ahci_cmd_ptr = (PIDE_AHCI_CMD)prd_base64;
|
||||
KdPrint2((PRINT_PREFIX " ahci_cmd_ptr %#x\n", AtaReq->ahci.ahci_cmd_ptr));
|
||||
} // end UniataAhciSetupCmdPtr()
|
||||
|
||||
PSCSI_REQUEST_BLOCK
|
||||
NTAPI
|
||||
BuildAhciInternalSrb (
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG DeviceNumber,
|
||||
IN ULONG lChannel,
|
||||
IN PUCHAR Buffer,
|
||||
IN ULONG Length
|
||||
)
|
||||
{
|
||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||
PSCSI_REQUEST_BLOCK srb;
|
||||
// PCDB cdb;
|
||||
PATA_REQ AtaReq = chan->AhciInternalAtaReq;
|
||||
|
||||
KdPrint(("BuildAhciInternalSrb: lChan %d [%#x]\n", lChannel, DeviceNumber));
|
||||
|
||||
if(!AtaReq) {
|
||||
KdPrint2((PRINT_PREFIX " !chan->AhciInternalAtaReq\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//RtlZeroMemory((PCHAR) AtaReq, sizeof(ATA_REQ));
|
||||
//RtlZeroMemory((PCHAR) AtaReq, FIELD_OFFSET(ATA_REQ, ahci));
|
||||
UniAtaClearAtaReq(AtaReq);
|
||||
|
||||
srb = chan->AhciInternalSrb;
|
||||
|
||||
RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
|
||||
|
||||
srb->PathId = (UCHAR)lChannel;
|
||||
srb->TargetId = (UCHAR)DeviceNumber;
|
||||
srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
|
||||
srb->Length = sizeof(SCSI_REQUEST_BLOCK);
|
||||
|
||||
// Set flags to disable synchronous negociation.
|
||||
//srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
|
||||
|
||||
// Set timeout to 4 seconds.
|
||||
srb->TimeOutValue = 4;
|
||||
|
||||
srb->CdbLength = 6;
|
||||
srb->DataBuffer = Buffer;
|
||||
srb->DataTransferLength = Length;
|
||||
srb->SrbExtension = AtaReq;
|
||||
|
||||
AtaReq->Srb = srb;
|
||||
AtaReq->DataBuffer = (PUSHORT)Buffer;
|
||||
AtaReq->TransferLength = Length;
|
||||
|
||||
//if(!AtaReq->ahci.ahci_cmd_ptr) {
|
||||
//UniataAhciSetupCmdPtr(AtaReq);
|
||||
//AtaReq->ahci.ahci_cmd_ptr = &(chan->AhciCtlBlock->cmd);
|
||||
//AtaReq->ahci.ahci_base64 = chan->AHCI_CTL_PhAddr + FIELD_OFFSET(IDE_AHCI_CHANNEL_CTL_BLOCK, cmd);
|
||||
//}
|
||||
//AtaReq->ahci.ahci_cmd_ptr = &(AtaReq->ahci_cmd0);
|
||||
//AtaReq->ahci.ahci_base64 = NULL; // indicate that we should copy command to proper place
|
||||
|
||||
KdPrint2((PRINT_PREFIX " Srb %#x, AtaReq %#x, CMD %#x ph %I64x\n", srb, AtaReq,
|
||||
AtaReq->ahci.ahci_cmd_ptr, AtaReq->ahci.ahci_base64));
|
||||
|
||||
/* // Set CDB operation code.
|
||||
cdb = (PCDB)srb->Cdb;
|
||||
cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
|
||||
cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
|
||||
*/
|
||||
return srb;
|
||||
} // end BuildAhciInternalSrb()
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2008-2011 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2008-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
id_probe.cpp
|
||||
|
@ -123,6 +123,14 @@ UniataAhciInit(
|
|||
IN PVOID HwDeviceExtension
|
||||
);
|
||||
|
||||
#if DBG
|
||||
VOID
|
||||
NTAPI
|
||||
UniataDumpAhciPortRegs(
|
||||
IN PHW_CHANNEL chan
|
||||
);
|
||||
#endif
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
UniataAhciDetect(
|
||||
|
@ -149,8 +157,14 @@ UniataAhciSetupFIS_H2D(
|
|||
IN UCHAR command,
|
||||
IN ULONGLONG lba,
|
||||
IN USHORT count,
|
||||
IN USHORT feature,
|
||||
IN ULONG flags
|
||||
IN USHORT feature
|
||||
);
|
||||
|
||||
UCHAR
|
||||
NTAPI
|
||||
UniataAhciWaitCommandReady(
|
||||
IN PHW_CHANNEL chan,
|
||||
IN ULONG timeout
|
||||
);
|
||||
|
||||
UCHAR
|
||||
|
@ -159,6 +173,24 @@ UniataAhciSendCommand(
|
|||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG lChannel,
|
||||
IN ULONG DeviceNumber,
|
||||
IN USHORT ahci_flags,
|
||||
IN ULONG timeout
|
||||
);
|
||||
|
||||
UCHAR
|
||||
NTAPI
|
||||
UniataAhciSendPIOCommand(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG lChannel,
|
||||
IN ULONG DeviceNumber,
|
||||
IN PSCSI_REQUEST_BLOCK Srb,
|
||||
IN PUCHAR data,
|
||||
IN ULONG length,
|
||||
IN UCHAR command,
|
||||
IN ULONGLONG lba,
|
||||
IN USHORT count,
|
||||
IN USHORT feature,
|
||||
IN USHORT ahci_flags,
|
||||
IN ULONG flags,
|
||||
IN ULONG timeout
|
||||
);
|
||||
|
@ -289,7 +321,32 @@ UniataAhciUlongFromRFIS(
|
|||
(((ULONG)(RCV_FIS[5])) << 16) |
|
||||
(((ULONG)(RCV_FIS[4])) << 8) |
|
||||
((ULONG)(RCV_FIS[12])) );
|
||||
}
|
||||
} // end UniataAhciUlongFromRFIS()
|
||||
|
||||
__inline
|
||||
USHORT
|
||||
UniAtaAhciAdjustIoFlags(
|
||||
IN UCHAR command,
|
||||
IN USHORT ahci_flags,
|
||||
IN ULONG fis_size,
|
||||
IN ULONG DeviceNumber
|
||||
)
|
||||
{
|
||||
ahci_flags |= (fis_size / sizeof(ULONG)) | (DeviceNumber << 12);
|
||||
if(!command) {
|
||||
return ahci_flags;
|
||||
}
|
||||
|
||||
if(AtaCommandFlags[command] & ATA_CMD_FLAG_Out) {
|
||||
ahci_flags |= ATA_AHCI_CMD_WRITE;
|
||||
}
|
||||
/*
|
||||
if(AtaCommandFlags[command] & ATA_CMD_FLAG_In) {
|
||||
ahci_flags |= ATA_AHCI_CMD_READ;
|
||||
}
|
||||
*/
|
||||
return ahci_flags;
|
||||
} // end UniAtaAhciAdjustIoFlags()
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
|
@ -314,4 +371,14 @@ UniataAhciSetupCmdPtr(
|
|||
IN OUT PATA_REQ AtaReq
|
||||
);
|
||||
|
||||
PSCSI_REQUEST_BLOCK
|
||||
NTAPI
|
||||
BuildAhciInternalSrb (
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN ULONG DeviceNumber,
|
||||
IN ULONG lChannel,
|
||||
IN PUCHAR Buffer = NULL,
|
||||
IN ULONG Length = 0
|
||||
);
|
||||
|
||||
#endif //__UNIATA_SATA__H__
|
||||
|
|
|
@ -98,6 +98,19 @@ typedef union _CDB {
|
|||
UCHAR Control;
|
||||
} ERASE, *PERASE;
|
||||
|
||||
struct _ERASE10 {
|
||||
UCHAR OperationCode;
|
||||
UCHAR Reserved : 1;
|
||||
UCHAR Immediate : 1;
|
||||
UCHAR ERA : 1;
|
||||
UCHAR Reserved1 : 2;
|
||||
UCHAR Lun : 3;
|
||||
UCHAR LBA[4];
|
||||
UCHAR Reserved2;
|
||||
UCHAR TransferBlocks[2];
|
||||
UCHAR Control;
|
||||
} ERASE10, *PERASE10;
|
||||
|
||||
#define FormatUnit_Code_Mask 0x07
|
||||
#define FormatUnit_Cmp 0x08
|
||||
#define FormatUnit_Fmt 0x10
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2002-2005 Alexandr A. Telyatnikov (Alter)
|
||||
Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
|
||||
|
||||
Module Name:
|
||||
tools.h
|
||||
|
@ -94,195 +94,6 @@ typedef struct _FOUR_BYTE {
|
|||
}
|
||||
#define DEC_TO_BCD(x) (((x / 10) << 4) + (x % 10))
|
||||
|
||||
/*
|
||||
|
||||
#if defined _X86_ && !defined(__GNUC__)
|
||||
|
||||
#define MOV_DD_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov eax,[ebx] \
|
||||
__asm bswap eax \
|
||||
__asm mov ebx,_to_ \
|
||||
__asm mov [ebx],eax \
|
||||
}
|
||||
|
||||
#define MOV_DW_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov ax,[ebx] \
|
||||
__asm rol ax,8 \
|
||||
__asm mov ebx,_to_ \
|
||||
__asm mov [ebx],ax \
|
||||
}
|
||||
|
||||
#define REVERSE_DD(a) { \
|
||||
PFOUR_BYTE _from_; \
|
||||
_from_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov eax,[ebx] \
|
||||
__asm bswap eax \
|
||||
__asm mov [ebx],eax \
|
||||
}
|
||||
|
||||
#define REVERSE_DW(a) { \
|
||||
PFOUR_BYTE _from_; \
|
||||
_from_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov eax,_from_ \
|
||||
__asm rol word ptr [eax],8 \
|
||||
}
|
||||
|
||||
#define MOV_DW2DD_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov ax,[ebx] \
|
||||
__asm rol ax,8 \
|
||||
__asm mov ebx,_to_ \
|
||||
__asm mov [ebx+2],ax \
|
||||
__asm mov [ebx],0 \
|
||||
}
|
||||
|
||||
#define MOV_SWP_DW2DD(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm xor eax,eax \
|
||||
__asm mov ax,[ebx] \
|
||||
__asm rol ax,8 \
|
||||
__asm mov ebx,_to_ \
|
||||
__asm mov [ebx],eax \
|
||||
}
|
||||
|
||||
#define MOV_MSF(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov eax,[ebx] \
|
||||
__asm mov ebx,_to_ \
|
||||
__asm mov [ebx],ax \
|
||||
__asm shr eax,16 \
|
||||
__asm mov [ebx+2],al \
|
||||
}
|
||||
|
||||
#define MOV_MSF_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov eax,[ebx] \
|
||||
__asm mov ebx,_to_ \
|
||||
__asm mov [ebx+2],al \
|
||||
__asm bswap eax \
|
||||
__asm shr eax,8 \
|
||||
__asm mov [ebx],ax \
|
||||
}
|
||||
|
||||
#define XCHG_DD(a,b) \
|
||||
{ \
|
||||
PULONG _from_, _to_; \
|
||||
_from_ = ((PULONG)&(b)); \
|
||||
_to_ = ((PULONG)&(a)); \
|
||||
__asm mov ebx,_from_ \
|
||||
__asm mov ecx,_to_ \
|
||||
__asm mov eax,[ebx] \
|
||||
__asm xchg eax,[ecx] \
|
||||
__asm mov [ebx],eax \
|
||||
}
|
||||
|
||||
#else // NO X86 optimization , use generic C/C++
|
||||
|
||||
#define MOV_DD_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
_to_->Byte0 = _from_->Byte3; \
|
||||
_to_->Byte1 = _from_->Byte2; \
|
||||
_to_->Byte2 = _from_->Byte1; \
|
||||
_to_->Byte3 = _from_->Byte0; \
|
||||
}
|
||||
|
||||
#define MOV_DW_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
_to_->Byte0 = _from_->Byte1; \
|
||||
_to_->Byte1 = _from_->Byte0; \
|
||||
}
|
||||
|
||||
#define REVERSE_DD(a) { \
|
||||
ULONG _i_; \
|
||||
MOV_DD_SWP(_i_,(a)); \
|
||||
*((PULONG)&(a)) = _i_; \
|
||||
}
|
||||
|
||||
#define REVERSE_DW(a) { \
|
||||
USHORT _i_; \
|
||||
MOV_DW_SWP(_i_,(a)); \
|
||||
*((PUSHORT)&(a)) = _i_; \
|
||||
}
|
||||
|
||||
#define MOV_DW2DD_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
*((PUSHORT)_to_) = 0; \
|
||||
_to_->Byte2 = _from_->Byte1; \
|
||||
_to_->Byte3 = _from_->Byte0; \
|
||||
}
|
||||
|
||||
#define MOV_MSF(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
_to_->Byte0 = _from_->Byte0; \
|
||||
_to_->Byte1 = _from_->Byte1; \
|
||||
_to_->Byte2 = _from_->Byte2; \
|
||||
}
|
||||
|
||||
#define MOV_MSF_SWP(a,b) \
|
||||
{ \
|
||||
PFOUR_BYTE _from_, _to_; \
|
||||
_from_ = ((PFOUR_BYTE)&(b)); \
|
||||
_to_ = ((PFOUR_BYTE)&(a)); \
|
||||
_to_->Byte0 = _from_->Byte2; \
|
||||
_to_->Byte1 = _from_->Byte1; \
|
||||
_to_->Byte2 = _from_->Byte0; \
|
||||
}
|
||||
|
||||
#define XCHG_DD(a,b) \
|
||||
{ \
|
||||
ULONG _temp_; \
|
||||
PULONG _from_, _to_; \
|
||||
_from_ = ((PULONG)&(b)); \
|
||||
_to_ = ((PULONG)&(a)); \
|
||||
_temp_ = *_from_; \
|
||||
*_from_ = *_to_; \
|
||||
*_to_ = _temp_; \
|
||||
}
|
||||
|
||||
#endif // _X86_
|
||||
|
||||
#define MOV_3B_SWP(a,b) MOV_MSF_SWP(a,b)
|
||||
|
||||
*/
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
|
@ -298,7 +109,7 @@ if((a)!=NULL) { \
|
|||
KdPrint(("\n")); \
|
||||
}
|
||||
|
||||
#define BrutePoint() {}
|
||||
#define BrutePoint() { ASSERT(0); }
|
||||
|
||||
#define DbgAllocatePool(x,y) ExAllocatePool(x,y)
|
||||
#define DbgFreePool(x) ExFreePool(x)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#define UNIATA_VER_STR "41b5"
|
||||
#define UNIATA_VER_DOT 0.41.2.5
|
||||
#define UNIATA_VER_STR "42e2"
|
||||
#define UNIATA_VER_DOT 0.42.5.2
|
||||
#define UNIATA_VER_MJ 0
|
||||
#define UNIATA_VER_MN 41
|
||||
#define UNIATA_VER_SUB_MJ 2
|
||||
#define UNIATA_VER_SUB_MN 5
|
||||
#define UNIATA_VER_DOT_COMMA 0,41,2,5
|
||||
#define UNIATA_VER_DOT_STR "0.41.2.5"
|
||||
#define UNIATA_VER_MN 42
|
||||
#define UNIATA_VER_SUB_MJ 5
|
||||
#define UNIATA_VER_SUB_MN 2
|
||||
#define UNIATA_VER_DOT_COMMA 0,42,5,2
|
||||
#define UNIATA_VER_DOT_STR "0.42.5.2"
|
||||
#define UNIATA_VER_YEAR 2012
|
||||
#define UNIATA_VER_YEAR_STR "2012"
|
||||
|
|
Loading…
Reference in a new issue