Skip to content

Commit

Permalink
libata-sff: update bmdma host bus error handling
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed May 15, 2010
1 parent 1b959c4 commit 2a7adff
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions drivers/ata/libata-sff.c
Original file line number Diff line number Diff line change
Expand Up @@ -2379,7 +2379,7 @@ void ata_sff_error_handler(struct ata_port *ap)
ata_reset_fn_t hardreset = ap->ops->hardreset;
struct ata_queued_cmd *qc;
unsigned long flags;
int thaw = 0;
bool thaw = false;

qc = __ata_qc_from_tag(ap, ap->link.active_tag);
if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
Expand All @@ -2405,15 +2405,22 @@ void ata_sff_error_handler(struct ata_port *ap)
if (qc->err_mask == AC_ERR_TIMEOUT
&& (host_stat & ATA_DMA_ERR)) {
qc->err_mask = AC_ERR_HOST_BUS;
thaw = 1;
thaw = true;
}

ap->ops->bmdma_stop(qc);

/* if we're gonna thaw, make sure IRQ is clear */
if (thaw) {
ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap);

spin_unlock_irqrestore(ap->lock, flags);
ata_eh_thaw_port(ap);
spin_lock_irqsave(ap->lock, flags);
}
}

ata_sff_sync(ap); /* FIXME: We don't need this */
ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap);
/* We *MUST* do FIFO draining before we issue a reset as several
* devices helpfully clear their internal state and will lock solid
* if we touch the data port post reset. Pass qc in case anyone wants
Expand All @@ -2424,9 +2431,6 @@ void ata_sff_error_handler(struct ata_port *ap)

spin_unlock_irqrestore(ap->lock, flags);

if (thaw)
ata_eh_thaw_port(ap);

/* PIO and DMA engines have been stopped, perform recovery */

/* Ignore ata_sff_softreset if ctl isn't accessible and
Expand Down

0 comments on commit 2a7adff

Please sign in to comment.