Implemented Dpc Routine, managed Srb functions and some code fixes!
[reactos.git] / drivers / storage / storahci / storahci.h
index cca53f9..c8e1434 100644 (file)
  * PURPOSE:        To Implement AHCI Miniport driver targeting storport NT 5.2
  * PROGRAMMERS:    Aman Priyadarshi (aman.eureka@gmail.com)
  */
-#include "miniport.h"
-#include "storport.h"
 
-#define AHCI_POOL_TAG 'ahci'
+#include <ntddk.h>
+#include <ata.h>
+#include <storport.h>
+
+#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             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_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
+
+// ATAPI Functions
+#define ATA_FUNCTION_ATAPI_COMMAND          0x200
+
+// ATA Flags
+#define ATA_FLAGS_DATA_IN                   (1 << 1)
+#define ATA_FLAGS_DATA_OUT                  (1 << 2)
+
+#define IsAtaCommand(AtaFunction)           (AtaFunction & ATA_FUNCTION_ATA_COMMAND)
+#define IsAtapiCommand(AtaFunction)         (AtaFunction & ATA_FUNCTION_ATAPI_COMMAND)
+#define IsDataTransferNeeded(SrbExtension)  (SrbExtension->Flags & (ATA_FLAGS_DATA_IN | ATA_FLAGS_DATA_OUT))
+#define IsAdapterCAPS64(CAP)                (CAP & AHCI_Global_HBA_CAP_S64A)
+
+// 3.1.1 NCS = CAP[12:08] -> Align
+#define AHCI_Global_Port_CAP_NCS(x)            (((x) & 0xF00) >> 8)
+
+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
+#ifdef DBG
+    #define DebugPrint(format, ...) StorPortDebugPrint(0, format, __VA_ARGS__)
+#endif
+
+typedef
+VOID
+(*PAHCI_COMPLETION_ROUTINE) (
+    __in PVOID PortExtension,
+    __in PVOID Srb
+    );
+
+//////////////////////////////////////////////////////////////
+//              ---- Support Structures ---                 //
+//////////////////////////////////////////////////////////////
+
+// section 3.3.5
+typedef union _AHCI_INTERRUPT_STATUS
+{
+    struct
+    {
+        ULONG DHRS:1;       //Device to Host Register FIS Interrupt
+        ULONG PSS :1;       //PIO Setup FIS Interrupt
+        ULONG DSS :1;       //DMA Setup FIS Interrupt
+        ULONG SDBS :1;      //Set Device Bits Interrupt
+        ULONG UFS :1;       //Unknown FIS Interrupt
+        ULONG DPS :1;       //Descriptor Processed
+        ULONG PCS :1;       //Port Connect Change Status
+        ULONG DMPS :1;      //Device Mechanical Presence Status (DMPS)
+        ULONG Reserved :14;
+        ULONG PRCS :1;      //PhyRdy Change Status
+        ULONG IPMS :1;      //Incorrect Port Multiplier Status
+        ULONG OFS :1;       //Overflow Status
+        ULONG Reserved2 :1;
+        ULONG INFS :1;      //Interface Non-fatal Error Status
+        ULONG IFS :1;       //Interface Fatal Error Status
+        ULONG HBDS :1;      //Host Bus Data Error Status
+        ULONG HBFS :1;      //Host Bus Fatal Error Status
+        ULONG TFES :1;      //Task File Error Status
+        ULONG CPDS :1;      //Cold Port Detect Status
+    };
+
+    ULONG Status;
+} AHCI_INTERRUPT_STATUS;
 
 typedef struct _AHCI_FIS_DMA_SETUP
 {
@@ -21,17 +126,17 @@ typedef struct _AHCI_FIS_DMA_SETUP
     UCHAR Reserved[2];      // Reserved
     ULONG DmaBufferLow;     // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.
     ULONG DmaBufferHigh;
-    ULONG Reserved2;        //More reserved
-    ULONG DmaBufferOffset;  //Byte offset into buffer. First 2 bits must be 0
-    ULONG TranferCount;     //Number of bytes to transfer. Bit 0 must be 0
-    ULONG Reserved3;        //Reserved  
+    ULONG Reserved2;        // More reserved
+    ULONG DmaBufferOffset;  // Byte offset into buffer. First 2 bits must be 0
+    ULONG TranferCount;     // Number of bytes to transfer. Bit 0 must be 0
+    ULONG Reserved3;        // Reserved
 } AHCI_FIS_DMA_SETUP;
 
 typedef struct _AHCI_PIO_SETUP_FIS
 {
-    UCHAR FisType;      //0x5F
+    UCHAR FisType;
     UCHAR Reserved1 :5;
-    UCHAR D :1;         // 1 is write (device to host)
+    UCHAR D :1;
     UCHAR I :1;
     UCHAR Reserved2 :1;
     UCHAR Status;
@@ -54,12 +159,11 @@ typedef struct _AHCI_PIO_SETUP_FIS
 
     USHORT TransferCount;
     UCHAR Reserved5[2];
-
-}  AHCI_PIO_SETUP_FIS;
+} AHCI_PIO_SETUP_FIS;
 
 typedef struct _AHCI_D2H_REGISTER_FIS
 {
-    UCHAR FisType;  // 0x34
+    UCHAR FisType;
     UCHAR Reserved1 :6;
     UCHAR I:1;
     UCHAR Reserved2 :1;
@@ -83,9 +187,9 @@ typedef struct _AHCI_D2H_REGISTER_FIS
     UCHAR Reserved4[4];
 } AHCI_D2H_REGISTER_FIS;
 
-typedef struct _AHCI_SET_DEVICE_BITS_FIS {
-
-    UCHAR FisType;   //0xA1
+typedef struct _AHCI_SET_DEVICE_BITS_FIS
+{
+    UCHAR FisType;
 
     UCHAR PMPort: 4;
     UCHAR Reserved1 :2;
@@ -100,99 +204,290 @@ typedef struct _AHCI_SET_DEVICE_BITS_FIS {
     UCHAR Error;
 
     UCHAR Reserved5[4];
-}  AHCI_SET_DEVICE_BITS_FIS;
+} AHCI_SET_DEVICE_BITS_FIS;
+
+typedef struct _AHCI_QUEUE
+{
+    PVOID Buffer[MAXIMUM_QUEUE_BUFFER_SIZE];  // because Storahci hold Srb queue of 255 size
+    ULONG Head;
+    ULONG Tail;
+} AHCI_QUEUE, *PAHCI_QUEUE;
+
+//////////////////////////////////////////////////////////////
+//              ---------------------------                 //
+//////////////////////////////////////////////////////////////
+
+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 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;
+    ULONG DBAU;
+    ULONG RSV0;
 
-// 4.2.2
+    ULONG DBC : 22;
+    ULONG RSV1 : 9;
+    ULONG I : 1;
+} AHCI_PRDT, *PAHCI_PRDT;
+
+// 4.2.3 Command Table
+typedef struct _AHCI_COMMAND_TABLE
+{
+    // (16 * 32) + 64 + 16 + 48 = 648
+    // 128 byte aligned :D
+    UCHAR CFIS[64];
+    UCHAR ACMD[16];
+    UCHAR RSV0[48];
+    AHCI_PRDT PRDT[MAXIMUM_AHCI_PRDT_ENTRIES];
+} AHCI_COMMAND_TABLE, *PAHCI_COMMAND_TABLE;
+
+// 4.2.2 Command Header
 typedef struct _AHCI_COMMAND_HEADER
 {
-    ULONG HEADER_DESCRIPTION;   // DW 0
-    ULONG PRDBC;                // DW 1
-    ULONG CTBA0;                // DW 2
-    ULONG CTBA_U0;              // DW 3
-    ULONG Reserved[4];          // DW 4-7
+    AHCI_COMMAND_HEADER_DESCRIPTION DI;   // DW 0
+    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
 typedef struct _AHCI_RECEIVED_FIS
 {
-    AHCI_FIS_DMA_SETUP          DmaSetupFIS;      // 0x00 -- DMA Setup FIS
-    ULONG                       pad0;             // 4 BYTE padding
-    AHCI_PIO_SETUP_FIS          PioSetupFIS;      // 0x20 -- PIO Setup FIS
-    ULONG                       pad1[3];          // 12 BYTE padding
-    AHCI_D2H_REGISTER_FIS       RegisterFIS;      // 0x40 -- Register – Device to Host FIS
-    ULONG                       pad2;             // 4 BYTE padding
-    AHCI_SET_DEVICE_BITS_FIS    SetDeviceFIS;     // 0x58 -- Set Device Bit FIS
-    ULONG                       UnknowFIS[16];    // 0x60 -- Unknown FIS
-    ULONG                       Reserved[24];     // 0xA0 -- Reserved
+    struct _AHCI_FIS_DMA_SETUP          DmaSetupFIS;      // 0x00 -- DMA Setup FIS
+    ULONG                               pad0;             // 4 BYTE padding
+    struct _AHCI_PIO_SETUP_FIS          PioSetupFIS;      // 0x20 -- PIO Setup FIS
+    ULONG                               pad1[3];          // 12 BYTE padding
+    struct _AHCI_D2H_REGISTER_FIS       RegisterFIS;      // 0x40 -- Register – Device to Host FIS
+    ULONG                               pad2;             // 4 BYTE padding
+    struct _AHCI_SET_DEVICE_BITS_FIS    SetDeviceFIS;     // 0x58 -- Set Device Bit FIS
+    ULONG                               UnknowFIS[16];    // 0x60 -- Unknown FIS
+    ULONG                               Reserved[24];     // 0xA0 -- Reserved
 } AHCI_RECEIVED_FIS, *PAHCI_RECEIVED_FIS;
 
+// Holds Port Information
 typedef struct _AHCI_PORT
 {
-    ULONG   CLB;        // 0x00, command list base address, 1K-byte aligned
-    ULONG   CLBU;       // 0x04, command list base address upper 32 bits
-    ULONG   FB;         // 0x08, FIS base address, 256-byte aligned
-    ULONG   FBU;        // 0x0C, FIS base address upper 32 bits
-    ULONG   IS;         // 0x10, interrupt status
-    ULONG   IE;         // 0x14, interrupt enable
-    ULONG   CMD;        // 0x18, command and status
-    ULONG   RSV0;       // 0x1C, Reserved
-    ULONG   TFD;        // 0x20, task file data
-    ULONG   SIG;        // 0x24, signature
-    ULONG   SSTS;       // 0x28, SATA status (SCR0:SStatus)
-    ULONG   SCTL;       // 0x2C, SATA control (SCR2:SControl)
-    ULONG   SERR;       // 0x30, SATA error (SCR1:SError)
-    ULONG   SACT;       // 0x34, SATA active (SCR3:SActive)
-    ULONG   CI;         // 0x38, command issue
-    ULONG   SNTF;       // 0x3C, SATA notification (SCR4:SNotification)
-    ULONG   FBS;        // 0x40, FIS-based switch control
-    ULONG   RSV1[11];   // 0x44 ~ 0x6F, Reserved
-    ULONG   Vendor[4];  // 0x70 ~ 0x7F, vendor specific
+    ULONG   CLB;                                // 0x00, command list base address, 1K-byte aligned
+    ULONG   CLBU;                               // 0x04, command list base address upper 32 bits
+    ULONG   FB;                                 // 0x08, FIS base address, 256-byte aligned
+    ULONG   FBU;                                // 0x0C, FIS base address upper 32 bits
+    ULONG   IS;                                 // 0x10, interrupt status
+    ULONG   IE;                                 // 0x14, interrupt enable
+    ULONG   CMD;                                // 0x18, command and status
+    ULONG   RSV0;                               // 0x1C, Reserved
+    ULONG   TFD;                                // 0x20, task file data
+    ULONG   SIG;                                // 0x24, signature
+    ULONG   SSTS;                               // 0x28, SATA status (SCR0:SStatus)
+    ULONG   SCTL;                               // 0x2C, SATA control (SCR2:SControl)
+    ULONG   SERR;                               // 0x30, SATA error (SCR1:SError)
+    ULONG   SACT;                               // 0x34, SATA active (SCR3:SActive)
+    ULONG   CI;                                 // 0x38, command issue
+    ULONG   SNTF;                               // 0x3C, SATA notification (SCR4:SNotification)
+    ULONG   FBS;                                // 0x40, FIS-based switch control
+    ULONG   RSV1[11];                           // 0x44 ~ 0x6F, Reserved
+    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
-    ULONG CAP;                      // 0x00, Host capability
-    ULONG GHC;                      // 0x04, Global host control
-    ULONG IS;                       // 0x08, Interrupt status
-    ULONG PI;                       // 0x0C, Port implemented
-    ULONG VS;                       // 0x10, Version
-    ULONG CCC_CTL;                  // 0x14, Command completion coalescing control
-    ULONG CCC_PTS;                  // 0x18, Command completion coalescing ports
-    ULONG EM_LOC;                   // 0x1C, Enclosure management location
-    ULONG EM_CTL;                   // 0x20, Enclosure management control
-    ULONG CAP2;                     // 0x24, Host capabilities extended
-    ULONG BOHC;                     // 0x28, BIOS/OS handoff control and status
-
-    // 0x2C - 0x9F, Reserved
-    ULONG Reserved[0xA0-0x2C];
-
-    // 0xA0 - 0xFF, Vendor specific registers
-    ULONG VendorSpecific[0x100-0xA0];
-
-    AHCI_PORT PortList[32];//1~32
-
+    ULONG CAP;                                  // 0x00, Host capability
+    ULONG GHC;                                  // 0x04, Global host control
+    ULONG IS;                                   // 0x08, Interrupt status
+    ULONG PI;                                   // 0x0C, Port implemented
+    ULONG VS;                                   // 0x10, Version
+    ULONG CCC_CTL;                              // 0x14, Command completion coalescing control
+    ULONG CCC_PTS;                              // 0x18, Command completion coalescing ports
+    ULONG EM_LOC;                               // 0x1C, Enclosure management location
+    ULONG EM_CTL;                               // 0x20, Enclosure management control
+    ULONG CAP2;                                 // 0x24, Host capabilities extended
+    ULONG BOHC;                                 // 0x28, BIOS/OS handoff control and status
+    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;
 
-struct _AHCI_ADAPTER_EXTENSION;
-
+// Holds information for each attached attached port to a given adapter.
 typedef struct _AHCI_PORT_EXTENSION
 {
     ULONG PortNumber;
-    struct _AHCI_ADAPTER_EXTENSION* AdapterExtension;
-    PAHCI_COMMAND_HEADER CommandList;
+    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;                                // 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_PORT Port;
+    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;
 
+// Holds Adapter Information
 typedef struct _AHCI_ADAPTER_EXTENSION
 {
-    ULONG   AdapterNumber;
     ULONG   SystemIoBusNumber;
     ULONG   SlotNumber;
     ULONG   AhciBaseAddress;
-    ULONG   IS;                 // Interrupt status
-    ULONG   PortImplemented;
+    PULONG  IS;// Interrupt Status, In case of MSIM == `1`
+    ULONG   PortImplemented;// bit-mapping of ports which are implemented
+    ULONG   PortCount;
 
     USHORT  VendorID;
     USHORT  DeviceID;
@@ -201,14 +496,159 @@ typedef struct _AHCI_ADAPTER_EXTENSION
     ULONG   Version;
     ULONG   CAP;
     ULONG   CAP2;
+    ULONG   LastInterruptPort;
+    ULONG   CurrentCommandSlot;
 
-    PVOID NonCachedExtension;
+    PVOID NonCachedExtension; // holds virtual address to noncached buffer allocated for Port Extension
+
+    struct
+    {
+        // Message per port or shared port?
+        ULONG MessagePerPort : 1;
+        ULONG Removed : 1;
+        ULONG Reserved : 30; // not in use -- maintain 4 byte alignment
+    } StateFlags;
 
     PAHCI_MEMORY_REGISTERS ABAR_Address;
-    AHCI_PORT_EXTENSION PortExtension[32];
+    AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT];
 } AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
 
+typedef struct _LOCAL_SCATTER_GATHER_LIST
+{
+    ULONG                       NumberOfElements;
+    ULONG_PTR                   Reserved;
+    STOR_SCATTER_GATHER_ELEMENT List[MAXIMUM_AHCI_PRDT_ENTRIES];
+} LOCAL_SCATTER_GATHER_LIST, *PLOCAL_SCATTER_GATHER_LIST;
+
 typedef struct _AHCI_SRB_EXTENSION
 {
-    ULONG Reserved[4];
-} AHCI_SRB_EXTENSION;
+    AHCI_COMMAND_TABLE CommandTable;
+    ULONG AtaFunction;
+    ULONG Flags;
+
+    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;
+
+//////////////////////////////////////////////////////////////
+//                       Declarations                       //
+//////////////////////////////////////////////////////////////
+
+BOOLEAN
+AhciAdapterReset (
+    __in PAHCI_ADAPTER_EXTENSION AdapterExtension
+    );
+
+__inline
+VOID
+AhciZeroMemory (
+    __out PCHAR Buffer,
+    __in ULONG BufferSize
+    );
+
+__inline
+BOOLEAN
+IsPortValid (
+    __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
+    __in ULONG pathId
+    );
+
+UCHAR
+DeviceInquiryRequest (
+    __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
+    __in PSCSI_REQUEST_BLOCK Srb,
+    __in PCDB Cdb,
+    __in BOOLEAN HasProductDataRequest
+    );
+
+__inline
+BOOLEAN
+AddQueue (
+    __inout PAHCI_QUEUE Queue,
+    __in PVOID Srb
+    );
+
+__inline
+PVOID
+RemoveQueue (
+    __inout PAHCI_QUEUE Queue
+    );
+
+__inline
+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);