Hi guys, this is my first post here!
How can I tell when/if a PIO command sent through an AHCI controller is finished (e.g.: ATA commands 0xEC or 0x24)? I mean, I can easily tell that a DMA command (e.g.: 0x25) is finished because the controller receives a D2H (device to host) Register FIS that sets an interrupt which my driver (KMDF, Windows 8.1 x64) handles in it's ISR and DPC and then I'm immediately ready to send the next command (or do nothing).
Instead, if I send a PIO command, all I receive are PIO setup FISes. As per SATA AHCI 1.3.1 Specification and SATA 3.1 Specifications, I can tell if a specific PIO Setup FIS is the one which describes the last data transfer of a PIO command looking at the E_Status field. If neither BSY nor DRQ bits are set, then the data transfer which will follow that PIO Setup FIS is the last for that PIO command. However, after the interrupt raised by the last PIO Setup FIS, no other interrupts are set, so I'm not notified when the command has effectively finished the execution.
To be sure, I've tried enabling all interrupt conditions on the port I'm doing the tests (set port interrupt status register to 0xFFFFFFFF). Still no interrupts.
I've tried setting the interrupt on completion bit in each of the PRDs of the Scatter Gather list associated with the command. Still no interrupts. (by the way, I was not able to receive any Descriptor Processed Interrupts even when I tried on DMA commands...???)
How to tell if a PIO command is finished on AHCI Controller?
Re: How to tell if a PIO command is finished on AHCI Control
I think the "PIO command" you mentioned is PIO read commands, right ?(0xEC and 0x24 are all PIO "read")
As I knew, for PIO write commands after command completion there is D2H sent from device to AHCI. Thus you can use this D2H to distinguish if this command completed.
(of course you have to enable the DHRE bit in PxIE register)
For PIO read commands, you can enable DPE(Descriptor Processed Interrupt Enable) in PxIE. Besides the I bit in last PRD entry should be set to 1 to generate "descriptor processed" interrupt in PxIS. If both DPS and DPE are 1 then the device should assert interrupt to the system via either MSI or Pin-based mode
As I knew, for PIO write commands after command completion there is D2H sent from device to AHCI. Thus you can use this D2H to distinguish if this command completed.
(of course you have to enable the DHRE bit in PxIE register)
For PIO read commands, you can enable DPE(Descriptor Processed Interrupt Enable) in PxIE. Besides the I bit in last PRD entry should be set to 1 to generate "descriptor processed" interrupt in PxIS. If both DPS and DPE are 1 then the device should assert interrupt to the system via either MSI or Pin-based mode
How do you set the interrupt status register to 0xFFFFFFFF ? (via memory write to set this register?)To be sure, I've tried enabling all interrupt conditions on the port I'm doing the tests (set port interrupt status register to 0xFFFFFFFF). Still no interrupts.
No interrupts means "DPS in PxIS = 0" or "system(CPU) does not see the interrupt" ?I've tried setting the interrupt on completion bit in each of the PRDs of the Scatter Gather list associated with the command. Still no interrupts
Re: How to tell if a PIO command is finished on AHCI Control
Yes, they are PIO Data-In commands, which means they transfer data from device to host.liaoo wrote:I think the "PIO command" you mentioned is PIO read commands, right ?(0xEC and 0x24 are all PIO "read")
I've tried on other AHCI controllers (the one I'm working with is the AsMedia 1061).liaoo wrote:As I knew, for PIO write commands after command completion there is D2H sent from device to AHCI. Thus you can use this D2H to distinguish if this command completed.
(of course you have to enable the DHRE bit in PxIE register)
On a Marvell 9230 controller, no matter the command type (DMA or PIO), the controller reports the end of the command with an interrupt raised by D2H FISes. So, no problem.
On a Intel 7 Series/C216 Chipset Family controller, for DMA commands I receive the interrupt raised by the arrival of the D2H FIS which indicates the end of the command. For PIO commands, I only receive PIO Setup FISes. On this controller I've tried enabling the DPE and I receive interrupts (PxDPS set to 1). However, it's not certain that after I receive a Descriptor Processed interrupt the command is completed because if I read the PxCI register, the bit associated with the slot I used to send the command sometimes it's 0 (as expected) and sometimes it's 1. (however, SATA AHCI 1.3 Specifications strongly discourages the use of Descriptor Processed interrupts to establish when a command is finished)
BY THE WAY...
recently I was able to solve my problem on the AsMedia 1061 using the CCC feature (Command Completion Coalescing)
(the Intel controller does not support the CCC feature, I wonder what would be the correct way of telling when a PIO command is completed on that controller...)
Thanks anyway for your answer
Re: How to tell if a PIO command is finished on AHCI Control
Does this means even PIO data-in command, this controller receives D2H when command completed ?On a Marvell 9230 controller, no matter the command type (DMA or PIO), the controller reports the end of the command with an interrupt raised by D2H FISes. So, no problem
Based on my experience, assume there are 5 PRD entries for this command and we use DPS/DPE to identify if command completed then you should only set "I" bit of the last PRD to 1(that is, for PRD[4] only, other I bits are cleared). And you can distinguish if this command is completed. Maybe the best way is continuously checking if PxCI bit[x] is 0 or not(where x is the slot for command submission) or check if PRDBC = expected value !However, it's not certain that after I receive a Descriptor Processed interrupt the command is completed because if I read the PxCI register, the bit associated with the slot I used to send the command sometimes it's 0 (as expected) and sometimes it's 1.
Not all AHCI controller support CCC and the reason why you can solve this might be due to below:recently I was able to solve my problem on the AsMedia 1061 using the CCC feature (Command Completion Coalescing)
hCccComplete is incremented and there are no more commands outstanding on the selected ports for command completion coalescing and CCC_CTL.CC != 0.
F.Y.I
Re: How to tell if a PIO command is finished on AHCI Control
Yes, it's pretty strange.liaoo wrote:Does this means even PIO data-in command, this controller receives D2H when command completed ?
The CCC feature solves the problem because you can set it to send an interrupt every X commands have completed on the ports you have set to be part of the CCC feature. If you set X to 1, then you get an interrupt each time a command completesJubba wrote:Not all AHCI controller support CCC and the reason why you can solve this might be due to below:
hCccComplete is incremented and there are no more commands outstanding on the selected ports for command completion coalescing and CCC_CTL.CC != 0.
Re: How to tell if a PIO command is finished on AHCI Control
As I knew, if CCC_CTL.CC is set to Ex. 2 in your case then finally there will be one interrupt generated due to the interrupt condition I quoted.
And for the PIO data-in command, the transfer sequence might be as follows:
- issue command on slot x
- fetch command header
- fetch command FIS
(... below 4 repeats until all data transfer done...)
- send PIO setup FIS // the transfer count here can be configured
- fetch PRD entries
- data transfer
- update PRDBC
Thus maybe you can check if PRDBC reaches the expected value...
And for the PIO data-in command, the transfer sequence might be as follows:
- issue command on slot x
- fetch command header
- fetch command FIS
(... below 4 repeats until all data transfer done...)
- send PIO setup FIS // the transfer count here can be configured
- fetch PRD entries
- data transfer
- update PRDBC
Thus maybe you can check if PRDBC reaches the expected value...