diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-09 14:47:04 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 11:03:27 +0100 |
commit | 0577772720a4ecb050a230f75346f90b246e93c8 (patch) | |
tree | a3fba8bb57e77c932e08dd0d4bbe49adb6312e5e /freebsd/sys/cam | |
parent | Update to FreeBSD head 2016-12-10 (diff) | |
download | rtems-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.c | 832 | ||||
-rw-r--r-- | freebsd/sys/cam/scsi/scsi_all.h | 150 | ||||
-rw-r--r-- | freebsd/sys/cam/scsi/scsi_da.h | 14 |
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, |