srp.h

Go to the documentation of this file.
00001 #ifndef _GPXE_SRP_H
00002 #define _GPXE_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 <gpxe/iobuf.h>
00015 #include <gpxe/xfer.h>
00016 #include <gpxe/scsi.h>
00017 
00018 /*****************************************************************************
00019  *
00020  * Common fields
00021  *
00022  *****************************************************************************
00023  */
00024 
00025 /** An SRP information unit tag */
00026 struct srp_tag {
00027         uint32_t dwords[2];
00028 } __attribute__ (( packed ));
00029 
00030 /** An SRP port ID */
00031 struct srp_port_id {
00032         uint8_t bytes[16];
00033 } __attribute__ (( packed ));
00034 
00035 /** An SRP port ID pair */
00036 struct srp_port_ids {
00037         /** Initiator port ID */
00038         struct srp_port_id initiator;
00039         /** Target port ID */
00040         struct srp_port_id target;
00041 } __attribute__ (( packed ));
00042 
00043 /** SRP information unit common fields */
00044 struct srp_common {
00045         /** Information unit type */
00046         uint8_t type;
00047         /** Reserved */
00048         uint8_t reserved0[7];
00049         /** Tag */
00050         struct srp_tag tag;
00051 } __attribute__ (( packed ));
00052 
00053 /*****************************************************************************
00054  *
00055  * Login request
00056  *
00057  *****************************************************************************
00058  */
00059 
00060 /** An SRP login request information unit */
00061 struct srp_login_req {
00062         /** Information unit type
00063          *
00064          * This must be @c SRP_LOGIN_REQ
00065          */
00066         uint8_t type;
00067         /** Reserved */
00068         uint8_t reserved0[7];
00069         /** Tag */
00070         struct srp_tag tag;
00071         /** Requested maximum initiator to target IU length */
00072         uint32_t max_i_t_iu_len;
00073         /** Reserved */
00074         uint8_t reserved1[4];
00075         /** Required buffer formats
00076          *
00077          * This is the bitwise OR of one or more @c
00078          * SRP_LOGIN_REQ_FMT_XXX constants.
00079          */
00080         uint16_t required_buffer_formats;
00081         /** Flags
00082          *
00083          * This is the bitwise OR of zero or more @c
00084          * SRP_LOGIN_REQ_FLAG_XXX and @c SRP_LOGIN_REQ_MCA_XXX
00085          * constants.
00086          */
00087         uint8_t flags;
00088         /** Reserved */
00089         uint8_t reserved2[5];
00090         /** Initiator and target port identifiers */
00091         struct srp_port_ids port_ids;
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         struct 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         struct 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 /** Indirect data buffer descriptor format supported */
00246 #define SRP_LOGIN_REJ_FMT_IDBD 0x04
00247 
00248 /** Direct data buffer descriptor format supported */
00249 #define SRP_LOGIN_REJ_FMT_DDBD 0x02
00250 
00251 /*****************************************************************************
00252  *
00253  * Initiator logout
00254  *
00255  *****************************************************************************
00256  */
00257 
00258 /** An SRP initiator logout request */
00259 struct srp_i_logout {
00260         /** Information unit type
00261          *
00262          * This must be @c SRP_I_LOGOUT
00263          */
00264         uint8_t type;
00265         /** Reserved */
00266         uint8_t reserved0[7];
00267         /** Tag */
00268         struct srp_tag tag;
00269 } __attribute__ (( packed ));
00270 
00271 /** Type of an SRP initiator logout request */
00272 #define SRP_I_LOGOUT 0x03
00273 
00274 /*****************************************************************************
00275  *
00276  * Target logout
00277  *
00278  *****************************************************************************
00279  */
00280 
00281 /** An SRP target logout request */
00282 struct srp_t_logout {
00283         /** Information unit type
00284          *
00285          * This must be @c SRP_T_LOGOUT
00286          */
00287         uint8_t type;
00288         /** Flags
00289          *
00290          * This is the bitwise OR of zero or more @c
00291          * SRP_T_LOGOUT_FLAG_XXX constants.
00292          */
00293         uint8_t flags;
00294         /** Reserved */
00295         uint8_t reserved0[2];
00296         /** Reason
00297          *
00298          * This is a @c SRP_T_LOGOUT_REASON_XXX constant.
00299          */
00300         uint32_t reason;
00301         /** Tag */
00302         struct srp_tag tag;
00303 } __attribute__ (( packed ));
00304 
00305 /** Type of an SRP target logout request */
00306 #define SRP_T_LOGOUT 0x80
00307 
00308 /** The initiator specified solicited notification of logouts */
00309 #define SRP_T_LOGOUT_FLAG_SOLNT 0x01
00310 
00311 /** No reason specified */
00312 #define SRP_T_LOGOUT_REASON_UNKNOWN 0x00000000UL
00313 
00314 /** Inactive RDMA channel (reclaiming resources) */
00315 #define SRP_T_LOGOUT_REASON_INACTIVE 0x00000001UL
00316 
00317 /** Invalid information unit type code received by SRP target port */
00318 #define SRP_T_LOGOUT_REASON_INVALID_TYPE 0x00000002UL
00319 
00320 /** SRP initiator port sent response with no corresponding request */
00321 #define SRP_T_LOGOUT_REASON_SPURIOUS_RESPONSE 0x00000003UL
00322 
00323 /** RDMA channel disconnected due to multi-channel action code in new login */
00324 #define SRP_T_LOGOUT_REASON_MCA 0x00000004UL
00325 
00326 /** Unsuppported format code value specified in data-out buffer descriptor */
00327 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_OUT_FORMAT 0x00000005UL
00328 
00329 /** Unsuppported format code value specified in data-in buffer descriptor */
00330 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_IN_FORMAT 0x00000006UL
00331 
00332 /** Invalid length for IU type */
00333 #define SRP_T_LOGOUT_INVALID_IU_LEN 0x00000008UL
00334 
00335 /*****************************************************************************
00336  *
00337  * Task management
00338  *
00339  *****************************************************************************
00340  */
00341 
00342 /** An SRP task management request */
00343 struct srp_tsk_mgmt {
00344         /** Information unit type
00345          *
00346          * This must be @c SRP_TSK_MGMT
00347          */
00348         uint8_t type;
00349         /** Flags
00350          *
00351          * This is the bitwise OR of zero or more
00352          * @c SRP_TSK_MGMT_FLAG_XXX constants.
00353          */
00354         uint8_t flags;
00355         /** Reserved */
00356         uint8_t reserved0[6];
00357         /** Tag */
00358         struct srp_tag tag;
00359         /** Reserved */
00360         uint8_t reserved1[4];
00361         /** Logical unit number */
00362         struct scsi_lun lun;
00363         /** Reserved */
00364         uint8_t reserved2[2];
00365         /** Task management function
00366          *
00367          * This is a @c SRP_TASK_MGMT_FUNC_XXX constant
00368          */
00369         uint8_t function;
00370         /** Reserved */
00371         uint8_t reserved3[1];
00372         /** Tag of task to be managed */
00373         struct srp_tag managed_tag;
00374         /** Reserved */
00375         uint8_t reserved4[8];
00376 } __attribute__ (( packed ));
00377 
00378 /** Type of an SRP task management request */
00379 #define SRP_TSK_MGMT 0x01
00380 
00381 /** Use solicited notification for unsuccessful completions */
00382 #define SRP_TSK_MGMT_FLAG_UCSOLNT 0x04
00383 
00384 /** Use solicited notification for successful completions */
00385 #define SRP_TSK_MGMT_FLAG_SCSOLNT 0x02
00386 
00387 /** The task manager shall perform an ABORT TASK function */
00388 #define SRP_TSK_MGMT_FUNC_ABORT_TASK 0x01
00389 
00390 /** The task manager shall perform an ABORT TASK SET function */
00391 #define SRP_TSK_MGMT_FUNC_ABORT_TASK_SET 0x02
00392 
00393 /** The task manager shall perform a CLEAR TASK SET function */
00394 #define SRP_TSK_MGMT_FUNC_CLEAR_TASK_SET 0x04
00395 
00396 /** The task manager shall perform a LOGICAL UNIT RESET function */
00397 #define SRP_TSK_MGMT_FUNC_LOGICAL_UNIT_RESET 0x08
00398 
00399 /** The task manager shall perform a CLEAR ACA function */
00400 #define SRP_TSK_MGMT_FUNC_CLEAR_ACA 0x40
00401 
00402 /*****************************************************************************
00403  *
00404  * SCSI command
00405  *
00406  *****************************************************************************
00407  */
00408 
00409 /** An SRP SCSI command */
00410 struct srp_cmd {
00411         /** Information unit type
00412          *
00413          * This must be @c SRP_CMD
00414          */
00415         uint8_t type;
00416         /** Flags
00417          *
00418          * This is the bitwise OR of zero or more @c SRP_CMD_FLAG_XXX
00419          * constants.
00420          */
00421         uint8_t flags;
00422         /** Reserved */
00423         uint8_t reserved0[3];
00424         /** Data buffer descriptor formats
00425          *
00426          * This is the bitwise OR of one @c SRP_CMD_DO_FMT_XXX and one @c
00427          * SRP_CMD_DI_FMT_XXX constant.
00428          */
00429         uint8_t data_buffer_formats;
00430         /** Data-out buffer descriptor count */
00431         uint8_t data_out_buffer_count;
00432         /** Data-in buffer descriptor count */
00433         uint8_t data_in_buffer_count;
00434         /** Tag */
00435         struct srp_tag tag;
00436         /** Reserved */
00437         uint8_t reserved1[4];
00438         /** Logical unit number */
00439         struct scsi_lun lun;
00440         /** Reserved */
00441         uint8_t reserved2[1];
00442         /** Task attribute
00443          *
00444          * This is a @c SRP_CMD_TASK_ATTR_XXX constant.
00445          */
00446         uint8_t task_attr;
00447         /** Reserved */
00448         uint8_t reserved3[1];
00449         /** Additional CDB length */
00450         uint8_t additional_cdb_len;
00451         /** Command data block */
00452         union scsi_cdb cdb;
00453 } __attribute__ (( packed ));
00454 
00455 /** Type of an SRP SCSI command */
00456 #define SRP_CMD 0x02
00457 
00458 /** Use solicited notification for unsuccessful completions */
00459 #define SRP_CMD_FLAG_UCSOLNT 0x04
00460 
00461 /** Use solicited notification for successful completions */
00462 #define SRP_CMD_FLAG_SCSOLNT 0x02
00463 
00464 /** Data-out buffer format mask */
00465 #define SRP_CMD_DO_FMT_MASK 0xf0
00466 
00467 /** Direct data-out buffer format */
00468 #define SRP_CMD_DO_FMT_DIRECT 0x10
00469 
00470 /** Indirect data-out buffer format */
00471 #define SRP_CMD_DO_FMT_INDIRECT 0x20
00472 
00473 /** Data-in buffer format mask */
00474 #define SRP_CMD_DI_FMT_MASK 0x0f
00475 
00476 /** Direct data-in buffer format */
00477 #define SRP_CMD_DI_FMT_DIRECT 0x01
00478 
00479 /** Indirect data-in buffer format */
00480 #define SRP_CMD_DI_FMT_INDIRECT 0x02
00481 
00482 /** Use the rules for a simple task attribute */
00483 #define SRP_CMD_TASK_ATTR_SIMPLE 0x00
00484 
00485 /** Use the rules for a head of queue task attribute */
00486 #define SRP_CMD_TASK_ATTR_QUEUE_HEAD 0x01
00487 
00488 /** Use the rules for an ordered task attribute */
00489 #define SRP_CMD_TASK_ATTR_ORDERED 0x02
00490 
00491 /** Use the rules for an automatic contingent allegiance task attribute */
00492 #define SRP_CMD_TASK_ATTR_AUTOMATIC_CONTINGENT_ALLEGIANCE 0x08
00493 
00494 /** An SRP memory descriptor */
00495 struct srp_memory_descriptor {
00496         /** Virtual address */
00497         uint64_t address;
00498         /** Memory handle */
00499         uint32_t handle;
00500         /** Data length */
00501         uint32_t len;
00502 } __attribute__ (( packed ));
00503 
00504 /*****************************************************************************
00505  *
00506  * SCSI response
00507  *
00508  *****************************************************************************
00509  */
00510 
00511 /** An SRP SCSI response */
00512 struct srp_rsp {
00513         /** Information unit type
00514          *
00515          * This must be @c SRP_RSP
00516          */
00517         uint8_t type;
00518         /** Flags
00519          *
00520          * This is the bitwise OR of zero or more @c SRP_RSP_FLAG_XXX
00521          * constants.
00522          */
00523         uint8_t flags;
00524         /** Reserved */
00525         uint8_t reserved0[2];
00526         /** Request limit delta */
00527         uint32_t request_limit_delta;
00528         /** Tag */
00529         struct srp_tag tag;
00530         /** Reserved */
00531         uint8_t reserved1[2];
00532         /** Valid fields
00533          *
00534          * This is the bitwise OR of zero or more @c SRP_RSP_VALID_XXX
00535          * constants.
00536          */
00537         uint8_t valid;
00538         /** Status
00539          *
00540          * This is the SCSI status code.
00541          */
00542         uint8_t status;
00543         /** Data-out residual count */
00544         uint32_t data_out_residual_count;
00545         /** Data-in residual count */
00546         uint32_t data_in_residual_count;
00547         /** Sense data list length */
00548         uint32_t sense_data_len;
00549         /** Response data list length */
00550         uint32_t response_data_len;
00551 } __attribute__ (( packed ));
00552 
00553 /** Type of an SRP SCSI response */
00554 #define SRP_RSP 0xc1
00555 
00556 /** The initiator specified solicited notification of this response */
00557 #define SRP_RSP_FLAG_SOLNT 0x01
00558 
00559 /** Data-in residual count field is valid and represents an underflow */
00560 #define SRP_RSP_VALID_DIUNDER 0x20
00561 
00562 /** Data-in residual count field is valid and represents an overflow */
00563 #define SRP_RSP_VALID_DIOVER 0x10
00564 
00565 /** Data-out residual count field is valid and represents an underflow */
00566 #define SRP_RSP_VALID_DOUNDER 0x08
00567 
00568 /** Data-out residual count field is valid and represents an overflow */
00569 #define SRP_RSP_VALID_DOOVER 0x04
00570 
00571 /** Sense data list length field is valid */
00572 #define SRP_RSP_VALID_SNSVALID 0x02
00573 
00574 /** Response data list length field is valid */
00575 #define SRP_RSP_VALID_RSPVALID 0x01
00576 
00577 /**
00578  * Get response data portion of SCSI response
00579  *
00580  * @v rsp                       SCSI response
00581  * @ret response_data           Response data, or NULL if not present
00582  */
00583 static inline void * srp_rsp_response_data ( struct srp_rsp *rsp ) {
00584         return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
00585                  ( ( ( void * ) rsp ) + sizeof ( *rsp ) ) : NULL );
00586 }
00587 
00588 /**
00589  * Get length of response data portion of SCSI response
00590  *
00591  * @v rsp                       SCSI response
00592  * @ret response_data_len       Response data length
00593  */
00594 static inline size_t srp_rsp_response_data_len ( struct srp_rsp *rsp ) {
00595         return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
00596                  ntohl ( rsp->response_data_len ) : 0 );
00597 }
00598 
00599 /**
00600  * Get sense data portion of SCSI response
00601  *
00602  * @v rsp                       SCSI response
00603  * @ret sense_data              Sense data, or NULL if not present
00604  */
00605 static inline void * srp_rsp_sense_data ( struct srp_rsp *rsp ) {
00606         return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
00607                  ( ( ( void * ) rsp ) + sizeof ( *rsp ) +
00608                    srp_rsp_response_data_len ( rsp ) ) : NULL );
00609 }
00610 
00611 /**
00612  * Get length of sense data portion of SCSI response
00613  *
00614  * @v rsp                       SCSI response
00615  * @ret sense_data_len          Sense data length
00616  */
00617 static inline size_t srp_rsp_sense_data_len ( struct srp_rsp *rsp ) {
00618         return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
00619                  ntohl ( rsp->sense_data_len ) : 0 );
00620 }
00621 
00622 /*****************************************************************************
00623  *
00624  * Credit request
00625  *
00626  *****************************************************************************
00627  */
00628 
00629 /** An SRP credit request */
00630 struct srp_cred_req {
00631         /** Information unit type
00632          *
00633          * This must be @c SRP_CRED_REQ
00634          */
00635         uint8_t type;
00636         /** Flags
00637          *
00638          * This is the bitwise OR of zero or more
00639          * @c SRP_CRED_REQ_FLAG_XXX constants.
00640          */
00641         uint8_t flags;
00642         /** Reserved */
00643         uint8_t reserved0[2];
00644         /** Request limit delta */
00645         uint32_t request_limit_delta;
00646         /** Tag */
00647         struct srp_tag tag;
00648 } __attribute__ (( packed ));
00649 
00650 /** Type of an SRP credit request */
00651 #define SRP_CRED_REQ 0x81
00652 
00653 /** The initiator specified solicited notification of credit requests */
00654 #define SRP_CRED_REQ_FLAG_SOLNT 0x01
00655 
00656 /*****************************************************************************
00657  *
00658  * Credit response
00659  *
00660  *****************************************************************************
00661  */
00662 
00663 /** An SRP credit response */
00664 struct srp_cred_rsp {
00665         /** Information unit type
00666          *
00667          * This must be @c SRP_CRED_RSP
00668          */
00669         uint8_t type;
00670         /** Reserved */
00671         uint8_t reserved0[7];
00672         /** Tag */
00673         struct srp_tag tag;
00674 } __attribute__ (( packed ));
00675 
00676 /** Type of an SRP credit response */
00677 #define SRP_CRED_RSP 0x41
00678 
00679 /*****************************************************************************
00680  *
00681  * Asynchronous event request
00682  *
00683  *****************************************************************************
00684  */
00685 
00686 /** An SRP asynchronous event request */
00687 struct srp_aer_req {
00688         /** Information unit type
00689          *
00690          * This must be @c SRP_AER_REQ
00691          */
00692         uint8_t type;
00693         /** Flags
00694          *
00695          * This is the bitwise OR of zero or more @c
00696          * SRP_AER_REQ_FLAG_XXX constants.
00697          */
00698         uint8_t flags;
00699         /** Reserved */
00700         uint8_t reserved0[2];
00701         /** Request limit delta */
00702         uint32_t request_limit_delta;
00703         /** Tag */
00704         struct srp_tag tag;
00705         /** Reserved */
00706         uint8_t reserved1[4];
00707         /** Logical unit number */
00708         struct scsi_lun lun;
00709         /** Sense data list length */
00710         uint32_t sense_data_len;
00711         /** Reserved */
00712         uint8_t reserved2[4];
00713 } __attribute__ (( packed ));
00714 
00715 /** Type of an SRP asynchronous event request */
00716 #define SRP_AER_REQ 0x82
00717 
00718 /** The initiator specified solicited notification of asynchronous events */
00719 #define SRP_AER_REQ_FLAG_SOLNT 0x01
00720 
00721 /**
00722  * Get sense data portion of asynchronous event request
00723  *
00724  * @v aer_req                   SRP asynchronous event request
00725  * @ret sense_data              Sense data
00726  */
00727 static inline __always_inline void *
00728 srp_aer_req_sense_data ( struct srp_aer_req *aer_req ) {
00729         return ( ( ( void * ) aer_req ) + sizeof ( *aer_req ) );
00730 }
00731 
00732 /**
00733  * Get length of sense data portion of asynchronous event request
00734  *
00735  * @v aer_req                   SRP asynchronous event request
00736  * @ret sense_data_len          Sense data length
00737  */
00738 static inline __always_inline size_t
00739 srp_aer_req_sense_data_len ( struct srp_aer_req *aer_req ) {
00740         return ( ntohl ( aer_req->sense_data_len ) );
00741 }
00742 
00743 /*****************************************************************************
00744  *
00745  * Asynchronous event response
00746  *
00747  *****************************************************************************
00748  */
00749 
00750 /** An SRP asynchronous event response */
00751 struct srp_aer_rsp {
00752         /** Information unit type
00753          *
00754          * This must be @c SRP_AER_RSP
00755          */
00756         uint8_t type;
00757         /** Reserved */
00758         uint8_t reserved0[7];
00759         /** Tag */
00760         struct srp_tag tag;
00761 } __attribute__ (( packed ));
00762 
00763 /** Type of an SRP asynchronous event response */
00764 #define SRP_AER_RSP 0x42
00765 
00766 /*****************************************************************************
00767  *
00768  * Information units
00769  *
00770  *****************************************************************************
00771  */
00772 
00773 /** Maximum length of any initiator-to-target IU that we will send
00774  *
00775  * The longest IU is a SRP_CMD with no additional CDB and two direct
00776  * data buffer descriptors, which comes to 80 bytes.
00777  */
00778 #define SRP_MAX_I_T_IU_LEN 80
00779 
00780 /*****************************************************************************
00781  *
00782  * SRP device
00783  *
00784  *****************************************************************************
00785  */
00786 
00787 struct srp_device;
00788 
00789 /** An SRP transport type */
00790 struct srp_transport_type {
00791         /** Length of transport private data */
00792         size_t priv_len;
00793         /** Parse root path
00794          *
00795          * @v srp               SRP device
00796          * @v root_path         Root path
00797          * @ret                 Return status code
00798          */
00799         int ( * parse_root_path ) ( struct srp_device *srp,
00800                                     const char *root_path );
00801         /** Connect SRP session
00802          *
00803          * @v srp               SRP device
00804          * @ret rc              Return status code
00805          *
00806          * This method should open the underlying socket.
00807          */
00808         int ( * connect ) ( struct srp_device *srp );
00809 };
00810 
00811 /** An SRP device */
00812 struct srp_device {
00813         /** Reference count */
00814         struct refcnt refcnt;
00815 
00816         /** Initiator and target port IDs */
00817         struct srp_port_ids port_ids;
00818         /** Logical unit number */
00819         struct scsi_lun lun;
00820         /** Memory handle */
00821         uint32_t memory_handle;
00822 
00823         /** Current state
00824          *
00825          * This is the bitwise-OR of zero or more @c SRP_STATE_XXX
00826          * flags.
00827          */
00828         unsigned int state;
00829         /** Retry counter */
00830         unsigned int retry_count;
00831         /** Current SCSI command */
00832         struct scsi_command *command;
00833 
00834         /** Underlying data transfer interface */
00835         struct xfer_interface socket;
00836 
00837         /** Transport type */
00838         struct srp_transport_type *transport;
00839         /** Transport private data */
00840         char transport_priv[0];
00841 };
00842 
00843 /**
00844  * Get SRP transport private data
00845  *
00846  * @v srp               SRP device
00847  * @ret priv            SRP transport private data
00848  */
00849 static inline __always_inline void *
00850 srp_transport_priv ( struct srp_device *srp ) {
00851         return ( ( void * ) srp->transport_priv );
00852 }
00853 
00854 /** SRP state flags */
00855 enum srp_state {
00856         /** Underlying socket is open */
00857         SRP_STATE_SOCKET_OPEN = 0x0001,
00858         /** Session is logged in */
00859         SRP_STATE_LOGGED_IN = 0x0002,
00860 };
00861 
00862 /** Maximum number of SRP retry attempts */
00863 #define SRP_MAX_RETRIES 3
00864 
00865 extern int srp_attach ( struct scsi_device *scsi, const char *root_path );
00866 extern void srp_detach ( struct scsi_device *scsi );
00867 
00868 #endif /* _GPXE_SRP_H */

Generated on Tue Apr 6 20:01:08 2010 for gPXE by  doxygen 1.5.7.1