• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GPXE_SCSI_H
2 #define _GPXE_SCSI_H
3 
4 #include <stdint.h>
5 #include <gpxe/blockdev.h>
6 #include <gpxe/uaccess.h>
7 #include <gpxe/refcnt.h>
8 
9 /** @file
10  *
11  * SCSI devices
12  *
13  */
14 
15 FILE_LICENCE ( GPL2_OR_LATER );
16 
17 /**
18  * @defgroup scsiops SCSI operation codes
19  * @{
20  */
21 
22 #define SCSI_OPCODE_READ_10		0x28	/**< READ (10) */
23 #define SCSI_OPCODE_READ_16		0x88	/**< READ (16) */
24 #define SCSI_OPCODE_WRITE_10		0x2a	/**< WRITE (10) */
25 #define SCSI_OPCODE_WRITE_16		0x8a	/**< WRITE (16) */
26 #define SCSI_OPCODE_READ_CAPACITY_10	0x25	/**< READ CAPACITY (10) */
27 #define SCSI_OPCODE_SERVICE_ACTION_IN	0x9e	/**< SERVICE ACTION IN */
28 #define SCSI_SERVICE_ACTION_READ_CAPACITY_16 0x10 /**< READ CAPACITY (16) */
29 
30 /** @} */
31 
32 /**
33  * @defgroup scsiflags SCSI flags
34  * @{
35  */
36 
37 #define SCSI_FL_FUA_NV		0x02	/**< Force unit access to NVS */
38 #define SCSI_FL_FUA		0x08	/**< Force unit access */
39 #define SCSI_FL_DPO		0x10	/**< Disable cache page out */
40 
41 /** @} */
42 
43 /**
44  * @defgroup scsicdbs SCSI command data blocks
45  * @{
46  */
47 
48 /** A SCSI "READ (10)" CDB */
49 struct scsi_cdb_read_10 {
50 	/** Opcode (0x28) */
51 	uint8_t opcode;
52 	/** Flags */
53 	uint8_t flags;
54 	/** Start address
55 	 *
56 	 * This is a logical block number, in big-endian order.
57 	 */
58 	uint32_t lba;
59 	/** Group number */
60 	uint8_t group;
61 	/** Transfer length
62 	 *
63 	 * This is a logical block count, in big-endian order.
64 	 */
65 	uint16_t len;
66 	/** Control byte */
67 	uint8_t control;
68 } __attribute__ (( packed ));
69 
70 /** A SCSI "READ (16)" CDB */
71 struct scsi_cdb_read_16 {
72 	/** Opcode (0x88) */
73 	uint8_t opcode;
74 	/** Flags */
75 	uint8_t flags;
76 	/** Start address
77 	 *
78 	 * This is a logical block number, in big-endian order.
79 	 */
80 	uint64_t lba;
81 	/** Transfer length
82 	 *
83 	 * This is a logical block count, in big-endian order.
84 	 */
85 	uint32_t len;
86 	/** Group number */
87 	uint8_t group;
88 	/** Control byte */
89 	uint8_t control;
90 } __attribute__ (( packed ));
91 
92 /** A SCSI "WRITE (10)" CDB */
93 struct scsi_cdb_write_10 {
94 	/** Opcode (0x2a) */
95 	uint8_t opcode;
96 	/** Flags */
97 	uint8_t flags;
98 	/** Start address
99 	 *
100 	 * This is a logical block number, in big-endian order.
101 	 */
102 	uint32_t lba;
103 	/** Group number */
104 	uint8_t group;
105 	/** Transfer length
106 	 *
107 	 * This is a logical block count, in big-endian order.
108 	 */
109 	uint16_t len;
110 	/** Control byte */
111 	uint8_t control;
112 } __attribute__ (( packed ));
113 
114 /** A SCSI "WRITE (16)" CDB */
115 struct scsi_cdb_write_16 {
116 	/** Opcode (0x8a) */
117 	uint8_t opcode;
118 	/** Flags */
119 	uint8_t flags;
120 	/** Start address
121 	 *
122 	 * This is a logical block number, in big-endian order.
123 	 */
124 	uint64_t lba;
125 	/** Transfer length
126 	 *
127 	 * This is a logical block count, in big-endian order.
128 	 */
129 	uint32_t len;
130 	/** Group number */
131 	uint8_t group;
132 	/** Control byte */
133 	uint8_t control;
134 } __attribute__ (( packed ));
135 
136 /** A SCSI "READ CAPACITY (10)" CDB */
137 struct scsi_cdb_read_capacity_10 {
138 	/** Opcode (0x25) */
139 	uint8_t opcode;
140 	/** Reserved */
141 	uint8_t reserved_a;
142 	/** Logical block address
143 	 *
144 	 * Applicable only if the PMI bit is set.
145 	 */
146 	uint32_t lba;
147 	/** Reserved */
148 	uint8_t reserved_b[3];
149 	/** Control byte */
150 	uint8_t control;
151 } __attribute__ (( packed ));
152 
153 /** SCSI "READ CAPACITY (10)" parameter data */
154 struct scsi_capacity_10 {
155 	/** Maximum logical block number */
156 	uint32_t lba;
157 	/** Block length in bytes */
158 	uint32_t blksize;
159 } __attribute__ (( packed ));
160 
161 /** A SCSI "READ CAPACITY (16)" CDB */
162 struct scsi_cdb_read_capacity_16 {
163 	/** Opcode (0x9e) */
164 	uint8_t opcode;
165 	/** Service action */
166 	uint8_t service_action;
167 	/** Logical block address
168 	 *
169 	 * Applicable only if the PMI bit is set.
170 	 */
171 	uint64_t lba;
172 	/** Transfer length
173 	 *
174 	 * This is the size of the data-in buffer, in bytes.
175 	 */
176 	uint32_t len;
177 	/** Reserved */
178 	uint8_t reserved;
179 	/** Control byte */
180 	uint8_t control;
181 } __attribute__ (( packed ));
182 
183 /** SCSI "READ CAPACITY (16)" parameter data */
184 struct scsi_capacity_16 {
185 	/** Maximum logical block number */
186 	uint64_t lba;
187 	/** Block length in bytes */
188 	uint32_t blksize;
189 	/** Reserved */
190 	uint8_t reserved[20];
191 } __attribute__ (( packed ));
192 
193 /** A SCSI Command Data Block */
194 union scsi_cdb {
195 	struct scsi_cdb_read_10 read10;
196 	struct scsi_cdb_read_16 read16;
197 	struct scsi_cdb_write_10 write10;
198 	struct scsi_cdb_write_16 write16;
199 	struct scsi_cdb_read_capacity_10 readcap10;
200 	struct scsi_cdb_read_capacity_16 readcap16;
201 	unsigned char bytes[16];
202 };
203 
204 /** printf() format for dumping a scsi_cdb */
205 #define SCSI_CDB_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \
206 			"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
207 
208 /** printf() parameters for dumping a scsi_cdb */
209 #define SCSI_CDB_DATA(cdb)						  \
210 	(cdb).bytes[0], (cdb).bytes[1], (cdb).bytes[2], (cdb).bytes[3],	  \
211 	(cdb).bytes[4], (cdb).bytes[5], (cdb).bytes[6], (cdb).bytes[7],	  \
212 	(cdb).bytes[8], (cdb).bytes[9], (cdb).bytes[10], (cdb).bytes[11], \
213 	(cdb).bytes[12], (cdb).bytes[13], (cdb).bytes[14], (cdb).bytes[15]
214 
215 /** @} */
216 
217 /** A SCSI command */
218 struct scsi_command {
219 	/** CDB for this command */
220 	union scsi_cdb cdb;
221 	/** Data-out buffer (may be NULL) */
222 	userptr_t data_out;
223 	/** Data-out buffer length
224 	 *
225 	 * Must be zero if @c data_out is NULL
226 	 */
227 	size_t data_out_len;
228 	/** Data-in buffer (may be NULL) */
229 	userptr_t data_in;
230 	/** Data-in buffer length
231 	 *
232 	 * Must be zero if @c data_in is NULL
233 	 */
234 	size_t data_in_len;
235 	/** SCSI status code */
236 	uint8_t status;
237 	/** SCSI sense response code */
238 	uint8_t sense_response;
239 	/** Command status code */
240 	int rc;
241 };
242 
243 /** A SCSI LUN
244  *
245  * This is a four-level LUN as specified by SAM-2, in big-endian
246  * order.
247  */
248 struct scsi_lun {
249 	uint16_t u16[4];
250 }  __attribute__ (( packed ));
251 
252 /** A SCSI device */
253 struct scsi_device {
254 	/** Block device interface */
255 	struct block_device blockdev;
256 	/**
257 	 * Issue SCSI command
258 	 *
259 	 * @v scsi		SCSI device
260 	 * @v command		SCSI command
261 	 * @ret rc		Return status code
262 	 *
263 	 * Note that a successful return status code indicates only
264 	 * that the SCSI command was issued.  The caller must check
265 	 * the status field in the command structure to see when the
266 	 * command completes and whether, for example, the device
267 	 * returned CHECK CONDITION or some other non-success status
268 	 * code.
269 	 */
270 	int ( * command ) ( struct scsi_device *scsi,
271 			    struct scsi_command *command );
272 	/** Backing device */
273 	struct refcnt *backend;
274 };
275 
276 extern int scsi_detached_command ( struct scsi_device *scsi,
277 				   struct scsi_command *command );
278 extern int init_scsidev ( struct scsi_device *scsi );
279 extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun );
280 
281 #endif /* _GPXE_SCSI_H */
282