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