AHCI-SATA Interface almost ready.
[reactos.git] / drivers / storage / storahci / storahci.c
index 6e21584..c3d16c9 100644 (file)
@@ -8,12 +8,19 @@
 #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
 );
 
 /**
@@ -28,7 +35,7 @@ VOID AhciZeroMemory(
  * Return true if intialization was successful
  */
 BOOLEAN AhciPortInitialize(
-  __in  PAHCI_PORT_EXTENSION                portExtension
+  __in      PAHCI_PORT_EXTENSION                portExtension
 )
 {
     ULONG mappedLength;
@@ -36,17 +43,24 @@ BOOLEAN AhciPortInitialize(
     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’)
@@ -55,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();
 
@@ -71,15 +93,17 @@ BOOLEAN 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;
 
@@ -91,6 +115,7 @@ BOOLEAN AhciAllocateResourceForAdapter(
         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);
@@ -99,38 +124,27 @@ BOOLEAN AhciAllocateResourceForAdapter(
     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++;
         }
     }
@@ -139,7 +153,201 @@ BOOLEAN AhciAllocateResourceForAdapter(
 }// -- 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
@@ -170,13 +378,13 @@ BOOLEAN AhciAllocateResourceForAdapter(
  *
  * @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;
@@ -184,15 +392,17 @@ ULONG AhciFindAdapter(
     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,
@@ -202,8 +412,10 @@ ULONG AhciFindAdapter(
                         (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;
@@ -212,6 +424,8 @@ ULONG AhciFindAdapter(
     // 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)
@@ -232,8 +446,10 @@ ULONG AhciFindAdapter(
         }
     }
 
-    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);
@@ -245,48 +461,54 @@ ULONG AhciFindAdapter(
     // 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
@@ -301,14 +523,14 @@ ULONG AhciFindAdapter(
  * 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));
@@ -317,7 +539,11 @@ ULONG DriverEntry(
     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;
@@ -332,7 +558,7 @@ ULONG DriverEntry(
     // set required extension sizes
     hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
     hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
-    
+
     // register our hw init data
     status = StorPortInitialize(
                     DriverObject,
@@ -340,6 +566,7 @@ ULONG DriverEntry(
                     &hwInitializationData,
                     NULL);
 
+    StorPortDebugPrint(0, "\tstatus:%x\n", status);
     return status;
 }// -- DriverEntry();
 
@@ -355,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
  * 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
  *
@@ -363,29 +590,32 @@ ULONG DriverEntry(
  * 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();
 
 /**
@@ -396,12 +626,36 @@ BOOLEAN 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()