Author: apriyadarshi
Date: Tue Jul 5 16:51:17 2016
New Revision: 71822
URL:
http://svn.reactos.org/svn/reactos?rev=71822&view=rev
Log:
- Handled DET = 03h case.
- Registered (Interrupt enable and SERR clear) working port.
Everything is working now! :D
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] Tue Jul 5
16:51:17 2016
@@ -209,6 +209,8 @@
{
ULONG index;
AHCI_PORT_CMD cmd;
+ AHCI_TASK_FILE_DATA tfd;
+ AHCI_INTERRUPT_ENABLE ie;
AHCI_SERIAL_ATA_STATUS ssts;
AHCI_SERIAL_ATA_CONTROL sctl;
PAHCI_ADAPTER_EXTENSION AdapterExtension;
@@ -268,13 +270,104 @@
}
ssts.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->SSTS);
- if (ssts.DET == 0x4)
- {
- // no device found
- return FALSE;
- }
-
- DebugPrint("\tDET: %d %d\n", ssts.DET, cmd.ST);
+ switch (ssts.DET)
+ {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ default:
+ // unhandled case
+ DebugPrint("\tDET == %x Unsupported\n", ssts.DET);
+ return FALSE;
+ case 0x3:
+ {
+ NT_ASSERT(cmd.ST == 0);
+
+ // make sure FIS Recieve is enabled (cmd.FRE)
+ index = 0;
+ do
+ {
+ StorPortStallExecution(10000);
+ cmd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
+ cmd.FRE = 1;
+ StorPortWriteRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD, cmd.Status);
+ index++;
+ }
+ while((cmd.FR != 1) && (index < 3));
+
+ if (cmd.FR != 1)
+ {
+ // failed to start FIS DMA engine
+ // it can crash the driver later
+ return FALSE;
+ }
+
+ // start port channel
+ // set cmd.ST
+
+ NT_ASSERT(cmd.FRE == 1);
+ NT_ASSERT(cmd.CR == 0);
+
+ // why assert? well If we face such condition on DET = 0x3
+ // then we don't have port in idle state and hence before executing
this part of code
+ // we must have restarted it.
+ tfd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->TFD);
+
+ if ((tfd.STS.BSY) || (tfd.STS.DRQ))
+ {
+ DebugPrint("\tUnhandled Case BSY-DRQ\n");
+ }
+
+ // clear pending interrupts
+ StorPortWriteRegisterUlong(AdapterExtension,
&PortExtension->Port->SERR, (ULONG)~0);
+ StorPortWriteRegisterUlong(AdapterExtension,
&PortExtension->Port->IS, (ULONG)~0);
+ StorPortWriteRegisterUlong(AdapterExtension, AdapterExtension->IS, (1
<< PortExtension->PortNumber));
+
+ // set IE
+ ie.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->IE);
+ ie.DHRE = 1;
+ ie.PSE = 1;
+ ie.DSE = 1;
+ ie.SDBE = 1;
+
+ ie.UFE = 0;
+ ie.DPE = 0;
+ ie.PCE = 1;
+
+ ie.DMPE = 0;
+
+ ie.PRCE = 1;
+ ie.IPME = 0;
+ ie.OFE = 1;
+ ie.INFE = 1;
+ ie.IFE = 1;
+ ie.HBDE = 1;
+ ie.HBFE = 1;
+ ie.TFEE = 1;
+
+ cmd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
+ ie.CPDE = cmd.CPD;
+
+ StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->IE, ie.Status);
+
+ cmd.ST = 1;
+ StorPortWriteRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD, cmd.Status);
+ cmd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
+
+ if (cmd.ST != 1)
+ {
+ DebugPrint("\tFailed to start Port\n");
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ case 0x4:
+ // no device found
+ return FALSE;
+ }
+
+ DebugPrint("\tInvalid DET value: %x\n", ssts.DET);
return FALSE;
}// -- AhciStartPort();
@@ -322,10 +415,6 @@
{
PortExtension = &adapterExtension->PortExtension[index];
PortExtension->IsActive = AhciStartPort(PortExtension);
- if (PortExtension->IsActive == FALSE)
- {
- DebugPrint("\tPort Disabled: %d\n", index);
- }
}
}
@@ -516,6 +605,7 @@
portPending = StorPortReadRegisterUlong(AdapterExtension, AdapterExtension->IS);
// we process interrupt for implemented ports only
portCount = AdapterExtension->PortCount;
+ DebugPrint("\tPortPending: %d\n", portPending);
portPending = portPending & AdapterExtension->PortImplemented;
if (portPending == 0)
@@ -1207,7 +1297,9 @@
cmd.Status = StorPortReadRegisterUlong(AdapterExtension,
&PortExtension->Port->CMD);
if (cmd.ST == 0) // PxCMD.ST == 0
+ {
return;
+ }
// get the lowest set bit
tmp = QueueSlots & (QueueSlots - 1);
@@ -1223,6 +1315,8 @@
// mark this CommandIssuedSlots
// to validate in completeIssuedCommand
PortExtension->CommandIssuedSlots |= slotToActivate;
+
+ DebugPrint("\tslotToActivate: %d\n", slotToActivate);
// tell the HBA to issue this Command Slot to the given port
StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CI,
slotToActivate);
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] Tue Jul 5
16:51:17 2016
@@ -66,7 +66,7 @@
#define AHCI_Global_Port_CAP_NCS(x) (((x) & 0xF00) >> 8)
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-#if DEBUG
+#ifdef DBG
#define DebugPrint(format, ...) StorPortDebugPrint(0, format, __VA_ARGS__)
#endif
@@ -295,6 +295,25 @@
ULONG Status;
} AHCI_SERIAL_ATA_STATUS;
+typedef union _AHCI_TASK_FILE_DATA
+{
+ struct
+ {
+ struct _STS
+ {
+ UCHAR ERR : 1;
+ UCHAR CS1 : 2;
+ UCHAR DRQ : 1;
+ UCHAR CS2 : 3;
+ UCHAR BSY : 1;
+ } STS;
+ UCHAR ERR;
+ USHORT RSV;
+ };
+
+ ULONG Status;
+} AHCI_TASK_FILE_DATA;
+
typedef struct _AHCI_PRDT
{
ULONG DBA;
@@ -365,27 +384,32 @@
ULONG Vendor[4]; // 0x70 ~ 0x7F, vendor specific
} AHCI_PORT, *PAHCI_PORT;
-#ifdef DEBUG
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLB) == 0x00);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLBU) == 0x04);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, FB) == 0x08);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBU) == 0x0C);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, IS) == 0x10);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, IE) == 0x14);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, CMD) == 0x18);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV0) == 0x1C);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, TFD) == 0x20);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, SIG) == 0x24);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, SSTS) == 0x28);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, SCTL) == 0x2C);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, SERR) == 0x30);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, SACT) == 0x34);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, CI) == 0x38);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, SNTF) == 0x3C);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBS) == 0x40);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV1) == 0x44);
- C_ASSERT(FIELD_OFFSET(AHCI_PORT, Vendor) == 0x70);
-#endif
+typedef struct _AHCI_INTERRUPT_ENABLE
+{
+ struct
+ {
+ ULONG DHRE :1;
+ ULONG PSE :1;
+ ULONG DSE :1;
+ ULONG SDBE :1;
+ ULONG UFE :1;
+ ULONG DPE :1;
+ ULONG PCE :1;
+ ULONG DMPE :1;
+ ULONG DW5_Reserved :14;
+ ULONG PRCE :1;
+ ULONG IPME :1;
+ ULONG OFE :1;
+ ULONG DW5_Reserved2 :1;
+ ULONG INFE :1;
+ ULONG IFE :1;
+ ULONG HBDE :1;
+ ULONG HBFE :1;
+ ULONG TFEE :1;
+ ULONG CPDE :1;
+ };
+ ULONG Status;
+} AHCI_INTERRUPT_ENABLE;
typedef struct _AHCI_MEMORY_REGISTERS
{
@@ -406,22 +430,6 @@
AHCI_PORT PortList[MAXIMUM_AHCI_PORT_COUNT];
} AHCI_MEMORY_REGISTERS, *PAHCI_MEMORY_REGISTERS;
-#ifdef DEBUG
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP) == 0x00);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, GHC) == 0x04);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, IS) == 0x08);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PI) == 0x0C);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VS) == 0x10);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_CTL) == 0x14);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_PTS) == 0x18);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_LOC) == 0x1C);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_CTL) == 0x20);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP2) == 0x24);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, BOHC) == 0x28);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, Reserved) == 0x2C);
- C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VendorSpecific) == 0xA0);
-#endif
-
// Holds information for each attached attached port to a given adapter.
typedef struct _AHCI_PORT_EXTENSION
{
@@ -559,3 +567,42 @@
GetSrbExtension(
__in PSCSI_REQUEST_BLOCK Srb
);
+
+//////////////////////////////////////////////////////////////
+// Assertions //
+//////////////////////////////////////////////////////////////
+
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP) == 0x00);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, GHC) == 0x04);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, IS) == 0x08);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PI) == 0x0C);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VS) == 0x10);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_CTL) == 0x14);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CCC_PTS) == 0x18);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_LOC) == 0x1C);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, EM_CTL) == 0x20);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, CAP2) == 0x24);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, BOHC) == 0x28);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, Reserved) == 0x2C);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, VendorSpecific) == 0xA0);
+C_ASSERT(FIELD_OFFSET(AHCI_MEMORY_REGISTERS, PortList) == 0x100);
+
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLB) == 0x00);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, CLBU) == 0x04);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, FB) == 0x08);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBU) == 0x0C);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, IS) == 0x10);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, IE) == 0x14);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, CMD) == 0x18);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV0) == 0x1C);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, TFD) == 0x20);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, SIG) == 0x24);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, SSTS) == 0x28);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, SCTL) == 0x2C);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, SERR) == 0x30);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, SACT) == 0x34);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, CI) == 0x38);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, SNTF) == 0x3C);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, FBS) == 0x40);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, RSV1) == 0x44);
+C_ASSERT(FIELD_OFFSET(AHCI_PORT, Vendor) == 0x70);