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 */
1.5.7.1