aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_svw.c
diff options
context:
space:
mode:
authorDavid Milburn <dmilburn@redhat.com>2012-10-29 19:00:22 -0400
committerJeff Garzik <jgarzik@redhat.com>2012-11-15 23:54:41 -0500
commitb03e66a6be91f8389fcd902ab6c1563db1c9c06b (patch)
tree97049500a3dd0fd3c7c7801d5f6a697b006f1fb1 /drivers/ata/sata_svw.c
parentcd705d5ad49bb8894dda2726dcaef8f63ddeba43 (diff)
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>
Diffstat (limited to 'drivers/ata/sata_svw.c')
-rw-r--r--drivers/ata/sata_svw.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 44a4256533e1..08608de87e4e 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link,
142 return 0; 142 return 0;
143} 143}
144 144
145static 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;
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
162static 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}
145 178
146static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) 179static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
147{ 180{
@@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = {
346 379
347static struct ata_port_operations k2_sata_ops = { 380static struct ata_port_operations k2_sata_ops = {
348 .inherits = &ata_bmdma_port_ops, 381 .inherits = &ata_bmdma_port_ops,
382 .softreset = k2_sata_softreset,
383 .hardreset = k2_sata_hardreset,
349 .sff_tf_load = k2_sata_tf_load, 384 .sff_tf_load = k2_sata_tf_load,
350 .sff_tf_read = k2_sata_tf_read, 385 .sff_tf_read = k2_sata_tf_read,
351 .sff_check_status = k2_stat_check_status, 386 .sff_check_status = k2_stat_check_status,