aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_pcmcia.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-03-24 06:23:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-03-24 22:48:26 -0400
commit3d47aa8e7e7b2aa09256590388aa8dddc79280f9 (patch)
tree82f4c85842e5e02489eb0533609dabb865e55198 /drivers/ata/pata_pcmcia.c
parentc0f2ee34a5a0b79fd98d965ad8ae765d4639bfa5 (diff)
[libata] Drain data on errors
If the device is signalling that there is data to drain after an error we should read the bytes out and throw them away. Without this some devices and controllers get wedged and don't recover. Based on earlier work by Mark Lord Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_pcmcia.c')
-rw-r--r--drivers/ata/pata_pcmcia.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index a5cbcc280b23..f4d009ed50ac 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -42,7 +42,7 @@
42 42
43 43
44#define DRV_NAME "pata_pcmcia" 44#define DRV_NAME "pata_pcmcia"
45#define DRV_VERSION "0.3.3" 45#define DRV_VERSION "0.3.5"
46 46
47/* 47/*
48 * Private data structure to glue stuff together 48 * Private data structure to glue stuff together
@@ -126,6 +126,37 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev,
126 return buflen; 126 return buflen;
127} 127}
128 128
129/**
130 * pcmcia_8bit_drain_fifo - Stock FIFO drain logic for SFF controllers
131 * @qc: command
132 *
133 * Drain the FIFO and device of any stuck data following a command
134 * failing to complete. In some cases this is neccessary before a
135 * reset will recover the device.
136 *
137 */
138
139void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc)
140{
141 int count;
142 struct ata_port *ap;
143
144 /* We only need to flush incoming data when a command was running */
145 if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
146 return;
147
148 ap = qc->ap;
149
150 /* Drain up to 64K of data before we give up this recovery method */
151 for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
152 && count++ < 65536;)
153 ioread8(ap->ioaddr.data_addr);
154
155 if (count)
156 ata_port_printk(ap, KERN_WARNING, "drained %d bytes to clear DRQ.\n",
157 count);
158
159}
129 160
130static struct scsi_host_template pcmcia_sht = { 161static struct scsi_host_template pcmcia_sht = {
131 ATA_PIO_SHT(DRV_NAME), 162 ATA_PIO_SHT(DRV_NAME),
@@ -143,6 +174,7 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
143 .sff_data_xfer = ata_data_xfer_8bit, 174 .sff_data_xfer = ata_data_xfer_8bit,
144 .cable_detect = ata_cable_40wire, 175 .cable_detect = ata_cable_40wire,
145 .set_mode = pcmcia_set_mode_8bit, 176 .set_mode = pcmcia_set_mode_8bit,
177 .drain_fifo = pcmcia_8bit_drain_fifo,
146}; 178};
147 179
148#define CS_CHECK(fn, ret) \ 180#define CS_CHECK(fn, ret) \