Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / srp.h
1 #ifndef _IPXE_SRP_H
2 #define _IPXE_SRP_H
3
4 /** @file
5  *
6  * SCSI RDMA Protocol
7  *
8  */
9
10 FILE_LICENCE ( BSD2 );
11
12 #include <stdint.h>
13 #include <byteswap.h>
14 #include <ipxe/iobuf.h>
15 #include <ipxe/xfer.h>
16 #include <ipxe/scsi.h>
17 #include <ipxe/acpi.h>
18
19 /*****************************************************************************
20  *
21  * Common fields
22  *
23  *****************************************************************************
24  */
25
26 /** An SRP information unit tag */
27 union srp_tag {
28         uint8_t bytes[8];
29         uint32_t dwords[2];
30 } __attribute__ (( packed ));
31
32 /** SRP tag magic marker */
33 #define SRP_TAG_MAGIC 0x69505845
34
35 /** An SRP port ID */
36 union srp_port_id {
37         uint8_t bytes[16];
38         uint32_t dwords[4];
39 } __attribute__ (( packed ));
40
41 /** SRP information unit common fields */
42 struct srp_common {
43         /** Information unit type */
44         uint8_t type;
45         /** Reserved */
46         uint8_t reserved0[7];
47         /** Tag */
48         union srp_tag tag;
49 } __attribute__ (( packed ));
50
51 /*****************************************************************************
52  *
53  * Login request
54  *
55  *****************************************************************************
56  */
57
58 /** An SRP login request information unit */
59 struct srp_login_req {
60         /** Information unit type
61          *
62          * This must be @c SRP_LOGIN_REQ
63          */
64         uint8_t type;
65         /** Reserved */
66         uint8_t reserved0[7];
67         /** Tag */
68         union srp_tag tag;
69         /** Requested maximum initiator to target IU length */
70         uint32_t max_i_t_iu_len;
71         /** Reserved */
72         uint8_t reserved1[4];
73         /** Required buffer formats
74          *
75          * This is the bitwise OR of one or more @c
76          * SRP_LOGIN_REQ_FMT_XXX constants.
77          */
78         uint16_t required_buffer_formats;
79         /** Flags
80          *
81          * This is the bitwise OR of zero or more @c
82          * SRP_LOGIN_REQ_FLAG_XXX and @c SRP_LOGIN_REQ_MCA_XXX
83          * constants.
84          */
85         uint8_t flags;
86         /** Reserved */
87         uint8_t reserved2[5];
88         /** Initiator port identifier */
89         union srp_port_id initiator;
90         /** Target port identifier */
91         union srp_port_id target;
92 } __attribute__ (( packed ));
93
94 /** Type of an SRP login request */
95 #define SRP_LOGIN_REQ 0x00
96
97 /** Require indirect data buffer descriptor format */
98 #define SRP_LOGIN_REQ_FMT_IDBD 0x04
99
100 /** Require direct data buffer descriptor format */
101 #define SRP_LOGIN_REQ_FMT_DDBD 0x02
102
103 /** Use solicited notification for asynchronous events */
104 #define SRP_LOGIN_REQ_FLAG_AESOLNT 0x40
105
106 /** Use solicited notification for credit request */
107 #define SRP_LOGIN_REQ_FLAG_CRSOLNT 0x20
108
109 /** Use solicited notification for logouts */
110 #define SRP_LOGIN_REQ_FLAG_LOSOLNT 0x10
111
112 /** Multi-channel action mask */
113 #define SRP_LOGIN_REQ_MCA_MASK 0x03
114
115 /** Single RDMA channel operation */
116 #define SRP_LOGIN_REQ_MCA_SINGLE_CHANNEL 0x00
117
118 /** Multiple independent RDMA channel operation */
119 #define SRP_LOGIN_REQ_MCA_MULTIPLE_CHANNELS 0x01
120
121 /*****************************************************************************
122  *
123  * Login response
124  *
125  *****************************************************************************
126  */
127
128 /** An SRP login response */
129 struct srp_login_rsp {
130         /** Information unit type
131          *
132          * This must be @c SRP_LOGIN_RSP
133          */
134         uint8_t type;
135         /** Reserved */
136         uint8_t reserved0[3];
137         /** Request limit delta */
138         uint32_t request_limit_delta;
139         /** Tag */
140         union srp_tag tag;
141         /** Maximum initiator to target IU length */
142         uint32_t max_i_t_iu_len;
143         /** Maximum target to initiator IU length */
144         uint32_t max_t_i_iu_len;
145         /** Supported buffer formats
146          *
147          * This is the bitwise OR of one or more @c
148          * SRP_LOGIN_RSP_FMT_XXX constants.
149          */
150         uint16_t supported_buffer_formats;
151         /** Flags
152          *
153          * This is the bitwise OR of zero or more @c
154          * SRP_LOGIN_RSP_FLAG_XXX and @c SRP_LOGIN_RSP_MCR_XXX
155          * constants.
156          */
157         uint8_t flags;
158         /** Reserved */
159         uint8_t reserved1[25];
160 } __attribute__ (( packed ));
161
162 /** Type of an SRP login response */
163 #define SRP_LOGIN_RSP 0xc0
164
165 /** Indirect data buffer descriptor format supported */
166 #define SRP_LOGIN_RSP_FMT_IDBD 0x04
167
168 /** Direct data buffer descriptor format supported */
169 #define SRP_LOGIN_RSP_FMT_DDBD 0x02
170
171 /** Solicited notification is supported */
172 #define SRP_LOGIN_RSP_FLAG_SOLNTSUP 0x10
173
174 /** Multi-channel result mask */
175 #define SRP_LOGIN_RSP_MCR_MASK 0x03
176
177 /** No existing RDMA channels were associated with the same I_T nexus */
178 #define SRP_LOGIN_RSP_MCR_NO_EXISTING_CHANNELS 0x00
179
180 /** One or more existing RDMA channels were terminated */
181 #define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_TERMINATED 0x01
182
183 /** One or more existing RDMA channels continue to operate independently */
184 #define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_CONTINUE 0x02
185
186 /*****************************************************************************
187  *
188  * Login rejection
189  *
190  *****************************************************************************
191  */
192
193 /** An SRP login rejection */
194 struct srp_login_rej {
195         /** Information unit type
196          *
197          * This must be @c SRP_LOGIN_REJ
198          */
199         uint8_t type;
200         /** Reserved */
201         uint8_t reserved0[3];
202         /** Reason
203          *
204          * This is a @c SRP_LOGIN_REJ_REASON_XXX constant.
205          */
206         uint32_t reason;
207         /** Tag */
208         union srp_tag tag;
209         /** Reserved */
210         uint8_t reserved1[8];
211         /** Supported buffer formats
212          *
213          * This is the bitwise OR of one or more @c
214          * SRP_LOGIN_REJ_FMT_XXX constants.
215          */
216         uint16_t supported_buffer_formats;
217         /** Reserved */
218         uint8_t reserved2[6];
219 } __attribute__ (( packed ));
220
221 /** Type of an SRP login rejection */
222 #define SRP_LOGIN_REJ 0xc2
223
224 /** Unable to establish RDMA channel, no reason specified */
225 #define SRP_LOGIN_REJ_REASON_UNKNOWN 0x00010000UL
226
227 /** Insufficient RDMA channel resources */
228 #define SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES 0x00010001UL
229
230 /** Requested maximum initiator to target IU length value too large */
231 #define SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN 0x00010002UL
232
233 /** Unable to associate RDMA channel with specified I_T nexus */
234 #define SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE 0x00010003UL
235
236 /** One or more requested data buffer descriptor formats are not supported */
237 #define SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT 0x00010004UL
238
239 /** SRP target port does not support multiple RDMA channels per I_T nexus */
240 #define SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS 0x00010005UL
241
242 /** RDMA channel limit reached for this initiator */
243 #define SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS 0x00010006UL
244
245 /** SRP login rejection reason is defined */
246 #define SRP_LOGIN_REJ_REASON_DEFINED( reason ) \
247         ( ( (reason) & 0xfffffff0UL ) == 0x00010000UL )
248
249 /** Indirect data buffer descriptor format supported */
250 #define SRP_LOGIN_REJ_FMT_IDBD 0x04
251
252 /** Direct data buffer descriptor format supported */
253 #define SRP_LOGIN_REJ_FMT_DDBD 0x02
254
255 /*****************************************************************************
256  *
257  * Initiator logout
258  *
259  *****************************************************************************
260  */
261
262 /** An SRP initiator logout request */
263 struct srp_i_logout {
264         /** Information unit type
265          *
266          * This must be @c SRP_I_LOGOUT
267          */
268         uint8_t type;
269         /** Reserved */
270         uint8_t reserved0[7];
271         /** Tag */
272         union srp_tag tag;
273 } __attribute__ (( packed ));
274
275 /** Type of an SRP initiator logout request */
276 #define SRP_I_LOGOUT 0x03
277
278 /*****************************************************************************
279  *
280  * Target logout
281  *
282  *****************************************************************************
283  */
284
285 /** An SRP target logout request */
286 struct srp_t_logout {
287         /** Information unit type
288          *
289          * This must be @c SRP_T_LOGOUT
290          */
291         uint8_t type;
292         /** Flags
293          *
294          * This is the bitwise OR of zero or more @c
295          * SRP_T_LOGOUT_FLAG_XXX constants.
296          */
297         uint8_t flags;
298         /** Reserved */
299         uint8_t reserved0[2];
300         /** Reason
301          *
302          * This is a @c SRP_T_LOGOUT_REASON_XXX constant.
303          */
304         uint32_t reason;
305         /** Tag */
306         union srp_tag tag;
307 } __attribute__ (( packed ));
308
309 /** Type of an SRP target logout request */
310 #define SRP_T_LOGOUT 0x80
311
312 /** The initiator specified solicited notification of logouts */
313 #define SRP_T_LOGOUT_FLAG_SOLNT 0x01
314
315 /** No reason specified */
316 #define SRP_T_LOGOUT_REASON_UNKNOWN 0x00000000UL
317
318 /** Inactive RDMA channel (reclaiming resources) */
319 #define SRP_T_LOGOUT_REASON_INACTIVE 0x00000001UL
320
321 /** Invalid information unit type code received by SRP target port */
322 #define SRP_T_LOGOUT_REASON_INVALID_TYPE 0x00000002UL
323
324 /** SRP initiator port sent response with no corresponding request */
325 #define SRP_T_LOGOUT_REASON_SPURIOUS_RESPONSE 0x00000003UL
326
327 /** RDMA channel disconnected due to multi-channel action code in new login */
328 #define SRP_T_LOGOUT_REASON_MCA 0x00000004UL
329
330 /** Unsuppported format code value specified in data-out buffer descriptor */
331 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_OUT_FORMAT 0x00000005UL
332
333 /** Unsuppported format code value specified in data-in buffer descriptor */
334 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_IN_FORMAT 0x00000006UL
335
336 /** Invalid length for IU type */
337 #define SRP_T_LOGOUT_INVALID_IU_LEN 0x00000008UL
338
339 /*****************************************************************************
340  *
341  * Task management
342  *
343  *****************************************************************************
344  */
345
346 /** An SRP task management request */
347 struct srp_tsk_mgmt {
348         /** Information unit type
349          *
350          * This must be @c SRP_TSK_MGMT
351          */
352         uint8_t type;
353         /** Flags
354          *
355          * This is the bitwise OR of zero or more
356          * @c SRP_TSK_MGMT_FLAG_XXX constants.
357          */
358         uint8_t flags;
359         /** Reserved */
360         uint8_t reserved0[6];
361         /** Tag */
362         union srp_tag tag;
363         /** Reserved */
364         uint8_t reserved1[4];
365         /** Logical unit number */
366         struct scsi_lun lun;
367         /** Reserved */
368         uint8_t reserved2[2];
369         /** Task management function
370          *
371          * This is a @c SRP_TASK_MGMT_FUNC_XXX constant
372          */
373         uint8_t function;
374         /** Reserved */
375         uint8_t reserved3[1];
376         /** Tag of task to be managed */
377         union srp_tag managed_tag;
378         /** Reserved */
379         uint8_t reserved4[8];
380 } __attribute__ (( packed ));
381
382 /** Type of an SRP task management request */
383 #define SRP_TSK_MGMT 0x01
384
385 /** Use solicited notification for unsuccessful completions */
386 #define SRP_TSK_MGMT_FLAG_UCSOLNT 0x04
387
388 /** Use solicited notification for successful completions */
389 #define SRP_TSK_MGMT_FLAG_SCSOLNT 0x02
390
391 /** The task manager shall perform an ABORT TASK function */
392 #define SRP_TSK_MGMT_FUNC_ABORT_TASK 0x01
393
394 /** The task manager shall perform an ABORT TASK SET function */
395 #define SRP_TSK_MGMT_FUNC_ABORT_TASK_SET 0x02
396
397 /** The task manager shall perform a CLEAR TASK SET function */
398 #define SRP_TSK_MGMT_FUNC_CLEAR_TASK_SET 0x04
399
400 /** The task manager shall perform a LOGICAL UNIT RESET function */
401 #define SRP_TSK_MGMT_FUNC_LOGICAL_UNIT_RESET 0x08
402
403 /** The task manager shall perform a CLEAR ACA function */
404 #define SRP_TSK_MGMT_FUNC_CLEAR_ACA 0x40
405
406 /*****************************************************************************
407  *
408  * SCSI command
409  *
410  *****************************************************************************
411  */
412
413 /** An SRP SCSI command */
414 struct srp_cmd {
415         /** Information unit type
416          *
417          * This must be @c SRP_CMD
418          */
419         uint8_t type;
420         /** Flags
421          *
422          * This is the bitwise OR of zero or more @c SRP_CMD_FLAG_XXX
423          * constants.
424          */
425         uint8_t flags;
426         /** Reserved */
427         uint8_t reserved0[3];
428         /** Data buffer descriptor formats
429          *
430          * This is the bitwise OR of one @c SRP_CMD_DO_FMT_XXX and one @c
431          * SRP_CMD_DI_FMT_XXX constant.
432          */
433         uint8_t data_buffer_formats;
434         /** Data-out buffer descriptor count */
435         uint8_t data_out_buffer_count;
436         /** Data-in buffer descriptor count */
437         uint8_t data_in_buffer_count;
438         /** Tag */
439         union srp_tag tag;
440         /** Reserved */
441         uint8_t reserved1[4];
442         /** Logical unit number */
443         struct scsi_lun lun;
444         /** Reserved */
445         uint8_t reserved2[1];
446         /** Task attribute
447          *
448          * This is a @c SRP_CMD_TASK_ATTR_XXX constant.
449          */
450         uint8_t task_attr;
451         /** Reserved */
452         uint8_t reserved3[1];
453         /** Additional CDB length */
454         uint8_t additional_cdb_len;
455         /** Command data block */
456         union scsi_cdb cdb;
457 } __attribute__ (( packed ));
458
459 /** Type of an SRP SCSI command */
460 #define SRP_CMD 0x02
461
462 /** Use solicited notification for unsuccessful completions */
463 #define SRP_CMD_FLAG_UCSOLNT 0x04
464
465 /** Use solicited notification for successful completions */
466 #define SRP_CMD_FLAG_SCSOLNT 0x02
467
468 /** Data-out buffer format mask */
469 #define SRP_CMD_DO_FMT_MASK 0xf0
470
471 /** Direct data-out buffer format */
472 #define SRP_CMD_DO_FMT_DIRECT 0x10
473
474 /** Indirect data-out buffer format */
475 #define SRP_CMD_DO_FMT_INDIRECT 0x20
476
477 /** Data-in buffer format mask */
478 #define SRP_CMD_DI_FMT_MASK 0x0f
479
480 /** Direct data-in buffer format */
481 #define SRP_CMD_DI_FMT_DIRECT 0x01
482
483 /** Indirect data-in buffer format */
484 #define SRP_CMD_DI_FMT_INDIRECT 0x02
485
486 /** Use the rules for a simple task attribute */
487 #define SRP_CMD_TASK_ATTR_SIMPLE 0x00
488
489 /** Use the rules for a head of queue task attribute */
490 #define SRP_CMD_TASK_ATTR_QUEUE_HEAD 0x01
491
492 /** Use the rules for an ordered task attribute */
493 #define SRP_CMD_TASK_ATTR_ORDERED 0x02
494
495 /** Use the rules for an automatic contingent allegiance task attribute */
496 #define SRP_CMD_TASK_ATTR_AUTOMATIC_CONTINGENT_ALLEGIANCE 0x08
497
498 /** An SRP memory descriptor */
499 struct srp_memory_descriptor {
500         /** Virtual address */
501         uint64_t address;
502         /** Memory handle */
503         uint32_t handle;
504         /** Data length */
505         uint32_t len;
506 } __attribute__ (( packed ));
507
508 /*****************************************************************************
509  *
510  * SCSI response
511  *
512  *****************************************************************************
513  */
514
515 /** An SRP SCSI response */
516 struct srp_rsp {
517         /** Information unit type
518          *
519          * This must be @c SRP_RSP
520          */
521         uint8_t type;
522         /** Flags
523          *
524          * This is the bitwise OR of zero or more @c SRP_RSP_FLAG_XXX
525          * constants.
526          */
527         uint8_t flags;
528         /** Reserved */
529         uint8_t reserved0[2];
530         /** Request limit delta */
531         uint32_t request_limit_delta;
532         /** Tag */
533         union srp_tag tag;
534         /** Reserved */
535         uint8_t reserved1[2];
536         /** Valid fields
537          *
538          * This is the bitwise OR of zero or more @c SRP_RSP_VALID_XXX
539          * constants.
540          */
541         uint8_t valid;
542         /** Status
543          *
544          * This is the SCSI status code.
545          */
546         uint8_t status;
547         /** Data-out residual count */
548         uint32_t data_out_residual_count;
549         /** Data-in residual count */
550         uint32_t data_in_residual_count;
551         /** Sense data list length */
552         uint32_t sense_data_len;
553         /** Response data list length */
554         uint32_t response_data_len;
555 } __attribute__ (( packed ));
556
557 /** Type of an SRP SCSI response */
558 #define SRP_RSP 0xc1
559
560 /** The initiator specified solicited notification of this response */
561 #define SRP_RSP_FLAG_SOLNT 0x01
562
563 /** Data-in residual count field is valid and represents an underflow */
564 #define SRP_RSP_VALID_DIUNDER 0x20
565
566 /** Data-in residual count field is valid and represents an overflow */
567 #define SRP_RSP_VALID_DIOVER 0x10
568
569 /** Data-out residual count field is valid and represents an underflow */
570 #define SRP_RSP_VALID_DOUNDER 0x08
571
572 /** Data-out residual count field is valid and represents an overflow */
573 #define SRP_RSP_VALID_DOOVER 0x04
574
575 /** Sense data list length field is valid */
576 #define SRP_RSP_VALID_SNSVALID 0x02
577
578 /** Response data list length field is valid */
579 #define SRP_RSP_VALID_RSPVALID 0x01
580
581 /**
582  * Get response data portion of SCSI response
583  *
584  * @v rsp                       SCSI response
585  * @ret response_data           Response data, or NULL if not present
586  */
587 static inline const void * srp_rsp_response_data ( const struct srp_rsp *rsp ) {
588         return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
589                  ( ( ( const void * ) rsp ) + sizeof ( *rsp ) ) : NULL );
590 }
591
592 /**
593  * Get length of response data portion of SCSI response
594  *
595  * @v rsp                       SCSI response
596  * @ret response_data_len       Response data length
597  */
598 static inline size_t srp_rsp_response_data_len ( const struct srp_rsp *rsp ) {
599         return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
600                  ntohl ( rsp->response_data_len ) : 0 );
601 }
602
603 /**
604  * Get sense data portion of SCSI response
605  *
606  * @v rsp                       SCSI response
607  * @ret sense_data              Sense data, or NULL if not present
608  */
609 static inline const void * srp_rsp_sense_data ( const struct srp_rsp *rsp ) {
610         return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
611                  ( ( ( const void * ) rsp ) + sizeof ( *rsp ) +
612                    srp_rsp_response_data_len ( rsp ) ) : NULL );
613 }
614
615 /**
616  * Get length of sense data portion of SCSI response
617  *
618  * @v rsp                       SCSI response
619  * @ret sense_data_len          Sense data length
620  */
621 static inline size_t srp_rsp_sense_data_len ( const struct srp_rsp *rsp ) {
622         return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
623                  ntohl ( rsp->sense_data_len ) : 0 );
624 }
625
626 /*****************************************************************************
627  *
628  * Credit request
629  *
630  *****************************************************************************
631  */
632
633 /** An SRP credit request */
634 struct srp_cred_req {
635         /** Information unit type
636          *
637          * This must be @c SRP_CRED_REQ
638          */
639         uint8_t type;
640         /** Flags
641          *
642          * This is the bitwise OR of zero or more
643          * @c SRP_CRED_REQ_FLAG_XXX constants.
644          */
645         uint8_t flags;
646         /** Reserved */
647         uint8_t reserved0[2];
648         /** Request limit delta */
649         uint32_t request_limit_delta;
650         /** Tag */
651         union srp_tag tag;
652 } __attribute__ (( packed ));
653
654 /** Type of an SRP credit request */
655 #define SRP_CRED_REQ 0x81
656
657 /** The initiator specified solicited notification of credit requests */
658 #define SRP_CRED_REQ_FLAG_SOLNT 0x01
659
660 /*****************************************************************************
661  *
662  * Credit response
663  *
664  *****************************************************************************
665  */
666
667 /** An SRP credit response */
668 struct srp_cred_rsp {
669         /** Information unit type
670          *
671          * This must be @c SRP_CRED_RSP
672          */
673         uint8_t type;
674         /** Reserved */
675         uint8_t reserved0[7];
676         /** Tag */
677         union srp_tag tag;
678 } __attribute__ (( packed ));
679
680 /** Type of an SRP credit response */
681 #define SRP_CRED_RSP 0x41
682
683 /*****************************************************************************
684  *
685  * Asynchronous event request
686  *
687  *****************************************************************************
688  */
689
690 /** An SRP asynchronous event request */
691 struct srp_aer_req {
692         /** Information unit type
693          *
694          * This must be @c SRP_AER_REQ
695          */
696         uint8_t type;
697         /** Flags
698          *
699          * This is the bitwise OR of zero or more @c
700          * SRP_AER_REQ_FLAG_XXX constants.
701          */
702         uint8_t flags;
703         /** Reserved */
704         uint8_t reserved0[2];
705         /** Request limit delta */
706         uint32_t request_limit_delta;
707         /** Tag */
708         union srp_tag tag;
709         /** Reserved */
710         uint8_t reserved1[4];
711         /** Logical unit number */
712         struct scsi_lun lun;
713         /** Sense data list length */
714         uint32_t sense_data_len;
715         /** Reserved */
716         uint8_t reserved2[4];
717 } __attribute__ (( packed ));
718
719 /** Type of an SRP asynchronous event request */
720 #define SRP_AER_REQ 0x82
721
722 /** The initiator specified solicited notification of asynchronous events */
723 #define SRP_AER_REQ_FLAG_SOLNT 0x01
724
725 /**
726  * Get sense data portion of asynchronous event request
727  *
728  * @v aer_req                   SRP asynchronous event request
729  * @ret sense_data              Sense data
730  */
731 static inline __always_inline void *
732 srp_aer_req_sense_data ( struct srp_aer_req *aer_req ) {
733         return ( ( ( void * ) aer_req ) + sizeof ( *aer_req ) );
734 }
735
736 /**
737  * Get length of sense data portion of asynchronous event request
738  *
739  * @v aer_req                   SRP asynchronous event request
740  * @ret sense_data_len          Sense data length
741  */
742 static inline __always_inline size_t
743 srp_aer_req_sense_data_len ( struct srp_aer_req *aer_req ) {
744         return ( ntohl ( aer_req->sense_data_len ) );
745 }
746
747 /*****************************************************************************
748  *
749  * Asynchronous event response
750  *
751  *****************************************************************************
752  */
753
754 /** An SRP asynchronous event response */
755 struct srp_aer_rsp {
756         /** Information unit type
757          *
758          * This must be @c SRP_AER_RSP
759          */
760         uint8_t type;
761         /** Reserved */
762         uint8_t reserved0[7];
763         /** Tag */
764         union srp_tag tag;
765 } __attribute__ (( packed ));
766
767 /** Type of an SRP asynchronous event response */
768 #define SRP_AER_RSP 0x42
769
770 /*****************************************************************************
771  *
772  * SRP boot firmware table
773  *
774  * The working draft specification for the SRP boot firmware table can
775  * be found at
776  *
777  *   http://ipxe.org/wiki/srp/sbft
778  *
779  *****************************************************************************
780  */
781
782 /** SRP Boot Firmware Table signature */
783 #define SBFT_SIG ACPI_SIGNATURE ( 's', 'B', 'F', 'T' )
784
785 /** An offset from the start of the sBFT */
786 typedef uint16_t sbft_off_t;
787
788 /**
789  * SRP Boot Firmware Table
790  */
791 struct sbft_table {
792         /** ACPI header */
793         struct acpi_description_header acpi;
794         /** Offset to SCSI subtable */
795         sbft_off_t scsi_offset;
796         /** Offset to SRP subtable */
797         sbft_off_t srp_offset;
798         /** Offset to IB subtable, if present */
799         sbft_off_t ib_offset;
800         /** Reserved */
801         uint8_t reserved[6];
802 } __attribute__ (( packed ));
803
804 /**
805  * sBFT SCSI subtable
806  */
807 struct sbft_scsi_subtable {
808         /** LUN */
809         struct scsi_lun lun;
810 } __attribute__ (( packed ));
811
812 /**
813  * sBFT SRP subtable
814  */
815 struct sbft_srp_subtable {
816         /** Initiator port identifier */
817         union srp_port_id initiator;
818         /** Target port identifier */
819         union srp_port_id target;
820 } __attribute__ (( packed ));
821
822 /*****************************************************************************
823  *
824  * SRP devices
825  *
826  *****************************************************************************
827  */
828
829 extern int srp_open ( struct interface *block, struct interface *socket,
830                       union srp_port_id *initiator, union srp_port_id *target,
831                       uint32_t memory_handle, struct scsi_lun *lun );
832
833 #endif /* _IPXE_SRP_H */