diff options
author | Yuri Pankov <yuri.pankov@nexenta.com> | 2013-12-18 22:52:49 +0400 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2013-12-23 08:31:31 -0800 |
commit | 2acf01fd73874e9b92c066e8deb5270d92b083ba (patch) | |
tree | 7c0e4fb0438b799244cb3187c213caf4d2d432cd | |
parent | 24766d6b5e8d2ed5f6aff0dad6e9ae49121d4c30 (diff) | |
download | illumos-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.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/scsi/impl/scsi_subr.c | 1 | ||||
-rw-r--r-- | usr/src/uts/common/io/scsi/targets/sd.c | 126 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sata/impl/sata.h | 2 |
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 |