mirror of
https://github.com/reactos/reactos.git
synced 2025-07-25 12:04:01 +00:00
Required changes to meet community coding style.
svn path=/branches/GSoC_2016/AHCI/; revision=71500
This commit is contained in:
parent
a60737f997
commit
c62ab931ac
3 changed files with 292 additions and 260 deletions
|
@ -2,7 +2,7 @@ TARGETNAME = storahci
|
||||||
TARGETTYPE = MINIPORT
|
TARGETTYPE = MINIPORT
|
||||||
|
|
||||||
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
|
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
|
||||||
|
|
||||||
INCLUDES = %BUILD%\inc
|
INCLUDES = %BUILD%\inc
|
||||||
LIBS = %BUILD%\lib
|
LIBS = %BUILD%\lib
|
||||||
SOURCES = storahci.c
|
SOURCES = storahci.c
|
||||||
|
|
|
@ -1,231 +1,263 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GNU GPLv2 only as published by the Free Software Foundation
|
||||||
|
* PURPOSE: To Implement AHCI Miniport driver targeting storport NT 5.2
|
||||||
|
* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
|
||||||
|
*/
|
||||||
|
|
||||||
#include "storahci.h"
|
#include "storahci.h"
|
||||||
|
|
||||||
BOOLEAN AhciAdapterReset(
|
BOOLEAN AhciAdapterReset(
|
||||||
__in PAHCI_ADAPTER_EXTENSION adapterExtension
|
__in PAHCI_ADAPTER_EXTENSION adapterExtension
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name AhciFindAdapter
|
||||||
|
* @implemented
|
||||||
|
*
|
||||||
|
* The HwStorFindAdapter routine uses the supplied configuration to determine whether a specific
|
||||||
|
* HBA is supported and, if it is, to return configuration information about that adapter.
|
||||||
|
*
|
||||||
|
* 10.1 Platform Communication
|
||||||
|
* http://www.intel.in/content/dam/www/public/us/en/documents/technical-specifications/serial-ata-ahci-spec-rev1_2.pdf
|
||||||
|
|
||||||
|
* @param DeviceExtension
|
||||||
|
* @param HwContext
|
||||||
|
* @param BusInformation
|
||||||
|
* @param ArgumentString
|
||||||
|
* @param ConfigInfo
|
||||||
|
* @param Reserved3
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* SP_RETURN_FOUND
|
||||||
|
* Indicates that a supported HBA was found and that the HBA-relevant configuration information was successfully determined and set in the PORT_CONFIGURATION_INFORMATION structure.
|
||||||
|
*
|
||||||
|
* SP_RETURN_ERROR
|
||||||
|
* Indicates that an HBA was found but there was an error obtaining the configuration information. If possible, such an error should be logged with StorPortLogError.
|
||||||
|
*
|
||||||
|
* SP_RETURN_BAD_CONFIG
|
||||||
|
* Indicates that the supplied configuration information was invalid for the adapter.
|
||||||
|
*
|
||||||
|
* SP_RETURN_NOT_FOUND
|
||||||
|
* Indicates that no supported HBA was found for the supplied configuration information.
|
||||||
|
*
|
||||||
|
* @remarks Called by Storport.
|
||||||
|
*/
|
||||||
ULONG AhciFindAdapter(
|
ULONG AhciFindAdapter(
|
||||||
IN PVOID DeviceExtension,
|
IN PVOID DeviceExtension,
|
||||||
__in PVOID HwContext,
|
__in PVOID HwContext,
|
||||||
__in PVOID BusInformation,
|
__in PVOID BusInformation,
|
||||||
__in IN PVOID ArgumentString,
|
__in IN PVOID ArgumentString,
|
||||||
__inout PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
__inout PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
||||||
__in PBOOLEAN Reserved3
|
__in PBOOLEAN Reserved3
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Description :
|
ULONG ghc;
|
||||||
* The HwStorFindAdapter routine uses the supplied configuration to determine whether a specific
|
ULONG portCount, portImplemented;
|
||||||
* HBA is supported and, if it is, to return configuration information about that adapter.
|
ULONG pci_cfg_len;
|
||||||
*
|
UCHAR pci_cfg_buf[0x30];
|
||||||
* Refernce:
|
|
||||||
* 10.1 Platform Communication
|
|
||||||
* http://www.intel.in/content/dam/www/public/us/en/documents/technical-specifications/serial-ata-ahci-spec-rev1_2.pdf
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* SP_RETURN_FOUND
|
|
||||||
* Indicates that a supported HBA was found and that the HBA-relevant configuration information was successfully determined and set in the PORT_CONFIGURATION_INFORMATION structure.
|
|
||||||
*
|
|
||||||
* SP_RETURN_ERROR
|
|
||||||
* Indicates that an HBA was found but there was an error obtaining the configuration information. If possible, such an error should be logged with StorPortLogError.
|
|
||||||
*
|
|
||||||
* SP_RETURN_BAD_CONFIG
|
|
||||||
* Indicates that the supplied configuration information was invalid for the adapter.
|
|
||||||
*
|
|
||||||
* SP_RETURN_NOT_FOUND
|
|
||||||
* Indicates that no supported HBA was found for the supplied configuration information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ULONG ghc;
|
|
||||||
ULONG portCount, portImplemented;
|
|
||||||
ULONG pci_cfg_len;
|
|
||||||
UCHAR pci_cfg_buf[0x30];
|
|
||||||
|
|
||||||
PAHCI_MEMORY_REGISTERS abar;
|
|
||||||
PPCI_COMMON_CONFIG pciConfigData;
|
|
||||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
|
||||||
|
|
||||||
adapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
|
|
||||||
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
|
|
||||||
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
|
|
||||||
|
|
||||||
// get PCI configuration header
|
|
||||||
pci_cfg_len = StorPortGetBusData(
|
|
||||||
adapterExtension,
|
|
||||||
PCIConfiguration,
|
|
||||||
adapterExtension->SystemIoBusNumber,
|
|
||||||
adapterExtension->SlotNumber,
|
|
||||||
(PVOID)pci_cfg_buf,
|
|
||||||
(ULONG)0x30);
|
|
||||||
|
|
||||||
if (pci_cfg_len != 0x30)
|
|
||||||
return SP_RETURN_ERROR;//Not a valid device at the given bus number
|
|
||||||
|
|
||||||
pciConfigData = (PPCI_COMMON_CONFIG)pci_cfg_buf;
|
|
||||||
adapterExtension->VendorID = pciConfigData->VendorID;
|
|
||||||
adapterExtension->DeviceID = pciConfigData->DeviceID;
|
|
||||||
adapterExtension->RevisionID = pciConfigData->RevisionID;
|
|
||||||
// The last PCI base address register (BAR[5], header offset 0x24) points to the AHCI base memory, it’s called ABAR (AHCI Base Memory Register).
|
|
||||||
adapterExtension->AhciBaseAddress = pciConfigData->u.type0.BaseAddresses[5] & (0xFFFFFFF0);
|
|
||||||
|
|
||||||
// 2.1.11
|
|
||||||
abar = NULL;
|
|
||||||
if (ConfigInfo->NumberOfAccessRanges > 0)
|
|
||||||
{
|
|
||||||
ULONG accessIndex;
|
|
||||||
for (accessIndex = 0; accessIndex < ConfigInfo->NumberOfAccessRanges; accessIndex++)
|
|
||||||
{
|
|
||||||
if ((*(ConfigInfo->AccessRanges))[accessIndex].RangeStart.QuadPart == adapterExtension->AhciBaseAddress)
|
|
||||||
{
|
|
||||||
abar = (PAHCI_MEMORY_REGISTERS)StorPortGetDeviceBase(
|
|
||||||
adapterExtension,
|
|
||||||
ConfigInfo->AdapterInterfaceType,
|
|
||||||
ConfigInfo->SystemIoBusNumber,
|
|
||||||
(*(ConfigInfo->AccessRanges))[accessIndex].RangeStart,
|
|
||||||
(*(ConfigInfo->AccessRanges))[accessIndex].RangeLength,
|
|
||||||
(BOOLEAN)!(*(ConfigInfo->AccessRanges))[accessIndex].RangeInMemory);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abar == NULL)
|
|
||||||
return SP_RETURN_ERROR; // corrupted information supplied
|
|
||||||
|
|
||||||
adapterExtension->ABAR_Address = abar;
|
|
||||||
adapterExtension->CAP = StorPortReadRegisterUlong(adapterExtension, &abar->CAP);
|
|
||||||
adapterExtension->CAP2 = StorPortReadRegisterUlong(adapterExtension, &abar->CAP2);
|
|
||||||
adapterExtension->Version = StorPortReadRegisterUlong(adapterExtension, &abar->VS);
|
|
||||||
|
|
||||||
// 10.1.2
|
|
||||||
// 1. Indicate that system software is AHCI aware by setting GHC.AE to ‘1’.
|
|
||||||
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
|
|
||||||
// AE := Highest Significant bit of GHC
|
|
||||||
if ((ghc & (0x1<<31)) == 1)//Hmm, controller was already in power state
|
|
||||||
{
|
|
||||||
// reset controller to have it in know state
|
|
||||||
DebugPrint("AhciFindAdapter -> AE Already set, Reset()\n");
|
|
||||||
if (!AhciAdapterReset(adapterExtension))
|
|
||||||
return SP_RETURN_ERROR;// reset failed
|
|
||||||
}
|
|
||||||
|
|
||||||
ghc = 0x1<<31;// only AE=1
|
|
||||||
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
|
||||||
|
|
||||||
adapterExtension->IS = abar->IS;
|
|
||||||
adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension, &abar->PI);
|
|
||||||
|
|
||||||
if (adapterExtension->PortImplemented == 0)
|
|
||||||
return SP_RETURN_ERROR;
|
|
||||||
|
|
||||||
// get port count -- Number of set bits in `adapterExtension->PortImplemented`
|
|
||||||
portCount = 0;
|
|
||||||
portImplemented = adapterExtension->PortImplemented;
|
|
||||||
while(portImplemented > 0)
|
|
||||||
{
|
|
||||||
portCount++;
|
|
||||||
portImplemented &= (portImplemented - 1);// i love playing with bits :D
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigInfo->MaximumTransferLength = 128 * 1024;//128 KB
|
|
||||||
ConfigInfo->NumberOfPhysicalBreaks = 0x21;
|
|
||||||
ConfigInfo->MaximumNumberOfTargets = 1;
|
|
||||||
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
|
|
||||||
ConfigInfo->ResetTargetSupported = TRUE;
|
|
||||||
ConfigInfo->NumberOfBuses = 32;
|
|
||||||
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
|
|
||||||
ConfigInfo->ScatterGather = TRUE;
|
|
||||||
|
|
||||||
// Turn IE -- Interrupt Enabled
|
|
||||||
ghc |= 0x2;
|
|
||||||
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return SP_RETURN_FOUND;
|
|
||||||
}// -- AhciFindAdapter();
|
|
||||||
|
|
||||||
ULONG DriverEntry(
|
|
||||||
IN PVOID DriverObject,
|
|
||||||
IN PVOID RegistryPath
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Description :
|
|
||||||
* Initial Entrypoint for storahci miniport driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
HW_INITIALIZATION_DATA hwInitializationData;
|
|
||||||
ULONG i, status;
|
|
||||||
|
|
||||||
DebugPrint("Storahci -> DriverEntry()\n");
|
|
||||||
|
|
||||||
// initialize the hardware data structure
|
|
||||||
for (i = 0; i < sizeof(HW_INITIALIZATION_DATA); i++)
|
|
||||||
((PUCHAR)&hwInitializationData)[i] = 0;
|
|
||||||
|
|
||||||
// set size of hardware initialization structure
|
|
||||||
hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
|
|
||||||
|
|
||||||
// identity required miniport entry point routines
|
|
||||||
hwInitializationData.HwFindAdapter = AhciFindAdapter;
|
|
||||||
|
|
||||||
// adapter specific information
|
|
||||||
hwInitializationData.NeedPhysicalAddresses = TRUE;
|
|
||||||
hwInitializationData.TaggedQueuing = TRUE;
|
|
||||||
hwInitializationData.AutoRequestSense = TRUE;
|
|
||||||
hwInitializationData.MultipleRequestPerLu = TRUE;
|
|
||||||
|
|
||||||
hwInitializationData.NumberOfAccessRanges = 6;
|
|
||||||
hwInitializationData.AdapterInterfaceType = PCIBus;
|
|
||||||
hwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
|
|
||||||
|
|
||||||
// set required extension sizes
|
|
||||||
hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
|
|
||||||
hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
|
|
||||||
|
|
||||||
// register our hw init data
|
PAHCI_MEMORY_REGISTERS abar;
|
||||||
status = StorPortInitialize(
|
PPCI_COMMON_CONFIG pciConfigData;
|
||||||
DriverObject,
|
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||||
RegistryPath,
|
|
||||||
&hwInitializationData,
|
adapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
|
||||||
NULL);
|
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
|
||||||
|
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
|
||||||
|
|
||||||
|
// get PCI configuration header
|
||||||
|
pci_cfg_len = StorPortGetBusData(
|
||||||
|
adapterExtension,
|
||||||
|
PCIConfiguration,
|
||||||
|
adapterExtension->SystemIoBusNumber,
|
||||||
|
adapterExtension->SlotNumber,
|
||||||
|
(PVOID)pci_cfg_buf,
|
||||||
|
(ULONG)0x30);
|
||||||
|
|
||||||
|
if (pci_cfg_len != 0x30)
|
||||||
|
return SP_RETURN_ERROR;//Not a valid device at the given bus number
|
||||||
|
|
||||||
|
pciConfigData = (PPCI_COMMON_CONFIG)pci_cfg_buf;
|
||||||
|
adapterExtension->VendorID = pciConfigData->VendorID;
|
||||||
|
adapterExtension->DeviceID = pciConfigData->DeviceID;
|
||||||
|
adapterExtension->RevisionID = pciConfigData->RevisionID;
|
||||||
|
// The last PCI base address register (BAR[5], header offset 0x24) points to the AHCI base memory, it’s called ABAR (AHCI Base Memory Register).
|
||||||
|
adapterExtension->AhciBaseAddress = pciConfigData->u.type0.BaseAddresses[5] & (0xFFFFFFF0);
|
||||||
|
|
||||||
|
// 2.1.11
|
||||||
|
abar = NULL;
|
||||||
|
if (ConfigInfo->NumberOfAccessRanges > 0)
|
||||||
|
{
|
||||||
|
ULONG accessIndex;
|
||||||
|
for (accessIndex = 0; accessIndex < ConfigInfo->NumberOfAccessRanges; accessIndex++)
|
||||||
|
{
|
||||||
|
if ((*(ConfigInfo->AccessRanges))[accessIndex].RangeStart.QuadPart == adapterExtension->AhciBaseAddress)
|
||||||
|
{
|
||||||
|
abar = (PAHCI_MEMORY_REGISTERS)StorPortGetDeviceBase(
|
||||||
|
adapterExtension,
|
||||||
|
ConfigInfo->AdapterInterfaceType,
|
||||||
|
ConfigInfo->SystemIoBusNumber,
|
||||||
|
(*(ConfigInfo->AccessRanges))[accessIndex].RangeStart,
|
||||||
|
(*(ConfigInfo->AccessRanges))[accessIndex].RangeLength,
|
||||||
|
(BOOLEAN)!(*(ConfigInfo->AccessRanges))[accessIndex].RangeInMemory);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abar == NULL)
|
||||||
|
return SP_RETURN_ERROR; // corrupted information supplied
|
||||||
|
|
||||||
|
adapterExtension->ABAR_Address = abar;
|
||||||
|
adapterExtension->CAP = StorPortReadRegisterUlong(adapterExtension, &abar->CAP);
|
||||||
|
adapterExtension->CAP2 = StorPortReadRegisterUlong(adapterExtension, &abar->CAP2);
|
||||||
|
adapterExtension->Version = StorPortReadRegisterUlong(adapterExtension, &abar->VS);
|
||||||
|
|
||||||
|
// 10.1.2
|
||||||
|
// 1. Indicate that system software is AHCI aware by setting GHC.AE to ‘1’.
|
||||||
|
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
|
||||||
|
// AE := Highest Significant bit of GHC
|
||||||
|
if ((ghc & (0x1<<31)) == 1)//Hmm, controller was already in power state
|
||||||
|
{
|
||||||
|
// reset controller to have it in know state
|
||||||
|
DebugPrint("AhciFindAdapter -> AE Already set, Reset()\n");
|
||||||
|
if (!AhciAdapterReset(adapterExtension))
|
||||||
|
return SP_RETURN_ERROR;// reset failed
|
||||||
|
}
|
||||||
|
|
||||||
|
ghc = 0x1<<31;// only AE=1
|
||||||
|
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||||
|
|
||||||
|
adapterExtension->IS = abar->IS;
|
||||||
|
adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension, &abar->PI);
|
||||||
|
|
||||||
|
if (adapterExtension->PortImplemented == 0)
|
||||||
|
return SP_RETURN_ERROR;
|
||||||
|
|
||||||
|
// get port count -- Number of set bits in `adapterExtension->PortImplemented`
|
||||||
|
portCount = 0;
|
||||||
|
portImplemented = adapterExtension->PortImplemented;
|
||||||
|
while(portImplemented > 0)
|
||||||
|
{
|
||||||
|
portCount++;
|
||||||
|
portImplemented &= (portImplemented - 1);// i love playing with bits :D
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigInfo->MaximumTransferLength = 128 * 1024;//128 KB
|
||||||
|
ConfigInfo->NumberOfPhysicalBreaks = 0x21;
|
||||||
|
ConfigInfo->MaximumNumberOfTargets = 1;
|
||||||
|
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
|
||||||
|
ConfigInfo->ResetTargetSupported = TRUE;
|
||||||
|
ConfigInfo->NumberOfBuses = 32;
|
||||||
|
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
|
||||||
|
ConfigInfo->ScatterGather = TRUE;
|
||||||
|
|
||||||
|
// Turn IE -- Interrupt Enabled
|
||||||
|
ghc |= 0x2;
|
||||||
|
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return SP_RETURN_FOUND;
|
||||||
|
}// -- AhciFindAdapter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DriverEntry
|
||||||
|
* @implemented
|
||||||
|
*
|
||||||
|
* Initial Entrypoint for storahci miniport driver
|
||||||
|
*
|
||||||
|
* @param DriverObject
|
||||||
|
* @param RegistryPath
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* NT_STATUS in case of driver loaded successfully.
|
||||||
|
*/
|
||||||
|
ULONG DriverEntry(
|
||||||
|
IN PVOID DriverObject,
|
||||||
|
IN PVOID RegistryPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HW_INITIALIZATION_DATA hwInitializationData;
|
||||||
|
ULONG i, status;
|
||||||
|
|
||||||
|
DebugPrint("Storahci -> DriverEntry()\n");
|
||||||
|
|
||||||
|
// initialize the hardware data structure
|
||||||
|
for (i = 0; i < sizeof(HW_INITIALIZATION_DATA); i++)
|
||||||
|
((PUCHAR)&hwInitializationData)[i] = 0;
|
||||||
|
|
||||||
|
// set size of hardware initialization structure
|
||||||
|
hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
|
||||||
|
|
||||||
|
// identity required miniport entry point routines
|
||||||
|
hwInitializationData.HwFindAdapter = AhciFindAdapter;
|
||||||
|
|
||||||
|
// adapter specific information
|
||||||
|
hwInitializationData.NeedPhysicalAddresses = TRUE;
|
||||||
|
hwInitializationData.TaggedQueuing = TRUE;
|
||||||
|
hwInitializationData.AutoRequestSense = TRUE;
|
||||||
|
hwInitializationData.MultipleRequestPerLu = TRUE;
|
||||||
|
|
||||||
|
hwInitializationData.NumberOfAccessRanges = 6;
|
||||||
|
hwInitializationData.AdapterInterfaceType = PCIBus;
|
||||||
|
hwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}// -- DriverEntry();
|
}// -- DriverEntry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name AhciAdapterReset
|
||||||
|
* @implemented
|
||||||
|
*
|
||||||
|
* 10.4.3 HBA Reset
|
||||||
|
* If the HBA becomes unusable for multiple ports, and a software reset or port reset does not correct the
|
||||||
|
* problem, software may reset the entire HBA by setting GHC.HR to ‘1’. When software sets the GHC.HR
|
||||||
|
* bit to ‘1’, the HBA shall perform an internal reset action. The bit shall be cleared to ‘0’ by the HBA when
|
||||||
|
* the reset is complete. A software write of ‘0’ to GHC.HR shall have no effect. To perform the HBA reset,
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param adapterExtension
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* TRUE in case AHCI Controller RESTARTED successfully. i.e GHC.HR == 0
|
||||||
|
*/
|
||||||
BOOLEAN AhciAdapterReset(
|
BOOLEAN AhciAdapterReset(
|
||||||
PAHCI_ADAPTER_EXTENSION adapterExtension
|
PAHCI_ADAPTER_EXTENSION adapterExtension
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/*
|
ULONG ghc, ticks;
|
||||||
* 10.4.3 HBA Reset
|
PAHCI_MEMORY_REGISTERS abar = NULL;
|
||||||
* If the HBA becomes unusable for multiple ports, and a software reset or port reset does not correct the
|
|
||||||
* problem, software may reset the entire HBA by setting GHC.HR to ‘1’. When software sets the GHC.HR
|
|
||||||
* bit to ‘1’, the HBA shall perform an internal reset action. The bit shall be cleared to ‘0’ by the HBA when
|
|
||||||
* the reset is complete. A software write of ‘0’ to GHC.HR shall have no effect. To perform the HBA reset,
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
ULONG ghc, ticks;
|
|
||||||
PAHCI_MEMORY_REGISTERS abar = NULL;
|
|
||||||
|
|
||||||
abar = adapterExtension->ABAR_Address;
|
abar = adapterExtension->ABAR_Address;
|
||||||
|
|
||||||
if (abar == NULL) // basic sanity
|
if (abar == NULL) // basic sanity
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// HR -- Very first bit (lowest significant)
|
// HR -- Very first bit (lowest significant)
|
||||||
ghc = 1;
|
ghc = 1;
|
||||||
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||||
|
|
||||||
for (ticks = 0; (ticks < 50) &&
|
for (ticks = 0; (ticks < 50) &&
|
||||||
(StorPortReadRegisterUlong(adapterExtension, &abar->GHC) == 1);
|
(StorPortReadRegisterUlong(adapterExtension, &abar->GHC) == 1);
|
||||||
StorPortStallExecution(20000), ticks++);
|
StorPortStallExecution(20000), ticks++);
|
||||||
|
|
||||||
if (ticks == 50)//1 second
|
if (ticks == 50)//1 second
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}// -- AhciAdapterReset();
|
}// -- AhciAdapterReset();
|
||||||
|
|
|
@ -3,72 +3,72 @@
|
||||||
|
|
||||||
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;
|
} AHCI_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
|
||||||
|
|
||||||
// 0x2C - 0x9F, Reserved
|
// 0x2C - 0x9F, Reserved
|
||||||
ULONG Reserved[0xA0-0x2C];
|
ULONG Reserved[0xA0-0x2C];
|
||||||
|
|
||||||
// 0xA0 - 0xFF, Vendor specific registers
|
// 0xA0 - 0xFF, Vendor specific registers
|
||||||
ULONG VendorSpecific[0x100-0xA0];
|
ULONG VendorSpecific[0x100-0xA0];
|
||||||
|
|
||||||
AHCI_PORT PortList[32];//1~32
|
AHCI_PORT PortList[32];//1~32
|
||||||
|
|
||||||
} AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
|
} AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
|
||||||
|
|
||||||
typedef struct _AHCI_ADAPTER_EXTENSION
|
typedef struct _AHCI_ADAPTER_EXTENSION
|
||||||
{
|
{
|
||||||
ULONG AdapterNumber;
|
ULONG AdapterNumber;
|
||||||
ULONG SystemIoBusNumber;
|
ULONG SystemIoBusNumber;
|
||||||
ULONG SlotNumber;
|
ULONG SlotNumber;
|
||||||
ULONG AhciBaseAddress;
|
ULONG AhciBaseAddress;
|
||||||
ULONG IS; // Interrupt status
|
ULONG IS; // Interrupt status
|
||||||
ULONG PortImplemented;
|
ULONG PortImplemented;
|
||||||
|
|
||||||
USHORT VendorID;
|
USHORT VendorID;
|
||||||
USHORT DeviceID;
|
USHORT DeviceID;
|
||||||
USHORT RevisionID;
|
USHORT RevisionID;
|
||||||
|
|
||||||
ULONG Version;
|
ULONG Version;
|
||||||
ULONG CAP;
|
ULONG CAP;
|
||||||
ULONG CAP2;
|
ULONG CAP2;
|
||||||
PAHCI_MEMORY_REGISTERS ABAR_Address;
|
PAHCI_MEMORY_REGISTERS ABAR_Address;
|
||||||
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
|
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
|
||||||
|
|
||||||
typedef struct _AHCI_SRB_EXTENSION
|
typedef struct _AHCI_SRB_EXTENSION
|
||||||
{
|
{
|
||||||
ULONG AdapterNumber;
|
ULONG AdapterNumber;
|
||||||
} AHCI_SRB_EXTENSION;
|
} AHCI_SRB_EXTENSION;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue