提交 2a7adff0 编写于 作者: T Tejun Heo 提交者: Jeff Garzik

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: NTejun Heo <tj@kernel.org>
Signed-off-by: NJeff Garzik <jgarzik@redhat.com>
上级 1b959c41
...@@ -2379,7 +2379,7 @@ void ata_sff_error_handler(struct ata_port *ap) ...@@ -2379,7 +2379,7 @@ void ata_sff_error_handler(struct ata_port *ap)
ata_reset_fn_t hardreset = ap->ops->hardreset; ata_reset_fn_t hardreset = ap->ops->hardreset;
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
unsigned long flags; unsigned long flags;
int thaw = 0; bool thaw = false;
qc = __ata_qc_from_tag(ap, ap->link.active_tag); qc = __ata_qc_from_tag(ap, ap->link.active_tag);
if (qc && !(qc->flags & ATA_QCFLAG_FAILED)) if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
...@@ -2405,15 +2405,22 @@ void ata_sff_error_handler(struct ata_port *ap) ...@@ -2405,15 +2405,22 @@ void ata_sff_error_handler(struct ata_port *ap)
if (qc->err_mask == AC_ERR_TIMEOUT if (qc->err_mask == AC_ERR_TIMEOUT
&& (host_stat & ATA_DMA_ERR)) { && (host_stat & ATA_DMA_ERR)) {
qc->err_mask = AC_ERR_HOST_BUS; qc->err_mask = AC_ERR_HOST_BUS;
thaw = 1; thaw = true;
} }
ap->ops->bmdma_stop(qc); ap->ops->bmdma_stop(qc);
}
ata_sff_sync(ap); /* FIXME: We don't need this */ /* if we're gonna thaw, make sure IRQ is clear */
if (thaw) {
ap->ops->sff_check_status(ap); ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap); ap->ops->sff_irq_clear(ap);
spin_unlock_irqrestore(ap->lock, flags);
ata_eh_thaw_port(ap);
spin_lock_irqsave(ap->lock, flags);
}
}
/* We *MUST* do FIFO draining before we issue a reset as several /* We *MUST* do FIFO draining before we issue a reset as several
* devices helpfully clear their internal state and will lock solid * devices helpfully clear their internal state and will lock solid
* if we touch the data port post reset. Pass qc in case anyone wants * 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,9 +2431,6 @@ void ata_sff_error_handler(struct ata_port *ap)
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
if (thaw)
ata_eh_thaw_port(ap);
/* PIO and DMA engines have been stopped, perform recovery */ /* PIO and DMA engines have been stopped, perform recovery */
/* Ignore ata_sff_softreset if ctl isn't accessible and /* Ignore ata_sff_softreset if ctl isn't accessible and
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册