diff options
| -rw-r--r-- | drivers/ata/libata-sff.c | 45 | ||||
| -rw-r--r-- | drivers/ata/pata_pcmcia.c | 34 | ||||
| -rw-r--r-- | include/linux/libata.h | 3 |
3 files changed, 79 insertions, 3 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index f93dc029dfde..9a10cb055ac2 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
| @@ -52,6 +52,7 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
| 52 | .softreset = ata_sff_softreset, | 52 | .softreset = ata_sff_softreset, |
| 53 | .hardreset = sata_sff_hardreset, | 53 | .hardreset = sata_sff_hardreset, |
| 54 | .postreset = ata_sff_postreset, | 54 | .postreset = ata_sff_postreset, |
| 55 | .drain_fifo = ata_sff_drain_fifo, | ||
| 55 | .error_handler = ata_sff_error_handler, | 56 | .error_handler = ata_sff_error_handler, |
| 56 | .post_internal_cmd = ata_sff_post_internal_cmd, | 57 | .post_internal_cmd = ata_sff_post_internal_cmd, |
| 57 | 58 | ||
| @@ -2199,6 +2200,39 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes) | |||
| 2199 | EXPORT_SYMBOL_GPL(ata_sff_postreset); | 2200 | EXPORT_SYMBOL_GPL(ata_sff_postreset); |
| 2200 | 2201 | ||
| 2201 | /** | 2202 | /** |
| 2203 | * ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers | ||
| 2204 | * @qc: command | ||
| 2205 | * | ||
| 2206 | * Drain the FIFO and device of any stuck data following a command | ||
| 2207 | * failing to complete. In some cases this is neccessary before a | ||
| 2208 | * reset will recover the device. | ||
| 2209 | * | ||
| 2210 | */ | ||
| 2211 | |||
| 2212 | void ata_sff_drain_fifo(struct ata_queued_cmd *qc) | ||
| 2213 | { | ||
| 2214 | int count; | ||
| 2215 | struct ata_port *ap; | ||
| 2216 | |||
| 2217 | /* We only need to flush incoming data when a command was running */ | ||
| 2218 | if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE) | ||
| 2219 | return; | ||
| 2220 | |||
| 2221 | ap = qc->ap; | ||
| 2222 | /* Drain up to 64K of data before we give up this recovery method */ | ||
| 2223 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) | ||
| 2224 | && count < 32768; count++) | ||
| 2225 | ioread16(ap->ioaddr.data_addr); | ||
| 2226 | |||
| 2227 | /* Can become DEBUG later */ | ||
| 2228 | if (count) | ||
| 2229 | ata_port_printk(ap, KERN_DEBUG, | ||
| 2230 | "drained %d bytes to clear DRQ.\n", count); | ||
| 2231 | |||
| 2232 | } | ||
| 2233 | EXPORT_SYMBOL_GPL(ata_sff_drain_fifo); | ||
| 2234 | |||
| 2235 | /** | ||
| 2202 | * ata_sff_error_handler - Stock error handler for BMDMA controller | 2236 | * ata_sff_error_handler - Stock error handler for BMDMA controller |
| 2203 | * @ap: port to handle error for | 2237 | * @ap: port to handle error for |
| 2204 | * | 2238 | * |
| @@ -2239,7 +2273,8 @@ void ata_sff_error_handler(struct ata_port *ap) | |||
| 2239 | * really a timeout event, adjust error mask and | 2273 | * really a timeout event, adjust error mask and |
| 2240 | * cancel frozen state. | 2274 | * cancel frozen state. |
| 2241 | */ | 2275 | */ |
| 2242 | if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) { | 2276 | if (qc->err_mask == AC_ERR_TIMEOUT |
| 2277 | && (host_stat & ATA_DMA_ERR)) { | ||
| 2243 | qc->err_mask = AC_ERR_HOST_BUS; | 2278 | qc->err_mask = AC_ERR_HOST_BUS; |
| 2244 | thaw = 1; | 2279 | thaw = 1; |
| 2245 | } | 2280 | } |
| @@ -2250,6 +2285,13 @@ void ata_sff_error_handler(struct ata_port *ap) | |||
| 2250 | ata_sff_sync(ap); /* FIXME: We don't need this */ | 2285 | ata_sff_sync(ap); /* FIXME: We don't need this */ |
| 2251 | ap->ops->sff_check_status(ap); | 2286 | ap->ops->sff_check_status(ap); |
| 2252 | ap->ops->sff_irq_clear(ap); | 2287 | ap->ops->sff_irq_clear(ap); |
| 2288 | /* We *MUST* do FIFO draining before we issue a reset as several | ||
| 2289 | * devices helpfully clear their internal state and will lock solid | ||
| 2290 | * if we touch the data port post reset. Pass qc in case anyone wants | ||
| 2291 | * to do different PIO/DMA recovery or has per command fixups | ||
| 2292 | */ | ||
| 2293 | if (ap->ops->drain_fifo) | ||
| 2294 | ap->ops->drain_fifo(qc); | ||
| 2253 | 2295 | ||
| 2254 | spin_unlock_irqrestore(ap->lock, flags); | 2296 | spin_unlock_irqrestore(ap->lock, flags); |
| 2255 | 2297 | ||
| @@ -2959,4 +3001,3 @@ out: | |||
| 2959 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); | 3001 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); |
| 2960 | 3002 | ||
| 2961 | #endif /* CONFIG_PCI */ | 3003 | #endif /* CONFIG_PCI */ |
| 2962 | |||
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 | |||
| 139 | void 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 | ||
| 130 | static struct scsi_host_template pcmcia_sht = { | 161 | static 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) \ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 19af7d22a7f8..3a07a32dfc2e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -836,6 +836,8 @@ struct ata_port_operations { | |||
| 836 | void (*bmdma_start)(struct ata_queued_cmd *qc); | 836 | void (*bmdma_start)(struct ata_queued_cmd *qc); |
| 837 | void (*bmdma_stop)(struct ata_queued_cmd *qc); | 837 | void (*bmdma_stop)(struct ata_queued_cmd *qc); |
| 838 | u8 (*bmdma_status)(struct ata_port *ap); | 838 | u8 (*bmdma_status)(struct ata_port *ap); |
| 839 | |||
| 840 | void (*drain_fifo)(struct ata_queued_cmd *qc); | ||
| 839 | #endif /* CONFIG_ATA_SFF */ | 841 | #endif /* CONFIG_ATA_SFF */ |
| 840 | 842 | ||
| 841 | ssize_t (*em_show)(struct ata_port *ap, char *buf); | 843 | ssize_t (*em_show)(struct ata_port *ap, char *buf); |
| @@ -1587,6 +1589,7 @@ extern int ata_sff_softreset(struct ata_link *link, unsigned int *classes, | |||
| 1587 | extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class, | 1589 | extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class, |
| 1588 | unsigned long deadline); | 1590 | unsigned long deadline); |
| 1589 | extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes); | 1591 | extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes); |
| 1592 | extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc); | ||
| 1590 | extern void ata_sff_error_handler(struct ata_port *ap); | 1593 | extern void ata_sff_error_handler(struct ata_port *ap); |
| 1591 | extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc); | 1594 | extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc); |
| 1592 | extern int ata_sff_port_start(struct ata_port *ap); | 1595 | extern int ata_sff_port_start(struct ata_port *ap); |
