c1161de95975f303e37a9a2bc54dd5bb26c7e1c5
[gpxe.git] / src / include / gpxe / iscsi.h
1 #ifndef _GPXE_ISCSI_H
2 #define _GPXE_ISCSI_H
3
4 /** @file
5  *
6  * iSCSI protocol
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/tcp.h>
12 #include <gpxe/scsi.h>
13
14 /**
15  * iSCSI segment lengths
16  *
17  * iSCSI uses an icky structure with one one-byte field (a dword
18  * count) and one three-byte field (a byte count).  This structure,
19  * and the accompanying macros, relieve some of the pain.
20  */
21 union iscsi_segment_lengths {
22         struct {
23                 /** The AHS length (measured in dwords) */
24                 uint8_t ahs_len;
25                 /** The data length (measured in bytes), in network
26                  * byte order
27                  */
28                 uint8_t data_len[3];
29         } bytes;
30         /** Ths data length (measured in bytes), in network byte
31          * order, with ahs_len as the first byte.
32          */
33         uint32_t ahs_and_data_len;
34 };
35
36 /** The length of the additional header segment, in dwords */
37 #define ISCSI_AHS_LEN( segment_lengths ) \
38         ( (segment_lengths).bytes.ahs_len )
39
40 /** The length of the data segment, in bytes, excluding any padding */
41 #define ISCSI_DATA_LEN( segment_lengths ) \
42         ( ntohl ( (segment_lengths).ahs_and_data_len ) & 0xffffff )
43
44 /** The padding of the data segment, in bytes */
45 #define ISCSI_DATA_PAD_LEN( segment_lengths ) \
46         ( ( 0 - (segment_lengths).bytes.data_len[2] ) & 0x03 )
47
48 /** Set additional header and data segment lengths */
49 #define ISCSI_SET_LENGTHS( segment_lengths, ahs_len, data_len ) do {    \
50         (segment_lengths).ahs_and_data_len =                            \
51                 htonl ( data_len | ( ahs_len << 24 ) );                 \
52         } while ( 0 )
53
54 /**
55  * iSCSI basic header segment common fields
56  *
57  */
58 struct iscsi_bhs_common {
59         /** Opcode */
60         uint8_t opcode;
61         /** Flags */
62         uint8_t flags;
63         /** Fields specific to the PDU type */
64         uint8_t other_a[2];
65         /** Segment lengths */
66         union iscsi_segment_lengths lengths;
67         /** Fields specific to the PDU type */
68         uint8_t other_b[8];
69         /** Initiator Task Tag */
70         uint32_t itt;
71         /** Fields specific to the PDU type */
72         uint8_t other_c[28];
73 };
74
75 /** Opcode mask */
76 #define ISCSI_OPCODE_MASK 0x3f
77
78 /** Immediate delivery */
79 #define ISCSI_FLAG_IMMEDIATE 0x40
80
81 /** Final PDU of a sequence */
82 #define ISCSI_FLAG_FINAL 0x80
83
84 /**
85  * iSCSI basic header segment common request fields
86  *
87  */
88 struct iscsi_bhs_common_response {
89         /** Opcode */
90         uint8_t opcode;
91         /** Flags */
92         uint8_t flags;
93         /** Fields specific to the PDU type */
94         uint8_t other_a[2];
95         /** Segment lengths */
96         union iscsi_segment_lengths lengths;
97         /** Fields specific to the PDU type */
98         uint8_t other_b[8];
99         /** Initiator Task Tag */
100         uint32_t itt;
101         /** Fields specific to the PDU type */
102         uint8_t other_c[4];
103         /** Status sequence number */
104         uint32_t statsn;
105         /** Expected command sequence number */
106         uint32_t expcmdsn;
107         /** Fields specific to the PDU type */
108         uint8_t other_d[16];
109 };
110
111 /**
112  * iSCSI login request basic header segment
113  *
114  */
115 struct iscsi_bhs_login_request {
116         /** Opcode */
117         uint8_t opcode;
118         /** Flags */
119         uint8_t flags;
120         /** Maximum supported version number */
121         uint8_t version_max;
122         /** Minimum supported version number */
123         uint8_t version_min;
124         /** Segment lengths */
125         union iscsi_segment_lengths lengths;
126         /** Initiator session ID (IANA format) enterprise number and flags */
127         uint32_t isid_iana_en;
128         /** Initiator session ID (IANA format) qualifier */
129         uint16_t isid_iana_qual;
130         /** Target session identifying handle */
131         uint16_t tsih;
132         /** Initiator Task Tag */
133         uint32_t itt;
134         /** Connection ID */
135         uint16_t cid;
136         /** Reserved */
137         uint16_t reserved_a;
138         /** Command sequence number */
139         uint32_t cmdsn;
140         /** Expected status sequence number */
141         uint32_t expstatsn;
142         /** Reserved */
143         uint8_t reserved_b[16];
144 };
145
146 /** Login request opcode */
147 #define ISCSI_OPCODE_LOGIN_REQUEST 0x03
148
149 /** Willingness to transition to next stage */
150 #define ISCSI_LOGIN_FLAG_TRANSITION 0x80
151
152 /** Key=value pairs continued in subsequent request */
153 #define ISCSI_LOGIN_FLAG_CONTINUE 0x40
154
155 /* Current stage values and mask */
156 #define ISCSI_LOGIN_CSG_MASK 0x0c
157 #define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION 0x00
158 #define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION 0x04
159 #define ISCSI_LOGIN_CSG_FULL_FEATURE_PHASE 0x0c
160
161 /* Next stage values and mask */
162 #define ISCSI_LOGIN_NSG_MASK 0x03
163 #define ISCSI_LOGIN_NSG_SECURITY_NEGOTIATION 0x00
164 #define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION 0x01
165 #define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE 0x03
166
167 /** ISID IANA format marker */
168 #define ISCSI_ISID_IANA 0x40000000
169
170 /** Fen Systems Ltd. IANA enterprise number
171  *
172  * Permission is hereby granted to use Fen Systems Ltd.'s IANA
173  * enterprise number with this iSCSI implementation.
174  */
175 #define IANA_EN_FEN_SYSTEMS 10019
176
177 /**
178  * iSCSI login response basic header segment
179  *
180  */
181 struct iscsi_bhs_login_response {
182         /** Opcode */
183         uint8_t opcode;
184         /** Flags */
185         uint8_t flags;
186         /** Maximum supported version number */
187         uint8_t version_max;
188         /** Minimum supported version number */
189         uint8_t version_min;
190         /** Segment lengths */
191         union iscsi_segment_lengths lengths;
192         /** Initiator session ID (IANA format) enterprise number and flags */
193         uint32_t isid_iana_en;
194         /** Initiator session ID (IANA format) qualifier */
195         uint16_t isid_iana_qual;
196         /** Target session identifying handle */
197         uint16_t tsih;
198         /** Initiator Task Tag */
199         uint32_t itt;
200         /** Reserved */
201         uint32_t reserved_a;
202         /** Status sequence number */
203         uint32_t statsn;
204         /** Expected command sequence number */
205         uint32_t expcmdsn;
206         /** Maximum command sequence number */
207         uint32_t maxcmdsn;
208         /** Status class */
209         uint8_t status_class;
210         /** Status detail */
211         uint8_t status_detail;
212         /** Reserved */
213         uint8_t reserved_b[10];
214 };
215
216 /** Login response opcode */
217 #define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
218
219 /**
220  * iSCSI SCSI command basic header segment
221  *
222  */
223 struct iscsi_bhs_scsi_command {
224         /** Opcode */
225         uint8_t opcode;
226         /** Flags */
227         uint8_t flags;
228         /** Reserved */
229         uint16_t reserved_a;
230         /** Segment lengths */
231         union iscsi_segment_lengths lengths;
232         /** SCSI Logical Unit Number */
233         uint64_t lun;
234         /** Initiator Task Tag */
235         uint32_t itt;
236         /** Expected data transfer length */
237         uint32_t exp_len;
238         /** Command sequence number */
239         uint32_t cmdsn;
240         /** Expected status sequence number */
241         uint32_t expstatsn;
242         /** SCSI Command Descriptor Block (CDB) */
243         union scsi_cdb cdb;
244 };
245
246 /** SCSI command opcode */
247 #define ISCSI_OPCODE_SCSI_COMMAND 0x01
248
249 /** Command will read data */
250 #define ISCSI_COMMAND_FLAG_READ 0x40
251
252 /** Command will write data */
253 #define ISCSI_COMMAND_FLAG_WRITE 0x20
254
255 /* Task attributes */
256 #define ISCSI_COMMAND_ATTR_UNTAGGED 0x00
257 #define ISCSI_COMMAND_ATTR_SIMPLE 0x01
258 #define ISCSI_COMMAND_ATTR_ORDERED 0x02
259 #define ISCSI_COMMAND_ATTR_HEAD_OF_QUEUE 0x03
260 #define ISCSI_COMMAND_ATTR_ACA 0x04
261
262 /**
263  * iSCSI SCSI response basic header segment
264  *
265  */
266 struct iscsi_bhs_scsi_response {
267         /** Opcode */
268         uint8_t opcode;
269         /** Flags */
270         uint8_t flags;
271         /** Response code */
272         uint8_t response;
273         /** SCSI status code */
274         uint8_t status;
275         /** Segment lengths */
276         union iscsi_segment_lengths lengths;
277         /** Reserved */
278         uint8_t reserved_a[8];
279         /** Initiator Task Tag */
280         uint32_t itt;
281         /** SNACK tag */
282         uint32_t snack;
283         /** Status sequence number */
284         uint32_t statsn;
285         /** Expected command sequence number */
286         uint32_t expcmdsn;
287         /** Maximum command sequence number */
288         uint32_t maxcmdsn;
289         /** Expected data sequence number */
290         uint32_t expdatasn;
291         /** Reserved */
292         uint8_t reserved_b[8];
293 };
294
295 /** SCSI response opcode */
296 #define ISCSI_OPCODE_SCSI_RESPONSE 0x21
297
298 /** SCSI command completed at target */
299 #define ISCSI_RESPONSE_COMMAND_COMPLETE 0x00
300
301 /** SCSI target failure */
302 #define ISCSI_RESPONSE_TARGET_FAILURE 0x01
303
304 /** SCSI sense response code offset
305  *
306  * The SCSI response may contain unsolicited sense data in the data
307  * segment.  If it does, this is the offset to the sense response code
308  * byte, which is the only byte we care about.
309  */
310 #define ISCSI_SENSE_RESPONSE_CODE_OFFSET 2
311
312 /**
313  * iSCSI data-in basic header segment
314  *
315  */
316 struct iscsi_bhs_data_in {
317         /** Opcode */
318         uint8_t opcode;
319         /** Flags */
320         uint8_t flags;
321         /** Reserved */
322         uint8_t reserved_a;
323         /** SCSI status code */
324         uint8_t status;
325         /** Segment lengths */
326         union iscsi_segment_lengths lengths;
327         /** Logical Unit Number */
328         uint64_t lun;
329         /** Initiator Task Tag */
330         uint32_t itt;
331         /** Target Transfer Tag */
332         uint32_t ttt;
333         /** Status sequence number */
334         uint32_t statsn;
335         /** Expected command sequence number */
336         uint32_t expcmdsn;
337         /** Maximum command sequence number */
338         uint32_t maxcmdsn;
339         /** Data sequence number */
340         uint32_t datasn;
341         /** Buffer offset */
342         uint32_t offset;
343         /** Residual count */
344         uint32_t residual_count;
345 };
346
347 /** Data-in opcode */
348 #define ISCSI_OPCODE_DATA_IN 0x25
349
350 /** Data requires acknowledgement */
351 #define ISCSI_DATA_FLAG_ACKNOWLEDGE 0x40
352
353 /** Data overflow occurred */
354 #define ISCSI_DATA_FLAG_OVERFLOW 0x04
355
356 /** Data underflow occurred */
357 #define ISCSI_DATA_FLAG_UNDERFLOW 0x02
358
359 /** SCSI status code and overflow/underflow flags are valid */
360 #define ISCSI_DATA_FLAG_STATUS 0x01
361
362 /**
363  * iSCSI data-out basic header segment
364  *
365  */
366 struct iscsi_bhs_data_out {
367         /** Opcode */
368         uint8_t opcode;
369         /** Flags */
370         uint8_t flags;
371         /** Reserved */
372         uint16_t reserved_a;
373         /** Segment lengths */
374         union iscsi_segment_lengths lengths;
375         /** Logical Unit Number */
376         uint64_t lun;
377         /** Initiator Task Tag */
378         uint32_t itt;
379         /** Target Transfer Tag */
380         uint32_t ttt;
381         /** Reserved */
382         uint32_t reserved_b;
383         /** Expected status sequence number */
384         uint32_t expstatsn;
385         /** Reserved */
386         uint32_t reserved_c;
387         /** Data sequence number */
388         uint32_t datasn;
389         /** Buffer offset */
390         uint32_t offset;
391         /** Reserved */
392         uint32_t reserved_d;
393 };
394
395 /** Data-out opcode */
396 #define ISCSI_OPCODE_DATA_OUT 0x05
397
398 /**
399  * iSCSI request to transfer basic header segment
400  *
401  */
402 struct iscsi_bhs_r2t {
403         /** Opcode */
404         uint8_t opcode;
405         /** Flags */
406         uint8_t flags;
407         /** Reserved */
408         uint16_t reserved_a;
409         /** Segment lengths */
410         union iscsi_segment_lengths lengths;
411         /** Logical Unit Number */
412         uint64_t lun;
413         /** Initiator Task Tag */
414         uint32_t itt;
415         /** Target Transfer Tag */
416         uint32_t ttt;
417         /** Status sequence number */
418         uint32_t statsn;
419         /** Expected command sequence number */
420         uint32_t expcmdsn;
421         /** Maximum command sequence number */
422         uint32_t maxcmdsn;
423         /** R2T sequence number */
424         uint32_t r2tsn;
425         /** Buffer offset */
426         uint32_t offset;
427         /** Desired data transfer length */
428         uint32_t len;
429 };
430
431 /** R2T opcode */
432 #define ISCSI_OPCODE_R2T 0x31
433
434 /**
435  * An iSCSI basic header segment
436  */
437 union iscsi_bhs {
438         struct iscsi_bhs_common common;
439         struct iscsi_bhs_common_response common_response;
440         struct iscsi_bhs_login_request login_request;
441         struct iscsi_bhs_login_response login_response;
442         struct iscsi_bhs_scsi_command scsi_command;
443         struct iscsi_bhs_scsi_response scsi_response;
444         struct iscsi_bhs_data_in data_in;
445         struct iscsi_bhs_data_out data_out;
446         struct iscsi_bhs_r2t r2t;
447         unsigned char bytes[ sizeof ( struct iscsi_bhs_common ) ];
448 };
449
450 /** State of an iSCSI TX engine */
451 enum iscsi_tx_state {
452         /** Nothing to send */
453         ISCSI_TX_IDLE = 0,
454         /** Sending the basic header segment */
455         ISCSI_TX_BHS,
456         /** Sending the additional header segment */
457         ISCSI_TX_AHS,
458         /** Sending the data segment */
459         ISCSI_TX_DATA,
460         /** Sending the data segment padding */
461         ISCSI_TX_DATA_PADDING,
462 };
463
464 /** State of an iSCSI RX engine */
465 enum iscsi_rx_state {
466         /** Receiving the basic header segment */
467         ISCSI_RX_BHS = 0,
468         /** Receiving the additional header segment */
469         ISCSI_RX_AHS,
470         /** Receiving the data segment */
471         ISCSI_RX_DATA,
472         /** Receiving the data segment padding */
473         ISCSI_RX_DATA_PADDING,
474 };
475
476 /** An iSCSI session */
477 struct iscsi_session {
478         /** TCP connection for this session */
479         struct tcp_connection tcp;
480         /** Session status
481          *
482          * This is the bitwise-OR of zero or more ISCSI_STATUS_XXX
483          * constants.
484          */
485         int status;
486         /** Retry count
487          *
488          * Number of times that the connection has been retried.
489          * Reset upon a successful connection.
490          */
491         int retry_count;
492
493         /** Initiator IQN */
494         const char *initiator;
495         /** Target IQN */
496         const char *target;
497         /** Logical Unit Number (LUN) */
498         uint64_t lun;
499
500         /** Target session identifying handle
501          *
502          * This is assigned by the target when we first log in, and
503          * must be reused on subsequent login attempts.
504          */
505         uint16_t tsih;
506         /** Initiator task tag
507          *
508          * This is the tag of the current command.  It is incremented
509          * whenever a new command is started.
510          */
511         uint32_t itt;
512         /** Target transfer tag
513          *
514          * This is the tag attached to a sequence of data-out PDUs in
515          * response to an R2T.
516          */
517         uint32_t ttt;
518         /**
519          * Transfer offset
520          *
521          * This is the offset for an in-progress sequence of data-out
522          * PDUs in response to an R2T.
523          */
524         uint32_t transfer_offset;
525         /**
526          * Transfer length
527          *
528          * This is the length for an in-progress sequence of data-out
529          * PDUs in response to an R2T.
530          */
531         uint32_t transfer_len;
532         /** Command sequence number
533          *
534          * This is the sequence number of the current command, used to
535          * fill out the CmdSN field in iSCSI request PDUs.  It is
536          * updated with the value of the ExpCmdSN field whenever we
537          * receive an iSCSI response PDU containing such a field.
538          */
539         uint32_t cmdsn;
540         /** Status sequence number
541          *
542          * This is the most recent status sequence number present in
543          * the StatSN field of an iSCSI response PDU containing such a
544          * field.  Whenever we send an iSCSI request PDU, we fill out
545          * the ExpStatSN field with this value plus one.
546          */
547         uint32_t statsn;
548         
549         /** Basic header segment for current TX PDU */
550         union iscsi_bhs tx_bhs;
551         /** State of the TX engine */
552         enum iscsi_tx_state tx_state;
553         /** Byte offset within the current TX state */
554         size_t tx_offset;
555
556         /** Basic header segment for current RX PDU */
557         union iscsi_bhs rx_bhs;
558         /** State of the RX engine */
559         enum iscsi_rx_state rx_state;
560         /** Byte offset within the current RX state */
561         size_t rx_offset;
562
563         /** Current SCSI command
564          *
565          * Set to NULL when command is complete.
566          */
567         struct scsi_command *command;
568 };
569
570 /** Session is currently connected */
571 #define ISCSI_STATUS_CONNECTED 0x01
572
573 /** Session has completed */
574 #define ISCSI_STATUS_DONE 0x02
575
576 /** Session failed */
577 #define ISCSI_STATUS_ERR 0x04
578
579 /** Maximum number of retries at connecting */
580 #define ISCSI_MAX_RETRIES 2
581
582 extern int iscsi_issue ( struct iscsi_session *iscsi,
583                          struct scsi_command *command );
584
585 /** An iSCSI device */
586 struct iscsi_device {
587         /** SCSI device interface */
588         struct scsi_device scsi;
589         /** iSCSI protocol instance */
590         struct iscsi_session iscsi;
591 };
592
593 extern int init_iscsidev ( struct iscsi_device *iscsidev );
594
595 #endif /* _GPXE_ISCSI_H */