X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=drivers%2Fstorage%2Fstorahci%2Fstorahci.h;h=c8e14345a7204616f2051e84d681359a866f39c6;hp=1133904cc9c37368ef0b2c254c7af02cc918e990;hb=93ea02836069e43243b03cce8d8a59e6df180dd0;hpb=b8af2c601484c0e9180f140e0edfc46c1f88f383 diff --git a/drivers/storage/storahci/storahci.h b/drivers/storage/storahci/storahci.h index 1133904cc9c..c8e14345a72 100644 --- a/drivers/storage/storahci/storahci.h +++ b/drivers/storage/storahci/storahci.h @@ -10,19 +10,47 @@ #include #define DEBUG 1 +#pragma warning(disable:4214) // bit field types other than int +#pragma warning(disable:4201) // nameless struct/union -#define MAXIMUM_AHCI_PORT_COUNT 25 +#define MAXIMUM_AHCI_PORT_COUNT 32 #define MAXIMUM_AHCI_PRDT_ENTRIES 32 +#define MAXIMUM_AHCI_PORT_NCS 30 #define MAXIMUM_QUEUE_BUFFER_SIZE 255 #define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB +// device type (DeviceParams) +#define AHCI_DEVICE_TYPE_ATA 1 +#define AHCI_DEVICE_TYPE_ATAPI 2 +#define AHCI_DEVICE_TYPE_NODEVICE 3 + // section 3.1.2 -#define AHCI_Global_HBA_CONTROL_HR (1 << 0) -#define AHCI_Global_HBA_CONTROL_IE (1 << 1) -#define AHCI_Global_HBA_CONTROL_MRSM (1 << 2) -#define AHCI_Global_HBA_CONTROL_AE (1 << 31) #define AHCI_Global_HBA_CAP_S64A (1 << 31) +// FIS Types : http://wiki.osdev.org/AHCI +#define FIS_TYPE_REG_H2D 0x27 // Register FIS - host to device +#define FIS_TYPE_REG_D2H 0x34 // Register FIS - device to host +#define FIS_TYPE_DMA_ACT 0x39 // DMA activate FIS - device to host +#define FIS_TYPE_DMA_SETUP 0x41 // DMA setup FIS - bidirectional +#define FIS_TYPE_BIST 0x58 // BIST activate FIS - bidirectional +#define FIS_TYPE_PIO_SETUP 0x5F // PIO setup FIS - device to host +#define FIS_TYPE_DEV_BITS 0xA1 // Set device bits FIS - device to host + +#define AHCI_ATA_CFIS_FisType 0 +#define AHCI_ATA_CFIS_PMPort_C 1 +#define AHCI_ATA_CFIS_CommandReg 2 +#define AHCI_ATA_CFIS_FeaturesLow 3 +#define AHCI_ATA_CFIS_LBA0 4 +#define AHCI_ATA_CFIS_LBA1 5 +#define AHCI_ATA_CFIS_LBA2 6 +#define AHCI_ATA_CFIS_Device 7 +#define AHCI_ATA_CFIS_LBA3 8 +#define AHCI_ATA_CFIS_LBA4 9 +#define AHCI_ATA_CFIS_LBA5 10 +#define AHCI_ATA_CFIS_FeaturesHigh 11 +#define AHCI_ATA_CFIS_SectorCountLow 12 +#define AHCI_ATA_CFIS_SectorCountHigh 13 + // ATA Functions #define ATA_FUNCTION_ATA_COMMAND 0x100 #define ATA_FUNCTION_ATA_IDENTIFY 0x101 @@ -43,10 +71,17 @@ #define AHCI_Global_Port_CAP_NCS(x) (((x) & 0xF00) >> 8) #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) -#if DEBUG +#ifdef DBG #define DebugPrint(format, ...) StorPortDebugPrint(0, format, __VA_ARGS__) #endif +typedef +VOID +(*PAHCI_COMPLETION_ROUTINE) ( + __in PVOID PortExtension, + __in PVOID Srb + ); + ////////////////////////////////////////////////////////////// // ---- Support Structures --- // ////////////////////////////////////////////////////////////// @@ -186,23 +221,117 @@ typedef union _AHCI_COMMAND_HEADER_DESCRIPTION { struct { - ULONG CFL :5; // Command FIS Length - ULONG A :1; // IsATAPI - ULONG W :1; // Write - ULONG P :1; // Prefetchable - - ULONG R :1; // Reset - ULONG B :1; // BIST - ULONG C :1; //Clear Busy upon R_OK - ULONG DW0_Reserved :1; - ULONG PMP :4; //Port Multiplier Port - - ULONG PRDTL :16; //Physical Region Descriptor Table Length + ULONG CFL : 5; // Command FIS Length + ULONG A : 1; // IsATAPI + ULONG W : 1; // Write + ULONG P : 1; // Prefetchable + + ULONG R : 1; // Reset + ULONG B : 1; // BIST + ULONG C : 1; //Clear Busy upon R_OK + ULONG RSV : 1; + ULONG PMP : 4; //Port Multiplier Port + + ULONG PRDTL : 16; //Physical Region Descriptor Table Length }; ULONG Status; } AHCI_COMMAND_HEADER_DESCRIPTION; +typedef union _AHCI_GHC +{ + struct + { + ULONG HR : 1; + ULONG IE : 1; + ULONG MRSM : 1; + ULONG RSV0 : 28; + ULONG AE : 1; + }; + + ULONG Status; +} AHCI_GHC; + +// section 3.3.7 +typedef union _AHCI_PORT_CMD +{ + struct + { + ULONG ST : 1; + ULONG SUD : 1; + ULONG POD : 1; + ULONG CLO : 1; + ULONG FRE : 1; + ULONG RSV0 : 3; + ULONG CCS : 5; + ULONG MPSS : 1; + ULONG FR : 1; + ULONG CR : 1; + ULONG CPS : 1; + ULONG PMA : 1; + ULONG HPCP : 1; + ULONG MPSP : 1; + ULONG CPD : 1; + ULONG ESP : 1; + ULONG FBSCP : 1; + ULONG APSTE : 1; + ULONG ATAPI : 1; + ULONG DLAE : 1; + ULONG ALPE : 1; + ULONG ASP : 1; + ULONG ICC : 4; + }; + + ULONG Status; +} AHCI_PORT_CMD; + +typedef union _AHCI_SERIAL_ATA_CONTROL +{ + struct + { + ULONG DET :4; + ULONG SPD :4; + ULONG IPM :4; + ULONG SPM :4; + ULONG PMP :4; + ULONG DW11_Reserved :12; + }; + + ULONG Status; +} AHCI_SERIAL_ATA_CONTROL; + +typedef union _AHCI_SERIAL_ATA_STATUS +{ + struct + { + ULONG DET :4; + ULONG SPD :4; + ULONG IPM :4; + ULONG RSV0 :20; + }; + + ULONG Status; +} AHCI_SERIAL_ATA_STATUS; + +typedef union _AHCI_TASK_FILE_DATA +{ + struct + { + struct _STS + { + UCHAR ERR : 1; + UCHAR CS1 : 2; + UCHAR DRQ : 1; + UCHAR CS2 : 3; + UCHAR BSY : 1; + } STS; + UCHAR ERR; + USHORT RSV; + }; + + ULONG Status; +} AHCI_TASK_FILE_DATA; + typedef struct _AHCI_PRDT { ULONG DBA; @@ -229,10 +358,10 @@ typedef struct _AHCI_COMMAND_TABLE typedef struct _AHCI_COMMAND_HEADER { AHCI_COMMAND_HEADER_DESCRIPTION DI; // DW 0 - ULONG PRDBC; // DW 1 - ULONG CTBA0; // DW 2 - ULONG CTBA_U0; // DW 3 - ULONG Reserved[4]; // DW 4-7 + ULONG PRDBC; // DW 1 + ULONG CTBA; // DW 2 + ULONG CTBA_U; // DW 3 + ULONG Reserved[4]; // DW 4-7 } AHCI_COMMAND_HEADER, *PAHCI_COMMAND_HEADER; // Received FIS @@ -273,6 +402,34 @@ typedef struct _AHCI_PORT ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific } AHCI_PORT, *PAHCI_PORT; +typedef union _AHCI_INTERRUPT_ENABLE +{ + struct + { + ULONG DHRE :1; + ULONG PSE :1; + ULONG DSE :1; + ULONG SDBE :1; + ULONG UFE :1; + ULONG DPE :1; + ULONG PCE :1; + ULONG DMPE :1; + ULONG DW5_Reserved :14; + ULONG PRCE :1; + ULONG IPME :1; + ULONG OFE :1; + ULONG DW5_Reserved2 :1; + ULONG INFE :1; + ULONG IFE :1; + ULONG HBDE :1; + ULONG HBFE :1; + ULONG TFEE :1; + ULONG CPDE :1; + }; + + ULONG Status; +} AHCI_INTERRUPT_ENABLE; + typedef struct _AHCI_MEMORY_REGISTERS { // 0x00 - 0x2B, Generic Host Control @@ -287,23 +444,38 @@ typedef struct _AHCI_MEMORY_REGISTERS ULONG EM_CTL; // 0x20, Enclosure management control ULONG CAP2; // 0x24, Host capabilities extended ULONG BOHC; // 0x28, BIOS/OS handoff control and status - ULONG Reserved[0xA0-0x2C]; // 0x2C - 0x9F, Reserved - ULONG VendorSpecific[0x100-0xA0]; // 0xA0 - 0xFF, Vendor specific registers + ULONG Reserved[0x1d]; // 0x2C - 0x9F, Reserved + ULONG VendorSpecific[0x18]; // 0xA0 - 0xFF, Vendor specific registers AHCI_PORT PortList[MAXIMUM_AHCI_PORT_COUNT]; - } AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS; // Holds information for each attached attached port to a given adapter. typedef struct _AHCI_PORT_EXTENSION { ULONG PortNumber; - ULONG OccupiedSlots; // slots to which we have already assigned task - BOOLEAN IsActive; + ULONG QueueSlots; // slots which we have already assigned task (Slot) + ULONG CommandIssuedSlots; // slots which has been programmed + ULONG MaxPortQueueDepth; + + struct + { + UCHAR RemovableDevice; + UCHAR Lba48BitMode; + UCHAR AccessType; + UCHAR DeviceType; + UCHAR IsActive; + } DeviceParams; + + STOR_DPC CommandCompletion; PAHCI_PORT Port; // AHCI Port Infomation - AHCI_QUEUE SrbQueue; + AHCI_QUEUE SrbQueue; // pending Srbs + AHCI_QUEUE CompletionQueue; + PSCSI_REQUEST_BLOCK Slot[MAXIMUM_AHCI_PORT_NCS]; // Srbs which has been alloted a port PAHCI_RECEIVED_FIS ReceivedFIS; PAHCI_COMMAND_HEADER CommandList; STOR_DEVICE_POWER_STATE DevicePowerState; // Device Power State + PIDENTIFY_DEVICE_DATA IdentifyDeviceData; + STOR_PHYSICAL_ADDRESS IdentifyDeviceDataPhysicalAddress; struct _AHCI_ADAPTER_EXTENSION* AdapterExtension; // Port's Adapter Information } AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION; @@ -327,7 +499,7 @@ typedef struct _AHCI_ADAPTER_EXTENSION ULONG LastInterruptPort; ULONG CurrentCommandSlot; - PVOID NonCachedExtension;// holds virtual address to noncached buffer allocated for Port Extension + PVOID NonCachedExtension; // holds virtual address to noncached buffer allocated for Port Extension struct { @@ -353,9 +525,24 @@ typedef struct _AHCI_SRB_EXTENSION AHCI_COMMAND_TABLE CommandTable; ULONG AtaFunction; ULONG Flags; - ULONG CommandReg; + + UCHAR CommandReg; + UCHAR FeaturesLow; + UCHAR LBA0; + UCHAR LBA1; + UCHAR LBA2; + UCHAR Device; + UCHAR LBA3; + UCHAR LBA4; + UCHAR LBA5; + UCHAR FeaturesHigh; + + UCHAR SectorCountLow; + UCHAR SectorCountHigh; + ULONG SlotIndex; LOCAL_SCATTER_GATHER_LIST Sgl; + PAHCI_COMPLETION_ROUTINE CompletionRoutine; } AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION; ////////////////////////////////////////////////////////////// @@ -378,14 +565,15 @@ __inline BOOLEAN IsPortValid ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, - __in UCHAR pathId + __in ULONG pathId ); -ULONG +UCHAR DeviceInquiryRequest ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, - __in PCDB Cdb + __in PCDB Cdb, + __in BOOLEAN HasProductDataRequest ); __inline @@ -406,3 +594,61 @@ PAHCI_SRB_EXTENSION GetSrbExtension( __in PSCSI_REQUEST_BLOCK Srb ); + +////////////////////////////////////////////////////////////// +// Assertions // +////////////////////////////////////////////////////////////// + +// I assert every silly mistake I can do while coding +// because god never help me debugging the code +// but these asserts do :') + +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP) == 0x00); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, GHC) == 0x04); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, IS) == 0x08); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PI) == 0x0C); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VS) == 0x10); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_CTL) == 0x14); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_PTS) == 0x18); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_LOC) == 0x1C); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_CTL) == 0x20); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP2) == 0x24); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, BOHC) == 0x28); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, Reserved) == 0x2C); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VendorSpecific) == 0xA0); +C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PortList) == 0x100); + +C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLB) == 0x00); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLBU) == 0x04); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, FB) == 0x08); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBU) == 0x0C); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, IS) == 0x10); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, IE) == 0x14); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, CMD) == 0x18); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV0) == 0x1C); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, TFD) == 0x20); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, SIG) == 0x24); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, SSTS) == 0x28); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, SCTL) == 0x2C); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, SERR) == 0x30); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, SACT) == 0x34); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, CI) == 0x38); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, SNTF) == 0x3C); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBS) == 0x40); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV1) == 0x44); +C_ASSERT(FIELD_OFFSET(AHCI_PORT, Vendor) == 0x70); + +C_ASSERT((sizeof(AHCI_COMMAND_TABLE) % 128) == 0); + +C_ASSERT(sizeof(AHCI_GHC) == sizeof(ULONG)); +C_ASSERT(sizeof(AHCI_PORT_CMD) == sizeof(ULONG)); +C_ASSERT(sizeof(AHCI_TASK_FILE_DATA) == sizeof(ULONG)); +C_ASSERT(sizeof(AHCI_INTERRUPT_ENABLE) == sizeof(ULONG)); +C_ASSERT(sizeof(AHCI_SERIAL_ATA_STATUS) == sizeof(ULONG)); +C_ASSERT(sizeof(AHCI_SERIAL_ATA_CONTROL) == sizeof(ULONG)); +C_ASSERT(sizeof(AHCI_COMMAND_HEADER_DESCRIPTION) == sizeof(ULONG)); + +C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, CFIS) == 0x00); +C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, ACMD) == 0x40); +C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, RSV0) == 0x50); +C_ASSERT(FIELD_OFFSET(AHCI_COMMAND_TABLE, PRDT) == 0x80);