iPXE
srp.h
Go to the documentation of this file.
00001 #ifndef _IPXE_SRP_H
00002 #define _IPXE_SRP_H
00003 
00004 /** @file
00005  *
00006  * SCSI RDMA Protocol
00007  *
00008  */
00009 
00010 FILE_LICENCE ( BSD2 );
00011 
00012 #include <stdint.h>
00013 #include <byteswap.h>
00014 #include <ipxe/iobuf.h>
00015 #include <ipxe/xfer.h>
00016 #include <ipxe/scsi.h>
00017 #include <ipxe/acpi.h>
00018 
00019 /*****************************************************************************
00020  *
00021  * Common fields
00022  *
00023  *****************************************************************************
00024  */
00025 
00026 /** An SRP information unit tag */
00027 union srp_tag {
00028         uint8_t bytes[8];
00029         uint32_t dwords[2];
00030 } __attribute__ (( packed ));
00031 
00032 /** SRP tag magic marker */
00033 #define SRP_TAG_MAGIC 0x69505845
00034 
00035 /** An SRP port ID */
00036 union srp_port_id {
00037         uint8_t bytes[16];
00038         uint32_t dwords[4];
00039 } __attribute__ (( packed ));
00040 
00041 /** SRP information unit common fields */
00042 struct srp_common {
00043         /** Information unit type */
00044         uint8_t type;
00045         /** Reserved */
00046         uint8_t reserved0[7];
00047         /** Tag */
00048         union srp_tag tag;
00049 } __attribute__ (( packed ));
00050 
00051 /*****************************************************************************
00052  *
00053  * Login request
00054  *
00055  *****************************************************************************
00056  */
00057 
00058 /** An SRP login request information unit */
00059 struct srp_login_req {
00060         /** Information unit type
00061          *
00062          * This must be @c SRP_LOGIN_REQ
00063          */
00064         uint8_t type;
00065         /** Reserved */
00066         uint8_t reserved0[7];
00067         /** Tag */
00068         union srp_tag tag;
00069         /** Requested maximum initiator to target IU length */
00070         uint32_t max_i_t_iu_len;
00071         /** Reserved */
00072         uint8_t reserved1[4];
00073         /** Required buffer formats
00074          *
00075          * This is the bitwise OR of one or more @c
00076          * SRP_LOGIN_REQ_FMT_XXX constants.
00077          */
00078         uint16_t required_buffer_formats;
00079         /** Flags
00080          *
00081          * This is the bitwise OR of zero or more @c
00082          * SRP_LOGIN_REQ_FLAG_XXX and @c SRP_LOGIN_REQ_MCA_XXX
00083          * constants.
00084          */
00085         uint8_t flags;
00086         /** Reserved */
00087         uint8_t reserved2[5];
00088         /** Initiator port identifier */
00089         union srp_port_id initiator;
00090         /** Target port identifier */
00091         union srp_port_id target;
00092 } __attribute__ (( packed ));
00093 
00094 /** Type of an SRP login request */
00095 #define SRP_LOGIN_REQ 0x00
00096 
00097 /** Require indirect data buffer descriptor format */
00098 #define SRP_LOGIN_REQ_FMT_IDBD 0x04
00099 
00100 /** Require direct data buffer descriptor format */
00101 #define SRP_LOGIN_REQ_FMT_DDBD 0x02
00102 
00103 /** Use solicited notification for asynchronous events */
00104 #define SRP_LOGIN_REQ_FLAG_AESOLNT 0x40
00105 
00106 /** Use solicited notification for credit request */
00107 #define SRP_LOGIN_REQ_FLAG_CRSOLNT 0x20
00108 
00109 /** Use solicited notification for logouts */
00110 #define SRP_LOGIN_REQ_FLAG_LOSOLNT 0x10
00111 
00112 /** Multi-channel action mask */
00113 #define SRP_LOGIN_REQ_MCA_MASK 0x03
00114 
00115 /** Single RDMA channel operation */
00116 #define SRP_LOGIN_REQ_MCA_SINGLE_CHANNEL 0x00
00117 
00118 /** Multiple independent RDMA channel operation */
00119 #define SRP_LOGIN_REQ_MCA_MULTIPLE_CHANNELS 0x01
00120 
00121 /*****************************************************************************
00122  *
00123  * Login response
00124  *
00125  *****************************************************************************
00126  */
00127 
00128 /** An SRP login response */
00129 struct srp_login_rsp {
00130         /** Information unit type
00131          *
00132          * This must be @c SRP_LOGIN_RSP
00133          */
00134         uint8_t type;
00135         /** Reserved */
00136         uint8_t reserved0[3];
00137         /** Request limit delta */
00138         uint32_t request_limit_delta;
00139         /** Tag */
00140         union srp_tag tag;
00141         /** Maximum initiator to target IU length */
00142         uint32_t max_i_t_iu_len;
00143         /** Maximum target to initiator IU length */
00144         uint32_t max_t_i_iu_len;
00145         /** Supported buffer formats
00146          *
00147          * This is the bitwise OR of one or more @c
00148          * SRP_LOGIN_RSP_FMT_XXX constants.
00149          */
00150         uint16_t supported_buffer_formats;
00151         /** Flags
00152          *
00153          * This is the bitwise OR of zero or more @c
00154          * SRP_LOGIN_RSP_FLAG_XXX and @c SRP_LOGIN_RSP_MCR_XXX
00155          * constants.
00156          */
00157         uint8_t flags;
00158         /** Reserved */
00159         uint8_t reserved1[25];
00160 } __attribute__ (( packed ));
00161 
00162 /** Type of an SRP login response */
00163 #define SRP_LOGIN_RSP 0xc0
00164 
00165 /** Indirect data buffer descriptor format supported */
00166 #define SRP_LOGIN_RSP_FMT_IDBD 0x04
00167 
00168 /** Direct data buffer descriptor format supported */
00169 #define SRP_LOGIN_RSP_FMT_DDBD 0x02
00170 
00171 /** Solicited notification is supported */
00172 #define SRP_LOGIN_RSP_FLAG_SOLNTSUP 0x10
00173 
00174 /** Multi-channel result mask */
00175 #define SRP_LOGIN_RSP_MCR_MASK 0x03
00176 
00177 /** No existing RDMA channels were associated with the same I_T nexus */
00178 #define SRP_LOGIN_RSP_MCR_NO_EXISTING_CHANNELS 0x00
00179 
00180 /** One or more existing RDMA channels were terminated */
00181 #define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_TERMINATED 0x01
00182 
00183 /** One or more existing RDMA channels continue to operate independently */
00184 #define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_CONTINUE 0x02
00185 
00186 /*****************************************************************************
00187  *
00188  * Login rejection
00189  *
00190  *****************************************************************************
00191  */
00192 
00193 /** An SRP login rejection */
00194 struct srp_login_rej {
00195         /** Information unit type
00196          *
00197          * This must be @c SRP_LOGIN_REJ
00198          */
00199         uint8_t type;
00200         /** Reserved */
00201         uint8_t reserved0[3];
00202         /** Reason
00203          *
00204          * This is a @c SRP_LOGIN_REJ_REASON_XXX constant.
00205          */
00206         uint32_t reason;
00207         /** Tag */
00208         union srp_tag tag;
00209         /** Reserved */
00210         uint8_t reserved1[8];
00211         /** Supported buffer formats
00212          *
00213          * This is the bitwise OR of one or more @c
00214          * SRP_LOGIN_REJ_FMT_XXX constants.
00215          */
00216         uint16_t supported_buffer_formats;
00217         /** Reserved */
00218         uint8_t reserved2[6];
00219 } __attribute__ (( packed ));
00220 
00221 /** Type of an SRP login rejection */
00222 #define SRP_LOGIN_REJ 0xc2
00223 
00224 /** Unable to establish RDMA channel, no reason specified */
00225 #define SRP_LOGIN_REJ_REASON_UNKNOWN 0x00010000UL
00226 
00227 /** Insufficient RDMA channel resources */
00228 #define SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES 0x00010001UL
00229 
00230 /** Requested maximum initiator to target IU length value too large */
00231 #define SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN 0x00010002UL
00232 
00233 /** Unable to associate RDMA channel with specified I_T nexus */
00234 #define SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE 0x00010003UL
00235 
00236 /** One or more requested data buffer descriptor formats are not supported */
00237 #define SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT 0x00010004UL
00238 
00239 /** SRP target port does not support multiple RDMA channels per I_T nexus */
00240 #define SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS 0x00010005UL
00241 
00242 /** RDMA channel limit reached for this initiator */
00243 #define SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS 0x00010006UL
00244 
00245 /** SRP login rejection reason is defined */
00246 #define SRP_LOGIN_REJ_REASON_DEFINED( reason ) \
00247         ( ( (reason) & 0xfffffff0UL ) == 0x00010000UL )
00248 
00249 /** Indirect data buffer descriptor format supported */
00250 #define SRP_LOGIN_REJ_FMT_IDBD 0x04
00251 
00252 /** Direct data buffer descriptor format supported */
00253 #define SRP_LOGIN_REJ_FMT_DDBD 0x02
00254 
00255 /*****************************************************************************
00256  *
00257  * Initiator logout
00258  *
00259  *****************************************************************************
00260  */
00261 
00262 /** An SRP initiator logout request */
00263 struct srp_i_logout {
00264         /** Information unit type
00265          *
00266          * This must be @c SRP_I_LOGOUT
00267          */
00268         uint8_t type;
00269         /** Reserved */
00270         uint8_t reserved0[7];
00271         /** Tag */
00272         union srp_tag tag;
00273 } __attribute__ (( packed ));
00274 
00275 /** Type of an SRP initiator logout request */
00276 #define SRP_I_LOGOUT 0x03
00277 
00278 /*****************************************************************************
00279  *
00280  * Target logout
00281  *
00282  *****************************************************************************
00283  */
00284 
00285 /** An SRP target logout request */
00286 struct srp_t_logout {
00287         /** Information unit type
00288          *
00289          * This must be @c SRP_T_LOGOUT
00290          */
00291         uint8_t type;
00292         /** Flags
00293          *
00294          * This is the bitwise OR of zero or more @c
00295          * SRP_T_LOGOUT_FLAG_XXX constants.
00296          */
00297         uint8_t flags;
00298         /** Reserved */
00299         uint8_t reserved0[2];
00300         /** Reason
00301          *
00302          * This is a @c SRP_T_LOGOUT_REASON_XXX constant.
00303          */
00304         uint32_t reason;
00305         /** Tag */
00306         union srp_tag tag;
00307 } __attribute__ (( packed ));
00308 
00309 /** Type of an SRP target logout request */
00310 #define SRP_T_LOGOUT 0x80
00311 
00312 /** The initiator specified solicited notification of logouts */
00313 #define SRP_T_LOGOUT_FLAG_SOLNT 0x01
00314 
00315 /** No reason specified */
00316 #define SRP_T_LOGOUT_REASON_UNKNOWN 0x00000000UL
00317 
00318 /** Inactive RDMA channel (reclaiming resources) */
00319 #define SRP_T_LOGOUT_REASON_INACTIVE 0x00000001UL
00320 
00321 /** Invalid information unit type code received by SRP target port */
00322 #define SRP_T_LOGOUT_REASON_INVALID_TYPE 0x00000002UL
00323 
00324 /** SRP initiator port sent response with no corresponding request */
00325 #define SRP_T_LOGOUT_REASON_SPURIOUS_RESPONSE 0x00000003UL
00326 
00327 /** RDMA channel disconnected due to multi-channel action code in new login */
00328 #define SRP_T_LOGOUT_REASON_MCA 0x00000004UL
00329 
00330 /** Unsuppported format code value specified in data-out buffer descriptor */
00331 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_OUT_FORMAT 0x00000005UL
00332 
00333 /** Unsuppported format code value specified in data-in buffer descriptor */
00334 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_IN_FORMAT 0x00000006UL
00335 
00336 /** Invalid length for IU type */
00337 #define SRP_T_LOGOUT_INVALID_IU_LEN 0x00000008UL
00338 
00339 /*****************************************************************************
00340  *
00341  * Task management
00342  *
00343  *****************************************************************************
00344  */
00345 
00346 /** An SRP task management request */
00347 struct srp_tsk_mgmt {
00348         /** Information unit type
00349          *
00350          * This must be @c SRP_TSK_MGMT
00351          */
00352         uint8_t type;
00353         /** Flags
00354          *
00355          * This is the bitwise OR of zero or more
00356          * @c SRP_TSK_MGMT_FLAG_XXX constants.
00357          */
00358         uint8_t flags;
00359         /** Reserved */
00360         uint8_t reserved0[6];
00361         /** Tag */
00362         union srp_tag tag;
00363         /** Reserved */
00364         uint8_t reserved1[4];
00365         /** Logical unit number */
00366         struct scsi_lun lun;
00367         /** Reserved */
00368         uint8_t reserved2[2];
00369         /** Task management function
00370          *
00371          * This is a @c SRP_TASK_MGMT_FUNC_XXX constant
00372          */
00373         uint8_t function;
00374         /** Reserved */
00375         uint8_t reserved3[1];
00376         /** Tag of task to be managed */
00377         union srp_tag managed_tag;
00378         /** Reserved */
00379         uint8_t reserved4[8];
00380 } __attribute__ (( packed ));
00381 
00382 /** Type of an SRP task management request */
00383 #define SRP_TSK_MGMT 0x01
00384 
00385 /** Use solicited notification for unsuccessful completions */
00386 #define SRP_TSK_MGMT_FLAG_UCSOLNT 0x04
00387 
00388 /** Use solicited notification for successful completions */
00389 #define SRP_TSK_MGMT_FLAG_SCSOLNT 0x02
00390 
00391 /** The task manager shall perform an ABORT TASK function */
00392 #define SRP_TSK_MGMT_FUNC_ABORT_TASK 0x01
00393 
00394 /** The task manager shall perform an ABORT TASK SET function */
00395 #define SRP_TSK_MGMT_FUNC_ABORT_TASK_SET 0x02
00396 
00397 /** The task manager shall perform a CLEAR TASK SET function */
00398 #define SRP_TSK_MGMT_FUNC_CLEAR_TASK_SET 0x04
00399 
00400 /** The task manager shall perform a LOGICAL UNIT RESET function */
00401 #define SRP_TSK_MGMT_FUNC_LOGICAL_UNIT_RESET 0x08
00402 
00403 /** The task manager shall perform a CLEAR ACA function */
00404 #define SRP_TSK_MGMT_FUNC_CLEAR_ACA 0x40
00405 
00406 /*****************************************************************************
00407  *
00408  * SCSI command
00409  *
00410  *****************************************************************************
00411  */
00412 
00413 /** An SRP SCSI command */
00414 struct srp_cmd {
00415         /** Information unit type
00416          *
00417          * This must be @c SRP_CMD
00418          */
00419         uint8_t type;
00420         /** Flags
00421          *
00422          * This is the bitwise OR of zero or more @c SRP_CMD_FLAG_XXX
00423          * constants.
00424          */
00425         uint8_t flags;
00426         /** Reserved */
00427         uint8_t reserved0[3];
00428         /** Data buffer descriptor formats
00429          *
00430          * This is the bitwise OR of one @c SRP_CMD_DO_FMT_XXX and one @c
00431          * SRP_CMD_DI_FMT_XXX constant.
00432          */
00433         uint8_t data_buffer_formats;
00434         /** Data-out buffer descriptor count */
00435         uint8_t data_out_buffer_count;
00436         /** Data-in buffer descriptor count */
00437         uint8_t data_in_buffer_count;
00438         /** Tag */
00439         union srp_tag tag;
00440         /** Reserved */
00441         uint8_t reserved1[4];
00442         /** Logical unit number */
00443         struct scsi_lun lun;
00444         /** Reserved */
00445         uint8_t reserved2[1];
00446         /** Task attribute
00447          *
00448          * This is a @c SRP_CMD_TASK_ATTR_XXX constant.
00449          */
00450         uint8_t task_attr;
00451         /** Reserved */
00452         uint8_t reserved3[1];
00453         /** Additional CDB length */
00454         uint8_t additional_cdb_len;
00455         /** Command data block */
00456         union scsi_cdb cdb;
00457 } __attribute__ (( packed ));
00458 
00459 /** Type of an SRP SCSI command */
00460 #define SRP_CMD 0x02
00461 
00462 /** Use solicited notification for unsuccessful completions */
00463 #define SRP_CMD_FLAG_UCSOLNT 0x04
00464 
00465 /** Use solicited notification for successful completions */
00466 #define SRP_CMD_FLAG_SCSOLNT 0x02
00467 
00468 /** Data-out buffer format mask */
00469 #define SRP_CMD_DO_FMT_MASK 0xf0
00470 
00471 /** Direct data-out buffer format */
00472 #define SRP_CMD_DO_FMT_DIRECT 0x10
00473 
00474 /** Indirect data-out buffer format */
00475 #define SRP_CMD_DO_FMT_INDIRECT 0x20
00476 
00477 /** Data-in buffer format mask */
00478 #define SRP_CMD_DI_FMT_MASK 0x0f
00479 
00480 /** Direct data-in buffer format */
00481 #define SRP_CMD_DI_FMT_DIRECT 0x01
00482 
00483 /** Indirect data-in buffer format */
00484 #define SRP_CMD_DI_FMT_INDIRECT 0x02
00485 
00486 /** Use the rules for a simple task attribute */
00487 #define SRP_CMD_TASK_ATTR_SIMPLE 0x00
00488 
00489 /** Use the rules for a head of queue task attribute */
00490 #define SRP_CMD_TASK_ATTR_QUEUE_HEAD 0x01
00491 
00492 /** Use the rules for an ordered task attribute */
00493 #define SRP_CMD_TASK_ATTR_ORDERED 0x02
00494 
00495 /** Use the rules for an automatic contingent allegiance task attribute */
00496 #define SRP_CMD_TASK_ATTR_AUTOMATIC_CONTINGENT_ALLEGIANCE 0x08
00497 
00498 /** An SRP memory descriptor */
00499 struct srp_memory_descriptor {
00500         /** Virtual address */
00501         uint64_t address;
00502         /** Memory handle */
00503         uint32_t handle;
00504         /** Data length */
00505         uint32_t len;
00506 } __attribute__ (( packed ));
00507 
00508 /*****************************************************************************
00509  *
00510  * SCSI response
00511  *
00512  *****************************************************************************
00513  */
00514 
00515 /** An SRP SCSI response */
00516 struct srp_rsp {
00517         /** Information unit type
00518          *
00519          * This must be @c SRP_RSP
00520          */
00521         uint8_t type;
00522         /** Flags
00523          *
00524          * This is the bitwise OR of zero or more @c SRP_RSP_FLAG_XXX
00525          * constants.
00526          */
00527         uint8_t flags;
00528         /** Reserved */
00529         uint8_t reserved0[2];
00530         /** Request limit delta */
00531         uint32_t request_limit_delta;
00532         /** Tag */
00533         union srp_tag tag;
00534         /** Reserved */
00535         uint8_t reserved1[2];
00536         /** Valid fields
00537          *
00538          * This is the bitwise OR of zero or more @c SRP_RSP_VALID_XXX
00539          * constants.
00540          */
00541         uint8_t valid;
00542         /** Status
00543          *
00544          * This is the SCSI status code.
00545          */
00546         uint8_t status;
00547         /** Data-out residual count */
00548         uint32_t data_out_residual_count;
00549         /** Data-in residual count */
00550         uint32_t data_in_residual_count;
00551         /** Sense data list length */
00552         uint32_t sense_data_len;
00553         /** Response data list length */
00554         uint32_t response_data_len;
00555 } __attribute__ (( packed ));
00556 
00557 /** Type of an SRP SCSI response */
00558 #define SRP_RSP 0xc1
00559 
00560 /** The initiator specified solicited notification of this response */
00561 #define SRP_RSP_FLAG_SOLNT 0x01
00562 
00563 /** Data-in residual count field is valid and represents an underflow */
00564 #define SRP_RSP_VALID_DIUNDER 0x20
00565 
00566 /** Data-in residual count field is valid and represents an overflow */
00567 #define SRP_RSP_VALID_DIOVER 0x10
00568 
00569 /** Data-out residual count field is valid and represents an underflow */
00570 #define SRP_RSP_VALID_DOUNDER 0x08
00571 
00572 /** Data-out residual count field is valid and represents an overflow */
00573 #define SRP_RSP_VALID_DOOVER 0x04
00574 
00575 /** Sense data list length field is valid */
00576 #define SRP_RSP_VALID_SNSVALID 0x02
00577 
00578 /** Response data list length field is valid */
00579 #define SRP_RSP_VALID_RSPVALID 0x01
00580 
00581 /**
00582  * Get response data portion of SCSI response
00583  *
00584  * @v rsp                       SCSI response
00585  * @ret response_data           Response data, or NULL if not present
00586  */
00587 static inline const void * srp_rsp_response_data ( const struct srp_rsp *rsp ) {
00588         return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
00589                  ( ( ( const void * ) rsp ) + sizeof ( *rsp ) ) : NULL );
00590 }
00591 
00592 /**
00593  * Get length of response data portion of SCSI response
00594  *
00595  * @v rsp                       SCSI response
00596  * @ret response_data_len       Response data length
00597  */
00598 static inline size_t srp_rsp_response_data_len ( const struct srp_rsp *rsp ) {
00599         return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
00600                  ntohl ( rsp->response_data_len ) : 0 );
00601 }
00602 
00603 /**
00604  * Get sense data portion of SCSI response
00605  *
00606  * @v rsp                       SCSI response
00607  * @ret sense_data              Sense data, or NULL if not present
00608  */
00609 static inline const void * srp_rsp_sense_data ( const struct srp_rsp *rsp ) {
00610         return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
00611                  ( ( ( const void * ) rsp ) + sizeof ( *rsp ) +
00612                    srp_rsp_response_data_len ( rsp ) ) : NULL );
00613 }
00614 
00615 /**
00616  * Get length of sense data portion of SCSI response
00617  *
00618  * @v rsp                       SCSI response
00619  * @ret sense_data_len          Sense data length
00620  */
00621 static inline size_t srp_rsp_sense_data_len ( const struct srp_rsp *rsp ) {
00622         return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
00623                  ntohl ( rsp->sense_data_len ) : 0 );
00624 }
00625 
00626 /*****************************************************************************
00627  *
00628  * Credit request
00629  *
00630  *****************************************************************************
00631  */
00632 
00633 /** An SRP credit request */
00634 struct srp_cred_req {
00635         /** Information unit type
00636          *
00637          * This must be @c SRP_CRED_REQ
00638          */
00639         uint8_t type;
00640         /** Flags
00641          *
00642          * This is the bitwise OR of zero or more
00643          * @c SRP_CRED_REQ_FLAG_XXX constants.
00644          */
00645         uint8_t flags;
00646         /** Reserved */
00647         uint8_t reserved0[2];
00648         /** Request limit delta */
00649         uint32_t request_limit_delta;
00650         /** Tag */
00651         union srp_tag tag;
00652 } __attribute__ (( packed ));
00653 
00654 /** Type of an SRP credit request */
00655 #define SRP_CRED_REQ 0x81
00656 
00657 /** The initiator specified solicited notification of credit requests */
00658 #define SRP_CRED_REQ_FLAG_SOLNT 0x01
00659 
00660 /*****************************************************************************
00661  *
00662  * Credit response
00663  *
00664  *****************************************************************************
00665  */
00666 
00667 /** An SRP credit response */
00668 struct srp_cred_rsp {
00669         /** Information unit type
00670          *
00671          * This must be @c SRP_CRED_RSP
00672          */
00673         uint8_t type;
00674         /** Reserved */
00675         uint8_t reserved0[7];
00676         /** Tag */
00677         union srp_tag tag;
00678 } __attribute__ (( packed ));
00679 
00680 /** Type of an SRP credit response */
00681 #define SRP_CRED_RSP 0x41
00682 
00683 /*****************************************************************************
00684  *
00685  * Asynchronous event request
00686  *
00687  *****************************************************************************
00688  */
00689 
00690 /** An SRP asynchronous event request */
00691 struct srp_aer_req {
00692         /** Information unit type
00693          *
00694          * This must be @c SRP_AER_REQ
00695          */
00696         uint8_t type;
00697         /** Flags
00698          *
00699          * This is the bitwise OR of zero or more @c
00700          * SRP_AER_REQ_FLAG_XXX constants.
00701          */
00702         uint8_t flags;
00703         /** Reserved */
00704         uint8_t reserved0[2];
00705         /** Request limit delta */
00706         uint32_t request_limit_delta;
00707         /** Tag */
00708         union srp_tag tag;
00709         /** Reserved */
00710         uint8_t reserved1[4];
00711         /** Logical unit number */
00712         struct scsi_lun lun;
00713         /** Sense data list length */
00714         uint32_t sense_data_len;
00715         /** Reserved */
00716         uint8_t reserved2[4];
00717 } __attribute__ (( packed ));
00718 
00719 /** Type of an SRP asynchronous event request */
00720 #define SRP_AER_REQ 0x82
00721 
00722 /** The initiator specified solicited notification of asynchronous events */
00723 #define SRP_AER_REQ_FLAG_SOLNT 0x01
00724 
00725 /**
00726  * Get sense data portion of asynchronous event request
00727  *
00728  * @v aer_req                   SRP asynchronous event request
00729  * @ret sense_data              Sense data
00730  */
00731 static inline __always_inline void *
00732 srp_aer_req_sense_data ( struct srp_aer_req *aer_req ) {
00733         return ( ( ( void * ) aer_req ) + sizeof ( *aer_req ) );
00734 }
00735 
00736 /**
00737  * Get length of sense data portion of asynchronous event request
00738  *
00739  * @v aer_req                   SRP asynchronous event request
00740  * @ret sense_data_len          Sense data length
00741  */
00742 static inline __always_inline size_t
00743 srp_aer_req_sense_data_len ( struct srp_aer_req *aer_req ) {
00744         return ( ntohl ( aer_req->sense_data_len ) );
00745 }
00746 
00747 /*****************************************************************************
00748  *
00749  * Asynchronous event response
00750  *
00751  *****************************************************************************
00752  */
00753 
00754 /** An SRP asynchronous event response */
00755 struct srp_aer_rsp {
00756         /** Information unit type
00757          *
00758          * This must be @c SRP_AER_RSP
00759          */
00760         uint8_t type;
00761         /** Reserved */
00762         uint8_t reserved0[7];
00763         /** Tag */
00764         union srp_tag tag;
00765 } __attribute__ (( packed ));
00766 
00767 /** Type of an SRP asynchronous event response */
00768 #define SRP_AER_RSP 0x42
00769 
00770 /*****************************************************************************
00771  *
00772  * SRP boot firmware table
00773  *
00774  * The working draft specification for the SRP boot firmware table can
00775  * be found at
00776  *
00777  *   http://ipxe.org/wiki/srp/sbft
00778  *
00779  *****************************************************************************
00780  */
00781 
00782 /** SRP Boot Firmware Table signature */
00783 #define SBFT_SIG ACPI_SIGNATURE ( 's', 'B', 'F', 'T' )
00784 
00785 /** An offset from the start of the sBFT */
00786 typedef uint16_t sbft_off_t;
00787 
00788 /**
00789  * SRP Boot Firmware Table
00790  */
00791 struct sbft_table {
00792         /** ACPI header */
00793         struct acpi_header acpi;
00794         /** Offset to SCSI subtable */
00795         sbft_off_t scsi_offset;
00796         /** Offset to SRP subtable */
00797         sbft_off_t srp_offset;
00798         /** Offset to IB subtable, if present */
00799         sbft_off_t ib_offset;
00800         /** Reserved */
00801         uint8_t reserved[6];
00802 } __attribute__ (( packed ));
00803 
00804 /**
00805  * sBFT SCSI subtable
00806  */
00807 struct sbft_scsi_subtable {
00808         /** LUN */
00809         struct scsi_lun lun;
00810 } __attribute__ (( packed ));
00811 
00812 /**
00813  * sBFT SRP subtable
00814  */
00815 struct sbft_srp_subtable {
00816         /** Initiator port identifier */
00817         union srp_port_id initiator;
00818         /** Target port identifier */
00819         union srp_port_id target;
00820 } __attribute__ (( packed ));
00821 
00822 /*****************************************************************************
00823  *
00824  * SRP devices
00825  *
00826  *****************************************************************************
00827  */
00828 
00829 extern int srp_open ( struct interface *block, struct interface *socket,
00830                       union srp_port_id *initiator, union srp_port_id *target,
00831                       uint32_t memory_handle, struct scsi_lun *lun );
00832 
00833 #endif /* _IPXE_SRP_H */