libata: report protocol and full CDB on error
Protocol and CDB allocation size field are important in determining what went wrong with ATAPI commands. Report them on failure. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
@@ -1850,30 +1850,54 @@ static void ata_eh_link_report(struct ata_link *link)
|
|||||||
ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : "");
|
ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : "");
|
||||||
|
|
||||||
for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
|
for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
|
||||||
static const char *dma_str[] = {
|
|
||||||
[DMA_BIDIRECTIONAL] = "bidi",
|
|
||||||
[DMA_TO_DEVICE] = "out",
|
|
||||||
[DMA_FROM_DEVICE] = "in",
|
|
||||||
[DMA_NONE] = "",
|
|
||||||
};
|
|
||||||
struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
|
struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
|
||||||
struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
|
struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
|
||||||
|
const u8 *cdb = qc->cdb;
|
||||||
|
char data_buf[20] = "";
|
||||||
|
char cdb_buf[70] = "";
|
||||||
|
|
||||||
if (!(qc->flags & ATA_QCFLAG_FAILED) ||
|
if (!(qc->flags & ATA_QCFLAG_FAILED) ||
|
||||||
qc->dev->link != link || !qc->err_mask)
|
qc->dev->link != link || !qc->err_mask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (qc->dma_dir != DMA_NONE) {
|
||||||
|
static const char *dma_str[] = {
|
||||||
|
[DMA_BIDIRECTIONAL] = "bidi",
|
||||||
|
[DMA_TO_DEVICE] = "out",
|
||||||
|
[DMA_FROM_DEVICE] = "in",
|
||||||
|
};
|
||||||
|
static const char *prot_str[] = {
|
||||||
|
[ATA_PROT_PIO] = "pio",
|
||||||
|
[ATA_PROT_DMA] = "dma",
|
||||||
|
[ATA_PROT_NCQ] = "ncq",
|
||||||
|
[ATA_PROT_ATAPI] = "pio",
|
||||||
|
[ATA_PROT_ATAPI_DMA] = "dma",
|
||||||
|
};
|
||||||
|
|
||||||
|
snprintf(data_buf, sizeof(data_buf), " %s %u %s",
|
||||||
|
prot_str[qc->tf.protocol], qc->nbytes,
|
||||||
|
dma_str[qc->dma_dir]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_atapi_taskfile(&qc->tf))
|
||||||
|
snprintf(cdb_buf, sizeof(cdb_buf),
|
||||||
|
"cdb %02x %02x %02x %02x %02x %02x %02x %02x "
|
||||||
|
"%02x %02x %02x %02x %02x %02x %02x %02x\n ",
|
||||||
|
cdb[0], cdb[1], cdb[2], cdb[3],
|
||||||
|
cdb[4], cdb[5], cdb[6], cdb[7],
|
||||||
|
cdb[8], cdb[9], cdb[10], cdb[11],
|
||||||
|
cdb[12], cdb[13], cdb[14], cdb[15]);
|
||||||
|
|
||||||
ata_dev_printk(qc->dev, KERN_ERR,
|
ata_dev_printk(qc->dev, KERN_ERR,
|
||||||
"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
||||||
"tag %d cdb 0x%x data %u %s\n "
|
"tag %d%s\n %s"
|
||||||
"res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
"res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
||||||
"Emask 0x%x (%s)%s\n",
|
"Emask 0x%x (%s)%s\n",
|
||||||
cmd->command, cmd->feature, cmd->nsect,
|
cmd->command, cmd->feature, cmd->nsect,
|
||||||
cmd->lbal, cmd->lbam, cmd->lbah,
|
cmd->lbal, cmd->lbam, cmd->lbah,
|
||||||
cmd->hob_feature, cmd->hob_nsect,
|
cmd->hob_feature, cmd->hob_nsect,
|
||||||
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
|
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
|
||||||
cmd->device, qc->tag, qc->cdb[0], qc->nbytes,
|
cmd->device, qc->tag, data_buf, cdb_buf,
|
||||||
dma_str[qc->dma_dir],
|
|
||||||
res->command, res->feature, res->nsect,
|
res->command, res->feature, res->nsect,
|
||||||
res->lbal, res->lbam, res->lbah,
|
res->lbal, res->lbam, res->lbah,
|
||||||
res->hob_feature, res->hob_nsect,
|
res->hob_feature, res->hob_nsect,
|
||||||
|
Reference in New Issue
Block a user