8 #define SCSI_CMD_BUF_SIZE 16
9 #define SCSI_SENSE_LEN 18
10 #define SCSI_SENSE_LEN_SCANNER 32
11 #define SCSI_INQUIRY_LEN 36
14 SCSI_XFER_NONE
, /* TEST_UNIT_READY, ... */
15 SCSI_XFER_FROM_DEV
, /* READ, INQUIRY, MODE_SENSE, ... */
16 SCSI_XFER_TO_DEV
, /* WRITE, MODE_SELECT, ... */
24 SCSI_HOST_BAD_RESPONSE
,
26 SCSI_HOST_ERROR
= 0x07,
27 SCSI_HOST_RESET
= 0x08,
28 SCSI_HOST_TRANSPORT_DISRUPTED
= 0xe,
29 SCSI_HOST_TARGET_FAILURE
= 0x10,
30 SCSI_HOST_RESERVATION_ERROR
= 0x11,
31 SCSI_HOST_ALLOCATION_FAILURE
= 0x12,
32 SCSI_HOST_MEDIUM_ERROR
= 0x13,
35 typedef struct SCSICommand
{
36 uint8_t buf
[SCSI_CMD_BUF_SIZE
];
40 enum SCSIXferMode mode
;
43 typedef struct SCSISense
{
49 int scsi_build_sense(uint8_t *buf
, SCSISense sense
);
50 SCSISense
scsi_parse_sense_buf(const uint8_t *in_buf
, int in_len
);
51 int scsi_build_sense_buf(uint8_t *buf
, size_t max_size
, SCSISense sense
,
55 * Predefined sense codes
58 /* No sense data available */
59 extern const struct SCSISense sense_code_NO_SENSE
;
60 /* LUN not ready, Manual intervention required */
61 extern const struct SCSISense sense_code_LUN_NOT_READY
;
62 /* LUN not ready, Medium not present */
63 extern const struct SCSISense sense_code_NO_MEDIUM
;
64 /* LUN not ready, medium removal prevented */
65 extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED
;
66 /* Hardware error, internal target failure */
67 extern const struct SCSISense sense_code_TARGET_FAILURE
;
68 /* Illegal request, invalid command operation code */
69 extern const struct SCSISense sense_code_INVALID_OPCODE
;
70 /* Illegal request, LBA out of range */
71 extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE
;
72 /* Illegal request, Invalid field in CDB */
73 extern const struct SCSISense sense_code_INVALID_FIELD
;
74 /* Illegal request, Invalid field in parameter list */
75 extern const struct SCSISense sense_code_INVALID_PARAM
;
76 /* Illegal request, Invalid value in parameter list */
77 extern const struct SCSISense sense_code_INVALID_PARAM_VALUE
;
78 /* Illegal request, Parameter list length error */
79 extern const struct SCSISense sense_code_INVALID_PARAM_LEN
;
80 /* Illegal request, LUN not supported */
81 extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED
;
82 /* Illegal request, Saving parameters not supported */
83 extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED
;
84 /* Illegal request, Incompatible format */
85 extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT
;
86 /* Illegal request, medium removal prevented */
87 extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED
;
88 /* Illegal request, Invalid Transfer Tag */
89 extern const struct SCSISense sense_code_INVALID_TAG
;
90 /* Command aborted, I/O process terminated */
91 extern const struct SCSISense sense_code_IO_ERROR
;
92 /* Command aborted, I_T Nexus loss occurred */
93 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS
;
94 /* Command aborted, Logical Unit failure */
95 extern const struct SCSISense sense_code_LUN_FAILURE
;
96 /* Command aborted, LUN Communication failure */
97 extern const struct SCSISense sense_code_LUN_COMM_FAILURE
;
98 /* Command aborted, Overlapped Commands Attempted */
99 extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS
;
100 /* Medium error, Unrecovered read error */
101 extern const struct SCSISense sense_code_READ_ERROR
;
102 /* LUN not ready, Cause not reportable */
103 extern const struct SCSISense sense_code_NOT_READY
;
104 /* Unit attention, Capacity data has changed */
105 extern const struct SCSISense sense_code_CAPACITY_CHANGED
;
106 /* Unit attention, SCSI bus reset */
107 extern const struct SCSISense sense_code_SCSI_BUS_RESET
;
108 /* LUN not ready, Medium not present */
109 extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM
;
110 /* Unit attention, Power on, reset or bus device reset occurred */
111 extern const struct SCSISense sense_code_RESET
;
112 /* Unit attention, Medium may have changed*/
113 extern const struct SCSISense sense_code_MEDIUM_CHANGED
;
114 /* Unit attention, Reported LUNs data has changed */
115 extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED
;
116 /* Unit attention, Device internal reset */
117 extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET
;
118 /* Data Protection, Write Protected */
119 extern const struct SCSISense sense_code_WRITE_PROTECTED
;
120 /* Data Protection, Space Allocation Failed Write Protect */
121 extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED
;
123 #define SENSE_CODE(x) sense_code_ ## x
125 int scsi_sense_to_errno(int key
, int asc
, int ascq
);
126 int scsi_sense_buf_to_errno(const uint8_t *sense
, size_t sense_size
);
127 bool scsi_sense_buf_is_guest_recoverable(const uint8_t *sense
, size_t sense_size
);
129 int scsi_convert_sense(uint8_t *in_buf
, int in_len
,
130 uint8_t *buf
, int len
, bool fixed
);
131 const char *scsi_command_name(uint8_t cmd
);
133 uint64_t scsi_cmd_lba(SCSICommand
*cmd
);
134 uint32_t scsi_data_cdb_xfer(uint8_t *buf
);
135 uint32_t scsi_cdb_xfer(uint8_t *buf
);
136 int scsi_cdb_length(uint8_t *buf
);
138 /* Linux SG_IO interface. */
140 #define SG_ERR_DRIVER_TIMEOUT 0x06
141 #define SG_ERR_DRIVER_SENSE 0x08
144 int scsi_sense_from_errno(int errno_value
, SCSISense
*sense
);
145 int scsi_sense_from_host_status(uint8_t host_status
, SCSISense
*sense
);