Added AhciHwInterrupt -- Round Robin Implementation (SharedPort)

Added Support Function AhciInterruptHandler
Added DeviceInquiryRequest
- Need to implement EVPD.
SRB_FUNCTION_EXECUTE_SCSI for cdb->CDB10.OperationCode != SCSIOP_INQUIRY

svn path=/branches/GSoC_2016/AHCI/; revision=71589
This commit is contained in:
Aman Priyadarshi 2016-06-07 18:06:51 +00:00
parent d4c9e20b36
commit d8c1347c02
2 changed files with 133 additions and 22 deletions

View File

@ -7,22 +7,6 @@
#include "storahci.h"
BOOLEAN AhciAdapterReset(
__in PAHCI_ADAPTER_EXTENSION adapterExtension
);
__inline
VOID AhciZeroMemory(
__in PCHAR buffer,
__in ULONG bufferSize
);
__inline
BOOLEAN IsPortValid(
__in PAHCI_ADAPTER_EXTENSION adapterExtension,
__in UCHAR pathId
);
/**
* @name AhciPortInitialize
* @implemented
@ -191,6 +175,24 @@ BOOLEAN AhciHwInitialize(
return TRUE;
}// -- AhciHwInitialize();
/**
* @name AhciInterruptHandler
* @implemented
*
* Interrupt Handler for portExtension
*
* @param portExtension
*
*/
VOID AhciInterruptHandler(
__in PAHCI_PORT_EXTENSION portExtension
)
{
StorPortDebugPrint(0, "AhciInterruptHandler()\n");
StorPortDebugPrint(0, "\tPort Number: %d\n", portExtension->PortNumber);
}// -- AhciInterruptHandler();
/**
* @name AhciHwInterrupt
* @implemented
@ -207,12 +209,40 @@ BOOLEAN AhciHwInterrupt(
__in PVOID AdapterExtension
)
{
ULONG portPending, nextPort, i;
PAHCI_ADAPTER_EXTENSION adapterExtension;
StorPortDebugPrint(0, "AhciHwInterrupt()\n");
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
if (adapterExtension->StateFlags.Removed)
return FALSE;
portPending = StorPortReadRegisterUlong(adapterExtension, adapterExtension->IS);
// we process interrupt for implemented ports only
portPending = portPending & adapterExtension->PortImplemented;
if (portPending == 0)
return FALSE;
for (i = 1; i <= MAXIMUM_AHCI_PORT_COUNT; i++)
{
nextPort = (adapterExtension->LastInterruptPort + i) % MAXIMUM_AHCI_PORT_COUNT;
if ((portPending & (0x1 << nextPort)) == 0)
continue;
if (nextPort == adapterExtension->LastInterruptPort
|| adapterExtension->PortExtension[nextPort].IsActive == FALSE)
return FALSE;
// we can assign this interrupt to this port
adapterExtension->LastInterruptPort = nextPort;
AhciInterruptHandler(nextPort);
return TRUE;
}
return FALSE;
}// -- AhciHwInterrupt();
@ -302,7 +332,10 @@ BOOLEAN AhciHwStartIo(
PCDB cdb = (PCDB)&Srb->Cdb;
if (cdb->CDB10.OperationCode == SCSIOP_INQUIRY)
{
StorPortDebugPrint(0, "\tINQUIRY Called!\n");
Srb->SrbStatus = DeviceInquiryRequest(adapterExtension, Srb, cdb);
StorPortNotification(RequestComplete, adapterExtension, Srb);
return TRUE;
}
}
else
@ -343,7 +376,7 @@ BOOLEAN AhciHwResetBus(
adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
return TRUE;
return FALSE;
}// -- AhciHwResetBus();
/**
@ -455,15 +488,16 @@ ULONG AhciHwFindAdapter(
adapterExtension->CAP = StorPortReadRegisterUlong(adapterExtension, &abar->CAP);
adapterExtension->CAP2 = StorPortReadRegisterUlong(adapterExtension, &abar->CAP2);
adapterExtension->Version = StorPortReadRegisterUlong(adapterExtension, &abar->VS);
adapterExtension->LastInterruptPort = -1;
// 10.1.2
// 1. Indicate that system software is AHCI aware by setting GHC.AE to 1.
// 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
ghc = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
// AE := Highest Significant bit of GHC
if ((ghc & AHCI_Global_HBA_CONTROL_AE) == 1)//Hmm, controller was already in power state
if ((ghc & AHCI_Global_HBA_CONTROL_AE) != 0)//Hmm, controller was already in power state
{
// reset controller to have it in know state
// reset controller to have it in known state
StorPortDebugPrint(0, "\tAE Already set, Reset()\n");
if (!AhciAdapterReset(adapterExtension)){
StorPortDebugPrint(0, "\tReset Failed!\n");
@ -603,7 +637,7 @@ BOOLEAN AhciAdapterReset(
return FALSE;
// HR -- Very first bit (lowest significant)
ghc = 1;
ghc = AHCI_Global_HBA_CONTROL_HR;
StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc);
for (ticks = 0; (ticks < 50) &&
@ -647,7 +681,7 @@ VOID AhciZeroMemory(
* @param PathId
*
* @return
* return TRUE if bus was successfully reset
* return TRUE if provided port is valid (implemented) or not
*/
__inline
BOOLEAN IsPortValid(
@ -657,5 +691,55 @@ BOOLEAN IsPortValid(
{
if (pathId >= MAXIMUM_AHCI_PORT_COUNT)
return FALSE;
return adapterExtension->PortExtension[pathId].IsActive;
}// -- IsPortValid()
/**
* @name DeviceInquiryRequest
* @implemented
*
* Tells wheather given port is implemented or not
*
* @param adapterExtension
* @param Srb
* @param Cdb
*
* @return
* return STOR status for DeviceInquiryRequest
*
* @remark
* http://www.seagate.com/staticfiles/support/disc/manuals/Interface%20manuals/100293068c.pdf
*/
ULONG DeviceInquiryRequest(
__in PAHCI_ADAPTER_EXTENSION adapterExtension,
__in PSCSI_REQUEST_BLOCK Srb,
__in PCDB Cdb
)
{
PVOID DataBuffer;
ULONG DataBufferLength;
StorPortDebugPrint(0, "DeviceInquiryRequest()\n");
// 3.6.1
// If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data
if (Cdb->CDB6INQUIRY3.EnableVitalProductData == 0)
{
StorPortDebugPrint(0, "\tEVPD Inquired\n");
}
else
{
StorPortDebugPrint(0, "\tVPD Inquired\n");
DataBuffer = Srb->DataBuffer;
DataBufferLength = Srb->DataTransferLength;
if (DataBuffer == NULL)
return SRB_STATUS_INVALID_REQUEST;
AhciZeroMemory((PCHAR)DataBuffer, DataBufferLength);
}
return SRB_STATUS_BAD_FUNCTION;
}// -- DeviceInquiryRequest();

View File

@ -212,6 +212,7 @@ typedef struct _AHCI_ADAPTER_EXTENSION
ULONG Version;
ULONG CAP;
ULONG CAP2;
ULONG LastInterruptPort;
PVOID NonCachedExtension;// holds virtual address to noncached buffer allocated for Port Extension
@ -231,3 +232,29 @@ typedef struct _AHCI_SRB_EXTENSION
{
ULONG Reserved[4];
} AHCI_SRB_EXTENSION;
//////////////////////////////////////////////////////////////
// Declarations //
//////////////////////////////////////////////////////////////
BOOLEAN AhciAdapterReset(
__in PAHCI_ADAPTER_EXTENSION adapterExtension
);
__inline
VOID AhciZeroMemory(
__in PCHAR buffer,
__in ULONG bufferSize
);
__inline
BOOLEAN IsPortValid(
__in PAHCI_ADAPTER_EXTENSION adapterExtension,
__in UCHAR pathId
);
ULONG DeviceInquiryRequest(
__in PAHCI_ADAPTER_EXTENSION adapterExtension,
__in PSCSI_REQUEST_BLOCK Srb,
__in PCDB Cdb
);