On 01/04/2010 11:15 AM, Russell King wrote:
It goes on to say that the interrupt status bit in the BM-DMA status
register will only be set after buffered data has been transferred -
which means reading the altstatus register to determine when the device
has finished would give a premature indication and doesn't take any
account of the BM-DMA buffering.
So I think Jeff is not right on the "must read altstatus" point.
I would not be surprised if lots of host controllers were actually buggy
in respect of reading any ATA device register mid-transfer - firstly a
started UDMA operation can't be stopped before at least one word has been
transferred, nor can it be stopped without first transferring the CRC
bytes. That's an awful lot of logic (and overhead) to be randomly
interacting with due to other shared devices interrupt activity.
Reading the BM-DMA status register (or equivalent on hosts) seems to be
the right way to tell if an interrupt is pending.
libata already does that, as does IDE:
case HSM_ST_LAST:
if (qc->tf.protocol == ATA_PROT_DMA ||
qc->tf.protocol == ATAPI_PROT_DMA) {
/* check status of DMA engine */
host_stat = ap->ops->bmdma_status(ap);
VPRINTK("ata%u: host_stat 0x%X\n",
ap->print_id, host_stat);
/* if it's not our irq... */
if (!(host_stat & ATA_DMA_INTR))
goto idle_irq;
[...]
/* check main status, clearing INTRQ if needed */
status = ata_sff_irq_status(ap); <-- reads AltStatus here
if (status & ATA_BUSY)
goto idle_irq;
IDE driver has basically the same logic in drive_is_ready()
I never said "must" read, I was only responding to the notion that
touching AltStatus at all, in general, was a violation of the ATA spec.
IFF there is a DMA status register available to be checked, and IFF
the transfer is DMA, then we do check that first.
Jeff
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html