Commit b03e66a6be91f8389fcd902ab6c1563db1c9c06b

Authored by David Milburn
Committed by Jeff Garzik
1 parent cd705d5ad4

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: David Milburn <dmilburn@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

Showing 1 changed file with 35 additions and 0 deletions Side-by-side Diff

drivers/ata/sata_svw.c
... ... @@ -142,7 +142,40 @@
142 142 return 0;
143 143 }
144 144  
  145 +static int k2_sata_softreset(struct ata_link *link,
  146 + unsigned int *class, unsigned long deadline)
  147 +{
  148 + u8 dmactl;
  149 + void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
145 150  
  151 + dmactl = readb(mmio + ATA_DMA_CMD);
  152 +
  153 + /* Clear the start bit */
  154 + if (dmactl & ATA_DMA_START) {
  155 + dmactl &= ~ATA_DMA_START;
  156 + writeb(dmactl, mmio + ATA_DMA_CMD);
  157 + }
  158 +
  159 + return ata_sff_softreset(link, class, deadline);
  160 +}
  161 +
  162 +static int k2_sata_hardreset(struct ata_link *link,
  163 + unsigned int *class, unsigned long deadline)
  164 +{
  165 + u8 dmactl;
  166 + void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
  167 +
  168 + dmactl = readb(mmio + ATA_DMA_CMD);
  169 +
  170 + /* Clear the start bit */
  171 + if (dmactl & ATA_DMA_START) {
  172 + dmactl &= ~ATA_DMA_START;
  173 + writeb(dmactl, mmio + ATA_DMA_CMD);
  174 + }
  175 +
  176 + return sata_sff_hardreset(link, class, deadline);
  177 +}
  178 +
146 179 static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
147 180 {
148 181 struct ata_ioports *ioaddr = &ap->ioaddr;
... ... @@ -346,6 +379,8 @@
346 379  
347 380 static struct ata_port_operations k2_sata_ops = {
348 381 .inherits = &ata_bmdma_port_ops,
  382 + .softreset = k2_sata_softreset,
  383 + .hardreset = k2_sata_hardreset,
349 384 .sff_tf_load = k2_sata_tf_load,
350 385 .sff_tf_read = k2_sata_tf_read,
351 386 .sff_check_status = k2_stat_check_status,