static void ata_eh_link_report()

in libata-eh.c [2211:2395]


static void ata_eh_link_report(struct ata_link *link)
{
	struct ata_port *ap = link->ap;
	struct ata_eh_context *ehc = &link->eh_context;
	struct ata_queued_cmd *qc;
	const char *frozen, *desc;
	char tries_buf[6] = "";
	int tag, nr_failed = 0;

	if (ehc->i.flags & ATA_EHI_QUIET)
		return;

	desc = NULL;
	if (ehc->i.desc[0] != '\0')
		desc = ehc->i.desc;

	ata_qc_for_each_raw(ap, qc, tag) {
		if (!(qc->flags & ATA_QCFLAG_FAILED) ||
		    ata_dev_phys_link(qc->dev) != link ||
		    ((qc->flags & ATA_QCFLAG_QUIET) &&
		     qc->err_mask == AC_ERR_DEV))
			continue;
		if (qc->flags & ATA_QCFLAG_SENSE_VALID && !qc->err_mask)
			continue;

		nr_failed++;
	}

	if (!nr_failed && !ehc->i.err_mask)
		return;

	frozen = "";
	if (ap->pflags & ATA_PFLAG_FROZEN)
		frozen = " frozen";

	if (ap->eh_tries < ATA_EH_MAX_TRIES)
		snprintf(tries_buf, sizeof(tries_buf), " t%d",
			 ap->eh_tries);

	if (ehc->i.dev) {
		ata_dev_err(ehc->i.dev, "exception Emask 0x%x "
			    "SAct 0x%x SErr 0x%x action 0x%x%s%s\n",
			    ehc->i.err_mask, link->sactive, ehc->i.serror,
			    ehc->i.action, frozen, tries_buf);
		if (desc)
			ata_dev_err(ehc->i.dev, "%s\n", desc);
	} else {
		ata_link_err(link, "exception Emask 0x%x "
			     "SAct 0x%x SErr 0x%x action 0x%x%s%s\n",
			     ehc->i.err_mask, link->sactive, ehc->i.serror,
			     ehc->i.action, frozen, tries_buf);
		if (desc)
			ata_link_err(link, "%s\n", desc);
	}

#ifdef CONFIG_ATA_VERBOSE_ERROR
	if (ehc->i.serror)
		ata_link_err(link,
		  "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
		  ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
		  ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
		  ehc->i.serror & SERR_DATA ? "UnrecovData " : "",
		  ehc->i.serror & SERR_PERSISTENT ? "Persist " : "",
		  ehc->i.serror & SERR_PROTOCOL ? "Proto " : "",
		  ehc->i.serror & SERR_INTERNAL ? "HostInt " : "",
		  ehc->i.serror & SERR_PHYRDY_CHG ? "PHYRdyChg " : "",
		  ehc->i.serror & SERR_PHY_INT_ERR ? "PHYInt " : "",
		  ehc->i.serror & SERR_COMM_WAKE ? "CommWake " : "",
		  ehc->i.serror & SERR_10B_8B_ERR ? "10B8B " : "",
		  ehc->i.serror & SERR_DISPARITY ? "Dispar " : "",
		  ehc->i.serror & SERR_CRC ? "BadCRC " : "",
		  ehc->i.serror & SERR_HANDSHAKE ? "Handshk " : "",
		  ehc->i.serror & SERR_LINK_SEQ_ERR ? "LinkSeq " : "",
		  ehc->i.serror & SERR_TRANS_ST_ERROR ? "TrStaTrns " : "",
		  ehc->i.serror & SERR_UNRECOG_FIS ? "UnrecFIS " : "",
		  ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : "");
#endif

	ata_qc_for_each_raw(ap, qc, tag) {
		struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
		char data_buf[20] = "";
		char cdb_buf[70] = "";

		if (!(qc->flags & ATA_QCFLAG_FAILED) ||
		    ata_dev_phys_link(qc->dev) != link || !qc->err_mask)
			continue;

		if (qc->dma_dir != DMA_NONE) {
			static const char *dma_str[] = {
				[DMA_BIDIRECTIONAL]	= "bidi",
				[DMA_TO_DEVICE]		= "out",
				[DMA_FROM_DEVICE]	= "in",
			};
			const char *prot_str = NULL;

			switch (qc->tf.protocol) {
			case ATA_PROT_UNKNOWN:
				prot_str = "unknown";
				break;
			case ATA_PROT_NODATA:
				prot_str = "nodata";
				break;
			case ATA_PROT_PIO:
				prot_str = "pio";
				break;
			case ATA_PROT_DMA:
				prot_str = "dma";
				break;
			case ATA_PROT_NCQ:
				prot_str = "ncq dma";
				break;
			case ATA_PROT_NCQ_NODATA:
				prot_str = "ncq nodata";
				break;
			case ATAPI_PROT_NODATA:
				prot_str = "nodata";
				break;
			case ATAPI_PROT_PIO:
				prot_str = "pio";
				break;
			case ATAPI_PROT_DMA:
				prot_str = "dma";
				break;
			}
			snprintf(data_buf, sizeof(data_buf), " %s %u %s",
				 prot_str, qc->nbytes, dma_str[qc->dma_dir]);
		}

		if (ata_is_atapi(qc->tf.protocol)) {
			const u8 *cdb = qc->cdb;
			size_t cdb_len = qc->dev->cdb_len;

			if (qc->scsicmd) {
				cdb = qc->scsicmd->cmnd;
				cdb_len = qc->scsicmd->cmd_len;
			}
			__scsi_format_command(cdb_buf, sizeof(cdb_buf),
					      cdb, cdb_len);
		} else
			ata_dev_err(qc->dev, "failed command: %s\n",
				    ata_get_cmd_name(cmd->command));

		ata_dev_err(qc->dev,
			"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
			"tag %d%s\n         %s"
			"res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
			"Emask 0x%x (%s)%s\n",
			cmd->command, cmd->feature, cmd->nsect,
			cmd->lbal, cmd->lbam, cmd->lbah,
			cmd->hob_feature, cmd->hob_nsect,
			cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
			cmd->device, qc->tag, data_buf, cdb_buf,
			res->command, res->feature, res->nsect,
			res->lbal, res->lbam, res->lbah,
			res->hob_feature, res->hob_nsect,
			res->hob_lbal, res->hob_lbam, res->hob_lbah,
			res->device, qc->err_mask, ata_err_string(qc->err_mask),
			qc->err_mask & AC_ERR_NCQ ? " <F>" : "");

#ifdef CONFIG_ATA_VERBOSE_ERROR
		if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
				    ATA_SENSE | ATA_ERR)) {
			if (res->command & ATA_BUSY)
				ata_dev_err(qc->dev, "status: { Busy }\n");
			else
				ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n",
				  res->command & ATA_DRDY ? "DRDY " : "",
				  res->command & ATA_DF ? "DF " : "",
				  res->command & ATA_DRQ ? "DRQ " : "",
				  res->command & ATA_SENSE ? "SENSE " : "",
				  res->command & ATA_ERR ? "ERR " : "");
		}

		if (cmd->command != ATA_CMD_PACKET &&
		    (res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF |
				     ATA_IDNF | ATA_ABORTED)))
			ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",
			  res->feature & ATA_ICRC ? "ICRC " : "",
			  res->feature & ATA_UNC ? "UNC " : "",
			  res->feature & ATA_AMNF ? "AMNF " : "",
			  res->feature & ATA_IDNF ? "IDNF " : "",
			  res->feature & ATA_ABORTED ? "ABRT " : "");
#endif
	}
}