Patchwork pata_bf54x: fix BMIDE status register emulation

login
register
mail settings
Submitter Zhang, Sonic
Date Dec. 31, 2011, 3:22 a.m.
Message ID <DB904C5425BA6F4E8424B3B51A1414D16D76860B88@NWD2CMBX1.ad.analog.com>
Download mbox | patch
Permalink /patch/133713/
State Not Applicable
Delegated to: David Miller
Headers show

Comments

Zhang, Sonic - Dec. 31, 2011, 3:22 a.m.
Hi Shtylyov,

After I review the BF54x ATAPI and DMA spec again, I have to NAK your following patch. The BF54x ATAPI DMA controller doesn't comply with INF-8038i.

Interrupts MULTI_DONE_INT, UDMAIN_DONE_INT and UDMAOUT_DONE_INT are generated by BF54x ATAPI host controller. They also indicate the completion of various types of ATAPI transfers.  So do interrupts MULTI_TERM_INT, UDMAIN_TERM_INT and UDMAOUT_TERM_INT, which indicate the device termination of the ATAPI DMA transfer.

In BF54x hardware reference manual:

After servicing the interrupt source associated with a bit, the user must
clear that interrupt source bit. ATA_DEV_INT is the interrupt generated by
the device. The rest of the interrupts are generated by the host. Either the
device or the host interrupt can be used by the firmware.

The PIO_DONE_INT, MULTI_DONE_INT, ULTRA_IN_DONE_INT, and
ULTRA_OUT_DONE_INT (W1C) bits indicate that interrupts have been
asserted on completion of various types of transfers.

The MULTI_TERM_INT (W1C) bit indicates that the interrupt has been
asserted on device terminate of the multiword DMA transfer.

The ULTRA_IN_TERM_INT and ULTRA_OUT_TERM_INT (W1C) bits indicate
that interrupts have been asserted on device termination of ultra DMA in
or out transfers.



Sonic


-----Original Message-----
From: Sergei Shtylyov [mailto:sshtylyov@ru.mvista.com]
Sent: Wednesday, December 28, 2011 11:37 PM
To: linux-ide@vger.kernel.org; jgarzik@pobox.com; Zhang, Sonic
Subject: [PATCH] pata_bf54x: fix BMIDE status register emulation

The author of this driver clearly wasn't familiar with the BMIDE specification
(also known as SFF-8038i) when he implemented the bmdma_status() method: first,
the interrupt bit of the BMIDE status register corresponds to nothing else but
INTRQ signal (ATAPI_DEV_INT here); second, the error bit is only set if the
controller encounters issue doing the bus master transfers, not on the DMA burst
termination interrupts like here (moreover, setting the error bit doesn't cause
an interrupt).

(The only thing I couldn't figure out is how to flush the FIFO to memory once
the interrupt happens as required by the mentioned spec.)

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>

---
The patch is against the current Linus' tree.
Sonic, if you still work in Analog Devices, please give this a try.

I looked over the driver, and it left pretty bad impression. In particular,
I highly doubt that the transfers with more than one S/G item can work. And
this is after the driver has been in the kernel for 4 years already...
Unfortunately, I have neither hardware nor much time to work on improving it...

 drivers/ata/pata_bf54x.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sergei Shtylyov - Dec. 31, 2011, 3:05 p.m.
Hello.

On 31-12-2011 7:22, Zhang, Sonic wrote:

> Hi Shtylyov,

    I prefer Sergei.
    And please wrap your messages at 80 characters or less.

> After I review the BF54x ATAPI and DMA spec again, I have to NAK your following patch.
> The BF54x ATAPI DMA controller doesn't comply with INF-8038i.

    If you are emulating SFF-8038i register interface (which you are doing by 
implementing "bmdma" set of libata methods -- and bmdma_status() method in 
perticular), you *have to comply*. Either comply, or don't do it at all.

> Interrupts MULTI_DONE_INT, UDMAIN_DONE_INT and UDMAOUT_DONE_INT are generated by BF54x ATAPI host controller. They also indicate the completion of various types of ATAPI transfers.  So do interrupts MULTI_TERM_INT, UDMAIN_TERM_INT and UDMAOUT_TERM_INT, which indicate the device termination of the ATAPI DMA transfer.

    Device can only terminate DMA burst at which point it's up to the host 
controller to decide whether it was the last burst or not. This can only be 
done with the help of the signals external to DMA interfacem, i.e. INTRQ.

> In BF54x hardware reference manual:

> After servicing the interrupt source associated with a bit, the user must
> clear that interrupt source bit. ATA_DEV_INT is the interrupt generated by
> the device. The rest of the interrupts are generated by the host. Either the
> device or the host interrupt can be used by the firmware.

> The PIO_DONE_INT, MULTI_DONE_INT, ULTRA_IN_DONE_INT, and
> ULTRA_OUT_DONE_INT (W1C) bits indicate that interrupts have been
> asserted on completion of various types of transfers.

> The MULTI_TERM_INT (W1C) bit indicates that the interrupt has been
> asserted on device terminate of the multiword DMA transfer.

> The ULTRA_IN_TERM_INT and ULTRA_OUT_TERM_INT (W1C) bits indicate
> that interrupts have been asserted on device termination of ultra DMA in
> or out transfers.

    I have read all that... it doesn't justify your NAK in any way. Just test 
the patch and report the result.

> Sonic

> -----Original Message-----
> From: Sergei Shtylyov [mailto:sshtylyov@ru.mvista.com]
> Sent: Wednesday, December 28, 2011 11:37 PM
> To: linux-ide@vger.kernel.org; jgarzik@pobox.com; Zhang, Sonic
> Subject: [PATCH] pata_bf54x: fix BMIDE status register emulation
>
> The author of this driver clearly wasn't familiar with the BMIDE specification
> (also known as SFF-8038i) when he implemented the bmdma_status() method: first,
> the interrupt bit of the BMIDE status register corresponds to nothing else but
> INTRQ signal (ATAPI_DEV_INT here); second, the error bit is only set if the
> controller encounters issue doing the bus master transfers, not on the DMA burst
> termination interrupts like here (moreover, setting the error bit doesn't cause
> an interrupt).
>
> (The only thing I couldn't figure out is how to flush the FIFO to memory once
> the interrupt happens as required by the mentioned spec.)
>
> Signed-off-by: Sergei Shtylyov<sshtylyov@ru.mvista.com>
>
> ---
> The patch is against the current Linus' tree.
> Sonic, if you still work in Analog Devices, please give this a try.
>
> I looked over the driver, and it left pretty bad impression. In particular,
> I highly doubt that the transfers with more than one S/G item can work. And
> this is after the driver has been in the kernel for 4 years already...
> Unfortunately, I have neither hardware nor much time to work on improving it...
>
>   drivers/ata/pata_bf54x.c |    8 ++------
>   1 file changed, 2 insertions(+), 6 deletions(-)
>
> Index: linux-2.6/drivers/ata/pata_bf54x.c
> ===================================================================
> --- linux-2.6.orig/drivers/ata/pata_bf54x.c
> +++ linux-2.6/drivers/ata/pata_bf54x.c
> @@ -1153,15 +1153,11 @@ static unsigned char bfin_bmdma_status(s
>   {
>          unsigned char host_stat = 0;
>          void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
> -       unsigned short int_status = ATAPI_GET_INT_STATUS(base);
>
> -       if (ATAPI_GET_STATUS(base)&  (MULTI_XFER_ON|ULTRA_XFER_ON))
> +       if (ATAPI_GET_STATUS(base)&  (MULTI_XFER_ON | ULTRA_XFER_ON))
>                  host_stat |= ATA_DMA_ACTIVE;
> -       if (int_status&  (MULTI_DONE_INT|UDMAIN_DONE_INT|UDMAOUT_DONE_INT|
> -               ATAPI_DEV_INT))
> +       if (ATAPI_GET_INT_STATUS(base)&  ATAPI_DEV_INT)
>                  host_stat |= ATA_DMA_INTR;
> -       if (int_status&  (MULTI_TERM_INT|UDMAIN_TERM_INT|UDMAOUT_TERM_INT))
> -               host_stat |= ATA_DMA_ERR|ATA_DMA_INTR;
>
>          dev_dbg(ap->dev, "ATAPI: host_stat=0x%x\n", host_stat);
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

Index: linux-2.6/drivers/ata/pata_bf54x.c
===================================================================
--- linux-2.6.orig/drivers/ata/pata_bf54x.c
+++ linux-2.6/drivers/ata/pata_bf54x.c
@@ -1153,15 +1153,11 @@  static unsigned char bfin_bmdma_status(s
 {
        unsigned char host_stat = 0;
        void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-       unsigned short int_status = ATAPI_GET_INT_STATUS(base);

-       if (ATAPI_GET_STATUS(base) & (MULTI_XFER_ON|ULTRA_XFER_ON))
+       if (ATAPI_GET_STATUS(base) & (MULTI_XFER_ON | ULTRA_XFER_ON))
                host_stat |= ATA_DMA_ACTIVE;
-       if (int_status & (MULTI_DONE_INT|UDMAIN_DONE_INT|UDMAOUT_DONE_INT|
-               ATAPI_DEV_INT))
+       if (ATAPI_GET_INT_STATUS(base) & ATAPI_DEV_INT)
                host_stat |= ATA_DMA_INTR;
-       if (int_status & (MULTI_TERM_INT|UDMAIN_TERM_INT|UDMAOUT_TERM_INT))
-               host_stat |= ATA_DMA_ERR|ATA_DMA_INTR;

        dev_dbg(ap->dev, "ATAPI: host_stat=0x%x\n", host_stat);