mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 09:50:02 +00:00
AHCI-SATA Interface almost ready.
- tested on VM. - need to implement Interrupt Routine (MessagePerPort) and ATA/ATAPI Based SCSI Query. svn path=/branches/GSoC_2016/AHCI/; revision=71588
This commit is contained in:
parent
37fd8e78e1
commit
d4c9e20b36
3 changed files with 236 additions and 104 deletions
|
@ -1,6 +1,7 @@
|
|||
TARGETNAME = storahci
|
||||
TARGETTYPE = MINIPORT
|
||||
|
||||
MSC_WARNING_LEVEL=/W4
|
||||
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
|
||||
|
||||
INCLUDES = %BUILD%\inc
|
||||
|
|
|
@ -11,11 +11,18 @@ BOOLEAN AhciAdapterReset(
|
|||
__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 @@ BOOLEAN AhciPortInitialize(
|
|||
|
||||
adapterExtension = portExtension->AdapterExtension;
|
||||
abar = adapterExtension->ABAR_Address;
|
||||
|
||||
portExtension->Port = &abar->PortList[portExtension->PortNumber];
|
||||
|
||||
commandListPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->CommandList, &mappedLength);
|
||||
|
@ -61,6 +69,14 @@ BOOLEAN AhciPortInitialize(
|
|||
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();
|
||||
|
||||
|
@ -117,32 +133,15 @@ BOOLEAN AhciAllocateResourceForAdapter(
|
|||
|
||||
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 @@ BOOLEAN AhciHwInitialize(
|
|||
__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 @@ BOOLEAN AhciHwInterrupt(
|
|||
|
||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}// -- AhciHwInterrupt();
|
||||
|
||||
/**
|
||||
|
@ -221,14 +235,87 @@ BOOLEAN AhciHwStartIo(
|
|||
|
||||
)
|
||||
{
|
||||
UCHAR function;
|
||||
UCHAR function, pathId;
|
||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||
|
||||
StorPortDebugPrint(0, "AhciHwStartIo()\n");
|
||||
|
||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
||||
pathId = Srb->PathId;
|
||||
function = Srb->Function;
|
||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
||||
|
||||
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-function-pnp
|
||||
// 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-srb-function-execute-scsi
|
||||
// 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();
|
||||
|
||||
|
@ -374,7 +461,7 @@ ULONG AhciHwFindAdapter(
|
|||
// 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 @@ ULONG AhciHwFindAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
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,12 +487,12 @@ ULONG AhciHwFindAdapter(
|
|||
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
|
||||
|
@ -414,9 +501,9 @@ ULONG AhciHwFindAdapter(
|
|||
return SP_RETURN_ERROR;
|
||||
}
|
||||
|
||||
for (index = 0; index < 32; index++)
|
||||
for (index = 0; index < MAXIMUM_AHCI_PORT_COUNT; index++)
|
||||
{
|
||||
if ((adapterExtension->PortImplemented & (1<<index)) != 0)
|
||||
if ((adapterExtension->PortImplemented & (0x1<<index)) != 0)
|
||||
AhciPortInitialize(&adapterExtension->PortExtension[index]);
|
||||
}
|
||||
|
||||
|
@ -443,7 +530,7 @@ ULONG DriverEntry(
|
|||
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));
|
||||
|
@ -478,6 +565,7 @@ ULONG DriverEntry(
|
|||
RegistryPath,
|
||||
&hwInitializationData,
|
||||
NULL);
|
||||
|
||||
StorPortDebugPrint(0, "\tstatus:%x\n", status);
|
||||
return status;
|
||||
}// -- DriverEntry();
|
||||
|
@ -538,6 +626,7 @@ BOOLEAN AhciAdapterReset(
|
|||
*
|
||||
* @param buffer
|
||||
*/
|
||||
__inline
|
||||
VOID AhciZeroMemory(
|
||||
__in PCHAR buffer,
|
||||
__in ULONG bufferSize
|
||||
|
@ -547,3 +636,26 @@ VOID AhciZeroMemory(
|
|||
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()
|
||||
|
|
|
@ -9,6 +9,17 @@
|
|||
#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
|
||||
{
|
||||
|
@ -54,12 +65,11 @@ typedef struct _AHCI_PIO_SETUP_FIS
|
|||
|
||||
USHORT TransferCount;
|
||||
UCHAR Reserved5[2];
|
||||
|
||||
} 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 @@ 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;
|
||||
|
@ -102,7 +112,11 @@ typedef struct _AHCI_SET_DEVICE_BITS_FIS {
|
|||
UCHAR Reserved5[4];
|
||||
} AHCI_SET_DEVICE_BITS_FIS;
|
||||
|
||||
// 4.2.2
|
||||
//////////////////////////////////////////////////////////////
|
||||
// --------------------------- //
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// 4.2.2 Command Header
|
||||
typedef struct _AHCI_COMMAND_HEADER
|
||||
{
|
||||
ULONG HEADER_DESCRIPTION; // DW 0
|
||||
|
@ -115,17 +129,18 @@ typedef struct _AHCI_COMMAND_HEADER
|
|||
// Received FIS
|
||||
typedef struct _AHCI_RECEIVED_FIS
|
||||
{
|
||||
AHCI_FIS_DMA_SETUP DmaSetupFIS; // 0x00 -- DMA Setup FIS
|
||||
struct _AHCI_FIS_DMA_SETUP DmaSetupFIS; // 0x00 -- DMA Setup FIS
|
||||
ULONG pad0; // 4 BYTE padding
|
||||
AHCI_PIO_SETUP_FIS PioSetupFIS; // 0x20 -- PIO Setup FIS
|
||||
struct _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
|
||||
struct _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
|
||||
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
|
||||
|
@ -163,36 +178,32 @@ 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
|
||||
|
||||
// 0x2C - 0x9F, Reserved
|
||||
ULONG Reserved[0xA0-0x2C];
|
||||
|
||||
// 0xA0 - 0xFF, Vendor specific registers
|
||||
ULONG VendorSpecific[0x100-0xA0];
|
||||
|
||||
AHCI_PORT PortList[32];//1~32
|
||||
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;
|
||||
PAHCI_COMMAND_HEADER CommandList;
|
||||
BOOLEAN IsActive;
|
||||
PAHCI_PORT Port; // AHCI Port Infomation
|
||||
PAHCI_RECEIVED_FIS ReceivedFIS;
|
||||
PAHCI_PORT Port;
|
||||
PAHCI_COMMAND_HEADER CommandList;
|
||||
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 @@ typedef struct _AHCI_ADAPTER_EXTENSION
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue