aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-05-10 15:41:28 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-05-14 22:38:44 -0400
commit2a7adff09ac3dd3d1facaf92b4a8cc1b92d370b6 (patch)
treea2c41f4ee10893795dbd04215798a2469bb994ae /drivers/ata
parent1b959c412bbf38ce0fa658183f72027ca8331ee3 (diff)
libata-sff: update bmdma host bus error handling
* Clearing IRQ from ata_sff_error_handler() is necessary only when the port is gonna be thawed before performing EH actions and some controllers don't like being accessed after certain failure modes until they're reset. Clear IRQ iff the port is being thawed. * When the controller succesfully indicated bus error, the point of thawing doesn't matter. Move thawing inside bmdma part of EH. This is a bit ugly but will ease code reorganization later. * Remove the unneeded ata_sff_sync(). Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-sff.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 3cc385dbfe2a..a4700af43d10 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2379,7 +2379,7 @@ void ata_sff_error_handler(struct ata_port *ap)
2379 ata_reset_fn_t hardreset = ap->ops->hardreset; 2379 ata_reset_fn_t hardreset = ap->ops->hardreset;
2380 struct ata_queued_cmd *qc; 2380 struct ata_queued_cmd *qc;
2381 unsigned long flags; 2381 unsigned long flags;
2382 int thaw = 0; 2382 bool thaw = false;
2383 2383
2384 qc = __ata_qc_from_tag(ap, ap->link.active_tag); 2384 qc = __ata_qc_from_tag(ap, ap->link.active_tag);
2385 if (qc && !(qc->flags & ATA_QCFLAG_FAILED)) 2385 if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
@@ -2405,15 +2405,22 @@ void ata_sff_error_handler(struct ata_port *ap)
2405 if (qc->err_mask == AC_ERR_TIMEOUT 2405 if (qc->err_mask == AC_ERR_TIMEOUT
2406 && (host_stat & ATA_DMA_ERR)) { 2406 && (host_stat & ATA_DMA_ERR)) {
2407 qc->err_mask = AC_ERR_HOST_BUS; 2407 qc->err_mask = AC_ERR_HOST_BUS;
2408 thaw = 1; 2408 thaw = true;
2409 } 2409 }
2410 2410
2411 ap->ops->bmdma_stop(qc); 2411 ap->ops->bmdma_stop(qc);
2412
2413 /* if we're gonna thaw, make sure IRQ is clear */
2414 if (thaw) {
2415 ap->ops->sff_check_status(ap);
2416 ap->ops->sff_irq_clear(ap);
2417
2418 spin_unlock_irqrestore(ap->lock, flags);
2419 ata_eh_thaw_port(ap);
2420 spin_lock_irqsave(ap->lock, flags);
2421 }
2412 } 2422 }
2413 2423
2414 ata_sff_sync(ap); /* FIXME: We don't need this */
2415 ap->ops->sff_check_status(ap);
2416 ap->ops->sff_irq_clear(ap);
2417 /* We *MUST* do FIFO draining before we issue a reset as several 2424 /* We *MUST* do FIFO draining before we issue a reset as several
2418 * devices helpfully clear their internal state and will lock solid 2425 * devices helpfully clear their internal state and will lock solid
2419 * if we touch the data port post reset. Pass qc in case anyone wants 2426 * if we touch the data port post reset. Pass qc in case anyone wants
@@ -2424,9 +2431,6 @@ void ata_sff_error_handler(struct ata_port *ap)
2424 2431
2425 spin_unlock_irqrestore(ap->lock, flags); 2432 spin_unlock_irqrestore(ap->lock, flags);
2426 2433
2427 if (thaw)
2428 ata_eh_thaw_port(ap);
2429
2430 /* PIO and DMA engines have been stopped, perform recovery */ 2434 /* PIO and DMA engines have been stopped, perform recovery */
2431 2435
2432 /* Ignore ata_sff_softreset if ctl isn't accessible and 2436 /* Ignore ata_sff_softreset if ctl isn't accessible and