So how can I handle PORT_CONNECT_STATUS_CHANGE Event And how to do a COMRESET.
The interrupt handling works well, I can ready data from Real Hardware if I do not COMRESET (But I cannot know which of the ports is ATAPI and the ATAPI Port on my laptop doesn't respond (I already know it is ATAPI))
Here is the code of the COMRESET :
Code: Select all
HbaPort->CommandStatus.Start = 0;
HbaPort->CommandStatus.FisReceiveEnable = 0;
while(HbaPort->CommandStatus.CurrentCommandSlot || HbaPort->CommandStatus.FisReceiveRunning);
Port->FirstD2h = 0;
// Some code allocating Received FIS & Command List ...
Port->Port->InterruptEnable.D2HRegisterFisInterruptEnable = 1;
Port->Port->InterruptEnable.PioSetupFisInterruptEnable = 1;
Port->Port->InterruptEnable.DmaSetupFisInterruptEnable = 1;
Port->Port->InterruptEnable.SetDeviceBitsFisInterruptEnable = 1;
Port->Port->InterruptEnable.UnknownFisInterruptEnable = 1;
Port->Port->InterruptEnable.DescriptorProcessedInterruptEnable = 1;
Port->Port->InterruptEnable.PortChangeInterruptEnable = 1;
Port->Port->InterruptEnable.DeviceMechanicalPresenceEnable = 1;
Port->Port->InterruptEnable.PhyRdyChangeInterruptEnable = 1;
Port->Port->InterruptEnable.IncorrectPortMultiplierEnable = 1;
Port->Port->InterruptEnable.OverflowEnable = 1;
Port->Port->InterruptEnable.InterfaceNonFatalErrorEnable = 1;
Port->Port->InterruptEnable.InterfaceFatalErrorEnable = 1;
Port->Port->InterruptEnable.HostBusDataErrorEnable = 1;
Port->Port->InterruptEnable.HostBusFatalErrorEnable = 1;
Port->Port->InterruptEnable.TaskFileErrorEnable = 1;
Port->Port->InterruptEnable.ColdPresenceDetectEnable = 1;
wr32(&Port->Port->SataError, -1); // Static function I made
Port->Port->CommandStatus.FisReceiveEnable = 1;
while(!Port->Port->CommandStatus.FisReceiveRunning);
BOOL DeviceDetected = 0;
if(Port->Ahci->Hba->HostCapabilities.SupportsStaggeredSpinup) {
Port->Port->CommandStatus.SpinupDevice = 1;
}
Port->Port->SataControl.DeviceDetectionInitialization = 1;
Sleep(3);
Port->Port->SataControl.DeviceDetectionInitialization = 0;
UINT Countdown = 20;
for(;;) {
// if(Port->FirstD2h && !HbaPort->SataStatus.DeviceDetection) break;
if(!Countdown) break;
Countdown--;
if(HbaPort->SataStatus.DeviceDetection == 3) {
if(Port->Ahci->Hba->HostCapabilities.SupportsStaggeredSpinup) {
}
DeviceDetected = 1;
break;
}
Sleep(1);
}
if(!DeviceDetected) {
if(Port->Ahci->Hba->HostCapabilities.SupportsStaggeredSpinup) {
Port->Port->CommandStatus.SpinupDevice = 0;
}
Port->DeviceDetected = 0;
return;
} else {
Port->DeviceDetected = 1;
// SystemDebugPrint(L"ATTACHED_DEVICE_ON_PORT");
}
// wait for first D2H FIS (Containing device signature)
Countdown = 25;
while(!Port->FirstD2h) {
Countdown--;
if(!Countdown) {
if(Port->Port->PortSignature.SectorCount == 0x101) break; // Port signnature received but no interrupt delivered
Port->DeviceDetected = 0;
return;
}
Sleep(1);
}
*(DWORD*)&Port->Port->SataError = -1; // Clear SATA_ERROR
if(*(DWORD*)&HbaPort->PortSignature == 0xEB140101) {
HbaPort->CommandStatus.DeviceIsAtapi = 1;
}
// Wait for device initialization (transfer of initial FIS & Device Signature...)
SystemDebugPrint(L"Port Signature : %x", HbaPort->PortSignature);
Port->Port->CommandStatus.FisReceiveEnable = 1;
Port->Port->CommandStatus.Start = 1;