#include "storahci.h"
BOOLEAN AhciAdapterReset(
- __in PAHCI_ADAPTER_EXTENSION adapterExtension
+ __in PAHCI_ADAPTER_EXTENSION adapterExtension
);
+__inline
VOID AhciZeroMemory(
- __in PCHAR buffer,
- __in ULONG bufferSize
+ __in PCHAR buffer,
+ __in ULONG bufferSize
+);
+
+__inline
+BOOLEAN IsPortValid(
+ __in PAHCI_ADAPTER_EXTENSION adapterExtension,
+ __in UCHAR pathId
);
/**
* Return true if intialization was successful
*/
BOOLEAN AhciPortInitialize(
- __in PAHCI_PORT_EXTENSION portExtension
+ __in PAHCI_PORT_EXTENSION portExtension
)
{
ULONG mappedLength;
PAHCI_ADAPTER_EXTENSION adapterExtension;
STOR_PHYSICAL_ADDRESS commandListPhysical, receivedFISPhysical;
+ StorPortDebugPrint(0, "AhciPortInitialize()\n");
+
adapterExtension = portExtension->AdapterExtension;
abar = adapterExtension->ABAR_Address;
+
portExtension->Port = &abar->PortList[portExtension->PortNumber];
commandListPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->CommandList, &mappedLength);
- if (mappedLength == 0 || (commandListPhysical.LowPart % 1024) != 0)
+ if (mappedLength == 0 || (commandListPhysical.LowPart % 1024) != 0){
+ StorPortDebugPrint(0, "\tcommandListPhysical mappedLength:%d\n", mappedLength);
return FALSE;
+ }
receivedFISPhysical = StorPortGetPhysicalAddress(adapterExtension, NULL, portExtension->ReceivedFIS, &mappedLength);
- if (mappedLength == 0 || (commandListPhysical.LowPart % 256) != 0)
+ if (mappedLength == 0 || (receivedFISPhysical.LowPart % 256) != 0){
+ StorPortDebugPrint(0, "\treceivedFISPhysical mappedLength:%d\n", mappedLength);
return FALSE;
+ }
// 10.1.2 For each implemented port, system software shall allocate memory for and program:
// PxCLB and PxCLBU (if CAP.S64A is set to ‘1’)
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();
* return TRUE if allocation was successful
*/
BOOLEAN AhciAllocateResourceForAdapter(
- __in PAHCI_ADAPTER_EXTENSION adapterExtension,
- __in PPORT_CONFIGURATION_INFORMATION ConfigInfo
+ __in PAHCI_ADAPTER_EXTENSION adapterExtension,
+ __in PPORT_CONFIGURATION_INFORMATION ConfigInfo
)
{
PVOID portsExtension = NULL;
PCHAR nonCachedExtension;
ULONG portCount, portImplemented, status, index, NCS, AlignedNCS, nonCachedExtensionSize, currentCount;
- // 3.1.1 NCS = CAP[12:08] -> Align
+ StorPortDebugPrint(0, "AhciAllocateResourceForAdapter()\n");
+
+ // 3.1.1 NCS = CAP[12:08] -> Align
NCS = (adapterExtension->CAP & 0xF00) >> 8;
AlignedNCS = ((NCS/8) + 1) * 8;
portCount++;
portImplemented &= (portImplemented-1);
}
+ StorPortDebugPrint(0, "\tPort Count: %d\n", portCount);
nonCachedExtensionSize = sizeof(AHCI_COMMAND_HEADER) * AlignedNCS + //should be 1K aligned
sizeof(AHCI_RECEIVED_FIS);
nonCachedExtensionSize *= portCount;
adapterExtension->NonCachedExtension = StorPortGetUncachedExtension(adapterExtension, ConfigInfo, nonCachedExtensionSize);
- if (adapterExtension->NonCachedExtension == NULL)
+ if (adapterExtension->NonCachedExtension == NULL) {
+ StorPortDebugPrint(0, "\tadapterExtension->NonCachedExtension == NULL\n");
return FALSE;
+ }
nonCachedExtension = (PCHAR)adapterExtension->NonCachedExtension;
AhciZeroMemory(nonCachedExtension, nonCachedExtensionSize);
-
-
- // allocate memory for port extension
- status = StorPortAllocatePool(
- adapterExtension,
- portCount * sizeof(AHCI_PORT_EXTENSION),
- AHCI_POOL_TAG,
- (PVOID*)&portsExtension);
-
- if (status != STOR_STATUS_SUCCESS)
- 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]->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);
+ 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);
currentCount++;
}
}
}// -- AhciAllocateResourceForAdapter();
/**
- * @name AhciFindAdapter
+ * @name AhciHwInitialize
+ * @implemented
+ *
+ * initializes the HBA and finds all devices that are of interest to the miniport driver.
+ *
+ * @param adapterExtension
+ *
+ * @return
+ * return TRUE if intialization was successful
+ */
+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();
+
+/**
+ * @name AhciHwInterrupt
+ * @implemented
+ *
+ * The Storport driver calls the HwStorInterrupt routine after the HBA generates an interrupt request.
+ *
+ * @param adapterExtension
+ *
+ * @return
+ * return TRUE Indicates that an interrupt was pending on adapter.
+ * return FALSE Indicates the interrupt was not ours.
+ */
+BOOLEAN AhciHwInterrupt(
+ __in PVOID AdapterExtension
+)
+{
+ PAHCI_ADAPTER_EXTENSION adapterExtension;
+
+ StorPortDebugPrint(0, "AhciHwInterrupt()\n");
+
+ adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
+
+ return FALSE;
+}// -- AhciHwInterrupt();
+
+/**
+ * @name AhciHwStartIo
+ * @implemented
+ *
+ * The Storport driver calls the HwStorStartIo routine one time for each incoming I/O request.
+ *
+ * @param adapterExtension
+ * @param Srb
+ *
+ * @return
+ * return TRUE if the request was accepted
+ * return FALSE if the request must be submitted later
+ */
+BOOLEAN AhciHwStartIo(
+ __in PVOID AdapterExtension,
+ __in PSCSI_REQUEST_BLOCK Srb
+
+)
+{
+ UCHAR function, pathId;
+ PAHCI_ADAPTER_EXTENSION adapterExtension;
+
+ StorPortDebugPrint(0, "AhciHwStartIo()\n");
+
+ 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();
+
+/**
+ * @name AhciHwResetBus
+ * @implemented
+ *
+ * The HwStorResetBus routine is called by the port driver to clear error conditions.
+ *
+ * @param adapterExtension
+ * @param PathId
+ *
+ * @return
+ * return TRUE if bus was successfully reset
+ */
+BOOLEAN AhciHwResetBus(
+ __in PVOID AdapterExtension,
+ __in ULONG PathId
+
+)
+{
+ PAHCI_ADAPTER_EXTENSION adapterExtension;
+
+ StorPortDebugPrint(0, "AhciHwResetBus()\n");
+
+ adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
+
+ return TRUE;
+}// -- AhciHwResetBus();
+
+/**
+ * @name AhciHwFindAdapter
* @implemented
*
* The HwStorFindAdapter routine uses the supplied configuration to determine whether a specific
*
* @remarks Called by Storport.
*/
-ULONG AhciFindAdapter(
- IN PVOID DeviceExtension,
- __in PVOID HwContext,
- __in PVOID BusInformation,
- __in IN PVOID ArgumentString,
- __inout PPORT_CONFIGURATION_INFORMATION ConfigInfo,
- __in PBOOLEAN Reserved3
+ULONG AhciHwFindAdapter(
+ __in PVOID AdapterExtension,
+ __in PVOID HwContext,
+ __in PVOID BusInformation,
+ __in PVOID ArgumentString,
+ __inout PPORT_CONFIGURATION_INFORMATION ConfigInfo,
+ __in PBOOLEAN Reserved3
)
{
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;
+ StorPortDebugPrint(0, "AhciHwFindAdapter()\n");
+
+ adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
-
+
// get PCI configuration header
pci_cfg_len = StorPortGetBusData(
adapterExtension,
(PVOID)pci_cfg_buf,
(ULONG)0x30);
- if (pci_cfg_len != 0x30)
+ if (pci_cfg_len != 0x30){
+ StorPortDebugPrint(0, "\tpci_cfg_len != 0x30 :: %d", pci_cfg_len);
return SP_RETURN_ERROR;//Not a valid device at the given bus number
+ }
pciConfigData = (PPCI_COMMON_CONFIG)pci_cfg_buf;
adapterExtension->VendorID = pciConfigData->VendorID;
// 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);
+ StorPortDebugPrint(0, "\tVendorID:%d DeviceID:%d RevisionID:%d\n", adapterExtension->VendorID, adapterExtension->DeviceID, adapterExtension->RevisionID);
+
// 2.1.11
abar = NULL;
if (ConfigInfo->NumberOfAccessRanges > 0)
}
}
- if (abar == NULL)
+ if (abar == NULL){
+ StorPortDebugPrint(0, "\tabar == NULL\n");
return SP_RETURN_ERROR; // corrupted information supplied
+ }
adapterExtension->ABAR_Address = abar;
adapterExtension->CAP = StorPortReadRegisterUlong(adapterExtension, &abar->CAP);
// 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
- DebugPrint("AhciFindAdapter -> AE Already set, Reset()\n");
- if (!AhciAdapterReset(adapterExtension))
+ StorPortDebugPrint(0, "\tAE Already set, Reset()\n");
+ if (!AhciAdapterReset(adapterExtension)){
+ StorPortDebugPrint(0, "\tReset Failed!\n");
return SP_RETURN_ERROR;// reset failed
+ }
}
- 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)
+ if (adapterExtension->PortImplemented == 0){
+ StorPortDebugPrint(0, "\tadapterExtension->PortImplemented == 0\n");
return SP_RETURN_ERROR;
+ }
ConfigInfo->MaximumTransferLength = 128 * 1024;//128 KB
ConfigInfo->NumberOfPhysicalBreaks = 0x21;
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 |= AHCI_Global_HBA_CONTROL_IE;
+ StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
+
// allocate necessary resource for each port
- if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo))
+ if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo)){
+ StorPortDebugPrint(0, "\tAhciAllocateResourceForAdapter() == FALSE\n");
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)
- AhciPortInitialize(adapterExtension->PortExtension[index]);
+ if ((adapterExtension->PortImplemented & (0x1<<index)) != 0)
+ AhciPortInitialize(&adapterExtension->PortExtension[index]);
}
- // Turn IE -- Interrupt Enabled
- ghc |= 0x2;
- StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
-
return SP_RETURN_FOUND;
-}// -- AhciFindAdapter();
+}// -- AhciHwFindAdapter();
/**
* @name DriverEntry
* NT_STATUS in case of driver loaded successfully.
*/
ULONG DriverEntry(
- IN PVOID DriverObject,
- IN PVOID RegistryPath
+ __in PVOID DriverObject,
+ __in PVOID RegistryPath
)
{
HW_INITIALIZATION_DATA hwInitializationData;
ULONG i, status;
- DebugPrint("Storahci -> DriverEntry()\n");
+ StorPortDebugPrint(0, "Storahci Loaded\n");
// initialize the hardware data structure
AhciZeroMemory((PCHAR)&hwInitializationData, sizeof(HW_INITIALIZATION_DATA));
hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
// identity required miniport entry point routines
- hwInitializationData.HwFindAdapter = AhciFindAdapter;
+ hwInitializationData.HwStartIo = AhciHwStartIo;
+ hwInitializationData.HwResetBus = AhciHwResetBus;
+ hwInitializationData.HwInterrupt = AhciHwInterrupt;
+ hwInitializationData.HwInitialize = AhciHwInitialize;
+ hwInitializationData.HwFindAdapter = AhciHwFindAdapter;
// adapter specific information
hwInitializationData.NeedPhysicalAddresses = TRUE;
// set required extension sizes
hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
-
+
// register our hw init data
status = StorPortInitialize(
DriverObject,
&hwInitializationData,
NULL);
+ StorPortDebugPrint(0, "\tstatus:%x\n", status);
return status;
}// -- DriverEntry();
* 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
*
* TRUE in case AHCI Controller RESTARTED successfully. i.e GHC.HR == 0
*/
BOOLEAN AhciAdapterReset(
- PAHCI_ADAPTER_EXTENSION adapterExtension
+ __in PAHCI_ADAPTER_EXTENSION adapterExtension
)
{
- ULONG ghc, ticks;
- PAHCI_MEMORY_REGISTERS abar = NULL;
+ ULONG ghc, ticks;
+ PAHCI_MEMORY_REGISTERS abar = NULL;
- abar = adapterExtension->ABAR_Address;
+ StorPortDebugPrint(0, "AhciAdapterReset()\n");
- if (abar == NULL) // basic sanity
+ abar = adapterExtension->ABAR_Address;
+ if (abar == NULL) // basic sanity
return FALSE;
- // HR -- Very first bit (lowest significant)
- ghc = 1;
- StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
+ // 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++);
+ for (ticks = 0; (ticks < 50) &&
+ (StorPortReadRegisterUlong(adapterExtension, &abar->GHC) == 1);
+ StorPortStallExecution(20000), ticks++);
- if (ticks == 50)//1 second
+ if (ticks == 50) { //1 second
+ StorPortDebugPrint(0, "\tDevice Timeout\n");
return FALSE;
+ }
- return TRUE;
+ return TRUE;
}// -- AhciAdapterReset();
/**
*
* @param buffer
*/
+__inline
VOID AhciZeroMemory(
- __in PCHAR buffer,
- __in ULONG bufferSize
+ __in PCHAR buffer,
+ __in ULONG bufferSize
)
{
ULONG i;
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()