mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 18:24:02 +00:00
- Handled DET = 03h case.
- Registered (Interrupt enable and SERR clear) working port. Everything is working now! :D svn path=/branches/GSoC_2016/AHCI/; revision=71822
This commit is contained in:
parent
49f68f18d2
commit
b86b9221d4
2 changed files with 187 additions and 46 deletions
|
@ -209,6 +209,8 @@ AhciStartPort (
|
|||
{
|
||||
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 @@ AhciStartPort (
|
|||
}
|
||||
|
||||
ssts.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SSTS);
|
||||
if (ssts.DET == 0x4)
|
||||
switch (ssts.DET)
|
||||
{
|
||||
// no device found
|
||||
return FALSE;
|
||||
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("\tDET: %d %d\n", ssts.DET, cmd.ST);
|
||||
DebugPrint("\tInvalid DET value: %x\n", ssts.DET);
|
||||
return FALSE;
|
||||
}// -- AhciStartPort();
|
||||
|
||||
|
@ -322,10 +415,6 @@ AhciHwInitialize (
|
|||
{
|
||||
PortExtension = &adapterExtension->PortExtension[index];
|
||||
PortExtension->IsActive = AhciStartPort(PortExtension);
|
||||
if (PortExtension->IsActive == FALSE)
|
||||
{
|
||||
DebugPrint("\tPort Disabled: %d\n", index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,6 +605,7 @@ AhciHwInterrupt(
|
|||
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 @@ AhciActivatePort (
|
|||
cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
|
||||
|
||||
if (cmd.ST == 0) // PxCMD.ST == 0
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get the lowest set bit
|
||||
tmp = QueueSlots & (QueueSlots - 1);
|
||||
|
@ -1224,6 +1316,8 @@ AhciActivatePort (
|
|||
// 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);
|
||||
|
||||
|
|
|
@ -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 @@ typedef union _AHCI_SERIAL_ATA_STATUS
|
|||
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 @@ typedef struct _AHCI_PORT
|
|||
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 @@ typedef struct _AHCI_MEMORY_REGISTERS
|
|||
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 @@ PAHCI_SRB_EXTENSION
|
|||
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);
|
Loading…
Reference in a new issue