summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/cam/scsi/scsi_all.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/cam/scsi/scsi_all.c')
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c832
1 files changed, 431 insertions, 401 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);
}