Author: apriyadarshi
Date: Mon Jul 4 19:01:07 2016
New Revision: 71809
URL:
http://svn.reactos.org/svn/reactos?rev=71809&view=rev
Log:
Debugging Port Device Status Check
Modified:
branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c
branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] Mon Jul 4
19:01:07 2016
@@ -23,6 +23,7 @@
__in PAHCI_PORT_EXTENSION PortExtension
)
{
+ AHCI_PORT_CMD cmd;
ULONG mappedLength, portNumber;
PAHCI_MEMORY_REGISTERS abar;
PAHCI_ADAPTER_EXTENSION adapterExtension;
@@ -59,6 +60,23 @@
{
DebugPrint("\treceivedFISPhysical mappedLength:%d\n", mappedLength);
return FALSE;
+ }
+
+ // Ensure that the controller is not in the running state by reading and examining
each
+ // implemented portâs PxCMD register. If PxCMD.ST, PxCMD.CR, PxCMD.FRE and
+ // PxCMD.FR are all cleared, the port is in an idle state. Otherwise, the port is not
idle and
+ // should be placed in the idle state prior to manipulating HBA and port specific
registers.
+ // System software places a port into the idle state by clearing PxCMD.ST and waiting
for
+ // PxCMD.CR to return â0â when read. Software should wait at least 500
milliseconds for
+ // this to occur. If PxCMD.FRE is set to â1â, software should clear it to â0â
and wait at least
+ // 500 milliseconds for PxCMD.FR to return â0â when read. If PxCMD.CR or PxCMD.FR
do
+ // not clear to â0â correctly, then software may attempt a port reset or a full
HBA reset to recove
+
+ // TODO: Check if port is in idle state or not, if not then restart port
+ cmd.Status = StorPortReadRegisterUlong(adapterExtension,
&PortExtension->Port->CMD);
+ if ((cmd.FR != 0) || (cmd.CR != 0) || (cmd.FRE != 0) || (cmd.ST != 0))
+ {
+ DebugPrint("\tPort is not idle: %x\n", cmd);
}
// 10.1.2 For each implemented port, system software shall allocate memory for and
program:
@@ -82,15 +100,13 @@
PortExtension->IdentifyDeviceData,
&mappedLength);
- NT_ASSERT(mappedLength == sizeof(IDENTIFY_DEVICE_DATA));
-
// 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));
+ StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->SERR,
(ULONG)~0);
+ StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->IS,
(ULONG)~0);
+ StorPortWriteRegisterUlong(adapterExtension, adapterExtension->IS, (1 <<
PortExtension->PortNumber));
return TRUE;
}// -- AhciPortInitialize();
@@ -113,7 +129,6 @@
__in PPORT_CONFIGURATION_INFORMATION ConfigInfo
)
{
- PVOID portsExtension = NULL;
PCHAR nonCachedExtension, tmp;
ULONG status, index, NCS, AlignedNCS;
ULONG portCount, portImplemented, nonCachedExtensionSize;
@@ -178,6 +193,92 @@
}// -- AhciAllocateResourceForAdapter();
/**
+ * @name AhciStartPort
+ * @implemented
+ *
+ * Try to start the port device
+ *
+ * @param AdapterExtension
+ * @param PortExtension
+ *
+ */
+BOOLEAN
+AhciStartPort (
+ __in PAHCI_PORT_EXTENSION PortExtension
+ )
+{
+ ULONG index;
+ AHCI_PORT_CMD cmd;
+ AHCI_SERIAL_ATA_STATUS ssts;
+ AHCI_SERIAL_ATA_CONTROL sctl;
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
+
+ DebugPrint("AhciStartPort()\n");
+
+ AdapterExtension = PortExtension->AdapterExtension;
+ cmd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
+
+ if ((cmd.FR == 1) && (cmd.CR == 1) && (cmd.FRE == 1) &&
(cmd.ST == 1))
+ {
+ // Already Running
+ return TRUE;
+ }
+
+ cmd.SUD = 1;
+ StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CMD,
cmd.Status);
+
+ if (((cmd.FR == 1) && (cmd.FRE == 0)) ||
+ ((cmd.CR == 1) && (cmd.ST == 0)))
+ {
+ DebugPrint("\tCOMRESET\n");
+ // perform COMRESET
+ // section 10.4.2
+
+ // Software causes a port reset (COMRESET) by writing 1h to the PxSCTL.DET field
to invoke a
+ // COMRESET on the interface and start a re-establishment of Phy layer
communications. Software shall
+ // wait at least 1 millisecond before clearing PxSCTL.DET to 0h; this ensures
that at least one COMRESET
+ // signal is sent over the interface. After clearing PxSCTL.DET to 0h, software
should wait for
+ // communication to be re-established as indicated by PxSSTS.DET being set to 3h.
Then software should
+ // write all 1s to the PxSERR register to clear any bits that were set as part of
the port reset.
+
+ sctl.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->SCTL);
+ sctl.DET = 1;
+ StorPortWriteRegisterUlong(AdapterExtension,
&PortExtension->Port->SCTL, sctl.Status);
+
+ StorPortStallExecution(1000);
+
+ sctl.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->SCTL);
+ sctl.DET = 0;
+ StorPortWriteRegisterUlong(AdapterExtension,
&PortExtension->Port->SCTL, sctl.Status);
+
+ // Poll DET to verify if a device is attached to the port
+ index = 0;
+ do
+ {
+ StorPortStallExecution(1000);
+ ssts.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->SSTS);
+
+ index++;
+ if (ssts.DET != 0)
+ {
+ break;
+ }
+ }
+ while(index < 30);
+ }
+
+ ssts.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->SSTS);
+ if (ssts.DET == 0x4)
+ {
+ // no device found
+ return FALSE;
+ }
+
+ DebugPrint("\tDET: %d %x %x\n", ssts.DET, PortExtension->Port->CMD,
PortExtension->Port->SSTS);
+ return FALSE;
+}// -- AhciStartPort();
+
+/**
* @name AhciHwInitialize
* @implemented
*
@@ -193,8 +294,10 @@
__in PVOID AdapterExtension
)
{
- ULONG ghc, messageCount, status;
+ ULONG ghc, messageCount, status, cmd, index;
+ PAHCI_PORT_EXTENSION PortExtension;
PAHCI_ADAPTER_EXTENSION adapterExtension;
+ AHCI_SERIAL_ATA_STATUS ssts;
DebugPrint("AhciHwInitialize()\n");
@@ -214,6 +317,19 @@
DebugPrint("\tMultiple MSI based message not supported\n");
}
+ for (index = 0; index < adapterExtension->PortCount; index++)
+ {
+ if ((adapterExtension->PortImplemented & (0x1 << index)) != 0)
+ {
+ PortExtension = &adapterExtension->PortExtension[index];
+ PortExtension->IsActive = AhciStartPort(PortExtension);
+ if (PortExtension->IsActive == FALSE)
+ {
+ DebugPrint("\tPort Disabled: %d\n", index);
+ }
+ }
+ }
+
return TRUE;
}// -- AhciHwInitialize();
@@ -251,7 +367,7 @@
{
if (((1 << i) & CommandsToComplete) != 0)
{
- Srb = &PortExtension->Slot[i];
+ Srb = PortExtension->Slot[i];
NT_ASSERT(Srb != NULL);
if (Srb->SrbStatus == SRB_STATUS_PENDING)
@@ -417,10 +533,14 @@
NT_ASSERT(IsPortValid(AdapterExtension, nextPort));
- if ((nextPort == AdapterExtension->LastInterruptPort) ||
- (AdapterExtension->PortExtension[nextPort].IsActive == FALSE))
+ if (nextPort == AdapterExtension->LastInterruptPort)
{
return FALSE;
+ }
+
+ if (AdapterExtension->PortExtension[nextPort].IsActive == FALSE)
+ {
+ continue;
}
// we can assign this interrupt to this port
@@ -722,6 +842,7 @@
}
ghc = AHCI_Global_HBA_CONTROL_AE;// only AE=1
+ // tell the controller that we know about AHCI
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
adapterExtension->IS = &abar->IS;
@@ -742,22 +863,23 @@
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
ConfigInfo->ScatterGather = TRUE;
+ // allocate necessary resource for each port
+ if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo))
+ {
+ DebugPrint("\tAhciAllocateResourceForAdapter() == FALSE\n");
+ return SP_RETURN_ERROR;
+ }
+
+ for (index = 0; index < adapterExtension->PortCount; index++)
+ {
+ if ((adapterExtension->PortImplemented & (0x1 << index)) != 0)
+ AhciPortInitialize(&adapterExtension->PortExtension[index]);
+ }
+
// Turn IE -- Interrupt Enabled
+ ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
ghc |= AHCI_Global_HBA_CONTROL_IE;
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
-
- // allocate necessary resource for each port
- if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo))
- {
- DebugPrint("\tAhciAllocateResourceForAdapter() == FALSE\n");
- return SP_RETURN_ERROR;
- }
-
- for (index = 0; index < adapterExtension->PortCount; index++)
- {
- if ((adapterExtension->PortImplemented & (0x1 << index)) != 0)
- AhciPortInitialize(&adapterExtension->PortExtension[index]);
- }
return SP_RETURN_FOUND;
}// -- AhciHwFindAdapter();
@@ -818,7 +940,7 @@
&hwInitializationData,
NULL);
- DebugPrint("\tstatus:%x\n", status);
+ DebugPrint("\tstatus: %x\n", status);
return status;
}// -- DriverEntry();
@@ -1043,7 +1165,7 @@
// mark this slot
PortExtension->Slot[SlotIndex] = Srb;
- PortExtension->QueueSlots |= SlotIndex;
+ PortExtension->QueueSlots |= 1 << SlotIndex;
return;
}// -- AhciProcessSrb();
@@ -1061,7 +1183,8 @@
__in PAHCI_PORT_EXTENSION PortExtension
)
{
- ULONG cmd, QueueSlots, slotToActivate, tmp;
+ AHCI_PORT_CMD cmd;
+ ULONG QueueSlots, slotToActivate, tmp;
PAHCI_ADAPTER_EXTENSION AdapterExtension;
DebugPrint("AhciActivatePort()\n");
@@ -1074,9 +1197,9 @@
// section 3.3.14
// Bits in this field shall only be set to â1â by software when PxCMD.ST is set
to â1â
- cmd = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
-
- if ((cmd&1) == 0) // PxCMD.ST == 0
+ cmd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
+
+ if (cmd.ST == 0) // PxCMD.ST == 0
return;
// get the lowest set bit
@@ -1215,16 +1338,19 @@
{
if (SrbExtension->CommandReg == IDE_COMMAND_IDENTIFY)
{
+ DebugPrint("Device: ATA\n");
AdapterExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_ATA;
}
else
{
+ DebugPrint("Device: ATAPI\n");
AdapterExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_ATAPI;
}
// TODO: Set Device Paramters
}
else if (SrbStatus == SRB_STATUS_NO_DEVICE)
{
+ DebugPrint("Device: No Device\n");
AdapterExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_NODEVICE;
}
else
Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
==============================================================================
--- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] (original)
+++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] Mon Jul 4
19:01:07 2016
@@ -215,22 +215,83 @@
{
struct
{
- ULONG CFL :5; // Command FIS Length
- ULONG A :1; // IsATAPI
- ULONG W :1; // Write
- ULONG P :1; // Prefetchable
-
- ULONG R :1; // Reset
- ULONG B :1; // BIST
- ULONG C :1; //Clear Busy upon R_OK
- ULONG DW0_Reserved :1;
- ULONG PMP :4; //Port Multiplier Port
-
- ULONG PRDTL :16; //Physical Region Descriptor Table Length
+ ULONG CFL : 5; // Command FIS Length
+ ULONG A : 1; // IsATAPI
+ ULONG W : 1; // Write
+ ULONG P : 1; // Prefetchable
+
+ ULONG R : 1; // Reset
+ ULONG B : 1; // BIST
+ ULONG C : 1; //Clear Busy upon R_OK
+ ULONG DW0_Reserved : 1;
+ ULONG PMP : 4; //Port Multiplier Port
+
+ ULONG PRDTL : 16; //Physical Region Descriptor Table Length
};
ULONG Status;
} AHCI_COMMAND_HEADER_DESCRIPTION;
+
+// section 3.3.7
+typedef union _AHCI_PORT_CMD
+{
+ struct
+ {
+ ULONG ST : 1;
+ ULONG SUD : 1;
+ ULONG POD : 1;
+ ULONG CLO : 1;
+ ULONG FRE : 1;
+ ULONG RSV0 : 3;
+ ULONG CCS : 5;
+ ULONG MPSS : 1;
+ ULONG FR : 1;
+ ULONG CR : 1;
+ ULONG CPS : 1;
+ ULONG PMA : 1;
+ ULONG HPCP : 1;
+ ULONG MPSP : 1;
+ ULONG CPD : 1;
+ ULONG ESP : 1;
+ ULONG FBSCP : 1;
+ ULONG APSTE : 1;
+ ULONG ATAPI : 1;
+ ULONG DLAE : 1;
+ ULONG ALPE : 1;
+ ULONG ASP : 1;
+ ULONG ICC : 4;
+ };
+
+ ULONG Status;
+} AHCI_PORT_CMD;
+
+typedef union _AHCI_SERIAL_ATA_CONTROL
+{
+ struct
+ {
+ ULONG DET :4;
+ ULONG SPD :4;
+ ULONG IPM :4;
+ ULONG SPM :4;
+ ULONG PMP :4;
+ ULONG DW11_Reserved :12;
+ };
+
+ ULONG Status;
+} AHCI_SERIAL_ATA_CONTROL;
+
+typedef union _AHCI_SERIAL_ATA_STATUS
+{
+ struct
+ {
+ ULONG DET :4;
+ ULONG SPD :4;
+ ULONG IPM :4;
+ ULONG RSV0 :20;
+ };
+
+ ULONG Status;
+} AHCI_SERIAL_ATA_STATUS;
typedef struct _AHCI_PRDT
{