How to tell if a PIO command is finished on AHCI Controller?

Programming, for all ages and all languages.
Post Reply
Jubba
Posts: 3
Joined: Thu May 08, 2014 1:31 am

How to tell if a PIO command is finished on AHCI Controller?

Post by Jubba »

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...???)
liaoo
Member
Member
Posts: 36
Joined: Wed Jun 13, 2012 8:37 pm

Re: How to tell if a PIO command is finished on AHCI Control

Post by liaoo »

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
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.
How do you set the interrupt status register to 0xFFFFFFFF ? (via memory write to set this register?)
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
No interrupts means "DPS in PxIS = 0" or "system(CPU) does not see the interrupt" ?
Jubba
Posts: 3
Joined: Thu May 08, 2014 1:31 am

Re: How to tell if a PIO command is finished on AHCI Control

Post by Jubba »

liaoo wrote:I think the "PIO command" you mentioned is PIO read commands, right ?(0xEC and 0x24 are all PIO "read")
Yes, they are PIO Data-In commands, which means they transfer data from device to host.
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)
I've tried on other AHCI controllers (the one I'm working with is the AsMedia 1061).

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 :)
liaoo
Member
Member
Posts: 36
Joined: Wed Jun 13, 2012 8:37 pm

Re: How to tell if a PIO command is finished on AHCI Control

Post by liaoo »

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
Does this means even PIO data-in command, this controller receives D2H when command completed ?
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.
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 !
recently I was able to solve my problem on the AsMedia 1061 using the CCC feature (Command Completion Coalescing)
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.

F.Y.I
Jubba
Posts: 3
Joined: Thu May 08, 2014 1:31 am

Re: How to tell if a PIO command is finished on AHCI Control

Post by Jubba »

liaoo wrote:Does this means even PIO data-in command, this controller receives D2H when command completed ?
Yes, it's pretty strange.
Jubba 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.
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 completes :mrgreen:
liaoo
Member
Member
Posts: 36
Joined: Wed Jun 13, 2012 8:37 pm

Re: How to tell if a PIO command is finished on AHCI Control

Post by liaoo »

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...
Post Reply