mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 10:14:44 +00:00
Implemented AhciBuild_PRDT
svn path=/branches/GSoC_2016/AHCI/; revision=71659
This commit is contained in:
parent
ca8a828d02
commit
b8af2c6014
3 changed files with 104 additions and 19 deletions
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
);
|
||||||
|
|
Loading…
Reference in a new issue