提交 b03e66a6 编写于 作者: D David Milburn 提交者: Jeff Garzik

sata_svw: check DMA start bit before reset

If kdump is triggered with pending IO, controller may not respond causing
kdump to fail.

http://marc.info/?l=linux-ide&m=133032255424658&w=2

During error recovery ata_do_dev_read_id never completes due hang
in mmio_insw.

ata_do_dev_read_id
 ata_sff_data_xfer
  ioread16_rep
   mmio_insw

if DMA start bit is cleared before reset, PIO command is successful
and kdump succeeds.
Signed-off-by: NDavid Milburn <dmilburn@redhat.com>
Signed-off-by: NJeff Garzik <jgarzik@redhat.com>
上级 cd705d5a
......@@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link,
return 0;
}
static int k2_sata_softreset(struct ata_link *link,
unsigned int *class, unsigned long deadline)
{
u8 dmactl;
void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
dmactl = readb(mmio + ATA_DMA_CMD);
/* Clear the start bit */
if (dmactl & ATA_DMA_START) {
dmactl &= ~ATA_DMA_START;
writeb(dmactl, mmio + ATA_DMA_CMD);
}
return ata_sff_softreset(link, class, deadline);
}
static int k2_sata_hardreset(struct ata_link *link,
unsigned int *class, unsigned long deadline)
{
u8 dmactl;
void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
dmactl = readb(mmio + ATA_DMA_CMD);
/* Clear the start bit */
if (dmactl & ATA_DMA_START) {
dmactl &= ~ATA_DMA_START;
writeb(dmactl, mmio + ATA_DMA_CMD);
}
return sata_sff_hardreset(link, class, deadline);
}
static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
......@@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = {
static struct ata_port_operations k2_sata_ops = {
.inherits = &ata_bmdma_port_ops,
.softreset = k2_sata_softreset,
.hardreset = k2_sata_hardreset,
.sff_tf_load = k2_sata_tf_load,
.sff_tf_read = k2_sata_tf_read,
.sff_check_status = k2_stat_check_status,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册