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, Parameter list length error */
61 extern const struct SCSISense sense_code_INVALID_PARAM_LEN
;
62 /* Illegal request, LUN not supported */
63 extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED
;
64 /* Illegal request, Saving parameters not supported */
65 extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED
;
66 /* Illegal request, Incompatible format */
67 extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT
;
68 /* Illegal request, medium removal prevented */
69 extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED
;
70 /* Illegal request, Invalid Transfer Tag */
71 extern const struct SCSISense sense_code_INVALID_TAG
;
72 /* Command aborted, I/O process terminated */
73 extern const struct SCSISense sense_code_IO_ERROR
;
74 /* Command aborted, I_T Nexus loss occurred */
75 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS
;
76 /* Command aborted, Logical Unit failure */
77 extern const struct SCSISense sense_code_LUN_FAILURE
;
78 /* Command aborted, LUN Communication failure */
79 extern const struct SCSISense sense_code_LUN_COMM_FAILURE
;
80 /* Command aborted, Overlapped Commands Attempted */
81 extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS
;
82 /* Medium error, Unrecovered read error */
83 extern const struct SCSISense sense_code_READ_ERROR
;
84 /* LUN not ready, Cause not reportable */
85 extern const struct SCSISense sense_code_NOT_READY
;
86 /* Unit attention, Capacity data has changed */
87 extern const struct SCSISense sense_code_CAPACITY_CHANGED
;
88 /* Unit attention, SCSI bus reset */
89 extern const struct SCSISense sense_code_SCSI_BUS_RESET
;
90 /* LUN not ready, Medium not present */
91 extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM
;
92 /* Unit attention, Power on, reset or bus device reset occurred */
93 extern const struct SCSISense sense_code_RESET
;
94 /* Unit attention, Medium may have changed*/
95 extern const struct SCSISense sense_code_MEDIUM_CHANGED
;
96 /* Unit attention, Reported LUNs data has changed */
97 extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED
;
98 /* Unit attention, Device internal reset */
99 extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET
;
100 /* Data Protection, Write Protected */
101 extern const struct SCSISense sense_code_WRITE_PROTECTED
;
102 /* Data Protection, Space Allocation Failed Write Protect */
103 extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED
;
105 #define SENSE_CODE(x) sense_code_ ## x
107 int scsi_sense_to_errno(int key
, int asc
, int ascq
);
108 int scsi_sense_buf_to_errno(const uint8_t *sense
, size_t sense_size
);
109 bool scsi_sense_buf_is_guest_recoverable(const uint8_t *sense
, size_t sense_size
);
111 int scsi_convert_sense(uint8_t *in_buf
, int in_len
,
112 uint8_t *buf
, int len
, bool fixed
);
113 const char *scsi_command_name(uint8_t cmd
);
115 uint64_t scsi_cmd_lba(SCSICommand
*cmd
);
116 uint32_t scsi_data_cdb_xfer(uint8_t *buf
);
117 uint32_t scsi_cdb_xfer(uint8_t *buf
);
118 int scsi_cdb_length(uint8_t *buf
);
120 /* Linux SG_IO interface. */
122 #define SG_ERR_DRIVER_TIMEOUT 0x06
123 #define SG_ERR_DRIVER_SENSE 0x08
125 #define SG_ERR_DID_OK 0x00
126 #define SG_ERR_DID_NO_CONNECT 0x01
127 #define SG_ERR_DID_BUS_BUSY 0x02
128 #define SG_ERR_DID_TIME_OUT 0x03
130 #define SG_ERR_DRIVER_SENSE 0x08
132 int sg_io_sense_from_errno(int errno_value
, struct sg_io_hdr
*io_hdr
,