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
|
TARGETNAME = storahci
|
||||||
TARGETTYPE = MINIPORT
|
TARGETTYPE = MINIPORT
|
||||||
|
|
||||||
|
MSC_WARNING_LEVEL=/W4
|
||||||
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
|
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
|
||||||
|
|
||||||
INCLUDES = %BUILD%\inc
|
INCLUDES = %BUILD%\inc
|
||||||
|
|
|
@ -11,11 +11,18 @@ BOOLEAN AhciAdapterReset(
|
||||||
__in PAHCI_ADAPTER_EXTENSION adapterExtension
|
__in PAHCI_ADAPTER_EXTENSION adapterExtension
|
||||||
);
|
);
|
||||||
|
|
||||||
|
__inline
|
||||||
VOID AhciZeroMemory(
|
VOID AhciZeroMemory(
|
||||||
__in PCHAR buffer,
|
__in PCHAR buffer,
|
||||||
__in ULONG bufferSize
|
__in ULONG bufferSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
__inline
|
||||||
|
BOOLEAN IsPortValid(
|
||||||
|
__in PAHCI_ADAPTER_EXTENSION adapterExtension,
|
||||||
|
__in UCHAR pathId
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name AhciPortInitialize
|
* @name AhciPortInitialize
|
||||||
* @implemented
|
* @implemented
|
||||||
|
@ -40,6 +47,7 @@ BOOLEAN AhciPortInitialize(
|
||||||
|
|
||||||
adapterExtension = portExtension->AdapterExtension;
|
adapterExtension = portExtension->AdapterExtension;
|
||||||
abar = adapterExtension->ABAR_Address;
|
abar = adapterExtension->ABAR_Address;
|
||||||
|
|
||||||
portExtension->Port = &abar->PortList[portExtension->PortNumber];
|
portExtension->Port = &abar->PortList[portExtension->PortNumber];
|
||||||
|
|
||||||
commandListPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->CommandList, &mappedLength);
|
commandListPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->CommandList, &mappedLength);
|
||||||
|
@ -61,6 +69,14 @@ BOOLEAN AhciPortInitialize(
|
||||||
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->CLB, commandListPhysical.LowPart);
|
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->CLB, commandListPhysical.LowPart);
|
||||||
StorPortWriteRegisterUlong(adapterExtension, &portExtension->Port->FB, receivedFISPhysical.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;
|
return TRUE;
|
||||||
}// -- AhciPortInitialize();
|
}// -- AhciPortInitialize();
|
||||||
|
|
||||||
|
@ -87,7 +103,7 @@ BOOLEAN AhciAllocateResourceForAdapter(
|
||||||
|
|
||||||
StorPortDebugPrint(0, "AhciAllocateResourceForAdapter()\n");
|
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;
|
NCS = (adapterExtension->CAP & 0xF00) >> 8;
|
||||||
AlignedNCS = ((NCS/8) + 1) * 8;
|
AlignedNCS = ((NCS/8) + 1) * 8;
|
||||||
|
|
||||||
|
@ -116,33 +132,16 @@ BOOLEAN AhciAllocateResourceForAdapter(
|
||||||
nonCachedExtension = (PCHAR)adapterExtension->NonCachedExtension;
|
nonCachedExtension = (PCHAR)adapterExtension->NonCachedExtension;
|
||||||
|
|
||||||
AhciZeroMemory(nonCachedExtension, nonCachedExtensionSize);
|
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;
|
nonCachedExtensionSize /= portCount;
|
||||||
currentCount = 0;
|
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)
|
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].PortNumber = index;
|
||||||
|
adapterExtension->PortExtension[index].IsActive = TRUE;
|
||||||
adapterExtension->PortExtension[index].AdapterExtension = adapterExtension;
|
adapterExtension->PortExtension[index].AdapterExtension = adapterExtension;
|
||||||
adapterExtension->PortExtension[index].CommandList = (PAHCI_COMMAND_HEADER)(nonCachedExtension + (currentCount*nonCachedExtensionSize));
|
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);
|
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
|
__in PVOID AdapterExtension
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ULONG ghc, messageCount, status;
|
||||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||||
|
|
||||||
StorPortDebugPrint(0, "AhciHwInitialize()\n");
|
StorPortDebugPrint(0, "AhciHwInitialize()\n");
|
||||||
|
|
||||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
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;
|
return TRUE;
|
||||||
}// -- AhciHwInitialize();
|
}// -- AhciHwInitialize();
|
||||||
|
@ -199,7 +213,7 @@ BOOLEAN AhciHwInterrupt(
|
||||||
|
|
||||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
||||||
|
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}// -- AhciHwInterrupt();
|
}// -- AhciHwInterrupt();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,14 +235,87 @@ BOOLEAN AhciHwStartIo(
|
||||||
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UCHAR function;
|
UCHAR function, pathId;
|
||||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||||
|
|
||||||
StorPortDebugPrint(0, "AhciHwStartIo()\n");
|
StorPortDebugPrint(0, "AhciHwStartIo()\n");
|
||||||
|
|
||||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
pathId = Srb->PathId;
|
||||||
function = Srb->Function;
|
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;
|
return TRUE;
|
||||||
}// -- AhciHwStartIo();
|
}// -- AhciHwStartIo();
|
||||||
|
|
||||||
|
@ -305,7 +392,7 @@ ULONG AhciHwFindAdapter(
|
||||||
ULONG portCount, portImplemented;
|
ULONG portCount, portImplemented;
|
||||||
ULONG pci_cfg_len;
|
ULONG pci_cfg_len;
|
||||||
UCHAR pci_cfg_buf[0x30];
|
UCHAR pci_cfg_buf[0x30];
|
||||||
|
|
||||||
PAHCI_MEMORY_REGISTERS abar;
|
PAHCI_MEMORY_REGISTERS abar;
|
||||||
PPCI_COMMON_CONFIG pciConfigData;
|
PPCI_COMMON_CONFIG pciConfigData;
|
||||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||||
|
@ -315,7 +402,7 @@ ULONG AhciHwFindAdapter(
|
||||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
|
||||||
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
|
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
|
||||||
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
|
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
|
||||||
|
|
||||||
// get PCI configuration header
|
// get PCI configuration header
|
||||||
pci_cfg_len = StorPortGetBusData(
|
pci_cfg_len = StorPortGetBusData(
|
||||||
adapterExtension,
|
adapterExtension,
|
||||||
|
@ -374,7 +461,7 @@ ULONG AhciHwFindAdapter(
|
||||||
// 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
|
// 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
|
||||||
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
|
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
|
||||||
// AE := Highest Significant bit of 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
|
// reset controller to have it in know state
|
||||||
StorPortDebugPrint(0, "\tAE Already set, Reset()\n");
|
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);
|
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||||
|
|
||||||
adapterExtension->IS = abar->IS;
|
adapterExtension->IS = &abar->IS;
|
||||||
adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension, &abar->PI);
|
adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension, &abar->PI);
|
||||||
|
|
||||||
if (adapterExtension->PortImplemented == 0){
|
if (adapterExtension->PortImplemented == 0){
|
||||||
|
@ -400,23 +487,23 @@ ULONG AhciHwFindAdapter(
|
||||||
ConfigInfo->MaximumNumberOfTargets = 1;
|
ConfigInfo->MaximumNumberOfTargets = 1;
|
||||||
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
|
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
|
||||||
ConfigInfo->ResetTargetSupported = TRUE;
|
ConfigInfo->ResetTargetSupported = TRUE;
|
||||||
ConfigInfo->NumberOfBuses = 32;
|
ConfigInfo->NumberOfBuses = MAXIMUM_AHCI_PORT_COUNT;
|
||||||
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
|
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
|
||||||
ConfigInfo->ScatterGather = TRUE;
|
ConfigInfo->ScatterGather = TRUE;
|
||||||
|
|
||||||
// Turn IE -- Interrupt Enabled
|
// Turn IE -- Interrupt Enabled
|
||||||
ghc |= 0x2;
|
ghc |= AHCI_Global_HBA_CONTROL_IE;
|
||||||
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||||
|
|
||||||
// allocate necessary resource for each port
|
// allocate necessary resource for each port
|
||||||
if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo)){
|
if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo)){
|
||||||
StorPortDebugPrint(0, "\tAhciAllocateResourceForAdapter() == FALSE\n");
|
StorPortDebugPrint(0, "\tAhciAllocateResourceForAdapter() == FALSE\n");
|
||||||
return SP_RETURN_ERROR;
|
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]);
|
AhciPortInitialize(&adapterExtension->PortExtension[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +530,7 @@ ULONG DriverEntry(
|
||||||
HW_INITIALIZATION_DATA hwInitializationData;
|
HW_INITIALIZATION_DATA hwInitializationData;
|
||||||
ULONG i, status;
|
ULONG i, status;
|
||||||
|
|
||||||
StorPortDebugPrint(0, "Storahci Loaded 10023\n");
|
StorPortDebugPrint(0, "Storahci Loaded\n");
|
||||||
|
|
||||||
// initialize the hardware data structure
|
// initialize the hardware data structure
|
||||||
AhciZeroMemory((PCHAR)&hwInitializationData, sizeof(HW_INITIALIZATION_DATA));
|
AhciZeroMemory((PCHAR)&hwInitializationData, sizeof(HW_INITIALIZATION_DATA));
|
||||||
|
@ -471,13 +558,14 @@ ULONG DriverEntry(
|
||||||
// set required extension sizes
|
// set required extension sizes
|
||||||
hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
|
hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
|
||||||
hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
|
hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
|
||||||
|
|
||||||
// register our hw init data
|
// register our hw init data
|
||||||
status = StorPortInitialize(
|
status = StorPortInitialize(
|
||||||
DriverObject,
|
DriverObject,
|
||||||
RegistryPath,
|
RegistryPath,
|
||||||
&hwInitializationData,
|
&hwInitializationData,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
StorPortDebugPrint(0, "\tstatus:%x\n", status);
|
StorPortDebugPrint(0, "\tstatus:%x\n", status);
|
||||||
return status;
|
return status;
|
||||||
}// -- DriverEntry();
|
}// -- DriverEntry();
|
||||||
|
@ -494,7 +582,7 @@ ULONG DriverEntry(
|
||||||
* software sets GHC.HR to ‘1’ and may poll until this bit is read to be ‘0’, at which point software knows that
|
* 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.
|
* 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
|
* 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
|
* @param adapterExtension
|
||||||
*
|
*
|
||||||
|
@ -538,6 +626,7 @@ BOOLEAN AhciAdapterReset(
|
||||||
*
|
*
|
||||||
* @param buffer
|
* @param buffer
|
||||||
*/
|
*/
|
||||||
|
__inline
|
||||||
VOID AhciZeroMemory(
|
VOID AhciZeroMemory(
|
||||||
__in PCHAR buffer,
|
__in PCHAR buffer,
|
||||||
__in ULONG bufferSize
|
__in ULONG bufferSize
|
||||||
|
@ -547,3 +636,26 @@ VOID AhciZeroMemory(
|
||||||
for (i = 0; i < bufferSize; i++)
|
for (i = 0; i < bufferSize; i++)
|
||||||
buffer[i] = 0;
|
buffer[i] = 0;
|
||||||
}// -- AhciZeroMemory();
|
}// -- 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()
|
||||||
|
|
|
@ -4,11 +4,22 @@
|
||||||
* PURPOSE: To Implement AHCI Miniport driver targeting storport NT 5.2
|
* PURPOSE: To Implement AHCI Miniport driver targeting storport NT 5.2
|
||||||
* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
|
* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "miniport.h"
|
#include "miniport.h"
|
||||||
#include "storport.h"
|
#include "storport.h"
|
||||||
|
|
||||||
#define AHCI_POOL_TAG 'ahci'
|
#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
|
typedef struct _AHCI_FIS_DMA_SETUP
|
||||||
{
|
{
|
||||||
|
@ -24,7 +35,7 @@ typedef struct _AHCI_FIS_DMA_SETUP
|
||||||
ULONG Reserved2; //More reserved
|
ULONG Reserved2; //More reserved
|
||||||
ULONG DmaBufferOffset; //Byte offset into buffer. First 2 bits must be 0
|
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 TranferCount; //Number of bytes to transfer. Bit 0 must be 0
|
||||||
ULONG Reserved3; //Reserved
|
ULONG Reserved3; //Reserved
|
||||||
} AHCI_FIS_DMA_SETUP;
|
} AHCI_FIS_DMA_SETUP;
|
||||||
|
|
||||||
typedef struct _AHCI_PIO_SETUP_FIS
|
typedef struct _AHCI_PIO_SETUP_FIS
|
||||||
|
@ -54,12 +65,11 @@ typedef struct _AHCI_PIO_SETUP_FIS
|
||||||
|
|
||||||
USHORT TransferCount;
|
USHORT TransferCount;
|
||||||
UCHAR Reserved5[2];
|
UCHAR Reserved5[2];
|
||||||
|
} AHCI_PIO_SETUP_FIS;
|
||||||
} AHCI_PIO_SETUP_FIS;
|
|
||||||
|
|
||||||
typedef struct _AHCI_D2H_REGISTER_FIS
|
typedef struct _AHCI_D2H_REGISTER_FIS
|
||||||
{
|
{
|
||||||
UCHAR FisType; // 0x34
|
UCHAR FisType;
|
||||||
UCHAR Reserved1 :6;
|
UCHAR Reserved1 :6;
|
||||||
UCHAR I:1;
|
UCHAR I:1;
|
||||||
UCHAR Reserved2 :1;
|
UCHAR Reserved2 :1;
|
||||||
|
@ -83,9 +93,9 @@ typedef struct _AHCI_D2H_REGISTER_FIS
|
||||||
UCHAR Reserved4[4];
|
UCHAR Reserved4[4];
|
||||||
} AHCI_D2H_REGISTER_FIS;
|
} AHCI_D2H_REGISTER_FIS;
|
||||||
|
|
||||||
typedef struct _AHCI_SET_DEVICE_BITS_FIS {
|
typedef struct _AHCI_SET_DEVICE_BITS_FIS
|
||||||
|
{
|
||||||
UCHAR FisType; //0xA1
|
UCHAR FisType;
|
||||||
|
|
||||||
UCHAR PMPort: 4;
|
UCHAR PMPort: 4;
|
||||||
UCHAR Reserved1 :2;
|
UCHAR Reserved1 :2;
|
||||||
|
@ -100,9 +110,13 @@ typedef struct _AHCI_SET_DEVICE_BITS_FIS {
|
||||||
UCHAR Error;
|
UCHAR Error;
|
||||||
|
|
||||||
UCHAR Reserved5[4];
|
UCHAR Reserved5[4];
|
||||||
} AHCI_SET_DEVICE_BITS_FIS;
|
} AHCI_SET_DEVICE_BITS_FIS;
|
||||||
|
|
||||||
// 4.2.2
|
//////////////////////////////////////////////////////////////
|
||||||
|
// --------------------------- //
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// 4.2.2 Command Header
|
||||||
typedef struct _AHCI_COMMAND_HEADER
|
typedef struct _AHCI_COMMAND_HEADER
|
||||||
{
|
{
|
||||||
ULONG HEADER_DESCRIPTION; // DW 0
|
ULONG HEADER_DESCRIPTION; // DW 0
|
||||||
|
@ -115,84 +129,81 @@ typedef struct _AHCI_COMMAND_HEADER
|
||||||
// Received FIS
|
// Received FIS
|
||||||
typedef struct _AHCI_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
|
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
|
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
|
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 UnknowFIS[16]; // 0x60 -- Unknown FIS
|
||||||
ULONG Reserved[24]; // 0xA0 -- Reserved
|
ULONG Reserved[24]; // 0xA0 -- Reserved
|
||||||
} AHCI_RECEIVED_FIS, *PAHCI_RECEIVED_FIS;
|
} AHCI_RECEIVED_FIS, *PAHCI_RECEIVED_FIS;
|
||||||
|
|
||||||
|
// Holds Port Information
|
||||||
typedef struct _AHCI_PORT
|
typedef struct _AHCI_PORT
|
||||||
{
|
{
|
||||||
ULONG CLB; // 0x00, command list base address, 1K-byte aligned
|
ULONG CLB; // 0x00, command list base address, 1K-byte aligned
|
||||||
ULONG CLBU; // 0x04, command list base address upper 32 bits
|
ULONG CLBU; // 0x04, command list base address upper 32 bits
|
||||||
ULONG FB; // 0x08, FIS base address, 256-byte aligned
|
ULONG FB; // 0x08, FIS base address, 256-byte aligned
|
||||||
ULONG FBU; // 0x0C, FIS base address upper 32 bits
|
ULONG FBU; // 0x0C, FIS base address upper 32 bits
|
||||||
ULONG IS; // 0x10, interrupt status
|
ULONG IS; // 0x10, interrupt status
|
||||||
ULONG IE; // 0x14, interrupt enable
|
ULONG IE; // 0x14, interrupt enable
|
||||||
ULONG CMD; // 0x18, command and status
|
ULONG CMD; // 0x18, command and status
|
||||||
ULONG RSV0; // 0x1C, Reserved
|
ULONG RSV0; // 0x1C, Reserved
|
||||||
ULONG TFD; // 0x20, task file data
|
ULONG TFD; // 0x20, task file data
|
||||||
ULONG SIG; // 0x24, signature
|
ULONG SIG; // 0x24, signature
|
||||||
ULONG SSTS; // 0x28, SATA status (SCR0:SStatus)
|
ULONG SSTS; // 0x28, SATA status (SCR0:SStatus)
|
||||||
ULONG SCTL; // 0x2C, SATA control (SCR2:SControl)
|
ULONG SCTL; // 0x2C, SATA control (SCR2:SControl)
|
||||||
ULONG SERR; // 0x30, SATA error (SCR1:SError)
|
ULONG SERR; // 0x30, SATA error (SCR1:SError)
|
||||||
ULONG SACT; // 0x34, SATA active (SCR3:SActive)
|
ULONG SACT; // 0x34, SATA active (SCR3:SActive)
|
||||||
ULONG CI; // 0x38, command issue
|
ULONG CI; // 0x38, command issue
|
||||||
ULONG SNTF; // 0x3C, SATA notification (SCR4:SNotification)
|
ULONG SNTF; // 0x3C, SATA notification (SCR4:SNotification)
|
||||||
ULONG FBS; // 0x40, FIS-based switch control
|
ULONG FBS; // 0x40, FIS-based switch control
|
||||||
ULONG RSV1[11]; // 0x44 ~ 0x6F, Reserved
|
ULONG RSV1[11]; // 0x44 ~ 0x6F, Reserved
|
||||||
ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific
|
ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific
|
||||||
} AHCI_PORT, *PAHCI_PORT;
|
} AHCI_PORT, *PAHCI_PORT;
|
||||||
|
|
||||||
typedef struct _AHCI_MEMORY_REGISTERS
|
typedef struct _AHCI_MEMORY_REGISTERS
|
||||||
{
|
{
|
||||||
// 0x00 - 0x2B, Generic Host Control
|
// 0x00 - 0x2B, Generic Host Control
|
||||||
ULONG CAP; // 0x00, Host capability
|
ULONG CAP; // 0x00, Host capability
|
||||||
ULONG GHC; // 0x04, Global host control
|
ULONG GHC; // 0x04, Global host control
|
||||||
ULONG IS; // 0x08, Interrupt status
|
ULONG IS; // 0x08, Interrupt status
|
||||||
ULONG PI; // 0x0C, Port implemented
|
ULONG PI; // 0x0C, Port implemented
|
||||||
ULONG VS; // 0x10, Version
|
ULONG VS; // 0x10, Version
|
||||||
ULONG CCC_CTL; // 0x14, Command completion coalescing control
|
ULONG CCC_CTL; // 0x14, Command completion coalescing control
|
||||||
ULONG CCC_PTS; // 0x18, Command completion coalescing ports
|
ULONG CCC_PTS; // 0x18, Command completion coalescing ports
|
||||||
ULONG EM_LOC; // 0x1C, Enclosure management location
|
ULONG EM_LOC; // 0x1C, Enclosure management location
|
||||||
ULONG EM_CTL; // 0x20, Enclosure management control
|
ULONG EM_CTL; // 0x20, Enclosure management control
|
||||||
ULONG CAP2; // 0x24, Host capabilities extended
|
ULONG CAP2; // 0x24, Host capabilities extended
|
||||||
ULONG BOHC; // 0x28, BIOS/OS handoff control and status
|
ULONG BOHC; // 0x28, BIOS/OS handoff control and status
|
||||||
|
ULONG Reserved[0xA0-0x2C]; // 0x2C - 0x9F, Reserved
|
||||||
// 0x2C - 0x9F, Reserved
|
ULONG VendorSpecific[0x100-0xA0]; // 0xA0 - 0xFF, Vendor specific registers
|
||||||
ULONG Reserved[0xA0-0x2C];
|
AHCI_PORT PortList[MAXIMUM_AHCI_PORT_COUNT];
|
||||||
|
|
||||||
// 0xA0 - 0xFF, Vendor specific registers
|
|
||||||
ULONG VendorSpecific[0x100-0xA0];
|
|
||||||
|
|
||||||
AHCI_PORT PortList[32];//1~32
|
|
||||||
|
|
||||||
} AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
|
} 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
|
typedef struct _AHCI_PORT_EXTENSION
|
||||||
{
|
{
|
||||||
ULONG PortNumber;
|
ULONG PortNumber;
|
||||||
struct _AHCI_ADAPTER_EXTENSION* AdapterExtension;
|
BOOLEAN IsActive;
|
||||||
PAHCI_COMMAND_HEADER CommandList;
|
PAHCI_PORT Port; // AHCI Port Infomation
|
||||||
PAHCI_RECEIVED_FIS ReceivedFIS;
|
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;
|
} AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION;
|
||||||
|
|
||||||
|
// Holds Adapter Information
|
||||||
typedef struct _AHCI_ADAPTER_EXTENSION
|
typedef struct _AHCI_ADAPTER_EXTENSION
|
||||||
{
|
{
|
||||||
ULONG AdapterNumber;
|
|
||||||
ULONG SystemIoBusNumber;
|
ULONG SystemIoBusNumber;
|
||||||
ULONG SlotNumber;
|
ULONG SlotNumber;
|
||||||
ULONG AhciBaseAddress;
|
ULONG AhciBaseAddress;
|
||||||
ULONG IS; // Interrupt status
|
PULONG IS;// Interrupt Status, In case of MSIM == `1`
|
||||||
ULONG PortImplemented;
|
ULONG PortImplemented;// bit-mapping of ports which are implemented
|
||||||
|
|
||||||
USHORT VendorID;
|
USHORT VendorID;
|
||||||
USHORT DeviceID;
|
USHORT DeviceID;
|
||||||
|
@ -202,10 +213,18 @@ typedef struct _AHCI_ADAPTER_EXTENSION
|
||||||
ULONG CAP;
|
ULONG CAP;
|
||||||
ULONG CAP2;
|
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;
|
PAHCI_MEMORY_REGISTERS ABAR_Address;
|
||||||
AHCI_PORT_EXTENSION PortExtension[32];
|
AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT];
|
||||||
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
|
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
|
||||||
|
|
||||||
typedef struct _AHCI_SRB_EXTENSION
|
typedef struct _AHCI_SRB_EXTENSION
|
||||||
|
|
Loading…
Reference in a new issue