Merge tag 'pull-for-6.2-291121-1' of https://github.com/stsquad/qemu into staging
[qemu.git] / include / scsi / utils.h
1 #ifndef SCSI_UTILS_H
2 #define SCSI_UTILS_H
3
4 #ifdef CONFIG_LINUX
5 #include <scsi/sg.h>
6 #endif
7
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
12
13 enum SCSIXferMode {
14 SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */
15 SCSI_XFER_FROM_DEV, /* READ, INQUIRY, MODE_SENSE, ... */
16 SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */
17 };
18
19 enum SCSIHostStatus {
20 SCSI_HOST_OK,
21 SCSI_HOST_NO_LUN,
22 SCSI_HOST_BUSY,
23 SCSI_HOST_TIME_OUT,
24 SCSI_HOST_BAD_RESPONSE,
25 SCSI_HOST_ABORTED,
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,
33 };
34
35 typedef struct SCSICommand {
36 uint8_t buf[SCSI_CMD_BUF_SIZE];
37 int len;
38 size_t xfer;
39 uint64_t lba;
40 enum SCSIXferMode mode;
41 } SCSICommand;
42
43 typedef struct SCSISense {
44 uint8_t key;
45 uint8_t asc;
46 uint8_t ascq;
47 } SCSISense;
48
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,
52 bool fixed_sense);
53
54 /*
55 * Predefined sense codes
56 */
57
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;
122
123 #define SENSE_CODE(x) sense_code_ ## x
124
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);
128
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);
132
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);
137
138 /* Linux SG_IO interface. */
139 #ifdef CONFIG_LINUX
140 #define SG_ERR_DRIVER_TIMEOUT 0x06
141 #define SG_ERR_DRIVER_SENSE 0x08
142 #endif
143
144 int scsi_sense_from_errno(int errno_value, SCSISense *sense);
145 int scsi_sense_from_host_status(uint8_t host_status, SCSISense *sense);
146
147 #endif