* [PATCH] pata_scc.c: Workaround for errata A308
@ 2007-07-10 9:29 Akira Iguchi
2007-07-13 15:45 ` Alan Cox
0 siblings, 1 reply; 3+ messages in thread
From: Akira Iguchi @ 2007-07-10 9:29 UTC (permalink / raw)
To: jeff; +Cc: kou.ishizaki, linux-ide
Workaround for errata A308: turn down the UDMA mode and retry
the DMA command when the data lost condition is detected.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Signed-off-by: Akira Iguchi <akira2.iguchi@toshiba.co.jp>
---
diff -purN -X linux-powerpc-git/Documentation/dontdiff linux-powerpc-git/drivers/ata/pata_scc.c linux-powerpc-git.mod/drivers/ata/pata_scc.c
--- linux-powerpc-git/drivers/ata/pata_scc.c 2007-06-11 12:03:24.000000000 +0900
+++ linux-powerpc-git.mod/drivers/ata/pata_scc.c 2007-07-10 17:13:01.000000000 +0900
@@ -238,6 +238,12 @@ static void scc_set_dmamode (struct ata_
else
offset = 0; /* 100MHz */
+ /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
+ if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) {
+ printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
+ speed = XFER_UDMA_4;
+ }
+
if (speed >= XFER_UDMA_0)
idx = speed - XFER_UDMA_0;
else
@@ -724,22 +730,36 @@ static void scc_bmdma_stop (struct ata_q
static u8 scc_bmdma_status (struct ata_port *ap)
{
- u8 host_stat;
void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
- host_stat = in_be32(mmio + SCC_DMA_STATUS);
-
- /* Workaround for PTERADD: emulate DMA_INTR when
- * - IDE_STATUS[ERR] = 1
- * - INT_STATUS[INTRQ] = 1
- * - DMA_STATUS[IORACTA] = 1
- */
- if (!(host_stat & ATA_DMA_INTR)) {
- u32 int_status = in_be32(mmio + SCC_DMA_INTST);
- if (ata_altstatus(ap) & ATA_ERR &&
- int_status & INTSTS_INTRQ &&
- host_stat & ATA_DMA_ACTIVE)
- host_stat |= ATA_DMA_INTR;
+ u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
+ u32 int_status = in_be32(mmio + SCC_DMA_INTST);
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+ static int retry = 0;
+
+ /* return if IOS_SS is cleared */
+ if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START))
+ return host_stat;
+
+ /* errata A252,A308 workaround: Step4 */
+ if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ)
+ return (host_stat | ATA_DMA_INTR);
+
+ /* errata A308 workaround Step5 */
+ if (int_status & INTSTS_IOIRQS) {
+ host_stat |= ATA_DMA_INTR;
+
+ /* We don't check ATAPI DMA because it is limited to UDMA4 */
+ if ((qc->tf.protocol == ATA_PROT_DMA &&
+ qc->dev->xfer_mode > XFER_UDMA_4)) {
+ if (!(int_status & INTSTS_ACTEINT)) {
+ printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n",
+ ap->print_id, retry);
+ host_stat |= ATA_DMA_ERR;
+ if (retry++)
+ ap->udma_mask >>= 1;
+ } else
+ retry = 0;
+ }
}
return host_stat;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] pata_scc.c: Workaround for errata A308
[not found] <200707100929.l6A9TOf3017780@toshiba.co.jp>
@ 2007-07-11 1:38 ` Jeff Garzik
0 siblings, 0 replies; 3+ messages in thread
From: Jeff Garzik @ 2007-07-11 1:38 UTC (permalink / raw)
To: Akira Iguchi; +Cc: kou.ishizaki, linux-ide
Akira Iguchi wrote:
> Workaround for errata A308: turn down the UDMA mode and retry
> the DMA command when the data lost condition is detected.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
> Signed-off-by: Akira Iguchi <akira2.iguchi@toshiba.co.jp>
applied
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] pata_scc.c: Workaround for errata A308
2007-07-10 9:29 Akira Iguchi
@ 2007-07-13 15:45 ` Alan Cox
0 siblings, 0 replies; 3+ messages in thread
From: Alan Cox @ 2007-07-13 15:45 UTC (permalink / raw)
To: Akira Iguchi; +Cc: jeff, kou.ishizaki, linux-ide
> +++ linux-powerpc-git.mod/drivers/ata/pata_scc.c 2007-07-10 17:13:01.000000000 +0900
> @@ -238,6 +238,12 @@ static void scc_set_dmamode (struct ata_
> else
> offset = 0; /* 100MHz */
>
> + /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
> + if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) {
> + printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
> + speed = XFER_UDMA_4;
> + }
> +
NAK
You should not be modifying the speed you set in set_dmamode. Use the
mode_filter hook to mask the higher modes for ATAPI instead.
> + /* errata A252,A308 workaround: Step4 */
> + if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ)
Can we have more brackets here for clarity ?
> + /* We don't check ATAPI DMA because it is limited to UDMA4 */
> + if ((qc->tf.protocol == ATA_PROT_DMA &&
> + qc->dev->xfer_mode > XFER_UDMA_4)) {
> + if (!(int_status & INTSTS_ACTEINT)) {
> + printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n",
> + ap->print_id, retry);
"data loss occurred", and even that sounds veyr scary so we should
probably try a more friendly message indicating that the user data has
not been lost but that the operation failed
> + host_stat |= ATA_DMA_ERR;
> + if (retry++)
> + ap->udma_mask >>= 1;
NAK - you don't know that you can safely mess with modes this way.
udma_mask might contain holes. You need to do ap->udma_mask &= ~(1 <<
current UDMA mode);
Alan
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-07-13 15:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <200707100929.l6A9TOf3017780@toshiba.co.jp>
2007-07-11 1:38 ` [PATCH] pata_scc.c: Workaround for errata A308 Jeff Garzik
2007-07-10 9:29 Akira Iguchi
2007-07-13 15:45 ` Alan Cox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).