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
13enum SCSIXferMode {
14 SCSI_XFER_NONE,
15 SCSI_XFER_FROM_DEV,
16 SCSI_XFER_TO_DEV,
17};
18
19enum 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
35typedef 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
43typedef struct SCSISense {
44 uint8_t key;
45 uint8_t asc;
46 uint8_t ascq;
47} SCSISense;
48
49int scsi_build_sense(uint8_t *buf, SCSISense sense);
50SCSISense scsi_parse_sense_buf(const uint8_t *in_buf, int in_len);
51int scsi_build_sense_buf(uint8_t *buf, size_t max_size, SCSISense sense,
52 bool fixed_sense);
53
54
55
56
57
58
59extern const struct SCSISense sense_code_NO_SENSE;
60
61extern const struct SCSISense sense_code_LUN_NOT_READY;
62
63extern const struct SCSISense sense_code_NO_MEDIUM;
64
65extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
66
67extern const struct SCSISense sense_code_TARGET_FAILURE;
68
69extern const struct SCSISense sense_code_INVALID_OPCODE;
70
71extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
72
73extern const struct SCSISense sense_code_INVALID_FIELD;
74
75extern const struct SCSISense sense_code_INVALID_PARAM;
76
77extern const struct SCSISense sense_code_INVALID_PARAM_VALUE;
78
79extern const struct SCSISense sense_code_INVALID_PARAM_LEN;
80
81extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
82
83extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
84
85extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
86
87extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
88
89extern const struct SCSISense sense_code_INVALID_TAG;
90
91extern const struct SCSISense sense_code_IO_ERROR;
92
93extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
94
95extern const struct SCSISense sense_code_LUN_FAILURE;
96
97extern const struct SCSISense sense_code_LUN_COMM_FAILURE;
98
99extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
100
101extern const struct SCSISense sense_code_READ_ERROR;
102
103extern const struct SCSISense sense_code_NOT_READY;
104
105extern const struct SCSISense sense_code_CAPACITY_CHANGED;
106
107extern const struct SCSISense sense_code_SCSI_BUS_RESET;
108
109extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
110
111extern const struct SCSISense sense_code_RESET;
112
113extern const struct SCSISense sense_code_MEDIUM_CHANGED;
114
115extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
116
117extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
118
119extern const struct SCSISense sense_code_WRITE_PROTECTED;
120
121extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
122
123#define SENSE_CODE(x) sense_code_ ## x
124
125int scsi_sense_to_errno(int key, int asc, int ascq);
126int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
127bool scsi_sense_buf_is_guest_recoverable(const uint8_t *sense, size_t sense_size);
128
129int scsi_convert_sense(uint8_t *in_buf, int in_len,
130 uint8_t *buf, int len, bool fixed);
131const char *scsi_command_name(uint8_t cmd);
132
133uint64_t scsi_cmd_lba(SCSICommand *cmd);
134uint32_t scsi_data_cdb_xfer(uint8_t *buf);
135uint32_t scsi_cdb_xfer(uint8_t *buf);
136int scsi_cdb_length(uint8_t *buf);
137
138
139#ifdef CONFIG_LINUX
140#define SG_ERR_DRIVER_TIMEOUT 0x06
141#define SG_ERR_DRIVER_SENSE 0x08
142#endif
143
144int scsi_sense_from_errno(int errno_value, SCSISense *sense);
145int scsi_sense_from_host_status(uint8_t host_status, SCSISense *sense);
146
147#endif
148