Implemented AhciBuild_PRDT

svn path=/branches/GSoC_2016/AHCI/; revision=71659
This commit is contained in:
Aman Priyadarshi 2016-06-22 16:08:45 +00:00
parent ca8a828d02
commit b8af2c6014
3 changed files with 104 additions and 19 deletions

View file

@ -82,9 +82,9 @@ AhciATAPI_CFIS
AhciBuild_PRDT AhciBuild_PRDT
Flags Flags
NOT_IMPLEMENTED IMPLEMENTED
Comment Comment
Need to configure command table according to Srb function NONE
AhciProcessSrb AhciProcessSrb
Flags Flags

View file

@ -259,7 +259,7 @@ AhciInterruptHandler (
// software should perform the appropriate error recovery actions based on whether // software should perform the appropriate error recovery actions based on whether
// non-queued commands were being issued or native command queuing commands were being issued. // non-queued commands were being issued or native command queuing commands were being issued.
DebugPrint("\tFata Error: %x\n", PxIS.Status); DebugPrint("\tFatal Error: %x\n", PxIS.Status);
} }
// Normal Command Completion // Normal Command Completion
@ -781,7 +781,7 @@ AhciATAPI_CFIS (
/** /**
* @name AhciBuild_PRDT * @name AhciBuild_PRDT
* @not_implemented * @implemented
* *
* Build PRDT for data transfer * Build PRDT for data transfer
* *
@ -797,9 +797,32 @@ AhciBuild_PRDT (
__in PAHCI_SRB_EXTENSION SrbExtension __in PAHCI_SRB_EXTENSION SrbExtension
) )
{ {
ULONG index;
PAHCI_COMMAND_TABLE cmdTable;
PLOCAL_SCATTER_GATHER_LIST sgl;
PAHCI_ADAPTER_EXTENSION AdapterExtension;
DebugPrint("AhciBuild_PRDT()\n"); DebugPrint("AhciBuild_PRDT()\n");
return -1; sgl = &SrbExtension->Sgl;
cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
AdapterExtension = PortExtension->AdapterExtension;
NT_ASSERT(sgl != NULL);
NT_ASSERT(sgl->NumberOfElements < MAXIMUM_AHCI_PRDT_ENTRIES);
for (index = 0; index < sgl->NumberOfElements; index++)
{
NT_ASSERT(sgl->List[index].Length <= MAXIMUM_TRANSFER_LENGTH);
cmdTable->PRDT[index].DBA = sgl->List[index].PhysicalAddress.LowPart;
if (IsAdapterCAPS64(AdapterExtension->CAP))
{
cmdTable->PRDT[index].DBAU = sgl->List[index].PhysicalAddress.HighPart;
}
}
return sgl->NumberOfElements;
}// -- AhciBuild_PRDT(); }// -- AhciBuild_PRDT();
/** /**
@ -830,24 +853,24 @@ AhciProcessSrb (
NT_ASSERT(Srb->PathId == PortExtension->PortNumber); NT_ASSERT(Srb->PathId == PortExtension->PortNumber);
SrbExtension = Srb->SrbExtension; SrbExtension = GetSrbExtension(Srb);
AdapterExtension = PortExtension->AdapterExtension; AdapterExtension = PortExtension->AdapterExtension;
NT_ASSERT(SrbExtension != NULL); NT_ASSERT(SrbExtension != NULL);
NT_ASSERT(SrbExtension->AtaFunction != 0); NT_ASSERT(SrbExtension->AtaFunction != 0);
if ((SrbExtension->AtaFunction == ATA_FUNCTION_ATA_IDENTIFY) && if ((SrbExtension->AtaFunction == ATA_FUNCTION_ATA_IDENTIFY) &&
(SrbExtension->Task.CommandReg == IDE_COMMAND_NOT_VALID)) (SrbExtension->CommandReg == IDE_COMMAND_NOT_VALID))
{ {
// Here we are safe to check SIG register // Here we are safe to check SIG register
sig = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SIG); sig = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SIG);
if (sig == 0x101) if (sig == 0x101)
{ {
SrbExtension->Task.CommandReg = IDE_COMMAND_IDENTIFY; SrbExtension->CommandReg = IDE_COMMAND_IDENTIFY;
} }
else else
{ {
SrbExtension->Task.CommandReg = IDE_COMMAND_ATAPI_IDENTIFY; SrbExtension->CommandReg = IDE_COMMAND_ATAPI_IDENTIFY;
} }
} }
@ -992,7 +1015,7 @@ AhciProcessIO (
tmpSrb = RemoveQueue(&PortExtension->SrbQueue); tmpSrb = RemoveQueue(&PortExtension->SrbQueue);
if (tmpSrb != NULL) if (tmpSrb != NULL)
{ {
NT_ASSERT(Srb->PathId == PathId); NT_ASSERT(tmpSrb->PathId == PathId);
AhciProcessSrb(PortExtension, tmpSrb, slotIndex); AhciProcessSrb(PortExtension, tmpSrb, slotIndex);
} }
else else
@ -1045,7 +1068,7 @@ DeviceInquiryRequest (
DebugPrint("DeviceInquiryRequest()\n"); DebugPrint("DeviceInquiryRequest()\n");
SrbExtension = Srb->SrbExtension; SrbExtension = GetSrbExtension(Srb);
// 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
@ -1055,7 +1078,7 @@ DeviceInquiryRequest (
NT_ASSERT(SrbExtension != NULL); NT_ASSERT(SrbExtension != NULL);
SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY; SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY;
SrbExtension->Task.CommandReg = IDE_COMMAND_NOT_VALID; SrbExtension->CommandReg = IDE_COMMAND_NOT_VALID;
} }
else else
{ {
@ -1211,7 +1234,7 @@ AddQueue (
NT_ASSERT(Queue->Head < MAXIMUM_QUEUE_BUFFER_SIZE); NT_ASSERT(Queue->Head < MAXIMUM_QUEUE_BUFFER_SIZE);
NT_ASSERT(Queue->Tail < MAXIMUM_QUEUE_BUFFER_SIZE); NT_ASSERT(Queue->Tail < MAXIMUM_QUEUE_BUFFER_SIZE);
if (Queue->Head == ((Queue->Tail + 1) % MAXIMUM_QUEUE_BUFFER_SIZE)) if (Queue->Tail == ((Queue->Head + 1) % MAXIMUM_QUEUE_BUFFER_SIZE))
return FALSE; return FALSE;
Queue->Buffer[Queue->Head++] = Srb; Queue->Buffer[Queue->Head++] = Srb;
@ -1251,3 +1274,34 @@ RemoveQueue (
return Srb; return Srb;
}// -- RemoveQueue(); }// -- RemoveQueue();
/**
* @name GetSrbExtension
* @implemented
*
* GetSrbExtension from Srb make sure It is properly aligned
*
* @param Srb
*
* @return
* return SrbExtension
*
*/
__inline
PAHCI_SRB_EXTENSION
GetSrbExtension (
__in PSCSI_REQUEST_BLOCK Srb
)
{
ULONG Offset;
ULONG_PTR SrbExtension;
SrbExtension = Srb->SrbExtension;
Offset = SrbExtension % 128;
// CommandTable should be 128 byte aligned
if (Offset != 0)
Offset = 128 - Offset;
return (PAHCI_SRB_EXTENSION)(SrbExtension + Offset);
}// -- PAHCI_SRB_EXTENSION();

View file

@ -12,6 +12,7 @@
#define DEBUG 1 #define DEBUG 1
#define MAXIMUM_AHCI_PORT_COUNT 25 #define MAXIMUM_AHCI_PORT_COUNT 25
#define MAXIMUM_AHCI_PRDT_ENTRIES 32
#define MAXIMUM_QUEUE_BUFFER_SIZE 255 #define MAXIMUM_QUEUE_BUFFER_SIZE 255
#define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB #define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB
@ -202,6 +203,28 @@ typedef union _AHCI_COMMAND_HEADER_DESCRIPTION
ULONG Status; ULONG Status;
} AHCI_COMMAND_HEADER_DESCRIPTION; } AHCI_COMMAND_HEADER_DESCRIPTION;
typedef struct _AHCI_PRDT
{
ULONG DBA;
ULONG DBAU;
ULONG RSV0;
ULONG DBC : 22;
ULONG RSV1 : 9;
ULONG I : 1;
} AHCI_PRDT, *PAHCI_PRDT;
// 4.2.3 Command Table
typedef struct _AHCI_COMMAND_TABLE
{
// (16 * 32) + 64 + 16 + 48 = 648
// 128 byte aligned :D
UCHAR CFIS[64];
UCHAR ACMD[16];
UCHAR RSV0[48];
AHCI_PRDT PRDT[MAXIMUM_AHCI_PRDT_ENTRIES];
} AHCI_COMMAND_TABLE, *PAHCI_COMMAND_TABLE;
// 4.2.2 Command Header // 4.2.2 Command Header
typedef struct _AHCI_COMMAND_HEADER typedef struct _AHCI_COMMAND_HEADER
{ {
@ -318,19 +341,21 @@ typedef struct _AHCI_ADAPTER_EXTENSION
AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT]; AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT];
} AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION; } AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION;
typedef struct _ATA_REGISTER typedef struct _LOCAL_SCATTER_GATHER_LIST
{ {
UCHAR CommandReg; ULONG NumberOfElements;
ULONG Reserved; ULONG_PTR Reserved;
} ATA_REGISTER; STOR_SCATTER_GATHER_ELEMENT List[MAXIMUM_AHCI_PRDT_ENTRIES];
} LOCAL_SCATTER_GATHER_LIST, *PLOCAL_SCATTER_GATHER_LIST;
typedef struct _AHCI_SRB_EXTENSION typedef struct _AHCI_SRB_EXTENSION
{ {
AHCI_COMMAND_TABLE CommandTable;
ULONG AtaFunction; ULONG AtaFunction;
ULONG Flags; ULONG Flags;
ATA_REGISTER Task; ULONG CommandReg;
ULONG SlotIndex; ULONG SlotIndex;
ULONG Reserved[4]; LOCAL_SCATTER_GATHER_LIST Sgl;
} AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION; } AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION;
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
@ -375,3 +400,9 @@ PVOID
RemoveQueue ( RemoveQueue (
__inout PAHCI_QUEUE Queue __inout PAHCI_QUEUE Queue
); );
__inline
PAHCI_SRB_EXTENSION
GetSrbExtension(
__in PSCSI_REQUEST_BLOCK Srb
);