Next: Interrupt Handler for completed FIS commands.

Notes.txt

svn path=/branches/GSoC_2016/AHCI/; revision=71681
This commit is contained in:
Aman Priyadarshi 2016-06-27 12:58:04 +00:00
parent b8af2c6014
commit 2cb1b3c60d
4 changed files with 156 additions and 19 deletions

View file

@ -24,11 +24,12 @@ AhciHwInitialize
AhciInterruptHandler AhciInterruptHandler
Flags Flags
IMPLEMENTED NOT_IMPLEMENTED
TESTED TESTED
Comment Comment
Fatal Error not supported Fatal Error not supported
Error Recovery not supported Error Recovery not supported
Complete Request Routine
AhciHwInterrupt AhciHwInterrupt
Flags Flags
@ -70,9 +71,9 @@ DriverEntry
AhciATA_CFIS AhciATA_CFIS
Flags Flags
NOT_IMPLEMENTED IMPLEMENTED
Comment Comment
Need to configure command table according to Srb function Need to implement NCQ
AhciATAPI_CFIS AhciATAPI_CFIS
Flags Flags
@ -95,9 +96,9 @@ AhciProcessSrb
AhciActivatePort AhciActivatePort
Flags Flags
NOT_IMPLEMENTED IMPLEMENTED
Comment Comment
NONE NCQ not supported
AhciProcessIO AhciProcessIO
Flags Flags

View file

@ -77,6 +77,13 @@ AhciPortInitialize (
StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->FBU, receivedFISPhysical.HighPart); StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->FBU, receivedFISPhysical.HighPart);
} }
PortExtension->IdentifyDeviceDataPhysicalAddress = StorPortGetPhysicalAddress(adapterExtension,
NULL,
PortExtension->IdentifyDeviceData,
&mappedLength);
NT_ASSERT(mappedLength == sizeof(IDENTIFY_DEVICE_DATA));
// set device power state flag to D0 // set device power state flag to D0
PortExtension->DevicePowerState = StorPowerDeviceD0; PortExtension->DevicePowerState = StorPowerDeviceD0;
@ -107,7 +114,7 @@ AhciAllocateResourceForAdapter (
) )
{ {
PVOID portsExtension = NULL; PVOID portsExtension = NULL;
PCHAR nonCachedExtension; PCHAR nonCachedExtension, tmp;
ULONG status, index, NCS, AlignedNCS; ULONG status, index, NCS, AlignedNCS;
ULONG portCount, portImplemented, nonCachedExtensionSize; ULONG portCount, portImplemented, nonCachedExtensionSize;
@ -130,7 +137,8 @@ AhciAllocateResourceForAdapter (
AdapterExtension->PortCount = portCount; AdapterExtension->PortCount = portCount;
nonCachedExtensionSize = sizeof(AHCI_COMMAND_HEADER) * AlignedNCS + //should be 1K aligned nonCachedExtensionSize = sizeof(AHCI_COMMAND_HEADER) * AlignedNCS + //should be 1K aligned
sizeof(AHCI_RECEIVED_FIS); sizeof(AHCI_RECEIVED_FIS) +
sizeof(IDENTIFY_DEVICE_DATA);
// align nonCachedExtensionSize to 1024 // align nonCachedExtensionSize to 1024
nonCachedExtensionSize = ROUND_UP(nonCachedExtensionSize, 1024); nonCachedExtensionSize = ROUND_UP(nonCachedExtensionSize, 1024);
@ -157,7 +165,11 @@ AhciAllocateResourceForAdapter (
AdapterExtension->PortExtension[index].IsActive = TRUE; AdapterExtension->PortExtension[index].IsActive = TRUE;
AdapterExtension->PortExtension[index].AdapterExtension = AdapterExtension; AdapterExtension->PortExtension[index].AdapterExtension = AdapterExtension;
AdapterExtension->PortExtension[index].CommandList = nonCachedExtension; AdapterExtension->PortExtension[index].CommandList = nonCachedExtension;
AdapterExtension->PortExtension[index].ReceivedFIS = (PAHCI_RECEIVED_FIS)(nonCachedExtension + sizeof(AHCI_COMMAND_HEADER) * AlignedNCS);
tmp = (PCHAR)(nonCachedExtension + sizeof(AHCI_COMMAND_HEADER) * AlignedNCS);
AdapterExtension->PortExtension[index].ReceivedFIS = (PAHCI_RECEIVED_FIS)tmp;
AdapterExtension->PortExtension[index].IdentifyDeviceData = (PIDENTIFY_DEVICE_DATA)(tmp + sizeof(AHCI_RECEIVED_FIS));
nonCachedExtension += nonCachedExtensionSize; nonCachedExtension += nonCachedExtensionSize;
} }
} }
@ -219,7 +231,7 @@ AhciInterruptHandler (
__in PAHCI_PORT_EXTENSION PortExtension __in PAHCI_PORT_EXTENSION PortExtension
) )
{ {
ULONG IS; ULONG is, ci, sact, outstanding;
AHCI_INTERRUPT_STATUS PxIS; AHCI_INTERRUPT_STATUS PxIS;
AHCI_INTERRUPT_STATUS PxISMasked; AHCI_INTERRUPT_STATUS PxISMasked;
PAHCI_ADAPTER_EXTENSION AdapterExtension; PAHCI_ADAPTER_EXTENSION AdapterExtension;
@ -283,8 +295,18 @@ AhciInterruptHandler (
// 10.7.1.1 // 10.7.1.1
// Clear port interrupt // Clear port interrupt
// It is set by the level of the virtual interrupt line being a set, and cleared by a write of 1 from the software. // It is set by the level of the virtual interrupt line being a set, and cleared by a write of 1 from the software.
IS = (1 << PortExtension->PortNumber); is = (1 << PortExtension->PortNumber);
StorPortWriteRegisterUlong(AdapterExtension, AdapterExtension->IS, IS); StorPortWriteRegisterUlong(AdapterExtension, AdapterExtension->IS, is);
ci = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CI);
sact = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SACT);
outstanding = ci | sact; // NOTE: Including both non-NCQ and NCQ based commands
if ((PortExtension->CommandIssuedSlots & (~outstanding)) != 0)
{
DebugPrint("\tCompleted Commands: %d\n", (PortExtension->CommandIssuedSlots & (~outstanding)));
PortExtension->CommandIssuedSlots &= outstanding;
}
return; return;
}// -- AhciInterruptHandler(); }// -- AhciInterruptHandler();
@ -741,7 +763,7 @@ DriverEntry (
/** /**
* @name AhciATA_CFIS * @name AhciATA_CFIS
* @not_implemented * @implemented
* *
* create ATA CFIS from Srb * create ATA CFIS from Srb
* *
@ -755,8 +777,33 @@ AhciATA_CFIS (
__in PAHCI_SRB_EXTENSION SrbExtension __in PAHCI_SRB_EXTENSION SrbExtension
) )
{ {
PAHCI_COMMAND_TABLE cmdTable;
DebugPrint("AhciATA_CFIS()\n"); DebugPrint("AhciATA_CFIS()\n");
cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
NT_ASSERT(sizeof(cmdTable->CFIS) == 64);
AhciZeroMemory(&cmdTable->CFIS, sizeof(cmdTable->CFIS));
cmdTable->CFIS[AHCI_ATA_CFIS_FisType] = 0x27; // FIS Type
cmdTable->CFIS[AHCI_ATA_CFIS_PMPort_C] = (1 << 7); // PM Port & C
cmdTable->CFIS[AHCI_ATA_CFIS_CommandReg] = SrbExtension->CommandReg;
cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesLow] = SrbExtension->FeaturesLow;
cmdTable->CFIS[AHCI_ATA_CFIS_LBA0] = SrbExtension->LBA0;
cmdTable->CFIS[AHCI_ATA_CFIS_LBA1] = SrbExtension->LBA1;
cmdTable->CFIS[AHCI_ATA_CFIS_LBA2] = SrbExtension->LBA2;
cmdTable->CFIS[AHCI_ATA_CFIS_Device] = SrbExtension->Device;
cmdTable->CFIS[AHCI_ATA_CFIS_LBA3] = SrbExtension->LBA3;
cmdTable->CFIS[AHCI_ATA_CFIS_LBA4] = SrbExtension->LBA4;
cmdTable->CFIS[AHCI_ATA_CFIS_LBA5] = SrbExtension->LBA5;
cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesHigh] = SrbExtension->FeaturesHigh;
cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountLow] = SrbExtension->SectorCountLow;
cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountHigh] = SrbExtension->SectorCountHigh;
return;
}// -- AhciATA_CFIS(); }// -- AhciATA_CFIS();
/** /**
@ -934,13 +981,13 @@ AhciProcessSrb (
} }
// mark this slot // mark this slot
PortExtension->OccupiedSlots |= SlotIndex; PortExtension->QueueSlots |= SlotIndex;
return; return;
}// -- AhciProcessSrb(); }// -- AhciProcessSrb();
/** /**
* @name AhciActivatePort * @name AhciActivatePort
* @not_implemented * @implemented
* *
* Program Port and populate command list * Program Port and populate command list
* *
@ -952,8 +999,40 @@ AhciActivatePort (
__in PAHCI_PORT_EXTENSION PortExtension __in PAHCI_PORT_EXTENSION PortExtension
) )
{ {
ULONG cmd, QueueSlots, slotToActivate, tmp;
PAHCI_ADAPTER_EXTENSION AdapterExtension;
DebugPrint("AhciActivatePort()\n"); DebugPrint("AhciActivatePort()\n");
AdapterExtension = PortExtension->AdapterExtension;
QueueSlots = PortExtension->QueueSlots;
if (QueueSlots == 0)
return;
// 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
return;
// get the lowest set bit
tmp = QueueSlots & (QueueSlots - 1);
if (tmp == 0)
slotToActivate = QueueSlots;
else
slotToActivate = (QueueSlots & (~tmp));
// mark that bit off in QueueSlots
PortExtension->QueueSlots &= ~slotToActivate;
// mark this CommandIssuedSlots
PortExtension->CommandIssuedSlots |= slotToActivate;
// tell the HBA to issue this Command Slot to the given port
StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CI, slotToActivate);
return; return;
}// -- AhciActivatePort(); }// -- AhciActivatePort();
@ -999,7 +1078,7 @@ AhciProcessIO (
// Acquire Lock // Acquire Lock
StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle); StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
occupiedSlots = PortExtension->OccupiedSlots; // Busy command slots for given port occupiedSlots = (PortExtension->QueueSlots | PortExtension->CommandIssuedSlots); // Busy command slots for given port
NCS = AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP); NCS = AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP);
commandSlotMask = (1 << NCS) - 1; // available slots mask commandSlotMask = (1 << NCS) - 1; // available slots mask
@ -1064,11 +1143,15 @@ DeviceInquiryRequest (
{ {
PVOID DataBuffer; PVOID DataBuffer;
ULONG DataBufferLength; ULONG DataBufferLength;
PAHCI_PORT_EXTENSION PortExtension;
PAHCI_SRB_EXTENSION SrbExtension; PAHCI_SRB_EXTENSION SrbExtension;
DebugPrint("DeviceInquiryRequest()\n"); DebugPrint("DeviceInquiryRequest()\n");
NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
SrbExtension = GetSrbExtension(Srb); SrbExtension = GetSrbExtension(Srb);
PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
// 3.6.1 // 3.6.1
// If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data // If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data
@ -1078,7 +1161,25 @@ DeviceInquiryRequest (
NT_ASSERT(SrbExtension != NULL); NT_ASSERT(SrbExtension != NULL);
SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY; SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY;
SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
SrbExtension->CommandReg = IDE_COMMAND_NOT_VALID; SrbExtension->CommandReg = IDE_COMMAND_NOT_VALID;
SrbExtension->FeaturesLow = 0;
SrbExtension->LBA0 = 0;
SrbExtension->LBA1 = 0;
SrbExtension->LBA2 = 0;
SrbExtension->Device = 0;
SrbExtension->LBA3 = 0;
SrbExtension->LBA4 = 0;
SrbExtension->LBA5 = 0;
SrbExtension->FeaturesHigh = 0;
SrbExtension->SectorCountLow = 0;
SrbExtension->SectorCountHigh = 0;
SrbExtension->Sgl.NumberOfElements = 1;
SrbExtension->Sgl.List[0].PhysicalAddress.LowPart = PortExtension->IdentifyDeviceDataPhysicalAddress.LowPart;
SrbExtension->Sgl.List[0].PhysicalAddress.HighPart = PortExtension->IdentifyDeviceDataPhysicalAddress.HighPart;
SrbExtension->Sgl.List[0].Length = sizeof(IDENTIFY_DEVICE_DATA);
} }
else else
{ {
@ -1093,10 +1194,13 @@ DeviceInquiryRequest (
} }
AhciZeroMemory(DataBuffer, DataBufferLength); AhciZeroMemory(DataBuffer, DataBufferLength);
// not supported
return SRB_STATUS_BAD_FUNCTION;
} }
AhciProcessIO(AdapterExtension, Srb->PathId, Srb); AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
return SRB_STATUS_SUCCESS; return SRB_STATUS_PENDING;
}// -- DeviceInquiryRequest(); }// -- DeviceInquiryRequest();
/** /**

View file

@ -23,6 +23,21 @@
#define AHCI_Global_HBA_CONTROL_AE (1 << 31) #define AHCI_Global_HBA_CONTROL_AE (1 << 31)
#define AHCI_Global_HBA_CAP_S64A (1 << 31) #define AHCI_Global_HBA_CAP_S64A (1 << 31)
#define AHCI_ATA_CFIS_FisType 0
#define AHCI_ATA_CFIS_PMPort_C 1
#define AHCI_ATA_CFIS_CommandReg 2
#define AHCI_ATA_CFIS_FeaturesLow 3
#define AHCI_ATA_CFIS_LBA0 4
#define AHCI_ATA_CFIS_LBA1 5
#define AHCI_ATA_CFIS_LBA2 6
#define AHCI_ATA_CFIS_Device 7
#define AHCI_ATA_CFIS_LBA3 8
#define AHCI_ATA_CFIS_LBA4 9
#define AHCI_ATA_CFIS_LBA5 10
#define AHCI_ATA_CFIS_FeaturesHigh 11
#define AHCI_ATA_CFIS_SectorCountLow 12
#define AHCI_ATA_CFIS_SectorCountHigh 13
// ATA Functions // ATA Functions
#define ATA_FUNCTION_ATA_COMMAND 0x100 #define ATA_FUNCTION_ATA_COMMAND 0x100
#define ATA_FUNCTION_ATA_IDENTIFY 0x101 #define ATA_FUNCTION_ATA_IDENTIFY 0x101
@ -297,13 +312,16 @@ typedef struct _AHCI_MEMORY_REGISTERS
typedef struct _AHCI_PORT_EXTENSION typedef struct _AHCI_PORT_EXTENSION
{ {
ULONG PortNumber; ULONG PortNumber;
ULONG OccupiedSlots; // slots to which we have already assigned task ULONG QueueSlots; // slots to which we have already assigned task
ULONG CommandIssuedSlots;
BOOLEAN IsActive; BOOLEAN IsActive;
PAHCI_PORT Port; // AHCI Port Infomation PAHCI_PORT Port; // AHCI Port Infomation
AHCI_QUEUE SrbQueue; AHCI_QUEUE SrbQueue;
PAHCI_RECEIVED_FIS ReceivedFIS; PAHCI_RECEIVED_FIS ReceivedFIS;
PAHCI_COMMAND_HEADER CommandList; PAHCI_COMMAND_HEADER CommandList;
STOR_DEVICE_POWER_STATE DevicePowerState; // Device Power State STOR_DEVICE_POWER_STATE DevicePowerState; // Device Power State
PIDENTIFY_DEVICE_DATA IdentifyDeviceData;
STOR_PHYSICAL_ADDRESS IdentifyDeviceDataPhysicalAddress;
struct _AHCI_ADAPTER_EXTENSION* AdapterExtension; // Port's Adapter Information struct _AHCI_ADAPTER_EXTENSION* AdapterExtension; // Port's Adapter Information
} AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION; } AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION;
@ -353,7 +371,21 @@ typedef struct _AHCI_SRB_EXTENSION
AHCI_COMMAND_TABLE CommandTable; AHCI_COMMAND_TABLE CommandTable;
ULONG AtaFunction; ULONG AtaFunction;
ULONG Flags; ULONG Flags;
ULONG CommandReg;
UCHAR CommandReg;
UCHAR FeaturesLow;
UCHAR LBA0;
UCHAR LBA1;
UCHAR LBA2;
UCHAR Device;
UCHAR LBA3;
UCHAR LBA4;
UCHAR LBA5;
UCHAR FeaturesHigh;
UCHAR SectorCountLow;
UCHAR SectorCountHigh;
ULONG SlotIndex; ULONG SlotIndex;
LOCAL_SCATTER_GATHER_LIST Sgl; LOCAL_SCATTER_GATHER_LIST Sgl;
} AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION; } AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION;

View file

@ -17,6 +17,6 @@
#define REACTOS_STR_FILE_VERSION VERSION_STR #define REACTOS_STR_FILE_VERSION VERSION_STR
#define REACTOS_STR_INTERNAL_NAME "storahci.sys" #define REACTOS_STR_INTERNAL_NAME "storahci.sys"
#define REACTOS_STR_ORIGINAL_FILENAME "storahci.sys" #define REACTOS_STR_ORIGINAL_FILENAME "storahci.sys"
#define REACTOS_STR_LEGAL_COPYRIGHT "Copyright 2010 ReactOS Team" #define REACTOS_STR_LEGAL_COPYRIGHT "Copyright 2016 ReactOS Team"
#define REACTOS_STR_PRODUCT_NAME "AHCI Driver for ReactOS" #define REACTOS_STR_PRODUCT_NAME "AHCI Driver for ReactOS"
#define REACTOS_STR_PRODUCT_VERSION VERSION_STR #define REACTOS_STR_PRODUCT_VERSION VERSION_STR