Author: apriyadarshi
Date: Tue Jun 7 11:05:32 2016
New Revision: 71588
URL:
http://svn.reactos.org/svn/reactos?rev=71588&view=rev
Log:
AHCI-SATA Interface almost ready.
- tested on VM.
- need to implement Interrupt Routine (MessagePerPort) and ATA/ATAPI Based SCSI Query.
Modified:
branches/GSoC_2016/AHCI/drivers/storage/storahci/sources
branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c
branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/sources
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/sources [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/sources [iso-8859-1] Tue Jun 7
11:05:32 2016
@@ -1,6 +1,7 @@
TARGETNAME = storahci
TARGETTYPE = MINIPORT
+MSC_WARNING_LEVEL=/W4
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
INCLUDES = %BUILD%\inc
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] Tue Jun 7
11:05:32 2016
@@ -11,11 +11,18 @@
__in PAHCI_ADAPTER_EXTENSION adapterExtension
);
+__inline
VOID AhciZeroMemory(
__in PCHAR buffer,
__in ULONG bufferSize
);
+__inline
+BOOLEAN IsPortValid(
+ __in PAHCI_ADAPTER_EXTENSION adapterExtension,
+ __in UCHAR pathId
+);
+
/**
* @name AhciPortInitialize
* @implemented
@@ -40,6 +47,7 @@
adapterExtension = portExtension->AdapterExtension;
abar = adapterExtension->ABAR_Address;
+
portExtension->Port = &abar->PortList[portExtension->PortNumber];
commandListPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL,
portExtension->CommandList, &mappedLength);
@@ -61,6 +69,14 @@
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->CLB,
commandListPhysical.LowPart);
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->FB,
receivedFISPhysical.LowPart);
+ // set device power state flag to D0
+ portExtension->DevicePowerState = StorPowerDeviceD0;
+
+ // clear pending interrupts
+ StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->SERR,
(ULONG)-1);
+ StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->IS,
(ULONG)-1);
+ StorPortWriteRegisterUlong(adapterExtension,
portExtension->AdapterExtension->IS, (1 << portExtension->PortNumber));
+
return TRUE;
}// -- AhciPortInitialize();
@@ -87,7 +103,7 @@
StorPortDebugPrint(0, "AhciAllocateResourceForAdapter()\n");
- // 3.1.1 NCS = CAP[12:08] -> Align
+ // 3.1.1 NCS = CAP[12:08] -> Align
NCS = (adapterExtension->CAP & 0xF00) >> 8;
AlignedNCS = ((NCS/8) + 1) * 8;
@@ -116,33 +132,16 @@
nonCachedExtension = (PCHAR)adapterExtension->NonCachedExtension;
AhciZeroMemory(nonCachedExtension, nonCachedExtensionSize);
-
-
- // allocate memory for port extension
- /* --> Allocate memory for port extension, but right now it is returning
STOR_STATUS_NOT_IMPLEMENTED
- so, for testing purpose, I allocated during driver entry itself.
- status = StorPortAllocatePool(
- adapterExtension,
- portCount * sizeof(AHCI_PORT_EXTENSION),
- AHCI_POOL_TAG,
- (PVOID*)&portsExtension);
-
- if (status != STOR_STATUS_SUCCESS){
- StorPortDebugPrint(0, "\tstatus : %x\n", status);
- return FALSE;
- }
-
- AhciZeroMemory((PCHAR)portsExtension, portCount * sizeof(AHCI_PORT_EXTENSION));
- */
+
nonCachedExtensionSize /= portCount;
currentCount = 0;
- for (index = 0; index < 32; index++)
- {
+ for (index = 0; index < MAXIMUM_AHCI_PORT_COUNT; index++)
+ {
+ adapterExtension->PortExtension[index].IsActive = FALSE;
if ((adapterExtension->PortImplemented & (1<<index)) != 0)
{
- //adapterExtension->PortExtension[index] =
(PAHCI_PORT_EXTENSION)((PCHAR)portsExtension + sizeof(AHCI_PORT_EXTENSION) *
currentCount);
-
adapterExtension->PortExtension[index].PortNumber = index;
+ adapterExtension->PortExtension[index].IsActive = TRUE;
adapterExtension->PortExtension[index].AdapterExtension =
adapterExtension;
adapterExtension->PortExtension[index].CommandList =
(PAHCI_COMMAND_HEADER)(nonCachedExtension + (currentCount*nonCachedExtensionSize));
adapterExtension->PortExtension[index].ReceivedFIS =
(PAHCI_RECEIVED_FIS)((PCHAR)adapterExtension->PortExtension[index].CommandList +
sizeof(AHCI_COMMAND_HEADER) * AlignedNCS);
@@ -168,11 +167,26 @@
__in PVOID AdapterExtension
)
{
+ ULONG ghc, messageCount, status;
PAHCI_ADAPTER_EXTENSION adapterExtension;
StorPortDebugPrint(0, "AhciHwInitialize()\n");
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
+ adapterExtension->StateFlags.MessagePerPort = FALSE;
+
+ // First check what type of interrupt/synchronization device is using
+ ghc = StorPortReadRegisterUlong(adapterExtension,
&adapterExtension->ABAR_Address->GHC);
+
+ //When set to â1â by hardware, indicates that the HBA requested more than one MSI
vector
+ //but has reverted to using the first vector only. When this bit is cleared to
â0â,
+ //the HBA has not reverted to single MSI mode (i.e. hardware is already in single MSI
mode,
+ //software has allocated the number of messages requested
+ if ((ghc & AHCI_Global_HBA_CONTROL_MRSM) == 0)
+ {
+ adapterExtension->StateFlags.MessagePerPort = TRUE;
+ StorPortDebugPrint(0, "\tMultiple MSI based message not supported\n");
+ }
return TRUE;
}// -- AhciHwInitialize();
@@ -199,7 +213,7 @@
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
- return TRUE;
+ return FALSE;
}// -- AhciHwInterrupt();
/**
@@ -221,14 +235,87 @@
)
{
- UCHAR function;
+ UCHAR function, pathId;
PAHCI_ADAPTER_EXTENSION adapterExtension;
StorPortDebugPrint(0, "AhciHwStartIo()\n");
+ pathId = Srb->PathId;
+ function = Srb->Function;
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
- function = Srb->Function;
-
+
+ if (!IsPortValid(adapterExtension, pathId))
+ {
+ Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
+ StorPortNotification(RequestComplete, adapterExtension, Srb);
+ return TRUE;
+ }
+
+ //
https://msdn.microsoft.com/windows/hardware/drivers/storage/handling-srb-fu…
+ // If the function member of an SRB is set to SRB_FUNCTION_PNP,
+ // the SRB is a structure of type SCSI_PNP_REQUEST_BLOCK.
+ if (function == SRB_FUNCTION_PNP)
+ {
+ PSCSI_PNP_REQUEST_BLOCK pnpRequest;
+
+ pnpRequest = (PSCSI_PNP_REQUEST_BLOCK)Srb;
+ if ((pnpRequest->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST) != 0)
+ {
+ if (pnpRequest->PnPAction == StorRemoveDevice ||
+ pnpRequest->PnPAction == StorSurpriseRemoval)
+ {
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ adapterExtension->StateFlags.Removed = 1;
+ StorPortDebugPrint(0, "\tadapter removed\n");
+ }
+ else if (pnpRequest->PnPAction == StorStopDevice)
+ {
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ StorPortDebugPrint(0, "\tRequested to Stop the adapter\n");
+ }
+ else
+ Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
+ StorPortNotification(RequestComplete, adapterExtension, Srb);
+ return TRUE;
+ }
+ }
+
+ if (function == SRB_FUNCTION_EXECUTE_SCSI)
+ {
+ //
https://msdn.microsoft.com/en-us/windows/hardware/drivers/storage/handling-…
+ // On receipt of an SRB_FUNCTION_EXECUTE_SCSI request, a miniport driver's
HwScsiStartIo
+ // routine does the following:
+ //
+ // - Gets and/or sets up whatever context the miniport driver maintains in its
device,
+ // logical unit, and/or SRB extensions
+ // For example, a miniport driver might set up a logical unit extension with
pointers
+ // to the SRB itself and the SRB DataBuffer pointer, the SRB DataTransferLength
value,
+ // and a driver-defined value (or CDB SCSIOP_XXX value) indicating the
operation to be
+ // carried out on the HBA.
+ //
+ // - Calls an internal routine to program the HBA, as partially directed by the
SrbFlags,
+ // for the requested operation
+ // For a device I/O operation, such an internal routine generally selects the
target device
+ // and sends the CDB over the bus to the target logical unit.
+ if (Srb->CdbLength > 0)
+ {
+ PCDB cdb = (PCDB)&Srb->Cdb;
+ if (cdb->CDB10.OperationCode == SCSIOP_INQUIRY)
+ {
+ StorPortDebugPrint(0, "\tINQUIRY Called!\n");
+ }
+ }
+ else
+ {
+ Srb->SrbStatus = SRB_STATUS_BAD_FUNCTION;
+ StorPortNotification(RequestComplete, adapterExtension, Srb);
+ return TRUE;
+ }
+ }
+
+ StorPortDebugPrint(0, "\tUnknow function code recieved: %x\n", function);
+ Srb->SrbStatus = SRB_STATUS_BAD_FUNCTION;
+ StorPortNotification(RequestComplete, adapterExtension, Srb);
return TRUE;
}// -- AhciHwStartIo();
@@ -305,7 +392,7 @@
ULONG portCount, portImplemented;
ULONG pci_cfg_len;
UCHAR pci_cfg_buf[0x30];
-
+
PAHCI_MEMORY_REGISTERS abar;
PPCI_COMMON_CONFIG pciConfigData;
PAHCI_ADAPTER_EXTENSION adapterExtension;
@@ -315,7 +402,7 @@
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
-
+
// get PCI configuration header
pci_cfg_len = StorPortGetBusData(
adapterExtension,
@@ -374,7 +461,7 @@
// 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
// AE := Highest Significant bit of GHC
- if ((ghc & (0x1<<31)) == 1)//Hmm, controller was already in power state
+ if ((ghc & AHCI_Global_HBA_CONTROL_AE) == 1)//Hmm, controller was already in
power state
{
// reset controller to have it in know state
StorPortDebugPrint(0, "\tAE Already set, Reset()\n");
@@ -384,10 +471,10 @@
}
}
- ghc = 0x1<<31;// only AE=1
+ ghc = AHCI_Global_HBA_CONTROL_AE;// only AE=1
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
- adapterExtension->IS = abar->IS;
+ adapterExtension->IS = &abar->IS;
adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension,
&abar->PI);
if (adapterExtension->PortImplemented == 0){
@@ -400,23 +487,23 @@
ConfigInfo->MaximumNumberOfTargets = 1;
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
ConfigInfo->ResetTargetSupported = TRUE;
- ConfigInfo->NumberOfBuses = 32;
+ ConfigInfo->NumberOfBuses = MAXIMUM_AHCI_PORT_COUNT;
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
ConfigInfo->ScatterGather = TRUE;
// Turn IE -- Interrupt Enabled
- ghc |= 0x2;
+ ghc |= AHCI_Global_HBA_CONTROL_IE;
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
-
+
// allocate necessary resource for each port
if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo)){
StorPortDebugPrint(0, "\tAhciAllocateResourceForAdapter() ==
FALSE\n");
return SP_RETURN_ERROR;
}
- for (index = 0; index < 32; index++)
- {
- if ((adapterExtension->PortImplemented & (1<<index)) != 0)
+ for (index = 0; index < MAXIMUM_AHCI_PORT_COUNT; index++)
+ {
+ if ((adapterExtension->PortImplemented & (0x1<<index)) != 0)
AhciPortInitialize(&adapterExtension->PortExtension[index]);
}
@@ -443,7 +530,7 @@
HW_INITIALIZATION_DATA hwInitializationData;
ULONG i, status;
- StorPortDebugPrint(0, "Storahci Loaded 10023\n");
+ StorPortDebugPrint(0, "Storahci Loaded\n");
// initialize the hardware data structure
AhciZeroMemory((PCHAR)&hwInitializationData, sizeof(HW_INITIALIZATION_DATA));
@@ -471,13 +558,14 @@
// set required extension sizes
hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
-
+
// register our hw init data
status = StorPortInitialize(
DriverObject,
RegistryPath,
&hwInitializationData,
NULL);
+
StorPortDebugPrint(0, "\tstatus:%x\n", status);
return status;
}// -- DriverEntry();
@@ -494,7 +582,7 @@
* software sets GHC.HR to â1â and may poll until this bit is read to be â0â, at
which point software knows that
* the HBA reset has completed.
* If the HBA has not cleared GHC.HR to â0â within 1 second of software setting
GHC.HR to â1â, the HBA is in
- * a hung or locked state.
+ * a hung or locked state.
*
* @param adapterExtension
*
@@ -538,6 +626,7 @@
*
* @param buffer
*/
+__inline
VOID AhciZeroMemory(
__in PCHAR buffer,
__in ULONG bufferSize
@@ -547,3 +636,26 @@
for (i = 0; i < bufferSize; i++)
buffer[i] = 0;
}// -- AhciZeroMemory();
+
+/**
+ * @name IsPortValid
+ * @implemented
+ *
+ * Tells wheather given port is implemented or not
+ *
+ * @param adapterExtension
+ * @param PathId
+ *
+ * @return
+ * return TRUE if bus was successfully reset
+ */
+__inline
+BOOLEAN IsPortValid(
+ __in PAHCI_ADAPTER_EXTENSION adapterExtension,
+ __in UCHAR pathId
+)
+{
+ if (pathId >= MAXIMUM_AHCI_PORT_COUNT)
+ return FALSE;
+ return adapterExtension->PortExtension[pathId].IsActive;
+}// -- IsPortValid()
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] Tue Jun 7
11:05:32 2016
@@ -4,11 +4,22 @@
* PURPOSE: To Implement AHCI Miniport driver targeting storport NT 5.2
* PROGRAMMERS: Aman Priyadarshi (aman.eureka(a)gmail.com)
*/
-
+
#include "miniport.h"
#include "storport.h"
#define AHCI_POOL_TAG 'ahci'
+#define MAXIMUM_AHCI_PORT_COUNT 12
+
+// section 3.1.2
+#define AHCI_Global_HBA_CONTROL_HR (0x1<<0)
+#define AHCI_Global_HBA_CONTROL_IE (0x1<<1)
+#define AHCI_Global_HBA_CONTROL_MRSM (0x1<<2)
+#define AHCI_Global_HBA_CONTROL_AE (0x1<<31)
+
+//////////////////////////////////////////////////////////////
+// ---- Support Structures --- //
+//////////////////////////////////////////////////////////////
typedef struct _AHCI_FIS_DMA_SETUP
{
@@ -24,7 +35,7 @@
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 Reserved3; //Reserved
} AHCI_FIS_DMA_SETUP;
typedef struct _AHCI_PIO_SETUP_FIS
@@ -54,12 +65,11 @@
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 +93,9 @@
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,9 +110,13 @@
UCHAR Error;
UCHAR Reserved5[4];
-} AHCI_SET_DEVICE_BITS_FIS;
-
-// 4.2.2
+} AHCI_SET_DEVICE_BITS_FIS;
+
+//////////////////////////////////////////////////////////////
+// --------------------------- //
+//////////////////////////////////////////////////////////////
+
+// 4.2.2 Command Header
typedef struct _AHCI_COMMAND_HEADER
{
ULONG HEADER_DESCRIPTION; // DW 0
@@ -115,84 +129,81 @@
// 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 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[0xA0-0x2C]; // 0x2C - 0x9F, Reserved
+ ULONG VendorSpecific[0x100-0xA0]; // 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;
+ BOOLEAN IsActive;
+ PAHCI_PORT Port; // AHCI Port Infomation
+ PAHCI_RECEIVED_FIS ReceivedFIS;
PAHCI_COMMAND_HEADER CommandList;
- PAHCI_RECEIVED_FIS ReceivedFIS;
- PAHCI_PORT Port;
+ STOR_DEVICE_POWER_STATE DevicePowerState; // Device Power State
+ 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
USHORT VendorID;
USHORT DeviceID;
@@ -202,10 +213,18 @@
ULONG CAP;
ULONG CAP2;
- 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 _AHCI_SRB_EXTENSION