1 #ifndef _IPXE_SCSI_H
2 #define _IPXE_SCSI_H
3 
4 #include <stdint.h>
5 #include <ipxe/uaccess.h>
6 #include <ipxe/interface.h>
7 
8 /** @file
9  *
10  * SCSI devices
11  *
12  */
13 
14 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
15 
16 /** Maximum block for READ/WRITE (10) commands */
17 #define SCSI_MAX_BLOCK_10 0xffffffffULL
18 
19 /**
20  * @defgroup scsiops SCSI operation codes
21  * @{
22  */
23 
24 #define SCSI_OPCODE_READ_10		0x28	/**< READ (10) */
25 #define SCSI_OPCODE_READ_16		0x88	/**< READ (16) */
26 #define SCSI_OPCODE_WRITE_10		0x2a	/**< WRITE (10) */
27 #define SCSI_OPCODE_WRITE_16		0x8a	/**< WRITE (16) */
28 #define SCSI_OPCODE_READ_CAPACITY_10	0x25	/**< READ CAPACITY (10) */
29 #define SCSI_OPCODE_SERVICE_ACTION_IN	0x9e	/**< SERVICE ACTION IN */
30 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */
31 #define SCSI_OPCODE_TEST_UNIT_READY	0x00	/**< TEST UNIT READY */
32 
33 /** @} */
34 
35 /**
36  * @defgroup scsiflags SCSI flags
37  * @{
38  */
39 
40 #define SCSI_FL_FUA_NV		0x02	/**< Force unit access to NVS */
41 #define SCSI_FL_FUA		0x08	/**< Force unit access */
42 #define SCSI_FL_DPO		0x10	/**< Disable cache page out */
43 
44 /** @} */
45 
46 /**
47  * @defgroup scsicdbs SCSI command data blocks
48  * @{
49  */
50 
51 /** A SCSI "READ (10)" CDB */
52 struct scsi_cdb_read_10 {
53 	/** Opcode (0x28) */
54 	uint8_t opcode;
55 	/** Flags */
56 	uint8_t flags;
57 	/** Start address
58 	 *
59 	 * This is a logical block number, in big-endian order.
60 	 */
61 	uint32_t lba;
62 	/** Group number */
63 	uint8_t group;
64 	/** Transfer length
65 	 *
66 	 * This is a logical block count, in big-endian order.
67 	 */
68 	uint16_t len;
69 	/** Control byte */
70 	uint8_t control;
71 } __attribute__ (( packed ));
72 
73 /** A SCSI "READ (16)" CDB */
74 struct scsi_cdb_read_16 {
75 	/** Opcode (0x88) */
76 	uint8_t opcode;
77 	/** Flags */
78 	uint8_t flags;
79 	/** Start address
80 	 *
81 	 * This is a logical block number, in big-endian order.
82 	 */
83 	uint64_t lba;
84 	/** Transfer length
85 	 *
86 	 * This is a logical block count, in big-endian order.
87 	 */
88 	uint32_t len;
89 	/** Group number */
90 	uint8_t group;
91 	/** Control byte */
92 	uint8_t control;
93 } __attribute__ (( packed ));
94 
95 /** A SCSI "WRITE (10)" CDB */
96 struct scsi_cdb_write_10 {
97 	/** Opcode (0x2a) */
98 	uint8_t opcode;
99 	/** Flags */
100 	uint8_t flags;
101 	/** Start address
102 	 *
103 	 * This is a logical block number, in big-endian order.
104 	 */
105 	uint32_t lba;
106 	/** Group number */
107 	uint8_t group;
108 	/** Transfer length
109 	 *
110 	 * This is a logical block count, in big-endian order.
111 	 */
112 	uint16_t len;
113 	/** Control byte */
114 	uint8_t control;
115 } __attribute__ (( packed ));
116 
117 /** A SCSI "WRITE (16)" CDB */
118 struct scsi_cdb_write_16 {
119 	/** Opcode (0x8a) */
120 	uint8_t opcode;
121 	/** Flags */
122 	uint8_t flags;
123 	/** Start address
124 	 *
125 	 * This is a logical block number, in big-endian order.
126 	 */
127 	uint64_t lba;
128 	/** Transfer length
129 	 *
130 	 * This is a logical block count, in big-endian order.
131 	 */
132 	uint32_t len;
133 	/** Group number */
134 	uint8_t group;
135 	/** Control byte */
136 	uint8_t control;
137 } __attribute__ (( packed ));
138 
139 /** A SCSI "READ CAPACITY (10)" CDB */
140 struct scsi_cdb_read_capacity_10 {
141 	/** Opcode (0x25) */
142 	uint8_t opcode;
143 	/** Reserved */
144 	uint8_t reserved_a;
145 	/** Logical block address
146 	 *
147 	 * Applicable only if the PMI bit is set.
148 	 */
149 	uint32_t lba;
150 	/** Reserved */
151 	uint8_t reserved_b[3];
152 	/** Control byte */
153 	uint8_t control;
154 } __attribute__ (( packed ));
155 
156 /** SCSI "READ CAPACITY (10)" parameter data */
157 struct scsi_capacity_10 {
158 	/** Maximum logical block number */
159 	uint32_t lba;
160 	/** Block length in bytes */
161 	uint32_t blksize;
162 } __attribute__ (( packed ));
163 
164 /** A SCSI "READ CAPACITY (16)" CDB */
165 struct scsi_cdb_read_capacity_16 {
166 	/** Opcode (0x9e) */
167 	uint8_t opcode;
168 	/** Service action */
169 	uint8_t service_action;
170 	/** Logical block address
171 	 *
172 	 * Applicable only if the PMI bit is set.
173 	 */
174 	uint64_t lba;
175 	/** Transfer length
176 	 *
177 	 * This is the size of the data-in buffer, in bytes.
178 	 */
179 	uint32_t len;
180 	/** Reserved */
181 	uint8_t reserved;
182 	/** Control byte */
183 	uint8_t control;
184 } __attribute__ (( packed ));
185 
186 /** SCSI "READ CAPACITY (16)" parameter data */
187 struct scsi_capacity_16 {
188 	/** Maximum logical block number */
189 	uint64_t lba;
190 	/** Block length in bytes */
191 	uint32_t blksize;
192 	/** Reserved */
193 	uint8_t reserved[20];
194 } __attribute__ (( packed ));
195 
196 /** A SCSI "TEST UNIT READY" CDB */
197 struct scsi_cdb_test_unit_ready {
198 	/** Opcode (0x00) */
199 	uint8_t opcode;
200 	/** Reserved */
201 	uint8_t reserved[4];
202 	/** Control byte */
203 	uint8_t control;
204 } __attribute__ (( packed ));
205 
206 /** A SCSI Command Data Block */
207 union scsi_cdb {
208 	struct scsi_cdb_read_10 read10;
209 	struct scsi_cdb_read_16 read16;
210 	struct scsi_cdb_write_10 write10;
211 	struct scsi_cdb_write_16 write16;
212 	struct scsi_cdb_read_capacity_10 readcap10;
213 	struct scsi_cdb_read_capacity_16 readcap16;
214 	struct scsi_cdb_test_unit_ready testready;
215 	unsigned char bytes[16];
216 };
217 
218 /** printf() format for dumping a scsi_cdb */
219 #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \
220 			"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
221 
222 /** printf() parameters for dumping a scsi_cdb */
223 #define SCSI_CDB_DATA(cdb)						  \
224 	(cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3],	  \
225 	(cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7],	  \
226 	(cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \
227 	(cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15]
228 
229 /** @} */
230 
231 /** A SCSI LUN
232  *
233  * This is a four-level LUN as specified by SAM-2, in big-endian
234  * order.
235  */
236 struct scsi_lun {
237 	uint16_t u16[4];
238 }  __attribute__ (( packed ));
239 
240 /** printf() format for dumping a scsi_lun */
241 #define SCSI_LUN_FORMAT "%04x-%04x-%04x-%04x"
242 
243 /** printf() parameters for dumping a scsi_lun */
244 #define SCSI_LUN_DATA(lun)						  \
245 	ntohs ( (lun).u16[0] ), ntohs ( (lun).u16[1] ),			  \
246 	ntohs ( (lun).u16[2] ), ntohs ( (lun).u16[3] )
247 
248 /** A SCSI command information unit */
249 struct scsi_cmd {
250 	/** LUN */
251 	struct scsi_lun lun;
252 	/** CDB for this command */
253 	union scsi_cdb cdb;
254 	/** Data-out buffer (may be NULL) */
255 	userptr_t data_out;
256 	/** Data-out buffer length
257 	 *
258 	 * Must be zero if @c data_out is NULL
259 	 */
260 	size_t data_out_len;
261 	/** Data-in buffer (may be NULL) */
262 	userptr_t data_in;
263 	/** Data-in buffer length
264 	 *
265 	 * Must be zero if @c data_in is NULL
266 	 */
267 	size_t data_in_len;
268 };
269 
270 /** SCSI fixed-format sense data */
271 struct scsi_sns_fixed {
272 	/** Response code */
273 	uint8_t code;
274 	/** Reserved */
275 	uint8_t reserved;
276 	/** Sense key */
277 	uint8_t key;
278 	/** Information */
279 	uint32_t info;
280 	/** Additional sense length */
281 	uint8_t len;
282 	/** Command-specific information */
283 	uint32_t cs_info;
284 	/** Additional sense code and qualifier */
285 	uint16_t additional;
286 } __attribute__ (( packed ));
287 
288 /** SCSI descriptor-format sense data */
289 struct scsi_sns_descriptor {
290 	/** Response code */
291 	uint8_t code;
292 	/** Sense key */
293 	uint8_t key;
294 	/** Additional sense code and qualifier */
295 	uint16_t additional;
296 } __attribute__ (( packed ));
297 
298 /** SCSI sense data */
299 union scsi_sns {
300 	/** Response code */
301 	uint8_t code;
302 	/** Fixed-format sense data */
303 	struct scsi_sns_fixed fixed;
304 	/** Descriptor-format sense data */
305 	struct scsi_sns_descriptor desc;
306 };
307 
308 /** SCSI sense response code mask */
309 #define SCSI_SENSE_CODE_MASK 0x7f
310 
311 /** Test if SCSI sense data is in fixed format
312  *
313  * @v code		Response code
314  * @ret is_fixed	Sense data is in fixed format
315  */
316 #define SCSI_SENSE_FIXED( code ) ( ( (code) & 0x7e ) == 0x70 )
317 
318 /** SCSI sense key mask */
319 #define SCSI_SENSE_KEY_MASK 0x0f
320 
321 /** A SCSI response information unit */
322 struct scsi_rsp {
323 	/** SCSI status code */
324 	uint8_t status;
325 	/** Data overrun (or negative underrun) */
326 	ssize_t overrun;
327 	/** Autosense data (if any)
328 	 *
329 	 * To minimise code size, this is stored as the first four
330 	 * bytes of a descriptor-format sense data block (even if the
331 	 * response code indicates fixed-format sense data).
332 	 */
333 	struct scsi_sns_descriptor sense;
334 };
335 
336 extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun );
337 extern void scsi_parse_sense ( const void *data, size_t len,
338 			       struct scsi_sns_descriptor *sense );
339 
340 extern int scsi_command ( struct interface *control, struct interface *data,
341 			  struct scsi_cmd *command );
342 #define scsi_command_TYPE( object_type )				\
343 	typeof ( int ( object_type, struct interface *data,		\
344 		       struct scsi_cmd *command ) )
345 
346 extern void scsi_response ( struct interface *intf, struct scsi_rsp *response );
347 #define scsi_response_TYPE( object_type ) \
348 	typeof ( void ( object_type, struct scsi_rsp *response ) )
349 
350 extern int scsi_open ( struct interface *block, struct interface *scsi,
351 		       struct scsi_lun *lun );
352 
353 #endif /* _IPXE_SCSI_H */
354