mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
== Storahci driver
- Added DriverEntry - Added AhciFindAdapter : Need to add code for port initialization. - Compile : OK - Test : NOT TESTED svn path=/branches/GSoC_2016/AHCI/; revision=71499
This commit is contained in:
parent
321bcc056d
commit
a60737f997
3
drivers/storage/storahci/makefile
Normal file
3
drivers/storage/storahci/makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
MINIMUM_NT_TARGET_VERSION=0x502
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
8
drivers/storage/storahci/sources
Normal file
8
drivers/storage/storahci/sources
Normal file
|
@ -0,0 +1,8 @@
|
|||
TARGETNAME = storahci
|
||||
TARGETTYPE = MINIPORT
|
||||
|
||||
TARGETLIBS=$(DDK_LIB_PATH)\storport.lib
|
||||
|
||||
INCLUDES = %BUILD%\inc
|
||||
LIBS = %BUILD%\lib
|
||||
SOURCES = storahci.c
|
231
drivers/storage/storahci/storahci.c
Normal file
231
drivers/storage/storahci/storahci.c
Normal file
|
@ -0,0 +1,231 @@
|
|||
#include "storahci.h"
|
||||
|
||||
BOOLEAN AhciAdapterReset(
|
||||
__in PAHCI_ADAPTER_EXTENSION adapterExtension
|
||||
);
|
||||
|
||||
ULONG AhciFindAdapter(
|
||||
IN PVOID DeviceExtension,
|
||||
__in PVOID HwContext,
|
||||
__in PVOID BusInformation,
|
||||
__in IN PVOID ArgumentString,
|
||||
__inout PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
||||
__in PBOOLEAN Reserved3
|
||||
)
|
||||
{
|
||||
/* Description :
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
status = StorPortInitialize(
|
||||
DriverObject,
|
||||
RegistryPath,
|
||||
&hwInitializationData,
|
||||
NULL);
|
||||
|
||||
return status;
|
||||
}// -- DriverEntry();
|
||||
|
||||
BOOLEAN AhciAdapterReset(
|
||||
PAHCI_ADAPTER_EXTENSION adapterExtension
|
||||
)
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
ULONG ghc, ticks;
|
||||
PAHCI_MEMORY_REGISTERS abar = NULL;
|
||||
|
||||
abar = adapterExtension->ABAR_Address;
|
||||
|
||||
if (abar == NULL) // basic sanity
|
||||
return FALSE;
|
||||
|
||||
// HR -- Very first bit (lowest significant)
|
||||
ghc = 1;
|
||||
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
|
||||
|
||||
for (ticks = 0; (ticks < 50) &&
|
||||
(StorPortReadRegisterUlong(adapterExtension, &abar->GHC) == 1);
|
||||
StorPortStallExecution(20000), ticks++);
|
||||
|
||||
if (ticks == 50)//1 second
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}// -- AhciAdapterReset();
|
74
drivers/storage/storahci/storahci.h
Normal file
74
drivers/storage/storahci/storahci.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "miniport.h"
|
||||
#include "storport.h"
|
||||
|
||||
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
|
||||
} AHCI_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
|
||||
|
||||
} AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
|
||||
|
||||
typedef struct _AHCI_ADAPTER_EXTENSION
|
||||
{
|
||||
ULONG AdapterNumber;
|
||||
ULONG SystemIoBusNumber;
|
||||
ULONG SlotNumber;
|
||||
ULONG AhciBaseAddress;
|
||||
ULONG IS; // Interrupt status
|
||||
ULONG PortImplemented;
|
||||
|
||||
USHORT VendorID;
|
||||
USHORT DeviceID;
|
||||
USHORT RevisionID;
|
||||
|
||||
ULONG Version;
|
||||
ULONG CAP;
|
||||
ULONG CAP2;
|
||||
PAHCI_MEMORY_REGISTERS ABAR_Address;
|
||||
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
|
||||
|
||||
typedef struct _AHCI_SRB_EXTENSION
|
||||
{
|
||||
ULONG AdapterNumber;
|
||||
} AHCI_SRB_EXTENSION;
|
Loading…
Reference in a new issue