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

libata: move EH repeat reporting into ata_eh_report()

EH is sometimes repeated without any error or action.  For example,
this happens when probing IDENTIFY fails because of a phantom device.
In these cases, all the repeated EH does is making sure there is no
unhandled error or pending action and return.  This repeation is
necessary to avoid losing any event which occurred while EH was in
progress.

Unfortunately, this dry run causes annonying "EH pending after
completion" message.  This patch moves the repeat reporting into
ata_eh_report() such that it's more compact and skipped on dry runs.
Signed-off-by: NTejun Heo <htejun@gmail.com>
Cc: Mikael Pettersson <mikep@it.uu.se>
Signed-off-by: NJeff Garzik <jeff@garzik.org>
上级 cbcdd875
...@@ -358,7 +358,7 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) ...@@ -358,7 +358,7 @@ enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
void ata_scsi_error(struct Scsi_Host *host) void ata_scsi_error(struct Scsi_Host *host)
{ {
struct ata_port *ap = ata_shost_to_port(host); struct ata_port *ap = ata_shost_to_port(host);
int i, repeat_cnt = ATA_EH_MAX_REPEAT; int i;
unsigned long flags; unsigned long flags;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
...@@ -424,6 +424,9 @@ void ata_scsi_error(struct Scsi_Host *host) ...@@ -424,6 +424,9 @@ void ata_scsi_error(struct Scsi_Host *host)
__ata_port_freeze(ap); __ata_port_freeze(ap);
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
/* initialize eh_tries */
ap->eh_tries = ATA_EH_MAX_TRIES;
} else } else
spin_unlock_wait(ap->lock); spin_unlock_wait(ap->lock);
...@@ -468,15 +471,12 @@ void ata_scsi_error(struct Scsi_Host *host) ...@@ -468,15 +471,12 @@ void ata_scsi_error(struct Scsi_Host *host)
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
if (ap->pflags & ATA_PFLAG_EH_PENDING) { if (ap->pflags & ATA_PFLAG_EH_PENDING) {
if (--repeat_cnt) { if (--ap->eh_tries) {
ata_port_printk(ap, KERN_INFO,
"EH pending after completion, "
"repeating EH (cnt=%d)\n", repeat_cnt);
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
goto repeat; goto repeat;
} }
ata_port_printk(ap, KERN_ERR, "EH pending after %d " ata_port_printk(ap, KERN_ERR, "EH pending after %d "
"tries, giving up\n", ATA_EH_MAX_REPEAT); "tries, giving up\n", ATA_EH_MAX_TRIES);
ap->pflags &= ~ATA_PFLAG_EH_PENDING; ap->pflags &= ~ATA_PFLAG_EH_PENDING;
} }
...@@ -1778,6 +1778,7 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -1778,6 +1778,7 @@ static void ata_eh_link_report(struct ata_link *link)
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context; struct ata_eh_context *ehc = &link->eh_context;
const char *frozen, *desc; const char *frozen, *desc;
char tries_buf[6];
int tag, nr_failed = 0; int tag, nr_failed = 0;
desc = NULL; desc = NULL;
...@@ -1802,18 +1803,23 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -1802,18 +1803,23 @@ static void ata_eh_link_report(struct ata_link *link)
if (ap->pflags & ATA_PFLAG_FROZEN) if (ap->pflags & ATA_PFLAG_FROZEN)
frozen = " frozen"; frozen = " frozen";
memset(tries_buf, 0, sizeof(tries_buf));
if (ap->eh_tries < ATA_EH_MAX_TRIES)
snprintf(tries_buf, sizeof(tries_buf) - 1, " t%d",
ap->eh_tries);
if (ehc->i.dev) { if (ehc->i.dev) {
ata_dev_printk(ehc->i.dev, KERN_ERR, "exception Emask 0x%x " ata_dev_printk(ehc->i.dev, KERN_ERR, "exception Emask 0x%x "
"SAct 0x%x SErr 0x%x action 0x%x%s\n", "SAct 0x%x SErr 0x%x action 0x%x%s%s\n",
ehc->i.err_mask, link->sactive, ehc->i.err_mask, link->sactive, ehc->i.serror,
ehc->i.serror, ehc->i.action, frozen); ehc->i.action, frozen, tries_buf);
if (desc) if (desc)
ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc); ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc);
} else { } else {
ata_link_printk(link, KERN_ERR, "exception Emask 0x%x " ata_link_printk(link, KERN_ERR, "exception Emask 0x%x "
"SAct 0x%x SErr 0x%x action 0x%x%s\n", "SAct 0x%x SErr 0x%x action 0x%x%s%s\n",
ehc->i.err_mask, link->sactive, ehc->i.err_mask, link->sactive, ehc->i.serror,
ehc->i.serror, ehc->i.action, frozen); ehc->i.action, frozen, tries_buf);
if (desc) if (desc)
ata_link_printk(link, KERN_ERR, "%s\n", desc); ata_link_printk(link, KERN_ERR, "%s\n", desc);
} }
......
...@@ -293,8 +293,8 @@ enum { ...@@ -293,8 +293,8 @@ enum {
ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET, ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
/* max repeat if error condition is still set after ->error_handler */ /* max tries if error condition is still set after ->error_handler */
ATA_EH_MAX_REPEAT = 5, ATA_EH_MAX_TRIES = 5,
/* how hard are we gonna try to probe/recover devices */ /* how hard are we gonna try to probe/recover devices */
ATA_PROBE_MAX_TRIES = 3, ATA_PROBE_MAX_TRIES = 3,
...@@ -581,6 +581,7 @@ struct ata_port { ...@@ -581,6 +581,7 @@ struct ata_port {
u32 msg_enable; u32 msg_enable;
struct list_head eh_done_q; struct list_head eh_done_q;
wait_queue_head_t eh_wait_q; wait_queue_head_t eh_wait_q;
int eh_tries;
pm_message_t pm_mesg; pm_message_t pm_mesg;
int *pm_result; int *pm_result;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册