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