1 #ifndef _GPXE_SRP_H 2 #define _GPXE_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 <gpxe/iobuf.h> 15 #include <gpxe/xfer.h> 16 #include <gpxe/scsi.h> 17 18 /***************************************************************************** 19 * 20 * Common fields 21 * 22 ***************************************************************************** 23 */ 24 25 /** An SRP information unit tag */ 26 struct srp_tag { 27 uint32_t dwords[2]; 28 } __attribute__ (( packed )); 29 30 /** An SRP port ID */ 31 struct srp_port_id { 32 uint8_t bytes[16]; 33 } __attribute__ (( packed )); 34 35 /** An SRP port ID pair */ 36 struct srp_port_ids { 37 /** Initiator port ID */ 38 struct srp_port_id initiator; 39 /** Target port ID */ 40 struct srp_port_id target; 41 } __attribute__ (( packed )); 42 43 /** SRP information unit common fields */ 44 struct srp_common { 45 /** Information unit type */ 46 uint8_t type; 47 /** Reserved */ 48 uint8_t reserved0[7]; 49 /** Tag */ 50 struct srp_tag tag; 51 } __attribute__ (( packed )); 52 53 /***************************************************************************** 54 * 55 * Login request 56 * 57 ***************************************************************************** 58 */ 59 60 /** An SRP login request information unit */ 61 struct srp_login_req { 62 /** Information unit type 63 * 64 * This must be @c SRP_LOGIN_REQ 65 */ 66 uint8_t type; 67 /** Reserved */ 68 uint8_t reserved0[7]; 69 /** Tag */ 70 struct srp_tag tag; 71 /** Requested maximum initiator to target IU length */ 72 uint32_t max_i_t_iu_len; 73 /** Reserved */ 74 uint8_t reserved1[4]; 75 /** Required buffer formats 76 * 77 * This is the bitwise OR of one or more @c 78 * SRP_LOGIN_REQ_FMT_XXX constants. 79 */ 80 uint16_t required_buffer_formats; 81 /** Flags 82 * 83 * This is the bitwise OR of zero or more @c 84 * SRP_LOGIN_REQ_FLAG_XXX and @c SRP_LOGIN_REQ_MCA_XXX 85 * constants. 86 */ 87 uint8_t flags; 88 /** Reserved */ 89 uint8_t reserved2[5]; 90 /** Initiator and target port identifiers */ 91 struct srp_port_ids port_ids; 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 struct 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 struct 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 /** Indirect data buffer descriptor format supported */ 246 #define SRP_LOGIN_REJ_FMT_IDBD 0x04 247 248 /** Direct data buffer descriptor format supported */ 249 #define SRP_LOGIN_REJ_FMT_DDBD 0x02 250 251 /***************************************************************************** 252 * 253 * Initiator logout 254 * 255 ***************************************************************************** 256 */ 257 258 /** An SRP initiator logout request */ 259 struct srp_i_logout { 260 /** Information unit type 261 * 262 * This must be @c SRP_I_LOGOUT 263 */ 264 uint8_t type; 265 /** Reserved */ 266 uint8_t reserved0[7]; 267 /** Tag */ 268 struct srp_tag tag; 269 } __attribute__ (( packed )); 270 271 /** Type of an SRP initiator logout request */ 272 #define SRP_I_LOGOUT 0x03 273 274 /***************************************************************************** 275 * 276 * Target logout 277 * 278 ***************************************************************************** 279 */ 280 281 /** An SRP target logout request */ 282 struct srp_t_logout { 283 /** Information unit type 284 * 285 * This must be @c SRP_T_LOGOUT 286 */ 287 uint8_t type; 288 /** Flags 289 * 290 * This is the bitwise OR of zero or more @c 291 * SRP_T_LOGOUT_FLAG_XXX constants. 292 */ 293 uint8_t flags; 294 /** Reserved */ 295 uint8_t reserved0[2]; 296 /** Reason 297 * 298 * This is a @c SRP_T_LOGOUT_REASON_XXX constant. 299 */ 300 uint32_t reason; 301 /** Tag */ 302 struct srp_tag tag; 303 } __attribute__ (( packed )); 304 305 /** Type of an SRP target logout request */ 306 #define SRP_T_LOGOUT 0x80 307 308 /** The initiator specified solicited notification of logouts */ 309 #define SRP_T_LOGOUT_FLAG_SOLNT 0x01 310 311 /** No reason specified */ 312 #define SRP_T_LOGOUT_REASON_UNKNOWN 0x00000000UL 313 314 /** Inactive RDMA channel (reclaiming resources) */ 315 #define SRP_T_LOGOUT_REASON_INACTIVE 0x00000001UL 316 317 /** Invalid information unit type code received by SRP target port */ 318 #define SRP_T_LOGOUT_REASON_INVALID_TYPE 0x00000002UL 319 320 /** SRP initiator port sent response with no corresponding request */ 321 #define SRP_T_LOGOUT_REASON_SPURIOUS_RESPONSE 0x00000003UL 322 323 /** RDMA channel disconnected due to multi-channel action code in new login */ 324 #define SRP_T_LOGOUT_REASON_MCA 0x00000004UL 325 326 /** Unsuppported format code value specified in data-out buffer descriptor */ 327 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_OUT_FORMAT 0x00000005UL 328 329 /** Unsuppported format code value specified in data-in buffer descriptor */ 330 #define SRP_T_LOGOUT_UNSUPPORTED_DATA_IN_FORMAT 0x00000006UL 331 332 /** Invalid length for IU type */ 333 #define SRP_T_LOGOUT_INVALID_IU_LEN 0x00000008UL 334 335 /***************************************************************************** 336 * 337 * Task management 338 * 339 ***************************************************************************** 340 */ 341 342 /** An SRP task management request */ 343 struct srp_tsk_mgmt { 344 /** Information unit type 345 * 346 * This must be @c SRP_TSK_MGMT 347 */ 348 uint8_t type; 349 /** Flags 350 * 351 * This is the bitwise OR of zero or more 352 * @c SRP_TSK_MGMT_FLAG_XXX constants. 353 */ 354 uint8_t flags; 355 /** Reserved */ 356 uint8_t reserved0[6]; 357 /** Tag */ 358 struct srp_tag tag; 359 /** Reserved */ 360 uint8_t reserved1[4]; 361 /** Logical unit number */ 362 struct scsi_lun lun; 363 /** Reserved */ 364 uint8_t reserved2[2]; 365 /** Task management function 366 * 367 * This is a @c SRP_TASK_MGMT_FUNC_XXX constant 368 */ 369 uint8_t function; 370 /** Reserved */ 371 uint8_t reserved3[1]; 372 /** Tag of task to be managed */ 373 struct srp_tag managed_tag; 374 /** Reserved */ 375 uint8_t reserved4[8]; 376 } __attribute__ (( packed )); 377 378 /** Type of an SRP task management request */ 379 #define SRP_TSK_MGMT 0x01 380 381 /** Use solicited notification for unsuccessful completions */ 382 #define SRP_TSK_MGMT_FLAG_UCSOLNT 0x04 383 384 /** Use solicited notification for successful completions */ 385 #define SRP_TSK_MGMT_FLAG_SCSOLNT 0x02 386 387 /** The task manager shall perform an ABORT TASK function */ 388 #define SRP_TSK_MGMT_FUNC_ABORT_TASK 0x01 389 390 /** The task manager shall perform an ABORT TASK SET function */ 391 #define SRP_TSK_MGMT_FUNC_ABORT_TASK_SET 0x02 392 393 /** The task manager shall perform a CLEAR TASK SET function */ 394 #define SRP_TSK_MGMT_FUNC_CLEAR_TASK_SET 0x04 395 396 /** The task manager shall perform a LOGICAL UNIT RESET function */ 397 #define SRP_TSK_MGMT_FUNC_LOGICAL_UNIT_RESET 0x08 398 399 /** The task manager shall perform a CLEAR ACA function */ 400 #define SRP_TSK_MGMT_FUNC_CLEAR_ACA 0x40 401 402 /***************************************************************************** 403 * 404 * SCSI command 405 * 406 ***************************************************************************** 407 */ 408 409 /** An SRP SCSI command */ 410 struct srp_cmd { 411 /** Information unit type 412 * 413 * This must be @c SRP_CMD 414 */ 415 uint8_t type; 416 /** Flags 417 * 418 * This is the bitwise OR of zero or more @c SRP_CMD_FLAG_XXX 419 * constants. 420 */ 421 uint8_t flags; 422 /** Reserved */ 423 uint8_t reserved0[3]; 424 /** Data buffer descriptor formats 425 * 426 * This is the bitwise OR of one @c SRP_CMD_DO_FMT_XXX and one @c 427 * SRP_CMD_DI_FMT_XXX constant. 428 */ 429 uint8_t data_buffer_formats; 430 /** Data-out buffer descriptor count */ 431 uint8_t data_out_buffer_count; 432 /** Data-in buffer descriptor count */ 433 uint8_t data_in_buffer_count; 434 /** Tag */ 435 struct srp_tag tag; 436 /** Reserved */ 437 uint8_t reserved1[4]; 438 /** Logical unit number */ 439 struct scsi_lun lun; 440 /** Reserved */ 441 uint8_t reserved2[1]; 442 /** Task attribute 443 * 444 * This is a @c SRP_CMD_TASK_ATTR_XXX constant. 445 */ 446 uint8_t task_attr; 447 /** Reserved */ 448 uint8_t reserved3[1]; 449 /** Additional CDB length */ 450 uint8_t additional_cdb_len; 451 /** Command data block */ 452 union scsi_cdb cdb; 453 } __attribute__ (( packed )); 454 455 /** Type of an SRP SCSI command */ 456 #define SRP_CMD 0x02 457 458 /** Use solicited notification for unsuccessful completions */ 459 #define SRP_CMD_FLAG_UCSOLNT 0x04 460 461 /** Use solicited notification for successful completions */ 462 #define SRP_CMD_FLAG_SCSOLNT 0x02 463 464 /** Data-out buffer format mask */ 465 #define SRP_CMD_DO_FMT_MASK 0xf0 466 467 /** Direct data-out buffer format */ 468 #define SRP_CMD_DO_FMT_DIRECT 0x10 469 470 /** Indirect data-out buffer format */ 471 #define SRP_CMD_DO_FMT_INDIRECT 0x20 472 473 /** Data-in buffer format mask */ 474 #define SRP_CMD_DI_FMT_MASK 0x0f 475 476 /** Direct data-in buffer format */ 477 #define SRP_CMD_DI_FMT_DIRECT 0x01 478 479 /** Indirect data-in buffer format */ 480 #define SRP_CMD_DI_FMT_INDIRECT 0x02 481 482 /** Use the rules for a simple task attribute */ 483 #define SRP_CMD_TASK_ATTR_SIMPLE 0x00 484 485 /** Use the rules for a head of queue task attribute */ 486 #define SRP_CMD_TASK_ATTR_QUEUE_HEAD 0x01 487 488 /** Use the rules for an ordered task attribute */ 489 #define SRP_CMD_TASK_ATTR_ORDERED 0x02 490 491 /** Use the rules for an automatic contingent allegiance task attribute */ 492 #define SRP_CMD_TASK_ATTR_AUTOMATIC_CONTINGENT_ALLEGIANCE 0x08 493 494 /** An SRP memory descriptor */ 495 struct srp_memory_descriptor { 496 /** Virtual address */ 497 uint64_t address; 498 /** Memory handle */ 499 uint32_t handle; 500 /** Data length */ 501 uint32_t len; 502 } __attribute__ (( packed )); 503 504 /***************************************************************************** 505 * 506 * SCSI response 507 * 508 ***************************************************************************** 509 */ 510 511 /** An SRP SCSI response */ 512 struct srp_rsp { 513 /** Information unit type 514 * 515 * This must be @c SRP_RSP 516 */ 517 uint8_t type; 518 /** Flags 519 * 520 * This is the bitwise OR of zero or more @c SRP_RSP_FLAG_XXX 521 * constants. 522 */ 523 uint8_t flags; 524 /** Reserved */ 525 uint8_t reserved0[2]; 526 /** Request limit delta */ 527 uint32_t request_limit_delta; 528 /** Tag */ 529 struct srp_tag tag; 530 /** Reserved */ 531 uint8_t reserved1[2]; 532 /** Valid fields 533 * 534 * This is the bitwise OR of zero or more @c SRP_RSP_VALID_XXX 535 * constants. 536 */ 537 uint8_t valid; 538 /** Status 539 * 540 * This is the SCSI status code. 541 */ 542 uint8_t status; 543 /** Data-out residual count */ 544 uint32_t data_out_residual_count; 545 /** Data-in residual count */ 546 uint32_t data_in_residual_count; 547 /** Sense data list length */ 548 uint32_t sense_data_len; 549 /** Response data list length */ 550 uint32_t response_data_len; 551 } __attribute__ (( packed )); 552 553 /** Type of an SRP SCSI response */ 554 #define SRP_RSP 0xc1 555 556 /** The initiator specified solicited notification of this response */ 557 #define SRP_RSP_FLAG_SOLNT 0x01 558 559 /** Data-in residual count field is valid and represents an underflow */ 560 #define SRP_RSP_VALID_DIUNDER 0x20 561 562 /** Data-in residual count field is valid and represents an overflow */ 563 #define SRP_RSP_VALID_DIOVER 0x10 564 565 /** Data-out residual count field is valid and represents an underflow */ 566 #define SRP_RSP_VALID_DOUNDER 0x08 567 568 /** Data-out residual count field is valid and represents an overflow */ 569 #define SRP_RSP_VALID_DOOVER 0x04 570 571 /** Sense data list length field is valid */ 572 #define SRP_RSP_VALID_SNSVALID 0x02 573 574 /** Response data list length field is valid */ 575 #define SRP_RSP_VALID_RSPVALID 0x01 576 577 /** 578 * Get response data portion of SCSI response 579 * 580 * @v rsp SCSI response 581 * @ret response_data Response data, or NULL if not present 582 */ 583 static inline void * srp_rsp_response_data ( struct srp_rsp *rsp ) { 584 return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ? 585 ( ( ( void * ) rsp ) + sizeof ( *rsp ) ) : NULL ); 586 } 587 588 /** 589 * Get length of response data portion of SCSI response 590 * 591 * @v rsp SCSI response 592 * @ret response_data_len Response data length 593 */ 594 static inline size_t srp_rsp_response_data_len ( struct srp_rsp *rsp ) { 595 return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ? 596 ntohl ( rsp->response_data_len ) : 0 ); 597 } 598 599 /** 600 * Get sense data portion of SCSI response 601 * 602 * @v rsp SCSI response 603 * @ret sense_data Sense data, or NULL if not present 604 */ 605 static inline void * srp_rsp_sense_data ( struct srp_rsp *rsp ) { 606 return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ? 607 ( ( ( void * ) rsp ) + sizeof ( *rsp ) + 608 srp_rsp_response_data_len ( rsp ) ) : NULL ); 609 } 610 611 /** 612 * Get length of sense data portion of SCSI response 613 * 614 * @v rsp SCSI response 615 * @ret sense_data_len Sense data length 616 */ 617 static inline size_t srp_rsp_sense_data_len ( struct srp_rsp *rsp ) { 618 return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ? 619 ntohl ( rsp->sense_data_len ) : 0 ); 620 } 621 622 /***************************************************************************** 623 * 624 * Credit request 625 * 626 ***************************************************************************** 627 */ 628 629 /** An SRP credit request */ 630 struct srp_cred_req { 631 /** Information unit type 632 * 633 * This must be @c SRP_CRED_REQ 634 */ 635 uint8_t type; 636 /** Flags 637 * 638 * This is the bitwise OR of zero or more 639 * @c SRP_CRED_REQ_FLAG_XXX constants. 640 */ 641 uint8_t flags; 642 /** Reserved */ 643 uint8_t reserved0[2]; 644 /** Request limit delta */ 645 uint32_t request_limit_delta; 646 /** Tag */ 647 struct srp_tag tag; 648 } __attribute__ (( packed )); 649 650 /** Type of an SRP credit request */ 651 #define SRP_CRED_REQ 0x81 652 653 /** The initiator specified solicited notification of credit requests */ 654 #define SRP_CRED_REQ_FLAG_SOLNT 0x01 655 656 /***************************************************************************** 657 * 658 * Credit response 659 * 660 ***************************************************************************** 661 */ 662 663 /** An SRP credit response */ 664 struct srp_cred_rsp { 665 /** Information unit type 666 * 667 * This must be @c SRP_CRED_RSP 668 */ 669 uint8_t type; 670 /** Reserved */ 671 uint8_t reserved0[7]; 672 /** Tag */ 673 struct srp_tag tag; 674 } __attribute__ (( packed )); 675 676 /** Type of an SRP credit response */ 677 #define SRP_CRED_RSP 0x41 678 679 /***************************************************************************** 680 * 681 * Asynchronous event request 682 * 683 ***************************************************************************** 684 */ 685 686 /** An SRP asynchronous event request */ 687 struct srp_aer_req { 688 /** Information unit type 689 * 690 * This must be @c SRP_AER_REQ 691 */ 692 uint8_t type; 693 /** Flags 694 * 695 * This is the bitwise OR of zero or more @c 696 * SRP_AER_REQ_FLAG_XXX constants. 697 */ 698 uint8_t flags; 699 /** Reserved */ 700 uint8_t reserved0[2]; 701 /** Request limit delta */ 702 uint32_t request_limit_delta; 703 /** Tag */ 704 struct srp_tag tag; 705 /** Reserved */ 706 uint8_t reserved1[4]; 707 /** Logical unit number */ 708 struct scsi_lun lun; 709 /** Sense data list length */ 710 uint32_t sense_data_len; 711 /** Reserved */ 712 uint8_t reserved2[4]; 713 } __attribute__ (( packed )); 714 715 /** Type of an SRP asynchronous event request */ 716 #define SRP_AER_REQ 0x82 717 718 /** The initiator specified solicited notification of asynchronous events */ 719 #define SRP_AER_REQ_FLAG_SOLNT 0x01 720 721 /** 722 * Get sense data portion of asynchronous event request 723 * 724 * @v aer_req SRP asynchronous event request 725 * @ret sense_data Sense data 726 */ 727 static inline __always_inline void * 728 srp_aer_req_sense_data ( struct srp_aer_req *aer_req ) { 729 return ( ( ( void * ) aer_req ) + sizeof ( *aer_req ) ); 730 } 731 732 /** 733 * Get length of sense data portion of asynchronous event request 734 * 735 * @v aer_req SRP asynchronous event request 736 * @ret sense_data_len Sense data length 737 */ 738 static inline __always_inline size_t 739 srp_aer_req_sense_data_len ( struct srp_aer_req *aer_req ) { 740 return ( ntohl ( aer_req->sense_data_len ) ); 741 } 742 743 /***************************************************************************** 744 * 745 * Asynchronous event response 746 * 747 ***************************************************************************** 748 */ 749 750 /** An SRP asynchronous event response */ 751 struct srp_aer_rsp { 752 /** Information unit type 753 * 754 * This must be @c SRP_AER_RSP 755 */ 756 uint8_t type; 757 /** Reserved */ 758 uint8_t reserved0[7]; 759 /** Tag */ 760 struct srp_tag tag; 761 } __attribute__ (( packed )); 762 763 /** Type of an SRP asynchronous event response */ 764 #define SRP_AER_RSP 0x42 765 766 /***************************************************************************** 767 * 768 * Information units 769 * 770 ***************************************************************************** 771 */ 772 773 /** Maximum length of any initiator-to-target IU that we will send 774 * 775 * The longest IU is a SRP_CMD with no additional CDB and two direct 776 * data buffer descriptors, which comes to 80 bytes. 777 */ 778 #define SRP_MAX_I_T_IU_LEN 80 779 780 /***************************************************************************** 781 * 782 * SRP device 783 * 784 ***************************************************************************** 785 */ 786 787 struct srp_device; 788 789 /** An SRP transport type */ 790 struct srp_transport_type { 791 /** Length of transport private data */ 792 size_t priv_len; 793 /** Parse root path 794 * 795 * @v srp SRP device 796 * @v root_path Root path 797 * @ret Return status code 798 */ 799 int ( * parse_root_path ) ( struct srp_device *srp, 800 const char *root_path ); 801 /** Connect SRP session 802 * 803 * @v srp SRP device 804 * @ret rc Return status code 805 * 806 * This method should open the underlying socket. 807 */ 808 int ( * connect ) ( struct srp_device *srp ); 809 }; 810 811 /** An SRP device */ 812 struct srp_device { 813 /** Reference count */ 814 struct refcnt refcnt; 815 816 /** Initiator and target port IDs */ 817 struct srp_port_ids port_ids; 818 /** Logical unit number */ 819 struct scsi_lun lun; 820 /** Memory handle */ 821 uint32_t memory_handle; 822 823 /** Current state 824 * 825 * This is the bitwise-OR of zero or more @c SRP_STATE_XXX 826 * flags. 827 */ 828 unsigned int state; 829 /** Retry counter */ 830 unsigned int retry_count; 831 /** Current SCSI command */ 832 struct scsi_command *command; 833 834 /** Underlying data transfer interface */ 835 struct xfer_interface socket; 836 837 /** Transport type */ 838 struct srp_transport_type *transport; 839 /** Transport private data */ 840 char transport_priv[0]; 841 }; 842 843 /** 844 * Get SRP transport private data 845 * 846 * @v srp SRP device 847 * @ret priv SRP transport private data 848 */ 849 static inline __always_inline void * 850 srp_transport_priv ( struct srp_device *srp ) { 851 return ( ( void * ) srp->transport_priv ); 852 } 853 854 /** SRP state flags */ 855 enum srp_state { 856 /** Underlying socket is open */ 857 SRP_STATE_SOCKET_OPEN = 0x0001, 858 /** Session is logged in */ 859 SRP_STATE_LOGGED_IN = 0x0002, 860 }; 861 862 /** Maximum number of SRP retry attempts */ 863 #define SRP_MAX_RETRIES 3 864 865 extern int srp_attach ( struct scsi_device *scsi, const char *root_path ); 866 extern void srp_detach ( struct scsi_device *scsi ); 867 868 #endif /* _GPXE_SRP_H */ 869