From 2cb1b3c60d6c68d1942c03c168026f12bf3ec587 Mon Sep 17 00:00:00 2001 From: Aman Priyadarshi Date: Mon, 27 Jun 2016 12:58:04 +0000 Subject: [PATCH] Next: Interrupt Handler for completed FIS commands. Notes.txt svn path=/branches/GSoC_2016/AHCI/; revision=71681 --- drivers/storage/storahci/Notes.txt | 11 +-- drivers/storage/storahci/storahci.c | 126 ++++++++++++++++++++++++--- drivers/storage/storahci/storahci.h | 36 +++++++- drivers/storage/storahci/storahci.rc | 2 +- 4 files changed, 156 insertions(+), 19 deletions(-) diff --git a/drivers/storage/storahci/Notes.txt b/drivers/storage/storahci/Notes.txt index 49cc39e6e44..c72c1ed1273 100644 --- a/drivers/storage/storahci/Notes.txt +++ b/drivers/storage/storahci/Notes.txt @@ -24,11 +24,12 @@ AhciHwInitialize AhciInterruptHandler Flags - IMPLEMENTED + NOT_IMPLEMENTED TESTED Comment Fatal Error not supported Error Recovery not supported + Complete Request Routine AhciHwInterrupt Flags @@ -70,9 +71,9 @@ DriverEntry AhciATA_CFIS Flags - NOT_IMPLEMENTED + IMPLEMENTED Comment - Need to configure command table according to Srb function + Need to implement NCQ AhciATAPI_CFIS Flags @@ -95,9 +96,9 @@ AhciProcessSrb AhciActivatePort Flags - NOT_IMPLEMENTED + IMPLEMENTED Comment - NONE + NCQ not supported AhciProcessIO Flags diff --git a/drivers/storage/storahci/storahci.c b/drivers/storage/storahci/storahci.c index 229edec0c8b..1bc4e6b5b0f 100644 --- a/drivers/storage/storahci/storahci.c +++ b/drivers/storage/storahci/storahci.c @@ -77,6 +77,13 @@ AhciPortInitialize ( 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 PortExtension->DevicePowerState = StorPowerDeviceD0; @@ -107,7 +114,7 @@ AhciAllocateResourceForAdapter ( ) { PVOID portsExtension = NULL; - PCHAR nonCachedExtension; + PCHAR nonCachedExtension, tmp; ULONG status, index, NCS, AlignedNCS; ULONG portCount, portImplemented, nonCachedExtensionSize; @@ -130,7 +137,8 @@ AhciAllocateResourceForAdapter ( AdapterExtension->PortCount = portCount; 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 nonCachedExtensionSize = ROUND_UP(nonCachedExtensionSize, 1024); @@ -157,7 +165,11 @@ AhciAllocateResourceForAdapter ( AdapterExtension->PortExtension[index].IsActive = TRUE; AdapterExtension->PortExtension[index].AdapterExtension = AdapterExtension; 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; } } @@ -219,7 +231,7 @@ AhciInterruptHandler ( __in PAHCI_PORT_EXTENSION PortExtension ) { - ULONG IS; + ULONG is, ci, sact, outstanding; AHCI_INTERRUPT_STATUS PxIS; AHCI_INTERRUPT_STATUS PxISMasked; PAHCI_ADAPTER_EXTENSION AdapterExtension; @@ -283,8 +295,18 @@ AhciInterruptHandler ( // 10.7.1.1 // 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. - IS = (1 << PortExtension->PortNumber); - StorPortWriteRegisterUlong(AdapterExtension, AdapterExtension->IS, IS); + is = (1 << PortExtension->PortNumber); + 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; }// -- AhciInterruptHandler(); @@ -741,7 +763,7 @@ DriverEntry ( /** * @name AhciATA_CFIS - * @not_implemented + * @implemented * * create ATA CFIS from Srb * @@ -755,8 +777,33 @@ AhciATA_CFIS ( __in PAHCI_SRB_EXTENSION SrbExtension ) { + PAHCI_COMMAND_TABLE cmdTable; + 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(); /** @@ -934,13 +981,13 @@ AhciProcessSrb ( } // mark this slot - PortExtension->OccupiedSlots |= SlotIndex; + PortExtension->QueueSlots |= SlotIndex; return; }// -- AhciProcessSrb(); /** * @name AhciActivatePort - * @not_implemented + * @implemented * * Program Port and populate command list * @@ -952,8 +999,40 @@ AhciActivatePort ( __in PAHCI_PORT_EXTENSION PortExtension ) { + ULONG cmd, QueueSlots, slotToActivate, tmp; + PAHCI_ADAPTER_EXTENSION AdapterExtension; + 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; }// -- AhciActivatePort(); @@ -999,7 +1078,7 @@ AhciProcessIO ( // Acquire Lock 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); commandSlotMask = (1 << NCS) - 1; // available slots mask @@ -1064,11 +1143,15 @@ DeviceInquiryRequest ( { PVOID DataBuffer; ULONG DataBufferLength; + PAHCI_PORT_EXTENSION PortExtension; PAHCI_SRB_EXTENSION SrbExtension; DebugPrint("DeviceInquiryRequest()\n"); + NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId)); + SrbExtension = GetSrbExtension(Srb); + PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; // 3.6.1 // 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); SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY; + SrbExtension->Flags |= ATA_FLAGS_DATA_IN; 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 { @@ -1093,10 +1194,13 @@ DeviceInquiryRequest ( } AhciZeroMemory(DataBuffer, DataBufferLength); + + // not supported + return SRB_STATUS_BAD_FUNCTION; } AhciProcessIO(AdapterExtension, Srb->PathId, Srb); - return SRB_STATUS_SUCCESS; + return SRB_STATUS_PENDING; }// -- DeviceInquiryRequest(); /** diff --git a/drivers/storage/storahci/storahci.h b/drivers/storage/storahci/storahci.h index 1133904cc9c..c75121b7a16 100644 --- a/drivers/storage/storahci/storahci.h +++ b/drivers/storage/storahci/storahci.h @@ -23,6 +23,21 @@ #define AHCI_Global_HBA_CONTROL_AE (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 #define ATA_FUNCTION_ATA_COMMAND 0x100 #define ATA_FUNCTION_ATA_IDENTIFY 0x101 @@ -297,13 +312,16 @@ typedef struct _AHCI_MEMORY_REGISTERS typedef struct _AHCI_PORT_EXTENSION { 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; PAHCI_PORT Port; // AHCI Port Infomation AHCI_QUEUE SrbQueue; PAHCI_RECEIVED_FIS ReceivedFIS; PAHCI_COMMAND_HEADER CommandList; 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 } AHCI_PORT_EXTENSION, *PAHCI_PORT_EXTENSION; @@ -353,7 +371,21 @@ typedef struct _AHCI_SRB_EXTENSION AHCI_COMMAND_TABLE CommandTable; ULONG AtaFunction; 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; LOCAL_SCATTER_GATHER_LIST Sgl; } AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION; diff --git a/drivers/storage/storahci/storahci.rc b/drivers/storage/storahci/storahci.rc index 1cc6dbff11a..5950ce2d1f1 100644 --- a/drivers/storage/storahci/storahci.rc +++ b/drivers/storage/storahci/storahci.rc @@ -17,6 +17,6 @@ #define REACTOS_STR_FILE_VERSION VERSION_STR #define REACTOS_STR_INTERNAL_NAME "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_VERSION VERSION_STR