xref: /qemu/include/scsi/utils.h (revision e5b5728cd330f533e02e483af8973ad7ffccce8b)
1*e5b5728cSPaolo Bonzini #ifndef SCSI_UTILS_H
2*e5b5728cSPaolo Bonzini #define SCSI_UTILS_H 1
3*e5b5728cSPaolo Bonzini 
4*e5b5728cSPaolo Bonzini #ifdef CONFIG_LINUX
5*e5b5728cSPaolo Bonzini #include <scsi/sg.h>
6*e5b5728cSPaolo Bonzini #endif
7*e5b5728cSPaolo Bonzini 
8*e5b5728cSPaolo Bonzini #define SCSI_CMD_BUF_SIZE      16
9*e5b5728cSPaolo Bonzini #define SCSI_SENSE_LEN         18
10*e5b5728cSPaolo Bonzini #define SCSI_SENSE_LEN_SCANNER 32
11*e5b5728cSPaolo Bonzini #define SCSI_INQUIRY_LEN       36
12*e5b5728cSPaolo Bonzini 
13*e5b5728cSPaolo Bonzini enum SCSIXferMode {
14*e5b5728cSPaolo Bonzini     SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
15*e5b5728cSPaolo Bonzini     SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
16*e5b5728cSPaolo Bonzini     SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
17*e5b5728cSPaolo Bonzini };
18*e5b5728cSPaolo Bonzini 
19*e5b5728cSPaolo Bonzini typedef struct SCSICommand {
20*e5b5728cSPaolo Bonzini     uint8_t buf[SCSI_CMD_BUF_SIZE];
21*e5b5728cSPaolo Bonzini     int len;
22*e5b5728cSPaolo Bonzini     size_t xfer;
23*e5b5728cSPaolo Bonzini     uint64_t lba;
24*e5b5728cSPaolo Bonzini     enum SCSIXferMode mode;
25*e5b5728cSPaolo Bonzini } SCSICommand;
26*e5b5728cSPaolo Bonzini 
27*e5b5728cSPaolo Bonzini typedef struct SCSISense {
28*e5b5728cSPaolo Bonzini     uint8_t key;
29*e5b5728cSPaolo Bonzini     uint8_t asc;
30*e5b5728cSPaolo Bonzini     uint8_t ascq;
31*e5b5728cSPaolo Bonzini } SCSISense;
32*e5b5728cSPaolo Bonzini 
33*e5b5728cSPaolo Bonzini /*
34*e5b5728cSPaolo Bonzini  * Predefined sense codes
35*e5b5728cSPaolo Bonzini  */
36*e5b5728cSPaolo Bonzini 
37*e5b5728cSPaolo Bonzini /* No sense data available */
38*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_NO_SENSE;
39*e5b5728cSPaolo Bonzini /* LUN not ready, Manual intervention required */
40*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_LUN_NOT_READY;
41*e5b5728cSPaolo Bonzini /* LUN not ready, Medium not present */
42*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_NO_MEDIUM;
43*e5b5728cSPaolo Bonzini /* LUN not ready, medium removal prevented */
44*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
45*e5b5728cSPaolo Bonzini /* Hardware error, internal target failure */
46*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_TARGET_FAILURE;
47*e5b5728cSPaolo Bonzini /* Illegal request, invalid command operation code */
48*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_INVALID_OPCODE;
49*e5b5728cSPaolo Bonzini /* Illegal request, LBA out of range */
50*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
51*e5b5728cSPaolo Bonzini /* Illegal request, Invalid field in CDB */
52*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_INVALID_FIELD;
53*e5b5728cSPaolo Bonzini /* Illegal request, Invalid field in parameter list */
54*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_INVALID_PARAM;
55*e5b5728cSPaolo Bonzini /* Illegal request, Parameter list length error */
56*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_INVALID_PARAM_LEN;
57*e5b5728cSPaolo Bonzini /* Illegal request, LUN not supported */
58*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
59*e5b5728cSPaolo Bonzini /* Illegal request, Saving parameters not supported */
60*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
61*e5b5728cSPaolo Bonzini /* Illegal request, Incompatible format */
62*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
63*e5b5728cSPaolo Bonzini /* Illegal request, medium removal prevented */
64*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
65*e5b5728cSPaolo Bonzini /* Illegal request, Invalid Transfer Tag */
66*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_INVALID_TAG;
67*e5b5728cSPaolo Bonzini /* Command aborted, I/O process terminated */
68*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_IO_ERROR;
69*e5b5728cSPaolo Bonzini /* Command aborted, I_T Nexus loss occurred */
70*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
71*e5b5728cSPaolo Bonzini /* Command aborted, Logical Unit failure */
72*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_LUN_FAILURE;
73*e5b5728cSPaolo Bonzini /* Command aborted, Overlapped Commands Attempted */
74*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
75*e5b5728cSPaolo Bonzini /* LUN not ready, Capacity data has changed */
76*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_CAPACITY_CHANGED;
77*e5b5728cSPaolo Bonzini /* LUN not ready, Medium not present */
78*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
79*e5b5728cSPaolo Bonzini /* Unit attention, Power on, reset or bus device reset occurred */
80*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_RESET;
81*e5b5728cSPaolo Bonzini /* Unit attention, Medium may have changed*/
82*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_MEDIUM_CHANGED;
83*e5b5728cSPaolo Bonzini /* Unit attention, Reported LUNs data has changed */
84*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
85*e5b5728cSPaolo Bonzini /* Unit attention, Device internal reset */
86*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
87*e5b5728cSPaolo Bonzini /* Data Protection, Write Protected */
88*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_WRITE_PROTECTED;
89*e5b5728cSPaolo Bonzini /* Data Protection, Space Allocation Failed Write Protect */
90*e5b5728cSPaolo Bonzini extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
91*e5b5728cSPaolo Bonzini 
92*e5b5728cSPaolo Bonzini #define SENSE_CODE(x) sense_code_ ## x
93*e5b5728cSPaolo Bonzini 
94*e5b5728cSPaolo Bonzini int scsi_sense_to_errno(int key, int asc, int ascq);
95*e5b5728cSPaolo Bonzini int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
96*e5b5728cSPaolo Bonzini 
97*e5b5728cSPaolo Bonzini int scsi_convert_sense(uint8_t *in_buf, int in_len,
98*e5b5728cSPaolo Bonzini                        uint8_t *buf, int len, bool fixed);
99*e5b5728cSPaolo Bonzini const char *scsi_command_name(uint8_t cmd);
100*e5b5728cSPaolo Bonzini 
101*e5b5728cSPaolo Bonzini uint64_t scsi_cmd_lba(SCSICommand *cmd);
102*e5b5728cSPaolo Bonzini uint32_t scsi_data_cdb_xfer(uint8_t *buf);
103*e5b5728cSPaolo Bonzini uint32_t scsi_cdb_xfer(uint8_t *buf);
104*e5b5728cSPaolo Bonzini int scsi_cdb_length(uint8_t *buf);
105*e5b5728cSPaolo Bonzini 
106*e5b5728cSPaolo Bonzini /* Linux SG_IO interface.  */
107*e5b5728cSPaolo Bonzini #ifdef CONFIG_LINUX
108*e5b5728cSPaolo Bonzini #define SG_ERR_DRIVER_TIMEOUT  0x06
109*e5b5728cSPaolo Bonzini #define SG_ERR_DRIVER_SENSE    0x08
110*e5b5728cSPaolo Bonzini 
111*e5b5728cSPaolo Bonzini #define SG_ERR_DID_OK          0x00
112*e5b5728cSPaolo Bonzini #define SG_ERR_DID_NO_CONNECT  0x01
113*e5b5728cSPaolo Bonzini #define SG_ERR_DID_BUS_BUSY    0x02
114*e5b5728cSPaolo Bonzini #define SG_ERR_DID_TIME_OUT    0x03
115*e5b5728cSPaolo Bonzini 
116*e5b5728cSPaolo Bonzini #define SG_ERR_DRIVER_SENSE    0x08
117*e5b5728cSPaolo Bonzini #endif
118*e5b5728cSPaolo Bonzini 
119*e5b5728cSPaolo Bonzini #endif
120