summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/cam
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-09 14:47:04 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 11:03:27 +0100
commit0577772720a4ecb050a230f75346f90b246e93c8 (patch)
treea3fba8bb57e77c932e08dd0d4bbe49adb6312e5e /freebsd/sys/cam
parentUpdate to FreeBSD head 2016-12-10 (diff)
downloadrtems-libbsd-0577772720a4ecb050a230f75346f90b246e93c8.tar.bz2
Update to FreeBSD head 2017-01-09
Git mirror commit 1f8e4a995a6ede4bdb24e6d335ccda2bdb0175ab.
Diffstat (limited to 'freebsd/sys/cam')
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c832
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.h150
-rw-r--r--freebsd/sys/cam/scsi/scsi_da.h14
3 files changed, 554 insertions, 442 deletions
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 9e8924c5..6ebf9eec 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -1240,58 +1240,58 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x0A, 0x00, SS_FATAL | ENOSPC,
"Error log overflow") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x00, SS_RDEF,
+ { SST(0x0B, 0x00, SS_NOP | SSQ_PRINT_SENSE,
"Warning") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x01, SS_RDEF,
+ { SST(0x0B, 0x01, SS_NOP | SSQ_PRINT_SENSE,
"Warning - specified temperature exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x02, SS_RDEF,
+ { SST(0x0B, 0x02, SS_NOP | SSQ_PRINT_SENSE,
"Warning - enclosure degraded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x03, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x03, SS_NOP | SSQ_PRINT_SENSE,
"Warning - background self-test failed") },
/* DTLPWRO AEBKVF */
- { SST(0x0B, 0x04, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x04, SS_NOP | SSQ_PRINT_SENSE,
"Warning - background pre-scan detected medium error") },
/* DTLPWRO AEBKVF */
- { SST(0x0B, 0x05, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x05, SS_NOP | SSQ_PRINT_SENSE,
"Warning - background medium scan detected medium error") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x06, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x06, SS_NOP | SSQ_PRINT_SENSE,
"Warning - non-volatile cache now volatile") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x07, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x07, SS_NOP | SSQ_PRINT_SENSE,
"Warning - degraded power to non-volatile cache") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x08, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x08, SS_NOP | SSQ_PRINT_SENSE,
"Warning - power loss expected") },
/* D */
- { SST(0x0B, 0x09, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x09, SS_NOP | SSQ_PRINT_SENSE,
"Warning - device statistics notification available") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x0A, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x0A, SS_NOP | SSQ_PRINT_SENSE,
"Warning - High critical temperature limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x0B, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x0B, SS_NOP | SSQ_PRINT_SENSE,
"Warning - Low critical temperature limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x0C, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x0C, SS_NOP | SSQ_PRINT_SENSE,
"Warning - High operating temperature limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x0D, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x0D, SS_NOP | SSQ_PRINT_SENSE,
"Warning - Low operating temperature limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x0E, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x0E, SS_NOP | SSQ_PRINT_SENSE,
"Warning - High citical humidity limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x0F, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x0F, SS_NOP | SSQ_PRINT_SENSE,
"Warning - Low citical humidity limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x10, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x10, SS_NOP | SSQ_PRINT_SENSE,
"Warning - High operating humidity limit exceeded") },
/* DTLPWROMAEBKVF */
- { SST(0x0B, 0x11, SS_RDEF, /* XXX TBD */
+ { SST(0x0B, 0x11, SS_NOP | SSQ_PRINT_SENSE,
"Warning - Low operating humidity limit exceeded") },
/* T R */
{ SST(0x0C, 0x00, SS_RDEF,
@@ -2620,253 +2620,259 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x5C, 0x02, SS_RDEF,
"Spindles not synchronized") },
/* DTLPWROMAEBKVF */
- { SST(0x5D, 0x00, SS_RDEF,
+ { SST(0x5D, 0x00, SS_NOP | SSQ_PRINT_SENSE,
"Failure prediction threshold exceeded") },
/* R B */
- { SST(0x5D, 0x01, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x01, SS_NOP | SSQ_PRINT_SENSE,
"Media failure prediction threshold exceeded") },
/* R */
- { SST(0x5D, 0x02, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x02, SS_NOP | SSQ_PRINT_SENSE,
"Logical unit failure prediction threshold exceeded") },
/* R */
- { SST(0x5D, 0x03, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x03, SS_NOP | SSQ_PRINT_SENSE,
"Spare area exhaustion prediction threshold exceeded") },
/* D B */
- { SST(0x5D, 0x10, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x10, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure general hard drive failure") },
/* D B */
- { SST(0x5D, 0x11, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x11, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure drive error rate too high") },
/* D B */
- { SST(0x5D, 0x12, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x12, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure data error rate too high") },
/* D B */
- { SST(0x5D, 0x13, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x13, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure seek error rate too high") },
/* D B */
- { SST(0x5D, 0x14, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x14, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure too many block reassigns") },
/* D B */
- { SST(0x5D, 0x15, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x15, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure access times too high") },
/* D B */
- { SST(0x5D, 0x16, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x16, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure start unit times too high") },
/* D B */
- { SST(0x5D, 0x17, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x17, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure channel parametrics") },
/* D B */
- { SST(0x5D, 0x18, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x18, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure controller detected") },
/* D B */
- { SST(0x5D, 0x19, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x19, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure throughput performance") },
/* D B */
- { SST(0x5D, 0x1A, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x1A, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure seek time performance") },
/* D B */
- { SST(0x5D, 0x1B, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x1B, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure spin-up retry count") },
/* D B */
- { SST(0x5D, 0x1C, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x1C, SS_NOP | SSQ_PRINT_SENSE,
"Hardware impending failure drive calibration retry count") },
/* D B */
- { SST(0x5D, 0x20, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x1D, SS_NOP | SSQ_PRINT_SENSE,
+ "Hardware impending failure power loss protection circuit") },
+ /* D B */
+ { SST(0x5D, 0x20, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure general hard drive failure") },
/* D B */
- { SST(0x5D, 0x21, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x21, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure drive error rate too high") },
/* D B */
- { SST(0x5D, 0x22, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x22, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure data error rate too high") },
/* D B */
- { SST(0x5D, 0x23, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x23, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure seek error rate too high") },
/* D B */
- { SST(0x5D, 0x24, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x24, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure too many block reassigns") },
/* D B */
- { SST(0x5D, 0x25, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x25, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure access times too high") },
/* D B */
- { SST(0x5D, 0x26, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x26, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure start unit times too high") },
/* D B */
- { SST(0x5D, 0x27, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x27, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure channel parametrics") },
/* D B */
- { SST(0x5D, 0x28, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x28, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure controller detected") },
/* D B */
- { SST(0x5D, 0x29, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x29, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure throughput performance") },
/* D B */
- { SST(0x5D, 0x2A, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x2A, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure seek time performance") },
/* D B */
- { SST(0x5D, 0x2B, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x2B, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure spin-up retry count") },
/* D B */
- { SST(0x5D, 0x2C, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x2C, SS_NOP | SSQ_PRINT_SENSE,
"Controller impending failure drive calibration retry count") },
/* D B */
- { SST(0x5D, 0x30, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x30, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure general hard drive failure") },
/* D B */
- { SST(0x5D, 0x31, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x31, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure drive error rate too high") },
/* D B */
- { SST(0x5D, 0x32, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x32, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure data error rate too high") },
/* D B */
- { SST(0x5D, 0x33, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x33, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure seek error rate too high") },
/* D B */
- { SST(0x5D, 0x34, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x34, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure too many block reassigns") },
/* D B */
- { SST(0x5D, 0x35, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x35, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure access times too high") },
/* D B */
- { SST(0x5D, 0x36, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x36, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure start unit times too high") },
/* D B */
- { SST(0x5D, 0x37, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x37, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure channel parametrics") },
/* D B */
- { SST(0x5D, 0x38, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x38, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure controller detected") },
/* D B */
- { SST(0x5D, 0x39, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x39, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure throughput performance") },
/* D B */
- { SST(0x5D, 0x3A, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x3A, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure seek time performance") },
/* D B */
- { SST(0x5D, 0x3B, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x3B, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure spin-up retry count") },
/* D B */
- { SST(0x5D, 0x3C, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x3C, SS_NOP | SSQ_PRINT_SENSE,
"Data channel impending failure drive calibration retry count") },
/* D B */
- { SST(0x5D, 0x40, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x40, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure general hard drive failure") },
/* D B */
- { SST(0x5D, 0x41, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x41, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure drive error rate too high") },
/* D B */
- { SST(0x5D, 0x42, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x42, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure data error rate too high") },
/* D B */
- { SST(0x5D, 0x43, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x43, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure seek error rate too high") },
/* D B */
- { SST(0x5D, 0x44, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x44, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure too many block reassigns") },
/* D B */
- { SST(0x5D, 0x45, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x45, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure access times too high") },
/* D B */
- { SST(0x5D, 0x46, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x46, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure start unit times too high") },
/* D B */
- { SST(0x5D, 0x47, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x47, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure channel parametrics") },
/* D B */
- { SST(0x5D, 0x48, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x48, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure controller detected") },
/* D B */
- { SST(0x5D, 0x49, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x49, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure throughput performance") },
/* D B */
- { SST(0x5D, 0x4A, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x4A, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure seek time performance") },
/* D B */
- { SST(0x5D, 0x4B, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x4B, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure spin-up retry count") },
/* D B */
- { SST(0x5D, 0x4C, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x4C, SS_NOP | SSQ_PRINT_SENSE,
"Servo impending failure drive calibration retry count") },
/* D B */
- { SST(0x5D, 0x50, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x50, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure general hard drive failure") },
/* D B */
- { SST(0x5D, 0x51, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x51, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure drive error rate too high") },
/* D B */
- { SST(0x5D, 0x52, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x52, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure data error rate too high") },
/* D B */
- { SST(0x5D, 0x53, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x53, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure seek error rate too high") },
/* D B */
- { SST(0x5D, 0x54, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x54, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure too many block reassigns") },
/* D B */
- { SST(0x5D, 0x55, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x55, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure access times too high") },
/* D B */
- { SST(0x5D, 0x56, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x56, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure start unit times too high") },
/* D B */
- { SST(0x5D, 0x57, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x57, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure channel parametrics") },
/* D B */
- { SST(0x5D, 0x58, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x58, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure controller detected") },
/* D B */
- { SST(0x5D, 0x59, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x59, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure throughput performance") },
/* D B */
- { SST(0x5D, 0x5A, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x5A, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure seek time performance") },
/* D B */
- { SST(0x5D, 0x5B, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x5B, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure spin-up retry count") },
/* D B */
- { SST(0x5D, 0x5C, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x5C, SS_NOP | SSQ_PRINT_SENSE,
"Spindle impending failure drive calibration retry count") },
/* D B */
- { SST(0x5D, 0x60, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x60, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure general hard drive failure") },
/* D B */
- { SST(0x5D, 0x61, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x61, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure drive error rate too high") },
/* D B */
- { SST(0x5D, 0x62, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x62, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure data error rate too high") },
/* D B */
- { SST(0x5D, 0x63, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x63, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure seek error rate too high") },
/* D B */
- { SST(0x5D, 0x64, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x64, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure too many block reassigns") },
/* D B */
- { SST(0x5D, 0x65, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x65, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure access times too high") },
/* D B */
- { SST(0x5D, 0x66, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x66, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure start unit times too high") },
/* D B */
- { SST(0x5D, 0x67, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x67, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure channel parametrics") },
/* D B */
- { SST(0x5D, 0x68, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x68, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure controller detected") },
/* D B */
- { SST(0x5D, 0x69, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x69, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure throughput performance") },
/* D B */
- { SST(0x5D, 0x6A, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x6A, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure seek time performance") },
/* D B */
- { SST(0x5D, 0x6B, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x6B, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure spin-up retry count") },
/* D B */
- { SST(0x5D, 0x6C, SS_RDEF, /* XXX TBD */
+ { SST(0x5D, 0x6C, SS_NOP | SSQ_PRINT_SENSE,
"Firmware impending failure drive calibration retry count") },
+ /* D B */
+ { SST(0x5D, 0x73, SS_NOP | SSQ_PRINT_SENSE,
+ "Media impending failure endurance limit met") },
/* DTLPWROMAEBKVF */
- { SST(0x5D, 0xFF, SS_RDEF,
+ { SST(0x5D, 0xFF, SS_NOP | SSQ_PRINT_SENSE,
"Failure prediction threshold exceeded (false)") },
/* DTLPWRO A K */
{ SST(0x5E, 0x00, SS_RDEF,
@@ -3744,335 +3750,300 @@ scsi_find_desc(struct scsi_sense_data_desc *sense, u_int sense_len,
#endif /* __rtems__ */
/*
- * Fill in SCSI sense data with the specified parameters. This routine can
- * fill in either fixed or descriptor type sense data.
+ * Fill in SCSI descriptor sense data with the specified parameters.
*/
-void
-scsi_set_sense_data_va(struct scsi_sense_data *sense_data,
- scsi_sense_data_type sense_format, int current_error,
- int sense_key, int asc, int ascq, va_list ap)
+static void
+scsi_set_sense_data_desc_va(struct scsi_sense_data *sense_data,
+ u_int *sense_len, scsi_sense_data_type sense_format, int current_error,
+ int sense_key, int asc, int ascq, va_list ap)
{
- int descriptor_sense;
+ struct scsi_sense_data_desc *sense;
scsi_sense_elem_type elem_type;
+ int space, len;
+ uint8_t *desc, *data;
- /*
- * Determine whether to return fixed or descriptor format sense
- * data. If the user specifies SSD_TYPE_NONE for some reason,
- * they'll just get fixed sense data.
- */
- if (sense_format == SSD_TYPE_DESC)
- descriptor_sense = 1;
- else
- descriptor_sense = 0;
-
- /*
- * Zero the sense data, so that we don't pass back any garbage data
- * to the user.
- */
memset(sense_data, 0, sizeof(*sense_data));
+ sense = (struct scsi_sense_data_desc *)sense_data;
+ if (current_error != 0)
+ sense->error_code = SSD_DESC_CURRENT_ERROR;
+ else
+ sense->error_code = SSD_DESC_DEFERRED_ERROR;
+ sense->sense_key = sense_key;
+ sense->add_sense_code = asc;
+ sense->add_sense_code_qual = ascq;
+ sense->flags = 0;
+
+ desc = &sense->sense_desc[0];
+ space = *sense_len - offsetof(struct scsi_sense_data_desc, sense_desc);
+ while ((elem_type = va_arg(ap, scsi_sense_elem_type)) !=
+ SSD_ELEM_NONE) {
+ if (elem_type >= SSD_ELEM_MAX) {
+ printf("%s: invalid sense type %d\n", __func__,
+ elem_type);
+ break;
+ }
+ len = va_arg(ap, int);
+ data = va_arg(ap, uint8_t *);
- if (descriptor_sense != 0) {
- struct scsi_sense_data_desc *sense;
-
- sense = (struct scsi_sense_data_desc *)sense_data;
- /*
- * The descriptor sense format eliminates the use of the
- * valid bit.
- */
- if (current_error != 0)
- sense->error_code = SSD_DESC_CURRENT_ERROR;
- else
- sense->error_code = SSD_DESC_DEFERRED_ERROR;
- sense->sense_key = sense_key;
- sense->add_sense_code = asc;
- sense->add_sense_code_qual = ascq;
- /*
- * Start off with no extra length, since the above data
- * fits in the standard descriptor sense information.
- */
- sense->extra_len = 0;
- while ((elem_type = (scsi_sense_elem_type)va_arg(ap,
- scsi_sense_elem_type)) != SSD_ELEM_NONE) {
- int sense_len, len_to_copy;
- uint8_t *data;
-
- if (elem_type >= SSD_ELEM_MAX) {
- printf("%s: invalid sense type %d\n", __func__,
- elem_type);
+ switch (elem_type) {
+ case SSD_ELEM_SKIP:
+ break;
+ case SSD_ELEM_DESC:
+ if (space < len) {
+ sense->flags |= SSDD_SDAT_OVFL;
break;
}
+ bcopy(data, desc, len);
+ desc += len;
+ space -= len;
+ break;
+ case SSD_ELEM_SKS: {
+ struct scsi_sense_sks *sks = (void *)desc;
- sense_len = (int)va_arg(ap, int);
- len_to_copy = MIN(sense_len, SSD_EXTRA_MAX -
- sense->extra_len);
- data = (uint8_t *)va_arg(ap, uint8_t *);
-
- /*
- * We've already consumed the arguments for this one.
- */
- if (elem_type == SSD_ELEM_SKIP)
- continue;
-
- switch (elem_type) {
- case SSD_ELEM_DESC: {
-
- /*
- * This is a straight descriptor. All we
- * need to do is copy the data in.
- */
- bcopy(data, &sense->sense_desc[
- sense->extra_len], len_to_copy);
- sense->extra_len += len_to_copy;
+ if (len > sizeof(sks->sense_key_spec))
+ break;
+ if (space < sizeof(*sks)) {
+ sense->flags |= SSDD_SDAT_OVFL;
break;
}
- case SSD_ELEM_SKS: {
- struct scsi_sense_sks sks;
-
- bzero(&sks, sizeof(sks));
+ sks->desc_type = SSD_DESC_SKS;
+ sks->length = sizeof(*sks) -
+ (offsetof(struct scsi_sense_sks, length) + 1);
+ bcopy(data, &sks->sense_key_spec, len);
+ desc += sizeof(*sks);
+ space -= sizeof(*sks);
+ break;
+ }
+ case SSD_ELEM_COMMAND: {
+ struct scsi_sense_command *cmd = (void *)desc;
- /*
- * This is already-formatted sense key
- * specific data. We just need to fill out
- * the header and copy everything in.
- */
- bcopy(data, &sks.sense_key_spec,
- MIN(len_to_copy,
- sizeof(sks.sense_key_spec)));
-
- sks.desc_type = SSD_DESC_SKS;
- sks.length = sizeof(sks) -
- offsetof(struct scsi_sense_sks, reserved1);
- bcopy(&sks,&sense->sense_desc[sense->extra_len],
- sizeof(sks));
- sense->extra_len += sizeof(sks);
+ if (len > sizeof(cmd->command_info))
+ break;
+ if (space < sizeof(*cmd)) {
+ sense->flags |= SSDD_SDAT_OVFL;
break;
}
- case SSD_ELEM_INFO:
- case SSD_ELEM_COMMAND: {
- struct scsi_sense_command cmd;
- struct scsi_sense_info info;
- uint8_t *data_dest;
- uint8_t *descriptor;
- int descriptor_size, i, copy_len;
-
- bzero(&cmd, sizeof(cmd));
- bzero(&info, sizeof(info));
-
- /*
- * Command or information data. The
- * operate in pretty much the same way.
- */
- if (elem_type == SSD_ELEM_COMMAND) {
- len_to_copy = MIN(len_to_copy,
- sizeof(cmd.command_info));
- descriptor = (uint8_t *)&cmd;
- descriptor_size = sizeof(cmd);
- data_dest =(uint8_t *)&cmd.command_info;
- cmd.desc_type = SSD_DESC_COMMAND;
- cmd.length = sizeof(cmd) -
- offsetof(struct scsi_sense_command,
- reserved);
- } else {
- len_to_copy = MIN(len_to_copy,
- sizeof(info.info));
- descriptor = (uint8_t *)&info;
- descriptor_size = sizeof(cmd);
- data_dest = (uint8_t *)&info.info;
- info.desc_type = SSD_DESC_INFO;
- info.byte2 = SSD_INFO_VALID;
- info.length = sizeof(info) -
- offsetof(struct scsi_sense_info,
- byte2);
- }
-
- /*
- * Copy this in reverse because the spec
- * (SPC-4) says that when 4 byte quantities
- * are stored in this 8 byte field, the
- * first four bytes shall be 0.
- *
- * So we fill the bytes in from the end, and
- * if we have less than 8 bytes to copy,
- * the initial, most significant bytes will
- * be 0.
- */
- for (i = sense_len - 1; i >= 0 &&
- len_to_copy > 0; i--, len_to_copy--)
- data_dest[len_to_copy - 1] = data[i];
+ cmd->desc_type = SSD_DESC_COMMAND;
+ cmd->length = sizeof(*cmd) -
+ (offsetof(struct scsi_sense_command, length) + 1);
+ bcopy(data, &cmd->command_info[
+ sizeof(cmd->command_info) - len], len);
+ desc += sizeof(*cmd);
+ space -= sizeof(*cmd);
+ break;
+ }
+ case SSD_ELEM_INFO: {
+ struct scsi_sense_info *info = (void *)desc;
- /*
- * This calculation looks much like the
- * initial len_to_copy calculation, but
- * we have to do it again here, because
- * we're looking at a larger amount that
- * may or may not fit. It's not only the
- * data the user passed in, but also the
- * rest of the descriptor.
- */
- copy_len = MIN(descriptor_size,
- SSD_EXTRA_MAX - sense->extra_len);
- bcopy(descriptor, &sense->sense_desc[
- sense->extra_len], copy_len);
- sense->extra_len += copy_len;
+ if (len > sizeof(info->info))
break;
- }
- case SSD_ELEM_FRU: {
- struct scsi_sense_fru fru;
- int copy_len;
-
- bzero(&fru, sizeof(fru));
-
- fru.desc_type = SSD_DESC_FRU;
- fru.length = sizeof(fru) -
- offsetof(struct scsi_sense_fru, reserved);
- fru.fru = *data;
-
- copy_len = MIN(sizeof(fru), SSD_EXTRA_MAX -
- sense->extra_len);
- bcopy(&fru, &sense->sense_desc[
- sense->extra_len], copy_len);
- sense->extra_len += copy_len;
+ if (space < sizeof(*info)) {
+ sense->flags |= SSDD_SDAT_OVFL;
break;
}
- case SSD_ELEM_STREAM: {
- struct scsi_sense_stream stream_sense;
- int copy_len;
-
- bzero(&stream_sense, sizeof(stream_sense));
- stream_sense.desc_type = SSD_DESC_STREAM;
- stream_sense.length = sizeof(stream_sense) -
- offsetof(struct scsi_sense_stream, reserved);
- stream_sense.byte3 = *data;
-
- copy_len = MIN(sizeof(stream_sense),
- SSD_EXTRA_MAX - sense->extra_len);
- bcopy(&stream_sense, &sense->sense_desc[
- sense->extra_len], copy_len);
- sense->extra_len += copy_len;
+ info->desc_type = SSD_DESC_INFO;
+ info->length = sizeof(*info) -
+ (offsetof(struct scsi_sense_info, length) + 1);
+ info->byte2 = SSD_INFO_VALID;
+ bcopy(data, &info->info[sizeof(info->info) - len], len);
+ desc += sizeof(*info);
+ space -= sizeof(*info);
+ break;
+ }
+ case SSD_ELEM_FRU: {
+ struct scsi_sense_fru *fru = (void *)desc;
+
+ if (len > sizeof(fru->fru))
break;
- }
- default:
- /*
- * We shouldn't get here, but if we do, do
- * nothing. We've already consumed the
- * arguments above.
- */
+ if (space < sizeof(*fru)) {
+ sense->flags |= SSDD_SDAT_OVFL;
break;
}
+ fru->desc_type = SSD_DESC_FRU;
+ fru->length = sizeof(*fru) -
+ (offsetof(struct scsi_sense_fru, length) + 1);
+ fru->fru = *data;
+ desc += sizeof(*fru);
+ space -= sizeof(*fru);
+ break;
}
- } else {
- struct scsi_sense_data_fixed *sense;
-
- sense = (struct scsi_sense_data_fixed *)sense_data;
-
- if (current_error != 0)
- sense->error_code = SSD_CURRENT_ERROR;
- else
- sense->error_code = SSD_DEFERRED_ERROR;
+ case SSD_ELEM_STREAM: {
+ struct scsi_sense_stream *stream = (void *)desc;
- sense->flags = sense_key;
- sense->add_sense_code = asc;
- sense->add_sense_code_qual = ascq;
- /*
- * We've set the ASC and ASCQ, so we have 6 more bytes of
- * valid data. If we wind up setting any of the other
- * fields, we'll bump this to 10 extra bytes.
- */
- sense->extra_len = 6;
-
- while ((elem_type = (scsi_sense_elem_type)va_arg(ap,
- scsi_sense_elem_type)) != SSD_ELEM_NONE) {
- int sense_len, len_to_copy;
- uint8_t *data;
-
- if (elem_type >= SSD_ELEM_MAX) {
- printf("%s: invalid sense type %d\n", __func__,
- elem_type);
+ if (len > sizeof(stream->byte3))
+ break;
+ if (space < sizeof(*stream)) {
+ sense->flags |= SSDD_SDAT_OVFL;
break;
}
+ stream->desc_type = SSD_DESC_STREAM;
+ stream->length = sizeof(*stream) -
+ (offsetof(struct scsi_sense_stream, length) + 1);
+ stream->byte3 = *data;
+ desc += sizeof(*stream);
+ space -= sizeof(*stream);
+ break;
+ }
+ default:
/*
- * If we get in here, just bump the extra length to
- * 10 bytes. That will encompass anything we're
- * going to set here.
+ * We shouldn't get here, but if we do, do nothing.
+ * We've already consumed the arguments above.
*/
- sense->extra_len = 10;
- sense_len = (int)va_arg(ap, int);
- data = (uint8_t *)va_arg(ap, uint8_t *);
+ break;
+ }
+ }
+ sense->extra_len = desc - &sense->sense_desc[0];
+ *sense_len = offsetof(struct scsi_sense_data_desc, extra_len) + 1 +
+ sense->extra_len;
+}
- switch (elem_type) {
- case SSD_ELEM_SKS:
- /*
- * The user passed in pre-formatted sense
- * key specific data.
- */
- bcopy(data, &sense->sense_key_spec[0],
- MIN(sizeof(sense->sense_key_spec),
- sense_len));
- break;
- case SSD_ELEM_INFO:
- case SSD_ELEM_COMMAND: {
- uint8_t *data_dest;
- int i;
-
- if (elem_type == SSD_ELEM_COMMAND) {
- data_dest = &sense->cmd_spec_info[0];
- len_to_copy = MIN(sense_len,
- sizeof(sense->cmd_spec_info));
- } else {
- data_dest = &sense->info[0];
- len_to_copy = MIN(sense_len,
- sizeof(sense->info));
- /*
- * We're setting the info field, so
- * set the valid bit.
- */
- sense->error_code |= SSD_ERRCODE_VALID;
- }
+/*
+ * Fill in SCSI fixed sense data with the specified parameters.
+ */
+static void
+scsi_set_sense_data_fixed_va(struct scsi_sense_data *sense_data,
+ u_int *sense_len, scsi_sense_data_type sense_format, int current_error,
+ int sense_key, int asc, int ascq, va_list ap)
+{
+ struct scsi_sense_data_fixed *sense;
+ scsi_sense_elem_type elem_type;
+ uint8_t *data;
+ int len;
- /*
- * Copy this in reverse so that if we have
- * less than 4 bytes to fill, the least
- * significant bytes will be at the end.
- * If we have more than 4 bytes, only the
- * least significant bytes will be included.
- */
- for (i = sense_len - 1; i >= 0 &&
- len_to_copy > 0; i--, len_to_copy--)
- data_dest[len_to_copy - 1] = data[i];
+ memset(sense_data, 0, sizeof(*sense_data));
+ sense = (struct scsi_sense_data_fixed *)sense_data;
+ if (current_error != 0)
+ sense->error_code = SSD_CURRENT_ERROR;
+ else
+ sense->error_code = SSD_DEFERRED_ERROR;
+ sense->flags = sense_key & SSD_KEY;
+ sense->extra_len = 0;
+ if (*sense_len >= 13) {
+ sense->add_sense_code = asc;
+ sense->extra_len = MAX(sense->extra_len, 5);
+ } else
+ sense->flags |= SSD_SDAT_OVFL;
+ if (*sense_len >= 14) {
+ sense->add_sense_code_qual = ascq;
+ sense->extra_len = MAX(sense->extra_len, 6);
+ } else
+ sense->flags |= SSD_SDAT_OVFL;
+
+ while ((elem_type = va_arg(ap, scsi_sense_elem_type)) !=
+ SSD_ELEM_NONE) {
+ if (elem_type >= SSD_ELEM_MAX) {
+ printf("%s: invalid sense type %d\n", __func__,
+ elem_type);
+ break;
+ }
+ len = va_arg(ap, int);
+ data = va_arg(ap, uint8_t *);
+ switch (elem_type) {
+ case SSD_ELEM_SKIP:
+ break;
+ case SSD_ELEM_SKS:
+ if (len > sizeof(sense->sense_key_spec))
break;
- }
- case SSD_ELEM_FRU:
- sense->fru = *data;
+ if (*sense_len < 18) {
+ sense->flags |= SSD_SDAT_OVFL;
break;
- case SSD_ELEM_STREAM:
- sense->flags |= *data;
+ }
+ bcopy(data, &sense->sense_key_spec[0], len);
+ sense->extra_len = MAX(sense->extra_len, 10);
+ break;
+ case SSD_ELEM_COMMAND:
+ if (*sense_len < 12) {
+ sense->flags |= SSD_SDAT_OVFL;
break;
- case SSD_ELEM_DESC:
- default:
-
- /*
- * If the user passes in descriptor sense,
- * we can't handle that in fixed format.
- * So just skip it, and any unknown argument
- * types.
- */
+ }
+ if (len > sizeof(sense->cmd_spec_info)) {
+ data += len - sizeof(sense->cmd_spec_info);
+ len -= len - sizeof(sense->cmd_spec_info);
+ }
+ bcopy(data, &sense->cmd_spec_info[
+ sizeof(sense->cmd_spec_info) - len], len);
+ sense->extra_len = MAX(sense->extra_len, 4);
+ break;
+ case SSD_ELEM_INFO:
+ /* Set VALID bit only if no overflow. */
+ sense->error_code |= SSD_ERRCODE_VALID;
+ while (len > sizeof(sense->info)) {
+ if (data[0] != 0)
+ sense->error_code &= ~SSD_ERRCODE_VALID;
+ data ++;
+ len --;
+ }
+ bcopy(data, &sense->info[sizeof(sense->info) - len], len);
+ break;
+ case SSD_ELEM_FRU:
+ if (*sense_len < 15) {
+ sense->flags |= SSD_SDAT_OVFL;
break;
}
+ sense->fru = *data;
+ sense->extra_len = MAX(sense->extra_len, 7);
+ break;
+ case SSD_ELEM_STREAM:
+ sense->flags |= *data &
+ (SSD_ILI | SSD_EOM | SSD_FILEMARK);
+ break;
+ default:
+
+ /*
+ * We can't handle that in fixed format. Skip it.
+ */
+ break;
}
}
+ *sense_len = offsetof(struct scsi_sense_data_fixed, extra_len) + 1 +
+ sense->extra_len;
+}
+
+/*
+ * Fill in SCSI sense data with the specified parameters. This routine can
+ * fill in either fixed or descriptor type sense data.
+ */
+void
+scsi_set_sense_data_va(struct scsi_sense_data *sense_data, u_int *sense_len,
+ scsi_sense_data_type sense_format, int current_error,
+ int sense_key, int asc, int ascq, va_list ap)
+{
+
+ if (*sense_len > SSD_FULL_SIZE)
+ *sense_len = SSD_FULL_SIZE;
+ if (sense_format == SSD_TYPE_DESC)
+ scsi_set_sense_data_desc_va(sense_data, sense_len,
+ sense_format, current_error, sense_key, asc, ascq, ap);
+ else
+ scsi_set_sense_data_fixed_va(sense_data, sense_len,
+ sense_format, current_error, sense_key, asc, ascq, ap);
+}
+
+void
+scsi_set_sense_data(struct scsi_sense_data *sense_data,
+ scsi_sense_data_type sense_format, int current_error,
+ int sense_key, int asc, int ascq, ...)
+{
+ va_list ap;
+ u_int sense_len = SSD_FULL_SIZE;
+
+ va_start(ap, ascq);
+ scsi_set_sense_data_va(sense_data, &sense_len, sense_format,
+ current_error, sense_key, asc, ascq, ap);
+ va_end(ap);
}
void
-scsi_set_sense_data(struct scsi_sense_data *sense_data,
+scsi_set_sense_data_len(struct scsi_sense_data *sense_data, u_int *sense_len,
scsi_sense_data_type sense_format, int current_error,
- int sense_key, int asc, int ascq, ...)
+ int sense_key, int asc, int ascq, ...)
{
va_list ap;
va_start(ap, ascq);
- scsi_set_sense_data_va(sense_data, sense_format, current_error,
- sense_key, asc, ascq, ap);
+ scsi_set_sense_data_va(sense_data, sense_len, sense_format,
+ current_error, sense_key, asc, ascq, ap);
va_end(ap);
}
@@ -4708,6 +4679,26 @@ scsi_sense_ata_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
sbuf_printf(sb, "device: %02x, ", res->device);
}
+void
+scsi_sense_forwarded_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
+ u_int sense_len, uint8_t *cdb, int cdb_len,
+ struct scsi_inquiry_data *inq_data,
+ struct scsi_sense_desc_header *header)
+{
+ struct scsi_sense_forwarded *forwarded;
+ const char *sense_key_desc;
+ const char *asc_desc;
+ int error_code, sense_key, asc, ascq;
+
+ forwarded = (struct scsi_sense_forwarded *)header;
+ scsi_extract_sense_len((struct scsi_sense_data *)forwarded->sense_data,
+ forwarded->length - 2, &error_code, &sense_key, &asc, &ascq, 1);
+ scsi_sense_desc(sense_key, asc, ascq, NULL, &sense_key_desc, &asc_desc);
+
+ sbuf_printf(sb, "Forwarded sense: %s asc:%x,%x (%s): ",
+ sense_key_desc, asc, ascq, asc_desc);
+}
+
/*
* Generic sense descriptor printing routine. This is used when we have
* not yet implemented a specific printing routine for this descriptor.
@@ -4755,7 +4746,8 @@ struct scsi_sense_desc_printer {
{SSD_DESC_STREAM, scsi_sense_stream_sbuf},
{SSD_DESC_BLOCK, scsi_sense_block_sbuf},
{SSD_DESC_ATA, scsi_sense_ata_sbuf},
- {SSD_DESC_PROGRESS, scsi_sense_progress_sbuf}
+ {SSD_DESC_PROGRESS, scsi_sense_progress_sbuf},
+ {SSD_DESC_FORWARDED, scsi_sense_forwarded_sbuf}
};
void
@@ -5693,6 +5685,32 @@ scsi_devid_is_lun_name(uint8_t *bufp)
}
int
+scsi_devid_is_lun_md5(uint8_t *bufp)
+{
+ struct scsi_vpd_id_descriptor *descr;
+
+ descr = (struct scsi_vpd_id_descriptor *)bufp;
+ if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+ return 0;
+ if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_MD5_LUN_ID)
+ return 0;
+ return 1;
+}
+
+int
+scsi_devid_is_lun_uuid(uint8_t *bufp)
+{
+ struct scsi_vpd_id_descriptor *descr;
+
+ descr = (struct scsi_vpd_id_descriptor *)bufp;
+ if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+ return 0;
+ if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_UUID)
+ return 0;
+ return 1;
+}
+
+int
scsi_devid_is_port_naa(uint8_t *bufp)
{
struct scsi_vpd_id_descriptor *descr;
@@ -7618,24 +7636,34 @@ scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
}
void
-scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
- void (*cbfcnp)(struct cam_periph *, union ccb *),
- u_int8_t tag_action, int dbd, u_int8_t page_code,
- u_int8_t page, u_int8_t *param_buf, u_int32_t param_len,
- u_int8_t sense_len, u_int32_t timeout)
+scsi_mode_sense(struct ccb_scsiio *csio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action,
+ int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len,
+ uint8_t sense_len, uint32_t timeout)
{
- scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd,
- page_code, page, param_buf, param_len, 0,
- sense_len, timeout);
+ scsi_mode_sense_subpage(csio, retries, cbfcnp, tag_action, dbd,
+ pc, page, 0, param_buf, param_len, 0, sense_len, timeout);
}
void
-scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
- void (*cbfcnp)(struct cam_periph *, union ccb *),
- u_int8_t tag_action, int dbd, u_int8_t page_code,
- u_int8_t page, u_int8_t *param_buf, u_int32_t param_len,
- int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout)
+scsi_mode_sense_len(struct ccb_scsiio *csio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action,
+ int dbd, uint8_t pc, uint8_t page, uint8_t *param_buf, uint32_t param_len,
+ int minimum_cmd_size, uint8_t sense_len, uint32_t timeout)
+{
+
+ scsi_mode_sense_subpage(csio, retries, cbfcnp, tag_action, dbd,
+ pc, page, 0, param_buf, param_len, minimum_cmd_size,
+ sense_len, timeout);
+}
+
+void
+scsi_mode_sense_subpage(struct ccb_scsiio *csio, uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action,
+ int dbd, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t *param_buf,
+ uint32_t param_len, int minimum_cmd_size, uint8_t sense_len,
+ uint32_t timeout)
{
u_int8_t cdb_len;
@@ -7654,7 +7682,8 @@ scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
scsi_cmd->opcode = MODE_SENSE_6;
if (dbd != 0)
scsi_cmd->byte2 |= SMS_DBD;
- scsi_cmd->page = page_code | page;
+ scsi_cmd->page = pc | page;
+ scsi_cmd->subpage = subpage;
scsi_cmd->length = param_len;
cdb_len = sizeof(*scsi_cmd);
} else {
@@ -7668,7 +7697,8 @@ scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
scsi_cmd->opcode = MODE_SENSE_10;
if (dbd != 0)
scsi_cmd->byte2 |= SMS_DBD;
- scsi_cmd->page = page_code | page;
+ scsi_cmd->page = pc | page;
+ scsi_cmd->subpage = subpage;
scsi_ulto2b(param_len, scsi_cmd->length);
cdb_len = sizeof(*scsi_cmd);
}
diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h
index 9c1376cf..64c45fb2 100644
--- a/freebsd/sys/cam/scsi/scsi_all.h
+++ b/freebsd/sys/cam/scsi/scsi_all.h
@@ -228,6 +228,7 @@ struct scsi_mode_select_6
u_int8_t opcode;
u_int8_t byte2;
#define SMS_SP 0x01
+#define SMS_RTD 0x02
#define SMS_PF 0x10
u_int8_t unused[2];
u_int8_t length;
@@ -662,6 +663,14 @@ struct scsi_log_fua_stat_and_perf {
uint8_t fuanv_write_int[8];
};
+struct scsi_log_informational_exceptions {
+ struct scsi_log_param_header hdr;
+#define SLP_IE_GEN 0x0000
+ uint8_t ie_asc;
+ uint8_t ie_ascq;
+ uint8_t temperature;
+};
+
struct scsi_control_page {
u_int8_t page_code;
u_int8_t page_length;
@@ -765,21 +774,6 @@ struct scsi_caching_page {
uint8_t non_cache_seg_size[3];
};
-/*
- * XXX KDM move this off to a vendor shim.
- */
-struct copan_debugconf_subpage {
- uint8_t page_code;
-#define DBGCNF_PAGE_CODE 0x00
- uint8_t subpage;
-#define DBGCNF_SUBPAGE_CODE 0xF0
- uint8_t page_length[2];
- uint8_t page_version;
-#define DBGCNF_VERSION 0x00
- uint8_t ctl_time_io_secs[2];
-};
-
-
struct scsi_info_exceptions_page {
u_int8_t page_code;
#define SIEP_PAGE_SAVABLE 0x80 /* Page is savable */
@@ -793,6 +787,12 @@ struct scsi_info_exceptions_page {
#define SIEP_FLAGS_EBACKERR 0x02
#define SIEP_FLAGS_LOGERR 0x01
u_int8_t mrie;
+#define SIEP_MRIE_NO 0x00
+#define SIEP_MRIE_UA 0x02
+#define SIEP_MRIE_REC_COND 0x03
+#define SIEP_MRIE_REC_UNCOND 0x04
+#define SIEP_MRIE_NO_SENSE 0x05
+#define SIEP_MRIE_ON_REQ 0x06
u_int8_t interval_timer[4];
u_int8_t report_count[4];
};
@@ -1457,6 +1457,7 @@ struct scsi_report_supported_opcodes
#define RSO_OPTIONS_ALL 0x00
#define RSO_OPTIONS_OC 0x01
#define RSO_OPTIONS_OC_SA 0x02
+#define RSO_OPTIONS_OC_ASA 0x03
uint8_t requested_opcode;
uint8_t requested_service_action[2];
uint8_t length[4];
@@ -1482,6 +1483,10 @@ struct scsi_report_supported_opcodes_descr
uint8_t flags;
#define RSO_SERVACTV 0x01
#define RSO_CTDP 0x02
+#define RSO_CDLP_MASK 0x0c
+#define RSO_CDLP_NO 0x00
+#define RSO_CDLP_A 0x04
+#define RSO_CDLP_B 0x08
uint8_t cdb_length[2];
struct scsi_report_supported_opcodes_timeout timeout[0];
};
@@ -1497,6 +1502,10 @@ struct scsi_report_supported_opcodes_one
uint8_t reserved;
uint8_t support;
#define RSO_ONE_CTDP 0x80
+#define RSO_ONE_CDLP_MASK 0x18
+#define RSO_ONE_CDLP_NO 0x00
+#define RSO_ONE_CDLP_A 0x08
+#define RSO_ONE_CDLP_B 0x10
#define RSO_ONE_SUP_MASK 0x07
#define RSO_ONE_SUP_UNAVAIL 0x00
#define RSO_ONE_SUP_NOT_SUP 0x01
@@ -1510,7 +1519,9 @@ struct scsi_report_supported_tmf
{
uint8_t opcode;
uint8_t service_action;
- uint8_t reserved[4];
+ uint8_t options;
+#define RST_REPD 0x80
+ uint8_t reserved[3];
uint8_t length[4];
uint8_t reserved1;
uint8_t control;
@@ -1531,7 +1542,34 @@ struct scsi_report_supported_tmf_data
#define RST_ITNRS 0x01
#define RST_QTSS 0x02
#define RST_QAES 0x04
- uint8_t reserved[2];
+ uint8_t reserved;
+ uint8_t length;
+};
+
+struct scsi_report_supported_tmf_ext_data
+{
+ uint8_t byte1;
+ uint8_t byte2;
+ uint8_t reserved;
+ uint8_t length;
+ uint8_t byte5;
+#define RST_TMFTMOV 0x01
+ uint8_t reserved2;
+ uint8_t byte7;
+#define RST_WAKETS 0x01
+#define RST_TRTS 0x02
+#define RST_QTTS 0x04
+#define RST_LURTS 0x08
+#define RST_CTSTS 0x10
+#define RST_CACATS 0x20
+#define RST_ATSTS 0x40
+#define RST_ATTS 0x80
+ uint8_t byte8;
+#define RST_ITNRTS 0x01
+#define RST_QTSTS 0x02
+#define RST_QAETS 0x04
+ uint8_t long_timeout[4];
+ uint8_t short_timeout[4];
};
struct scsi_report_timestamp
@@ -2157,6 +2195,7 @@ struct scsi_inquiry_data
#define SCSI_REV_SPC2 4
#define SCSI_REV_SPC3 5
#define SCSI_REV_SPC4 6
+#define SCSI_REV_SPC5 7
#define SID_ECMA 0x38
#define SID_ISO 0xC0
@@ -2477,10 +2516,17 @@ struct scsi_vpd_extended_inquiry_data
#define SVPD_EID_NV_SUP 0x02
#define SVPD_EID_V_SUP 0x01
uint8_t flags4;
+#define SVPD_EID_NO_PI_CHK 0x20
#define SVPD_EID_P_I_I_SUP 0x10
-#define SVPD_EID_LUICLT 0x01
+#define SVPD_EID_LUICLR 0x01
uint8_t flags5;
+#define SVPD_EID_LUCT_MASK 0xe0
+#define SVPD_EID_LUCT_NOT_REP 0x00
+#define SVPD_EID_LUCT_CONGL 0x20
+#define SVPD_EID_LUCT_GROUP 0x40
#define SVPD_EID_R_SUP 0x10
+#define SVPD_EID_RTD_SUP 0x08
+#define SVPD_EID_HSSRELEF 0x02
#define SVPD_EID_CBCS 0x01
uint8_t flags6;
#define SVPD_EID_MULTI_I_T_FW 0x0F
@@ -2491,10 +2537,16 @@ struct scsi_vpd_extended_inquiry_data
uint8_t est[2];
uint8_t flags7;
#define SVPD_EID_POA_SUP 0x80
-#define SVPD_EID_HRA_SUP 0x80
-#define SVPD_EID_VSA_SUP 0x80
+#define SVPD_EID_HRA_SUP 0x40
+#define SVPD_EID_VSA_SUP 0x20
uint8_t max_sense_length;
- uint8_t reserved2[50];
+ uint8_t bind_flags;
+#define SVPD_EID_IBS 0x80
+#define SVPD_EID_IAS 0x40
+#define SVPD_EID_SAC 0x04
+#define SVPD_EID_NRD1 0x02
+#define SVPD_EID_NRD0 0x01
+ uint8_t reserved2[49];
};
struct scsi_vpd_mode_page_policy_descr
@@ -3145,11 +3197,12 @@ struct scsi_sense_data_fixed
#define SSD_KEY_BLANK_CHECK 0x08
#define SSD_KEY_Vendor_Specific 0x09
#define SSD_KEY_COPY_ABORTED 0x0a
-#define SSD_KEY_ABORTED_COMMAND 0x0b
+#define SSD_KEY_ABORTED_COMMAND 0x0b
#define SSD_KEY_EQUAL 0x0c
#define SSD_KEY_VOLUME_OVERFLOW 0x0d
#define SSD_KEY_MISCOMPARE 0x0e
-#define SSD_KEY_COMPLETED 0x0f
+#define SSD_KEY_COMPLETED 0x0f
+#define SSD_SDAT_OVFL 0x10
#define SSD_ILI 0x20
#define SSD_EOM 0x40
#define SSD_FILEMARK 0x80
@@ -3187,7 +3240,9 @@ struct scsi_sense_data_desc
uint8_t sense_key;
uint8_t add_sense_code;
uint8_t add_sense_code_qual;
- uint8_t reserved[3];
+ uint8_t flags;
+#define SSDD_SDAT_OVFL 0x80
+ uint8_t reserved[2];
/*
* Note that SPC-4, section 4.5.2.1 says that the extra_len field
* must be less than or equal to 244.
@@ -3481,6 +3536,8 @@ struct scsi_sense_forwarded
#define SSD_FORWARDED_SDS_UNK 0x00
#define SSD_FORWARDED_SDS_EXSRC 0x01
#define SSD_FORWARDED_SDS_EXDST 0x02
+ uint8_t status;
+ uint8_t sense_data[];
};
/*
@@ -3653,13 +3710,15 @@ void scsi_desc_iterate(struct scsi_sense_data_desc *sense, u_int sense_len,
void *), void *arg);
uint8_t *scsi_find_desc(struct scsi_sense_data_desc *sense, u_int sense_len,
uint8_t desc_type);
-void scsi_set_sense_data(struct scsi_sense_data *sense_data,
+void scsi_set_sense_data(struct scsi_sense_data *sense_data,
scsi_sense_data_type sense_format, int current_error,
int sense_key, int asc, int ascq, ...) ;
+void scsi_set_sense_data_len(struct scsi_sense_data *sense_data,
+ u_int *sense_len, scsi_sense_data_type sense_format, int current_error,
+ int sense_key, int asc, int ascq, ...) ;
void scsi_set_sense_data_va(struct scsi_sense_data *sense_data,
- scsi_sense_data_type sense_format,
- int current_error, int sense_key, int asc,
- int ascq, va_list ap);
+ u_int *sense_len, scsi_sense_data_type sense_format,
+ int current_error, int sense_key, int asc, int ascq, va_list ap);
int scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len,
uint8_t info_type, uint64_t *info,
int64_t *signed_info);
@@ -3713,6 +3772,10 @@ void scsi_sense_ata_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
u_int sense_len, uint8_t *cdb, int cdb_len,
struct scsi_inquiry_data *inq_data,
struct scsi_sense_desc_header *header);
+void scsi_sense_forwarded_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
+ u_int sense_len, uint8_t *cdb, int cdb_len,
+ struct scsi_inquiry_data *inq_data,
+ struct scsi_sense_desc_header *header);
void scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
u_int sense_len, uint8_t *cdb, int cdb_len,
struct scsi_inquiry_data *inq_data,
@@ -3769,6 +3832,8 @@ int scsi_devid_is_lun_eui64(uint8_t *bufp);
int scsi_devid_is_lun_naa(uint8_t *bufp);
int scsi_devid_is_lun_name(uint8_t *bufp);
int scsi_devid_is_lun_t10(uint8_t *bufp);
+int scsi_devid_is_lun_md5(uint8_t *bufp);
+int scsi_devid_is_lun_uuid(uint8_t *bufp);
int scsi_devid_is_port_naa(uint8_t *bufp);
struct scsi_vpd_id_descriptor *
scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t len,
@@ -3912,21 +3977,24 @@ void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
u_int8_t sense_len, u_int32_t timeout);
void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
- void (*cbfcnp)(struct cam_periph *,
- union ccb *),
- u_int8_t tag_action, int dbd,
- u_int8_t page_code, u_int8_t page,
- u_int8_t *param_buf, u_int32_t param_len,
- u_int8_t sense_len, u_int32_t timeout);
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int dbd, uint8_t pc, uint8_t page,
+ uint8_t *param_buf, uint32_t param_len,
+ uint8_t sense_len, uint32_t timeout);
void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
- void (*cbfcnp)(struct cam_periph *,
- union ccb *),
- u_int8_t tag_action, int dbd,
- u_int8_t page_code, u_int8_t page,
- u_int8_t *param_buf, u_int32_t param_len,
- int minimum_cmd_size, u_int8_t sense_len,
- u_int32_t timeout);
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int dbd, uint8_t pc, uint8_t page,
+ uint8_t *param_buf, uint32_t param_len,
+ int minimum_cmd_size, uint8_t sense_len, uint32_t timeout);
+
+void scsi_mode_sense_subpage(struct ccb_scsiio *csio,
+ uint32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int dbd, uint8_t pc,
+ uint8_t page, uint8_t subpage,
+ uint8_t *param_buf, uint32_t param_len,
+ int minimum_cmd_size, uint8_t sense_len, uint32_t timeout);
void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,
diff --git a/freebsd/sys/cam/scsi/scsi_da.h b/freebsd/sys/cam/scsi/scsi_da.h
index e6eb95f1..a679114d 100644
--- a/freebsd/sys/cam/scsi/scsi_da.h
+++ b/freebsd/sys/cam/scsi/scsi_da.h
@@ -634,6 +634,20 @@ struct scsi_da_rw_recovery_page {
u_int8_t recovery_time_limit[2];
};
+struct scsi_da_verify_recovery_page {
+ u_int8_t page_code;
+#define SMS_VERIFY_ERROR_RECOVERY_PAGE 0x07
+ u_int8_t page_length;
+ u_int8_t byte3;
+#define SMS_VER_EER 0x08
+#define SMS_VER_PER 0x04
+#define SMS_VER_DTE 0x02
+#define SMS_VER_DCR 0x01
+ u_int8_t read_retry_count;
+ u_int8_t reserved[6];
+ u_int8_t recovery_time_limit[2];
+};
+
__BEGIN_DECLS
/*
* XXX These are only left out of the kernel build to silence warnings. If,