Commit b64bbc39 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

libata: improve EH report formatting



Requiring LLDs to format multiple error description messages properly
doesn't work too well.  Help LLDs a bit by making ata_ehi_push_desc()
insert ", " on each invocation.  __ata_ehi_push_desc() is the raw
version without the automatic separator.

While at it, make ehi_desc interface proper functions instead of
macros.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 975530e8
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1289,12 +1289,12 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
	if (irq_stat & PORT_IRQ_IF_ERR) {
		err_mask |= AC_ERR_ATA_BUS;
		action |= ATA_EH_SOFTRESET;
		ata_ehi_push_desc(ehi, ", interface fatal error");
		ata_ehi_push_desc(ehi, "interface fatal error");
	}

	if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) {
		ata_ehi_hotplugged(ehi);
		ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ?
		ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ?
			"connection status changed" : "PHY RDY changed");
	}

@@ -1303,7 +1303,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)

		err_mask |= AC_ERR_HSM;
		action |= ATA_EH_SOFTRESET;
		ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x",
		ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x",
				  unk[0], unk[1], unk[2], unk[3]);
	}

+3 −0
Original line number Diff line number Diff line
@@ -6945,6 +6945,9 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter);
EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
#endif /* CONFIG_PCI */

EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
EXPORT_SYMBOL_GPL(ata_port_abort);
+67 −2
Original line number Diff line number Diff line
@@ -85,6 +85,71 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
{ }
#endif /* CONFIG_PM */

static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt,
				 va_list args)
{
	ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
				     ATA_EH_DESC_LEN - ehi->desc_len,
				     fmt, args);
}

/**
 *	__ata_ehi_push_desc - push error description without adding separator
 *	@ehi: target EHI
 *	@fmt: printf format string
 *
 *	Format string according to @fmt and append it to @ehi->desc.
 *
 *	LOCKING:
 *	spin_lock_irqsave(host lock)
 */
void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	__ata_ehi_pushv_desc(ehi, fmt, args);
	va_end(args);
}

/**
 *	ata_ehi_push_desc - push error description with separator
 *	@ehi: target EHI
 *	@fmt: printf format string
 *
 *	Format string according to @fmt and append it to @ehi->desc.
 *	If @ehi->desc is not empty, ", " is added in-between.
 *
 *	LOCKING:
 *	spin_lock_irqsave(host lock)
 */
void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
{
	va_list args;

	if (ehi->desc_len)
		__ata_ehi_push_desc(ehi, ", ");

	va_start(args, fmt);
	__ata_ehi_pushv_desc(ehi, fmt, args);
	va_end(args);
}

/**
 *	ata_ehi_clear_desc - clean error description
 *	@ehi: target EHI
 *
 *	Clear @ehi->desc.
 *
 *	LOCKING:
 *	spin_lock_irqsave(host lock)
 */
void ata_ehi_clear_desc(struct ata_eh_info *ehi)
{
	ehi->desc[0] = '\0';
	ehi->desc_len = 0;
}

static void ata_ering_record(struct ata_ering *ering, int is_io,
			     unsigned int err_mask)
{
@@ -1524,14 +1589,14 @@ static void ata_eh_report(struct ata_port *ap)
			       ehc->i.err_mask, ap->sactive, ehc->i.serror,
			       ehc->i.action, frozen);
		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 {
		ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x "
				"SAct 0x%x SErr 0x%x action 0x%x%s\n",
				ehc->i.err_mask, ap->sactive, ehc->i.serror,
				ehc->i.action, frozen);
		if (desc)
			ata_port_printk(ap, KERN_ERR, "(%s)\n", desc);
			ata_port_printk(ap, KERN_ERR, "%s\n", desc);
	}

	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+4 −4
Original line number Diff line number Diff line
@@ -1411,12 +1411,12 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
			EDMA_ERR_INTRL_PAR)) {
		err_mask |= AC_ERR_ATA_BUS;
		action |= ATA_EH_HARDRESET;
		ata_ehi_push_desc(ehi, ", parity error");
		ata_ehi_push_desc(ehi, "parity error");
	}
	if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) {
		ata_ehi_hotplugged(ehi);
		ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ?
			", dev disconnect" : ", dev connect");
			"dev disconnect" : "dev connect");
	}

	if (IS_GEN_I(hpriv)) {
@@ -1425,7 +1425,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
		if (edma_err_cause & EDMA_ERR_SELF_DIS_5) {
			struct mv_port_priv *pp	= ap->private_data;
			pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
			ata_ehi_push_desc(ehi, ", EDMA self-disable");
			ata_ehi_push_desc(ehi, "EDMA self-disable");
		}
	} else {
		eh_freeze_mask = EDMA_EH_FREEZE;
@@ -1433,7 +1433,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
		if (edma_err_cause & EDMA_ERR_SELF_DIS) {
			struct mv_port_priv *pp	= ap->private_data;
			pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
			ata_ehi_push_desc(ehi, ", EDMA self-disable");
			ata_ehi_push_desc(ehi, "EDMA self-disable");
		}

		if (edma_err_cause & EDMA_ERR_SERR) {
+12 −10
Original line number Diff line number Diff line
@@ -715,19 +715,20 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
		int freeze = 0;

		ata_ehi_clear_desc(ehi);
		ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags );
		__ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags );
		if (flags & NV_CPB_RESP_ATA_ERR) {
			ata_ehi_push_desc(ehi, ": ATA error");
			ata_ehi_push_desc(ehi, "ATA error");
			ehi->err_mask |= AC_ERR_DEV;
		} else if (flags & NV_CPB_RESP_CMD_ERR) {
			ata_ehi_push_desc(ehi, ": CMD error");
			ata_ehi_push_desc(ehi, "CMD error");
			ehi->err_mask |= AC_ERR_DEV;
		} else if (flags & NV_CPB_RESP_CPB_ERR) {
			ata_ehi_push_desc(ehi, ": CPB error");
			ata_ehi_push_desc(ehi, "CPB error");
			ehi->err_mask |= AC_ERR_SYSTEM;
			freeze = 1;
		} else {
			/* notifier error, but no error in CPB flags? */
			ata_ehi_push_desc(ehi, "unknown");
			ehi->err_mask |= AC_ERR_OTHER;
			freeze = 1;
		}
@@ -854,20 +855,21 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
				struct ata_eh_info *ehi = &ap->eh_info;

				ata_ehi_clear_desc(ehi);
				ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status );
				__ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status );
				if (status & NV_ADMA_STAT_TIMEOUT) {
					ehi->err_mask |= AC_ERR_SYSTEM;
					ata_ehi_push_desc(ehi, ": timeout");
					ata_ehi_push_desc(ehi, "timeout");
				} else if (status & NV_ADMA_STAT_HOTPLUG) {
					ata_ehi_hotplugged(ehi);
					ata_ehi_push_desc(ehi, ": hotplug");
					ata_ehi_push_desc(ehi, "hotplug");
				} else if (status & NV_ADMA_STAT_HOTUNPLUG) {
					ata_ehi_hotplugged(ehi);
					ata_ehi_push_desc(ehi, ": hot unplug");
					ata_ehi_push_desc(ehi, "hot unplug");
				} else if (status & NV_ADMA_STAT_SERROR) {
					/* let libata analyze SError and figure out the cause */
					ata_ehi_push_desc(ehi, ": SError");
				}
					ata_ehi_push_desc(ehi, "SError");
				} else
					ata_ehi_push_desc(ehi, "unknown");
				ata_port_freeze(ap);
				continue;
			}
Loading