ata_bmdma_* calls in libata-core.c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Jeff-
My driver (and our controller) actually does do DMA, using an off-controller DMAC (the ARM PL080 on the Versatile board -- our controller talks the DMA protocol over the AMBA/AHB bus). I have successfully implemented ->qc_prep(), ->bmdma_setup(), and ->bmdma_start(). These functions setup scatter-gather lists, configure the DMAC and kick off the DMAC respectively. All works. That said, I do run into ata_bmdma_status() and ata_bmdma_stop() in ata_qc_timeout().
I suggest all BMDMA calls become callbacks that the driver can set to its own functions or assign to wrapper functions implemented in libata-core.c that call the inline functions in libata.h. Should I do this?
-mat
-----Original Message-----
From: Jeff Garzik [mailto:[email protected]]
Sent: Wednesday, February 02, 2005 11:25 AM
To: [email protected]
Subject: Re: ata_bmdma_* calls in libata-core.c
Quoted 5 lines · Mat Loikkanen
Jeff-
Could we somehow eliminate the direct calls to ata_bmdma_*() functions in
libata-core.c? Specifically, what's getting in my way currently are the calls withinata_qc_timeout(), called byata_eng_timeout(). I can't use
the
Quoted 2 lines
Libata callback
ata_eng_timeout()since I'm not BMDMA. What would be the correct fix: Make these BMDMA calls no-ops? Have the functions check
that
Quoted 6 lines
ap->ioaddr.bmdma_addrdoesn't equal some bad value (0xcdcdcdcd)? Or make all these ata_bmdma_stop/ack_irq/status() overridable callbacks like bmdma_setup/start()? The last option may be the most flexible, in case a non-BMDMA driver (like mine) would like to do something relevant in their place. I will change the code and send a patch to you if you tell me what your preference is.
Quite honestly, libata error handling is very basic, and could stand to be improved.
On the "other side" of the transaction, the command submission side of things, libata is design so that it provides a standard IDE BMDMA interface. If drivers do not have a purely BMDMA interface (AHCI is a good example here), the driver overrides library functions with its own.
However, for non-DMA controllers (your situation), there does not appear to be a big problem: ata_eng_timeout() and ata_qc_timeout() correctly check qc->tf.protocol before calling BMDMA functions, except for one case:
/* ack bmdma irq events */
ata_bmdma_ack_irq(ap);This is called in the PIO/non-data paths. This is correct for most controllers, who want an IRQ ack on the BMDMA register even though its not a DMA command... but in your case, this is incorrect.
So,
1) Do you see problems other than the call to ata_bmdma_ack_irq() ?
2) Feel free to suggest a patch which works around this. Maybe an ATA_FLAG_BMDMA_ACK_IRQ for those controllers that must call ata_bmdma_ack_irq() on non-DMA paths.
Jeff
Quoted 3 lines · Mat Loikkanen
I suggest all BMDMA calls become callbacks that the driver can set to its own functions or assign to wrapper functions implemented in
libata-core.cthat call the inline functions inlibata.h. Should I do this?
Yeah, that works for me.
Jeff