mirror of
https://github.com/reactos/reactos.git
synced 2024-10-08 18:29:05 +00:00
- Fixed CMakeLists issues reported by hbelusca
- Fixed ROS name issue reported by hbelusca - Handled non fatal device error interrupts - AhciProcessIO Implemented - code clean svn path=/branches/GSoC_2016/AHCI/; revision=71647
This commit is contained in:
parent
dcf485d6f3
commit
5b776020ae
|
@ -6,3 +6,4 @@ add_subdirectory(floppy)
|
||||||
add_subdirectory(ide)
|
add_subdirectory(ide)
|
||||||
add_subdirectory(port)
|
add_subdirectory(port)
|
||||||
add_subdirectory(scsiport)
|
add_subdirectory(scsiport)
|
||||||
|
add_subdirectory(storahci)
|
||||||
|
|
|
@ -1,27 +1,10 @@
|
||||||
|
add_definitions(-DDEBUG)
|
||||||
set_cpp()
|
|
||||||
|
|
||||||
include_directories(
|
|
||||||
BEFORE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
inc)
|
|
||||||
|
|
||||||
#add_definitions(-DDEBUG)
|
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
storahci.cpp
|
storahci.c)
|
||||||
ros_glue/ros_glue.cpp
|
|
||||||
stdafx.h)
|
|
||||||
|
|
||||||
add_library(storahci SHARED ${SOURCE} storahci.rc)
|
add_library(storahci SHARED ${SOURCE} storahci.rc)
|
||||||
|
|
||||||
if(NOT MSVC)
|
|
||||||
add_target_compile_flags(storahci "-Wno-narrowing")
|
|
||||||
if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
|
||||||
add_target_compile_flags(storahci "-Wno-unused-but-set-variable")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_pch(storahci stdafx.h SOURCE)
|
|
||||||
set_module_type(storahci kernelmodedriver)
|
set_module_type(storahci kernelmodedriver)
|
||||||
add_importlibs(storahci storport ntoskrnl hal)
|
add_importlibs(storahci storport ntoskrnl hal)
|
||||||
add_cd_file(TARGET storahci DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
add_cd_file(TARGET storahci DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
||||||
|
|
|
@ -216,19 +216,80 @@ AhciHwInitialize (
|
||||||
*
|
*
|
||||||
* @param PortExtension
|
* @param PortExtension
|
||||||
*
|
*
|
||||||
* @return
|
|
||||||
* return TRUE Indicates the interrupt was handled correctly
|
|
||||||
* return FALSE Indicates something went wrong
|
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
VOID
|
||||||
AhciInterruptHandler (
|
AhciInterruptHandler (
|
||||||
__in PAHCI_PORT_EXTENSION PortExtension
|
__in PAHCI_PORT_EXTENSION PortExtension
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ULONG IS;
|
||||||
|
AHCI_INTERRUPT_STATUS PxIS;
|
||||||
|
AHCI_INTERRUPT_STATUS PxISMasked;
|
||||||
|
PAHCI_ADAPTER_EXTENSION AdapterExtension;
|
||||||
|
|
||||||
DebugPrint("AhciInterruptHandler()\n");
|
DebugPrint("AhciInterruptHandler()\n");
|
||||||
DebugPrint("\tPort Number: %d\n", PortExtension->PortNumber);
|
DebugPrint("\tPort Number: %d\n", PortExtension->PortNumber);
|
||||||
|
|
||||||
return FALSE;
|
AdapterExtension = PortExtension->AdapterExtension;
|
||||||
|
NT_ASSERT(IsPortValid(AdapterExtension, PortExtension->PortNumber));
|
||||||
|
|
||||||
|
// 5.5.3
|
||||||
|
// 1. Software determines the cause of the interrupt by reading the PxIS register.
|
||||||
|
// It is possible for multiple bits to be set
|
||||||
|
// 2. Software clears appropriate bits in the PxIS register corresponding to the cause of the interrupt.
|
||||||
|
// 3. Software clears the interrupt bit in IS.IPS corresponding to the port.
|
||||||
|
// 4. If executing non-queued commands, software reads the PxCI register, and compares the current value to
|
||||||
|
// the list of commands previously issued by software that are still outstanding.
|
||||||
|
// If executing native queued commands, software reads the PxSACT register and compares the current
|
||||||
|
// value to the list of commands previously issued by software.
|
||||||
|
// Software completes with success any outstanding command whose corresponding bit has been cleared in
|
||||||
|
// the respective register. PxCI and PxSACT are volatile registers; software should only use their values
|
||||||
|
// to determine commands that have completed, not to determine which commands have previously been issued.
|
||||||
|
// 5. If there were errors, noted in the PxIS register, software performs error recovery actions (see section 6.2.2).
|
||||||
|
PxISMasked.Status = 0;
|
||||||
|
PxIS.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->IS);
|
||||||
|
|
||||||
|
// 6.2.2
|
||||||
|
// Fatal Error
|
||||||
|
// signified by the setting of PxIS.HBFS, PxIS.HBDS, PxIS.IFS, or PxIS.TFES
|
||||||
|
if (PxIS.HBFS || PxIS.HBDS || PxIS.IFS || PxIS.TFES)
|
||||||
|
{
|
||||||
|
// In this state, the HBA shall not issue any new commands nor acknowledge DMA Setup FISes to process
|
||||||
|
// any native command queuing commands. To recover, the port must be restarted
|
||||||
|
// To detect an error that requires software recovery actions to be performed,
|
||||||
|
// software should check whether any of the following status bits are set on an interrupt:
|
||||||
|
// PxIS.HBFS, PxIS.HBDS, PxIS.IFS, and PxIS.TFES. If any of these bits are set,
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
DebugPrint("\tFata Error: %x\n", PxIS.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal Command Completion
|
||||||
|
// 3.3.5
|
||||||
|
// A D2H Register FIS has been received with the ‘I’ bit set, and has been copied into system memory.
|
||||||
|
PxISMasked.DHRS = PxIS.DHRS;
|
||||||
|
// A PIO Setup FIS has been received with the ‘I’ bit set, it has been copied into system memory.
|
||||||
|
PxISMasked.PSS = PxIS.PSS;
|
||||||
|
// A DMA Setup FIS has been received with the ‘I’ bit set and has been copied into system memory.
|
||||||
|
PxISMasked.DSS = PxIS.DSS;
|
||||||
|
// A Set Device Bits FIS has been received with the ‘I’ bit set and has been copied into system memory/
|
||||||
|
PxISMasked.SDBS = PxIS.SDBS;
|
||||||
|
// A PRD with the ‘I’ bit set has transferred all of its data.
|
||||||
|
PxISMasked.DPS = PxIS.DPS;
|
||||||
|
|
||||||
|
if (PxISMasked.Status != 0)
|
||||||
|
{
|
||||||
|
StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->IS, PxISMasked.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
return;
|
||||||
}// -- AhciInterruptHandler();
|
}// -- AhciInterruptHandler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -276,6 +337,8 @@ AhciHwInterrupt(
|
||||||
if ((portPending & (0x1 << nextPort)) == 0)
|
if ((portPending & (0x1 << nextPort)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
NT_ASSERT(IsPortValid(AdapterExtension, nextPort));
|
||||||
|
|
||||||
if ((nextPort == adapterExtension->LastInterruptPort) ||
|
if ((nextPort == adapterExtension->LastInterruptPort) ||
|
||||||
(adapterExtension->PortExtension[nextPort].IsActive == FALSE))
|
(adapterExtension->PortExtension[nextPort].IsActive == FALSE))
|
||||||
{
|
{
|
||||||
|
@ -284,7 +347,11 @@ AhciHwInterrupt(
|
||||||
|
|
||||||
// we can assign this interrupt to this port
|
// we can assign this interrupt to this port
|
||||||
adapterExtension->LastInterruptPort = nextPort;
|
adapterExtension->LastInterruptPort = nextPort;
|
||||||
return AhciInterruptHandler(&adapterExtension->PortExtension[nextPort]);
|
AhciInterruptHandler(&adapterExtension->PortExtension[nextPort]);
|
||||||
|
|
||||||
|
// interrupt belongs to this device
|
||||||
|
// should always return TRUE
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugPrint("\tSomething went wrong");
|
DebugPrint("\tSomething went wrong");
|
||||||
|
@ -341,7 +408,7 @@ AhciHwStartIo (
|
||||||
{
|
{
|
||||||
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||||
adapterExtension->StateFlags.Removed = 1;
|
adapterExtension->StateFlags.Removed = 1;
|
||||||
DebugPrint("\tadapter removed\n");
|
DebugPrint("\tAdapter removed\n");
|
||||||
}
|
}
|
||||||
else if (pnpRequest->PnPAction == StorStopDevice)
|
else if (pnpRequest->PnPAction == StorStopDevice)
|
||||||
{
|
{
|
||||||
|
@ -417,6 +484,7 @@ AhciHwResetBus (
|
||||||
__in ULONG PathId
|
__in ULONG PathId
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
STOR_LOCK_HANDLE lockhandle;
|
||||||
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
PAHCI_ADAPTER_EXTENSION adapterExtension;
|
||||||
|
|
||||||
DebugPrint("AhciHwResetBus()\n");
|
DebugPrint("AhciHwResetBus()\n");
|
||||||
|
@ -425,7 +493,15 @@ AhciHwResetBus (
|
||||||
|
|
||||||
if (IsPortValid(AdapterExtension, PathId))
|
if (IsPortValid(AdapterExtension, PathId))
|
||||||
{
|
{
|
||||||
// TODO: Reset Port
|
AhciZeroMemory(&lockhandle, sizeof(lockhandle));
|
||||||
|
|
||||||
|
// Acquire Lock
|
||||||
|
StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
|
||||||
|
|
||||||
|
// TODO: Perform port reset
|
||||||
|
|
||||||
|
// Release lock
|
||||||
|
StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -665,6 +741,182 @@ DriverEntry (
|
||||||
return status;
|
return status;
|
||||||
}// -- DriverEntry();
|
}// -- DriverEntry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name AhciProcessSrb
|
||||||
|
* @not_implemented
|
||||||
|
*
|
||||||
|
* Prepare Srb for IO processing
|
||||||
|
*
|
||||||
|
* @param PortExtension
|
||||||
|
* @param Srb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
AhciProcessSrb (
|
||||||
|
__in PAHCI_PORT_EXTENSION PortExtension,
|
||||||
|
__in PSCSI_REQUEST_BLOCK Srb
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DebugPrint("AhciProcessSrb()\n");
|
||||||
|
|
||||||
|
NT_ASSERT(Srb->PathId == PortExtension->PortNumber);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}// -- AhciProcessSrb();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name AhciActivatePort
|
||||||
|
* @not_implemented
|
||||||
|
*
|
||||||
|
* Program Port and populate command list
|
||||||
|
*
|
||||||
|
* @param PortExtension
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
AhciActivatePort (
|
||||||
|
__in PAHCI_PORT_EXTENSION PortExtension
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DebugPrint("AhciActivatePort()\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}// -- AhciActivatePort();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name AhciProcessIO
|
||||||
|
* @implemented
|
||||||
|
*
|
||||||
|
* Acquire Exclusive lock to port, populate pending commands to command List
|
||||||
|
* program controller's port to process new commands in command list.
|
||||||
|
*
|
||||||
|
* @param AdapterExtension
|
||||||
|
* @param PathId
|
||||||
|
* @param Srb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
AhciProcessIO (
|
||||||
|
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
|
||||||
|
__in UCHAR PathId,
|
||||||
|
__in PSCSI_REQUEST_BLOCK Srb
|
||||||
|
)
|
||||||
|
{
|
||||||
|
STOR_LOCK_HANDLE lockhandle;
|
||||||
|
PSCSI_REQUEST_BLOCK tmpSrb;
|
||||||
|
PAHCI_PORT_EXTENSION PortExtension;
|
||||||
|
ULONG commandSlotMask, occupiedSlots, slotIndex;
|
||||||
|
|
||||||
|
DebugPrint("AhciProcessIO()\n");
|
||||||
|
DebugPrint("\tPathId: %d\n", PathId);
|
||||||
|
|
||||||
|
PortExtension = &AdapterExtension->PortExtension[PathId];
|
||||||
|
|
||||||
|
NT_ASSERT(PathId < MAXIMUM_AHCI_PORT_COUNT);
|
||||||
|
|
||||||
|
// add Srb to queue
|
||||||
|
AddQueue(&PortExtension->SrbQueue, Srb);
|
||||||
|
|
||||||
|
if (PortExtension->IsActive == FALSE)
|
||||||
|
return; // we should wait for device to get active
|
||||||
|
|
||||||
|
AhciZeroMemory(&lockhandle, sizeof(lockhandle));
|
||||||
|
|
||||||
|
// Acquire Lock
|
||||||
|
StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
|
||||||
|
|
||||||
|
occupiedSlots = PortExtension->OccupiedSlots; // Busy command slots for given port
|
||||||
|
commandSlotMask = (1 << AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP)) - 1; // available slots mask
|
||||||
|
|
||||||
|
commandSlotMask = (commandSlotMask & ~occupiedSlots);
|
||||||
|
if(commandSlotMask != 0)
|
||||||
|
{
|
||||||
|
// iterate over HBA port slots
|
||||||
|
for (slotIndex = 0; slotIndex <= AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP); slotIndex++)
|
||||||
|
{
|
||||||
|
// find first free slot
|
||||||
|
if ((commandSlotMask & (1 << slotIndex)) != 0)
|
||||||
|
{
|
||||||
|
tmpSrb = RemoveQueue(&PortExtension->SrbQueue);
|
||||||
|
if (tmpSrb != NULL)
|
||||||
|
{
|
||||||
|
NT_ASSERT(Srb->PathId == PathId);
|
||||||
|
AhciProcessSrb(PortExtension, tmpSrb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// program HBA port
|
||||||
|
AhciActivatePort(PortExtension);
|
||||||
|
|
||||||
|
// Release Lock
|
||||||
|
StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}// -- AhciProcessIO();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
DebugPrint("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)
|
||||||
|
{
|
||||||
|
DebugPrint("\tEVPD Inquired\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugPrint("\tVPD Inquired\n");
|
||||||
|
|
||||||
|
DataBuffer = Srb->DataBuffer;
|
||||||
|
DataBufferLength = Srb->DataTransferLength;
|
||||||
|
|
||||||
|
if (DataBuffer == NULL)
|
||||||
|
{
|
||||||
|
return SRB_STATUS_INVALID_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
AhciZeroMemory(DataBuffer, DataBufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
|
||||||
|
return SRB_STATUS_SUCCESS;
|
||||||
|
}// -- DeviceInquiryRequest();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name AhciAdapterReset
|
* @name AhciAdapterReset
|
||||||
* @implemented
|
* @implemented
|
||||||
|
@ -744,6 +996,8 @@ AhciZeroMemory (
|
||||||
{
|
{
|
||||||
Buffer[i] = 0;
|
Buffer[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}// -- AhciZeroMemory();
|
}// -- AhciZeroMemory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -776,111 +1030,65 @@ IsPortValid (
|
||||||
}// -- IsPortValid()
|
}// -- IsPortValid()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name AhciProcessIO
|
* @name AddQueue
|
||||||
* @not_implemented
|
|
||||||
*
|
|
||||||
* Acquire Exclusive lock to port, populate pending commands to command List
|
|
||||||
* program controller's port to process new commands in command list.
|
|
||||||
*
|
|
||||||
* @param AdapterExtension
|
|
||||||
* @param pathId
|
|
||||||
* @param Srb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
AhciProcessIO (
|
|
||||||
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
|
|
||||||
__in UCHAR pathId
|
|
||||||
)
|
|
||||||
{
|
|
||||||
STOR_LOCK_HANDLE lockhandle;
|
|
||||||
PAHCI_PORT_EXTENSION PortExtension;
|
|
||||||
ULONG commandSlotMask, occupiedSlots, slotIndex;
|
|
||||||
|
|
||||||
DebugPrint("AhciProcessIO()\n");
|
|
||||||
DebugPrint("\tPathId: %d\n", pathId);
|
|
||||||
|
|
||||||
PortExtension = &AdapterExtension->PortExtension[pathId];
|
|
||||||
|
|
||||||
NT_ASSERT(pathId < MAXIMUM_AHCI_PORT_COUNT);
|
|
||||||
|
|
||||||
if (PortExtension->IsActive == FALSE)
|
|
||||||
return; // we should wait for device to get active
|
|
||||||
|
|
||||||
AhciZeroMemory(&lockhandle, sizeof(lockhandle));
|
|
||||||
|
|
||||||
// Acquire Lock
|
|
||||||
StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
|
|
||||||
|
|
||||||
occupiedSlots = PortExtension->OccupiedSlots; // Busy command slots for given port
|
|
||||||
commandSlotMask = (1 << AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP)) - 1; // available slots mask
|
|
||||||
|
|
||||||
commandSlotMask = (commandSlotMask & ~occupiedSlots);
|
|
||||||
if(commandSlotMask != 0)
|
|
||||||
{
|
|
||||||
for (slotIndex = 0; slotIndex <= AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP); slotIndex++)
|
|
||||||
{
|
|
||||||
// find first free slot
|
|
||||||
if ((commandSlotMask & (1 << slotIndex)) != 0)
|
|
||||||
{
|
|
||||||
// TODO: remove from queue and process it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release Lock
|
|
||||||
StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
|
|
||||||
}// -- AhciProcessIO();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name DeviceInquiryRequest
|
|
||||||
* @implemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* Tells wheather given port is implemented or not
|
* Add Srb to Queue
|
||||||
*
|
*
|
||||||
* @param AdapterExtension
|
* @param Queue
|
||||||
* @param Srb
|
* @param Srb
|
||||||
* @param Cdb
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* return STOR status for DeviceInquiryRequest
|
* return TRUE if Srb is successfully added to Queue
|
||||||
*
|
*
|
||||||
* @remark
|
|
||||||
* http://www.seagate.com/staticfiles/support/disc/manuals/Interface%20manuals/100293068c.pdf
|
|
||||||
*/
|
*/
|
||||||
ULONG
|
__inline
|
||||||
DeviceInquiryRequest (
|
BOOLEAN
|
||||||
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
|
AddQueue (
|
||||||
__in PSCSI_REQUEST_BLOCK Srb,
|
__inout PAHCI_QUEUE Queue,
|
||||||
__in PCDB Cdb
|
__in PVOID Srb
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PVOID DataBuffer;
|
NT_ASSERT(Queue->Head < MAXIMUM_QUEUE_BUFFER_SIZE);
|
||||||
ULONG DataBufferLength;
|
NT_ASSERT(Queue->Tail < MAXIMUM_QUEUE_BUFFER_SIZE);
|
||||||
|
|
||||||
DebugPrint("DeviceInquiryRequest()\n");
|
if (Queue->Head == ((Queue->Tail + 1) % MAXIMUM_QUEUE_BUFFER_SIZE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
// 3.6.1
|
Queue->Buffer[Queue->Head++] = Srb;
|
||||||
// If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data
|
Queue->Head %= MAXIMUM_QUEUE_BUFFER_SIZE;
|
||||||
if (Cdb->CDB6INQUIRY3.EnableVitalProductData == 0)
|
|
||||||
{
|
|
||||||
DebugPrint("\tEVPD Inquired\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DebugPrint("\tVPD Inquired\n");
|
|
||||||
|
|
||||||
DataBuffer = Srb->DataBuffer;
|
return TRUE;
|
||||||
DataBufferLength = Srb->DataTransferLength;
|
}// -- AddQueue();
|
||||||
|
|
||||||
if (DataBuffer == NULL)
|
/**
|
||||||
{
|
* @name RemoveQueue
|
||||||
return SRB_STATUS_INVALID_REQUEST;
|
* @implemented
|
||||||
}
|
*
|
||||||
|
* Remove and return Srb from Queue
|
||||||
|
*
|
||||||
|
* @param Queue
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* return Srb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__inline
|
||||||
|
PVOID
|
||||||
|
RemoveQueue (
|
||||||
|
__inout PAHCI_QUEUE Queue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PVOID Srb;
|
||||||
|
|
||||||
AhciZeroMemory(DataBuffer, DataBufferLength);
|
NT_ASSERT(Queue->Head < MAXIMUM_QUEUE_BUFFER_SIZE);
|
||||||
}
|
NT_ASSERT(Queue->Tail < MAXIMUM_QUEUE_BUFFER_SIZE);
|
||||||
|
|
||||||
AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
|
if (Queue->Head == Queue->Tail)
|
||||||
return SRB_STATUS_SUCCESS;
|
return NULL;
|
||||||
}// -- DeviceInquiryRequest();
|
|
||||||
|
Srb = Queue->Buffer[Queue->Tail++];
|
||||||
|
Queue->Tail %= MAXIMUM_QUEUE_BUFFER_SIZE;
|
||||||
|
|
||||||
|
return Srb;
|
||||||
|
}// -- RemoveQueue();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
|
|
||||||
#define MAXIMUM_AHCI_PORT_COUNT 12
|
#define MAXIMUM_AHCI_PORT_COUNT 12
|
||||||
|
#define MAXIMUM_QUEUE_BUFFER_SIZE 255
|
||||||
#define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB
|
#define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB
|
||||||
|
|
||||||
// section 3.1.2
|
// section 3.1.2
|
||||||
|
@ -32,6 +33,35 @@
|
||||||
// ---- Support Structures --- //
|
// ---- Support Structures --- //
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// section 3.3.5
|
||||||
|
typedef union _AHCI_INTERRUPT_STATUS
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG DHRS:1; //Device to Host Register FIS Interrupt
|
||||||
|
ULONG PSS :1; //PIO Setup FIS Interrupt
|
||||||
|
ULONG DSS :1; //DMA Setup FIS Interrupt
|
||||||
|
ULONG SDBS :1; //Set Device Bits Interrupt
|
||||||
|
ULONG UFS :1; //Unknown FIS Interrupt
|
||||||
|
ULONG DPS :1; //Descriptor Processed
|
||||||
|
ULONG PCS :1; //Port Connect Change Status
|
||||||
|
ULONG DMPS :1; //Device Mechanical Presence Status (DMPS)
|
||||||
|
ULONG Reserved :14;
|
||||||
|
ULONG PRCS :1; //PhyRdy Change Status
|
||||||
|
ULONG IPMS :1; //Incorrect Port Multiplier Status
|
||||||
|
ULONG OFS :1; //Overflow Status
|
||||||
|
ULONG Reserved2 :1;
|
||||||
|
ULONG INFS :1; //Interface Non-fatal Error Status
|
||||||
|
ULONG IFS :1; //Interface Fatal Error Status
|
||||||
|
ULONG HBDS :1; //Host Bus Data Error Status
|
||||||
|
ULONG HBFS :1; //Host Bus Fatal Error Status
|
||||||
|
ULONG TFES :1; //Task File Error Status
|
||||||
|
ULONG CPDS :1; //Cold Port Detect Status
|
||||||
|
};
|
||||||
|
|
||||||
|
ULONG Status;
|
||||||
|
} AHCI_INTERRUPT_STATUS;
|
||||||
|
|
||||||
typedef struct _AHCI_FIS_DMA_SETUP
|
typedef struct _AHCI_FIS_DMA_SETUP
|
||||||
{
|
{
|
||||||
ULONG ULONG0_1; // FIS_TYPE_DMA_SETUP
|
ULONG ULONG0_1; // FIS_TYPE_DMA_SETUP
|
||||||
|
@ -123,6 +153,13 @@ typedef struct _AHCI_SET_DEVICE_BITS_FIS
|
||||||
UCHAR Reserved5[4];
|
UCHAR Reserved5[4];
|
||||||
} AHCI_SET_DEVICE_BITS_FIS;
|
} AHCI_SET_DEVICE_BITS_FIS;
|
||||||
|
|
||||||
|
typedef struct _AHCI_QUEUE
|
||||||
|
{
|
||||||
|
PVOID Buffer[MAXIMUM_QUEUE_BUFFER_SIZE]; // because Storahci hold Srb queue of 255 size
|
||||||
|
ULONG Head;
|
||||||
|
ULONG Tail;
|
||||||
|
} AHCI_QUEUE, *PAHCI_QUEUE;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// --------------------------- //
|
// --------------------------- //
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
@ -202,6 +239,7 @@ typedef struct _AHCI_PORT_EXTENSION
|
||||||
ULONG OccupiedSlots; // slots to which we have already assigned task
|
ULONG OccupiedSlots; // slots to which we have already assigned task
|
||||||
BOOLEAN IsActive;
|
BOOLEAN IsActive;
|
||||||
PAHCI_PORT Port; // AHCI Port Infomation
|
PAHCI_PORT Port; // AHCI Port Infomation
|
||||||
|
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
|
||||||
|
@ -274,3 +312,16 @@ DeviceInquiryRequest (
|
||||||
__in PSCSI_REQUEST_BLOCK Srb,
|
__in PSCSI_REQUEST_BLOCK Srb,
|
||||||
__in PCDB Cdb
|
__in PCDB Cdb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
__inline
|
||||||
|
BOOLEAN
|
||||||
|
AddQueue (
|
||||||
|
__inout PAHCI_QUEUE Queue,
|
||||||
|
__in PVOID Srb
|
||||||
|
);
|
||||||
|
|
||||||
|
__inline
|
||||||
|
PVOID
|
||||||
|
RemoveQueue (
|
||||||
|
__inout PAHCI_QUEUE Queue
|
||||||
|
);
|
||||||
|
|
|
@ -65,7 +65,7 @@ HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
|
||||||
HKR,,TypesSupported,%REG_DWORD%,7
|
HKR,,TypesSupported,%REG_DWORD%,7
|
||||||
|
|
||||||
[Strings]
|
[Strings]
|
||||||
ROS = "ROS"
|
ROS = "ReactOS"
|
||||||
DeviceDesc = "AHCI SATA Driver"
|
DeviceDesc = "AHCI SATA Driver"
|
||||||
SATA_AHCI.DeviceDesc = "Standard SATA AHCI Controller"
|
SATA_AHCI.DeviceDesc = "Standard SATA AHCI Controller"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue