summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2013-12-18 22:52:49 +0400
committerRobert Mustacchi <rm@joyent.com>2013-12-23 08:31:31 -0800
commit2acf01fd73874e9b92c066e8deb5270d92b083ba (patch)
tree7c0e4fb0438b799244cb3187c213caf4d2d432cd
parent24766d6b5e8d2ed5f6aff0dad6e9ae49121d4c30 (diff)
downloadillumos-joyent-2acf01fd73874e9b92c066e8deb5270d92b083ba.tar.gz
1787 SATL fails to handle returned SMART sense data
Reviewed by: Richard Elling <richard.elling@richardelling.com> Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/uts/common/io/sata/impl/sata.c2
-rw-r--r--usr/src/uts/common/io/scsi/impl/scsi_subr.c1
-rw-r--r--usr/src/uts/common/io/scsi/targets/sd.c126
-rw-r--r--usr/src/uts/common/sys/sata/impl/sata.h2
4 files changed, 74 insertions, 57 deletions
diff --git a/usr/src/uts/common/io/sata/impl/sata.c b/usr/src/uts/common/io/sata/impl/sata.c
index 67147e0c21..9ae3d4fcf3 100644
--- a/usr/src/uts/common/io/sata/impl/sata.c
+++ b/usr/src/uts/common/io/sata/impl/sata.c
@@ -7596,7 +7596,7 @@ sata_txlt_apt_completion(sata_pkt_t *sata_pkt)
*scsipkt->pkt_scbp = STATUS_CHECK;
sata_fill_ata_return_desc(sata_pkt,
KEY_RECOVERABLE_ERROR,
- SD_SCSI_ASC_ATP_INFO_AVAIL, 0);
+ SD_SCSI_ASC_APT_INFO_AVAIL, 0x1d);
}
if (spx->txlt_tmp_buf != NULL) {
diff --git a/usr/src/uts/common/io/scsi/impl/scsi_subr.c b/usr/src/uts/common/io/scsi/impl/scsi_subr.c
index 5defdf7e0d..f1c7f20f85 100644
--- a/usr/src/uts/common/io/scsi/impl/scsi_subr.c
+++ b/usr/src/uts/common/io/scsi/impl/scsi_subr.c
@@ -518,6 +518,7 @@ static struct scsi_asq_key_strings extended_sense_list[] = {
0x00, 0x1A, "rewind operation in progress",
0x00, 0x1B, "set capacity operation in progress",
0x00, 0x1C, "verify operation in progress",
+ 0x00, 0x1D, "ATA passthrough information available",
0x01, 0x00, "no index/sector signal",
0x02, 0x00, "no seek complete",
0x03, 0x00, "peripheral device write fault",
diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c
index 67529e7759..d9ca686014 100644
--- a/usr/src/uts/common/io/scsi/targets/sd.c
+++ b/usr/src/uts/common/io/scsi/targets/sd.c
@@ -18117,6 +18117,7 @@ sd_sense_key_recoverable_error(struct sd_lun *un,
{
struct sd_sense_info si;
uint8_t asc = scsi_sense_asc(sense_datap);
+ uint8_t ascq = scsi_sense_ascq(sense_datap);
ASSERT(un != NULL);
ASSERT(mutex_owned(SD_MUTEX(un)));
@@ -18125,6 +18126,14 @@ sd_sense_key_recoverable_error(struct sd_lun *un,
ASSERT(pktp != NULL);
/*
+ * 0x00, 0x1D: ATA PASSTHROUGH INFORMATION AVAILABLE
+ */
+ if (asc == 0x00 && ascq == 0x1D) {
+ sd_return_command(un, bp);
+ return;
+ }
+
+ /*
* 0x5D: FAILURE PREDICTION THRESHOLD EXCEEDED
*/
if ((asc == 0x5D) && (sd_report_pfa != 0)) {
@@ -31416,8 +31425,10 @@ sd_ssc_ereport_post(sd_ssc_t *ssc, enum sd_driver_assessment drv_assess)
* If we got here, we have a completed command, and we need
* to further investigate the sense data to see what kind
* of ereport we should post.
- * Post ereport.io.scsi.cmd.disk.dev.rqs.merr
- * if sense-key == 0x3.
+ * No ereport is needed if sense-key is KEY_RECOVERABLE_ERROR
+ * and asc/ascq is "ATA PASS-THROUGH INFORMATION AVAILABLE".
+ * Post ereport.io.scsi.cmd.disk.dev.rqs.merr if sense-key is
+ * KEY_MEDIUM_ERROR.
* Post ereport.io.scsi.cmd.disk.dev.rqs.derr otherwise.
* driver-assessment will be set based on the parameter
* drv_assess.
@@ -31426,11 +31437,16 @@ sd_ssc_ereport_post(sd_ssc_t *ssc, enum sd_driver_assessment drv_assess)
/*
* Here we have sense data available.
*/
- uint8_t sense_key;
- sense_key = scsi_sense_key(sensep);
- if (sense_key == 0x3) {
+ uint8_t sense_key = scsi_sense_key(sensep);
+ uint8_t sense_asc = scsi_sense_asc(sensep);
+ uint8_t sense_ascq = scsi_sense_ascq(sensep);
+
+ if (sense_key == KEY_RECOVERABLE_ERROR &&
+ sense_asc == 0x00 && sense_ascq == 0x1d)
+ return;
+
+ if (sense_key == KEY_MEDIUM_ERROR) {
/*
- * sense-key == 0x3(medium error),
* driver-assessment should be "fatal" if
* drv_assess is SD_FM_DRV_FATAL.
*/
@@ -31476,55 +31492,55 @@ sd_ssc_ereport_post(sd_ssc_t *ssc, enum sd_driver_assessment drv_assess)
DATA_TYPE_UINT64,
ssc->ssc_uscsi_info->ui_lba,
NULL);
- } else {
- /*
- * if sense-key == 0x4(hardware
- * error), driver-assessment should
- * be "fatal" if drv_assess is
- * SD_FM_DRV_FATAL.
- */
- scsi_fm_ereport_post(un->un_sd,
- uscsi_path_instance, NULL,
- "cmd.disk.dev.rqs.derr",
- uscsi_ena, devid,
- NULL, DDI_NOSLEEP, NULL,
- FM_VERSION,
- DATA_TYPE_UINT8, FM_EREPORT_VERS0,
- DEVID_IF_KNOWN(devid),
- "driver-assessment",
- DATA_TYPE_STRING,
- drv_assess == SD_FM_DRV_FATAL ?
- (sense_key == 0x4 ?
- "fatal" : "fail") : assessment,
- "op-code",
- DATA_TYPE_UINT8, op_code,
- "cdb",
- DATA_TYPE_UINT8_ARRAY, cdblen,
- ssc->ssc_uscsi_cmd->uscsi_cdb,
- "pkt-reason",
- DATA_TYPE_UINT8, uscsi_pkt_reason,
- "pkt-state",
- DATA_TYPE_UINT8, uscsi_pkt_state,
- "pkt-stats",
- DATA_TYPE_UINT32,
- uscsi_pkt_statistics,
- "stat-code",
- DATA_TYPE_UINT8,
- ssc->ssc_uscsi_cmd->uscsi_status,
- "key",
- DATA_TYPE_UINT8,
- scsi_sense_key(sensep),
- "asc",
- DATA_TYPE_UINT8,
- scsi_sense_asc(sensep),
- "ascq",
- DATA_TYPE_UINT8,
- scsi_sense_ascq(sensep),
- "sense-data",
- DATA_TYPE_UINT8_ARRAY,
- senlen, sensep,
- NULL);
- }
+ } else {
+ /*
+ * if sense-key == 0x4(hardware
+ * error), driver-assessment should
+ * be "fatal" if drv_assess is
+ * SD_FM_DRV_FATAL.
+ */
+ scsi_fm_ereport_post(un->un_sd,
+ uscsi_path_instance, NULL,
+ "cmd.disk.dev.rqs.derr",
+ uscsi_ena, devid,
+ NULL, DDI_NOSLEEP, NULL,
+ FM_VERSION,
+ DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+ DEVID_IF_KNOWN(devid),
+ "driver-assessment",
+ DATA_TYPE_STRING,
+ drv_assess == SD_FM_DRV_FATAL ?
+ (sense_key == 0x4 ?
+ "fatal" : "fail") : assessment,
+ "op-code",
+ DATA_TYPE_UINT8, op_code,
+ "cdb",
+ DATA_TYPE_UINT8_ARRAY, cdblen,
+ ssc->ssc_uscsi_cmd->uscsi_cdb,
+ "pkt-reason",
+ DATA_TYPE_UINT8, uscsi_pkt_reason,
+ "pkt-state",
+ DATA_TYPE_UINT8, uscsi_pkt_state,
+ "pkt-stats",
+ DATA_TYPE_UINT32,
+ uscsi_pkt_statistics,
+ "stat-code",
+ DATA_TYPE_UINT8,
+ ssc->ssc_uscsi_cmd->uscsi_status,
+ "key",
+ DATA_TYPE_UINT8,
+ scsi_sense_key(sensep),
+ "asc",
+ DATA_TYPE_UINT8,
+ scsi_sense_asc(sensep),
+ "ascq",
+ DATA_TYPE_UINT8,
+ scsi_sense_ascq(sensep),
+ "sense-data",
+ DATA_TYPE_UINT8_ARRAY,
+ senlen, sensep,
+ NULL);
+ }
} else {
/*
* For stat_code == STATUS_GOOD, this is not a
diff --git a/usr/src/uts/common/sys/sata/impl/sata.h b/usr/src/uts/common/sys/sata/impl/sata.h
index c2454f0e48..ca5a590e08 100644
--- a/usr/src/uts/common/sys/sata/impl/sata.h
+++ b/usr/src/uts/common/sys/sata/impl/sata.h
@@ -521,7 +521,7 @@ struct sata_apt_sense_data {
* usr/src/uts/common/sys/scsi/generic/sense.h
*/
#define SD_SCSI_ASC_NO_ADD_SENSE 0x00
-#define SD_SCSI_ASC_ATP_INFO_AVAIL 0x00
+#define SD_SCSI_ASC_APT_INFO_AVAIL 0x00
#define SD_SCSI_ASC_LU_NOT_READY 0x04
#define SD_SCSI_ASC_LU_NOT_RESPONSE 0x05
#define SD_SCSI_ASC_WRITE_ERR 0x0c