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, ... */
19 typedef struct SCSICommand
{
20 uint8_t buf
[SCSI_CMD_BUF_SIZE
];
24 enum SCSIXferMode mode
;
27 typedef struct SCSISense
{
33 int scsi_build_sense(uint8_t *buf
, SCSISense sense
);
34 SCSISense
scsi_parse_sense_buf(const uint8_t *in_buf
, int in_len
);
35 int scsi_build_sense_buf(uint8_t *buf
, size_t max_size
, SCSISense sense
,
39 * Predefined sense codes
42 /* No sense data available */
43 extern const struct SCSISense sense_code_NO_SENSE
;
44 /* LUN not ready, Manual intervention required */
45 extern const struct SCSISense sense_code_LUN_NOT_READY
;
46 /* LUN not ready, Medium not present */
47 extern const struct SCSISense sense_code_NO_MEDIUM
;
48 /* LUN not ready, medium removal prevented */
49 extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED
;
50 /* Hardware error, internal target failure */
51 extern const struct SCSISense sense_code_TARGET_FAILURE
;
52 /* Illegal request, invalid command operation code */
53 extern const struct SCSISense sense_code_INVALID_OPCODE
;
54 /* Illegal request, LBA out of range */
55 extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE
;
56 /* Illegal request, Invalid field in CDB */
57 extern const struct SCSISense sense_code_INVALID_FIELD
;
58 /* Illegal request, Invalid field in parameter list */
59 extern const struct SCSISense sense_code_INVALID_PARAM
;
60 /* Illegal request, Invalid value in parameter list */
61 extern const struct SCSISense sense_code_INVALID_PARAM_VALUE
;
62 /* Illegal request, Parameter list length error */
63 extern const struct SCSISense sense_code_INVALID_PARAM_LEN
;
64 /* Illegal request, LUN not supported */
65 extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED
;
66 /* Illegal request, Saving parameters not supported */
67 extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED
;
68 /* Illegal request, Incompatible format */
69 extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT
;
70 /* Illegal request, medium removal prevented */
71 extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED
;
72 /* Illegal request, Invalid Transfer Tag */
73 extern const struct SCSISense sense_code_INVALID_TAG
;
74 /* Command aborted, I/O process terminated */
75 extern const struct SCSISense sense_code_IO_ERROR
;
76 /* Command aborted, I_T Nexus loss occurred */
77 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS
;
78 /* Command aborted, Logical Unit failure */
79 extern const struct SCSISense sense_code_LUN_FAILURE
;
80 /* Command aborted, LUN Communication failure */
81 extern const struct SCSISense sense_code_LUN_COMM_FAILURE
;
82 /* Command aborted, Overlapped Commands Attempted */
83 extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS
;
84 /* Medium error, Unrecovered read error */
85 extern const struct SCSISense sense_code_READ_ERROR
;
86 /* LUN not ready, Cause not reportable */
87 extern const struct SCSISense sense_code_NOT_READY
;
88 /* Unit attention, Capacity data has changed */
89 extern const struct SCSISense sense_code_CAPACITY_CHANGED
;
90 /* Unit attention, SCSI bus reset */
91 extern const struct SCSISense sense_code_SCSI_BUS_RESET
;
92 /* LUN not ready, Medium not present */
93 extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM
;
94 /* Unit attention, Power on, reset or bus device reset occurred */
95 extern const struct SCSISense sense_code_RESET
;
96 /* Unit attention, Medium may have changed*/
97 extern const struct SCSISense sense_code_MEDIUM_CHANGED
;
98 /* Unit attention, Reported LUNs data has changed */
99 extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED
;
100 /* Unit attention, Device internal reset */
101 extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET
;
102 /* Data Protection, Write Protected */
103 extern const struct SCSISense sense_code_WRITE_PROTECTED
;
104 /* Data Protection, Space Allocation Failed Write Protect */
105 extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED
;
107 #define SENSE_CODE(x) sense_code_ ## x
109 int scsi_sense_to_errno(int key
, int asc
, int ascq
);
110 int scsi_sense_buf_to_errno(const uint8_t *sense
, size_t sense_size
);
111 bool scsi_sense_buf_is_guest_recoverable(const uint8_t *sense
, size_t sense_size
);
113 int scsi_convert_sense(uint8_t *in_buf
, int in_len
,
114 uint8_t *buf
, int len
, bool fixed
);
115 const char *scsi_command_name(uint8_t cmd
);
117 uint64_t scsi_cmd_lba(SCSICommand
*cmd
);
118 uint32_t scsi_data_cdb_xfer(uint8_t *buf
);
119 uint32_t scsi_cdb_xfer(uint8_t *buf
);
120 int scsi_cdb_length(uint8_t *buf
);
122 /* Linux SG_IO interface. */
124 #define SG_ERR_DRIVER_TIMEOUT 0x06
125 #define SG_ERR_DRIVER_SENSE 0x08
127 #define SG_ERR_DID_OK 0x00
128 #define SG_ERR_DID_NO_CONNECT 0x01
129 #define SG_ERR_DID_BUS_BUSY 0x02
130 #define SG_ERR_DID_TIME_OUT 0x03
132 #define SG_ERR_DRIVER_SENSE 0x08
134 int sg_io_sense_from_errno(int errno_value
, struct sg_io_hdr
*io_hdr
,