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