mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
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: Kou Ishizaki <kou.ishizaki@toshiba.co.jp> Signed-off-by: Akira Iguchi <akira2.iguchi@toshiba.co.jp> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
028a259633
commit
dcd0344775
1 changed files with 16 additions and 11 deletions
|
@ -238,12 +238,6 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
|
|||
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
|
||||
|
@ -264,6 +258,17 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
|
|||
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
|
||||
* @ap: Port to which output is sent
|
||||
|
@ -741,7 +746,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)
|
|||
return host_stat;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* errata A308 workaround Step5 */
|
||||
|
@ -752,11 +757,11 @@ static u8 scc_bmdma_status (struct ata_port *ap)
|
|||
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);
|
||||
printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n",
|
||||
ap->print_id);
|
||||
host_stat |= ATA_DMA_ERR;
|
||||
if (retry++)
|
||||
ap->udma_mask >>= 1;
|
||||
ap->udma_mask &= ~(1 << qc->dev->xfer_mode);
|
||||
} else
|
||||
retry = 0;
|
||||
}
|
||||
|
@ -1016,7 +1021,7 @@ static const struct ata_port_operations scc_pata_ops = {
|
|||
.port_disable = ata_port_disable,
|
||||
.set_piomode = scc_set_piomode,
|
||||
.set_dmamode = scc_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
.mode_filter = scc_mode_filter,
|
||||
|
||||
.tf_load = scc_tf_load,
|
||||
.tf_read = scc_tf_read,
|
||||
|
|
Loading…
Reference in a new issue