Commit dcd03447 authored by Akira Iguchi's avatar Akira Iguchi Committed by Jeff Garzik

pata_scc.c: small fixes (Workaround for errata A308)

This patch fixes some issues of the previous patch:
- Use mode_filter() hook to limit ATAPI UDMA mode
- "data loss" warning message
- handling of udma_mask
Signed-off-by: default avatarKou Ishizaki <kou.ishizaki@toshiba.co.jp>
Signed-off-by: default avatarAkira Iguchi <akira2.iguchi@toshiba.co.jp>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 028a2596
...@@ -238,12 +238,6 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) ...@@ -238,12 +238,6 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
else else
offset = 0; /* 100MHz */ 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) if (speed >= XFER_UDMA_0)
idx = speed - XFER_UDMA_0; idx = speed - XFER_UDMA_0;
else else
...@@ -264,6 +258,17 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) ...@@ -264,6 +258,17 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]);
} }
unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask)
{
/* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
if (adev->class == ATA_DEV_ATAPI &&
(mask & (0xE0 << ATA_SHIFT_UDMA))) {
printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
/** /**
* scc_tf_load - send taskfile registers to host controller * scc_tf_load - send taskfile registers to host controller
* @ap: Port to which output is sent * @ap: Port to which output is sent
...@@ -741,7 +746,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) ...@@ -741,7 +746,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)
return host_stat; return host_stat;
/* errata A252,A308 workaround: Step4 */ /* errata A252,A308 workaround: Step4 */
if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ) if ((ata_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ))
return (host_stat | ATA_DMA_INTR); return (host_stat | ATA_DMA_INTR);
/* errata A308 workaround Step5 */ /* errata A308 workaround Step5 */
...@@ -752,11 +757,11 @@ static u8 scc_bmdma_status (struct ata_port *ap) ...@@ -752,11 +757,11 @@ static u8 scc_bmdma_status (struct ata_port *ap)
if ((qc->tf.protocol == ATA_PROT_DMA && if ((qc->tf.protocol == ATA_PROT_DMA &&
qc->dev->xfer_mode > XFER_UDMA_4)) { qc->dev->xfer_mode > XFER_UDMA_4)) {
if (!(int_status & INTSTS_ACTEINT)) { if (!(int_status & INTSTS_ACTEINT)) {
printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n", printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n",
ap->print_id, retry); ap->print_id);
host_stat |= ATA_DMA_ERR; host_stat |= ATA_DMA_ERR;
if (retry++) if (retry++)
ap->udma_mask >>= 1; ap->udma_mask &= ~(1 << qc->dev->xfer_mode);
} else } else
retry = 0; retry = 0;
} }
...@@ -1016,7 +1021,7 @@ static const struct ata_port_operations scc_pata_ops = { ...@@ -1016,7 +1021,7 @@ static const struct ata_port_operations scc_pata_ops = {
.port_disable = ata_port_disable, .port_disable = ata_port_disable,
.set_piomode = scc_set_piomode, .set_piomode = scc_set_piomode,
.set_dmamode = scc_set_dmamode, .set_dmamode = scc_set_dmamode,
.mode_filter = ata_pci_default_filter, .mode_filter = scc_mode_filter,
.tf_load = scc_tf_load, .tf_load = scc_tf_load,
.tf_read = scc_tf_read, .tf_read = scc_tf_read,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment