diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 4 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 3 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 12 | ||||
-rw-r--r-- | drivers/ata/libata.h | 5 |
4 files changed, 21 insertions, 3 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index aebb7e3..ff57367 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -691,11 +691,11 @@ static int ata_rwcmd_protocol(struct ata_taskfile *tf, struct ata_device *dev) * RETURNS: * Block address read from @tf. */ -u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) +u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev) { u64 block = 0; - if (tf->flags & ATA_TFLAG_LBA) { + if (!dev || tf->flags & ATA_TFLAG_LBA) { if (tf->flags & ATA_TFLAG_LBA48) { block |= (u64)tf->hob_lbah << 40; block |= (u64)tf->hob_lbam << 32; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 9fa81d9..77ef43e 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1852,6 +1852,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ata_dev_dbg(dev, "NCQ Autosense %02x/%02x/%02x\n", sense_key, asc, ascq); ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq); + ata_scsi_set_sense_information(qc->scsicmd, &qc->result_tf); qc->flags |= ATA_QCFLAG_SENSE_VALID; } @@ -1894,6 +1895,8 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, tmp = ata_eh_request_sense(qc, qc->scsicmd); if (tmp) qc->err_mask |= tmp; + else + ata_scsi_set_sense_information(qc->scsicmd, tf); } else { ata_dev_warn(qc->dev, "sense data available but port frozen\n"); } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3ac5be3..3131adc 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -280,6 +280,18 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); } +void ata_scsi_set_sense_information(struct scsi_cmnd *cmd, + const struct ata_taskfile *tf) +{ + u64 information; + + if (!cmd) + return; + + information = ata_tf_read_block(tf, NULL); + scsi_set_sense_information(cmd->sense_buffer, information); +} + static ssize_t ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 8cfdd96..a998a17 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -67,7 +67,8 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, unsigned int tag); -extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev); +extern u64 ata_tf_read_block(const struct ata_taskfile *tf, + struct ata_device *dev); extern unsigned ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen, @@ -138,6 +139,8 @@ extern int ata_scsi_add_hosts(struct ata_host *host, extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern int ata_scsi_offline_dev(struct ata_device *dev); extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq); +extern void ata_scsi_set_sense_information(struct scsi_cmnd *cmd, + const struct ata_taskfile *tf); extern void ata_scsi_media_change_notify(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); |