1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2000 by Cisco Systems, Inc. All rights reserved. 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _ISCSI_H 28 #define _ISCSI_H 29 30 /* 31 * Block comment which describes the contents of this file. 32 */ 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 #include <sys/scsi/scsi.h> 39 #include <sys/ddi.h> 40 #include <sys/sunddi.h> 41 #include <sys/socket.h> 42 #include <sys/kstat.h> 43 #include <sys/sunddi.h> 44 #include <sys/sunmdi.h> 45 #include <sys/mdi_impldefs.h> 46 #include <sys/time.h> 47 #include <sys/nvpair.h> 48 #include <sys/sdt.h> 49 50 #include <sys/scsi/adapters/iscsi_if.h> 51 #include <sys/scsi/adapters/iscsi_protocol.h> 52 #include <iscsiAuthClient.h> 53 #include <iscsi_stats.h> 54 #include <iscsi_thread.h> 55 #include <nvfile.h> 56 57 #ifndef MIN 58 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 59 #endif 60 61 #ifndef TRUE 62 #define TRUE 1 63 #endif 64 65 #ifndef FALSE 66 #define FALSE 0 67 #endif 68 69 #define LOGIN_PDU_BUFFER_SIZE (16 * 1024) /* move somewhere else */ 70 71 /* 72 * Name Format of the different Task Queues 73 */ 74 #define ISCSI_SESS_IOTH_NAME_FORMAT "io_thrd_%d.%d" 75 #define ISCSI_SESS_WD_NAME_FORMAT "wd_thrd_%d.%d" 76 #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT "login_taskq_%d.%d" 77 #define ISCSI_CONN_RXTH_NAME_FORMAT "rx_thrd_%d.%d.%d" 78 #define ISCSI_CONN_TXTH_NAME_FORMAT "tx_thrd_%d.%d.%d" 79 80 /* 81 * The iSCSI driver will not build scatter/gather lists (iovec) longer 82 * than the value defined here. Asserts have been include in the code 83 * to check. 84 */ 85 #define ISCSI_MAX_IOVEC 5 86 87 #define ISCSI_DEFAULT_MAX_STORM_DELAY 32 88 89 /* 90 * The SNDBUF and RCVBUF size parameters for the sockets are just a 91 * guess for the time being (I think it is the values used by CISCO 92 * or UNH). Testing will have to be done to figure * out the impact 93 * of these values on performance. 94 */ 95 #define ISCSI_SOCKET_SNDBUF_SIZE (256 * 1024) 96 #define ISCSI_SOCKET_RCVBUF_SIZE (256 * 1024) 97 #define ISCSI_TCP_NODELAY_DEFAULT 0 98 #define ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT 2000 99 #define ISCSI_TCP_CABORT_THRESHOLD_DEFAULT 10000 100 #define ISCSI_TCP_ABORT_THRESHOLD_DEFAULT (30 * 1000) /* milliseconds */ 101 #define ISNS_TCP_ABORT_THRESHOLD_DEFAULT (3 * 1000) /* milliseconds */ 102 103 /* 104 * timeout value in seconds that we will poll and wait for data to be return 105 * from the device 106 */ 107 #define ISCSI_RX_TIMEOUT_VALUE 60 108 109 /* 110 * Convenient short hand defines 111 */ 112 #define TARGET_PROP "target" 113 #define LUN_PROP "lun" 114 #define MDI_GUID "wwn" 115 #define NDI_GUID "client-guid" 116 117 #define ISCSI_SIG_CMD 0x11111111 118 #define ISCSI_SIG_LUN 0x22222222 119 #define ISCSI_SIG_CONN 0x33333333 120 #define ISCSI_SIG_SESS 0x44444444 121 #define ISCSI_SIG_HBA 0x55555555 122 123 #define SENDTARGETS_DISCOVERY "SENDTARGETS_DISCOVERY" 124 125 #define ISCSI_LUN_MASK_MSB 0x00003f00 126 #define ISCSI_LUN_MASK_LSB 0x000000ff 127 #define ISCSI_LUN_BYTE_COPY(lun, report_lun_data) \ 128 lun[0] = (report_lun_data & ISCSI_LUN_MASK_MSB) >> 8; \ 129 lun[1] = (report_lun_data & ISCSI_LUN_MASK_LSB); 130 /* 131 * Not defined by iSCSI, but used in the login code to 132 * determine when to send the initial Login PDU 133 */ 134 #define ISCSI_INITIAL_LOGIN_STAGE -1 135 136 typedef enum iscsi_status { 137 /* Success */ 138 ISCSI_STATUS_SUCCESS = 0, 139 /* Driver / Kernel / Code error */ 140 ISCSI_STATUS_INTERNAL_ERROR, 141 /* ITT table is already full, unable to reserve slot */ 142 ISCSI_STATUS_ITT_TABLE_FULL, 143 /* Login on connection failed */ 144 ISCSI_STATUS_LOGIN_FAILED, 145 /* No connections are in the LOGGED_IN state */ 146 ISCSI_STATUS_NO_CONN_LOGGED_IN, 147 /* TCP Transfer Error */ 148 ISCSI_STATUS_TCP_TX_ERROR, 149 /* TCP Receive Error */ 150 ISCSI_STATUS_TCP_RX_ERROR, 151 /* iSCSI packet RCV timeout */ 152 ISCSI_STATUS_RX_TIMEOUT, 153 /* iSCSI Header Digest CRC error */ 154 ISCSI_STATUS_HEADER_DIGEST_ERROR, 155 /* iSCSI Data Digest CRC error */ 156 ISCSI_STATUS_DATA_DIGEST_ERROR, 157 /* kmem_alloc failure */ 158 ISCSI_STATUS_ALLOC_FAILURE, 159 /* cmd (tran_abort/reset) failed */ 160 ISCSI_STATUS_CMD_FAILED, 161 /* iSCSI protocol error */ 162 ISCSI_STATUS_PROTOCOL_ERROR, 163 /* iSCSI protocol version mismatch */ 164 ISCSI_STATUS_VERSION_MISMATCH, 165 /* iSCSI login negotiation failed */ 166 ISCSI_STATUS_NEGO_FAIL, 167 /* iSCSI login authentication failed */ 168 ISCSI_STATUS_AUTHENTICATION_FAILED, 169 /* iSCSI login redirection failed */ 170 ISCSI_STATUS_REDIRECTION_FAILED, 171 /* iSCSI uscsi status failure */ 172 ISCSI_STATUS_USCSI_FAILED, 173 /* data received would have overflowed given buffer */ 174 ISCSI_STATUS_DATA_OVERFLOW, 175 /* session/connection needs to shutdown */ 176 ISCSI_STATUS_SHUTDOWN, 177 /* logical unit in use */ 178 ISCSI_STATUS_BUSY 179 } iscsi_status_t; 180 #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS) 181 182 /* SNA32 check value used on increment of CmdSn values */ 183 #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */ 184 185 /* 186 * This is the maximum number of commands that can be outstanding 187 * on a iSCSI session at anyone point in time. 188 */ 189 #define ISCSI_CMD_TABLE_SIZE 1024 190 191 /* Used on connections thread create of receiver thread */ 192 extern pri_t minclsyspri; 193 194 /* 195 * Callers of iscsid_config_one/all must hold this 196 * semaphore across the calls. Otherwise a ndi_devi_enter() 197 * deadlock in the DDI layer may occur. 198 */ 199 extern ksema_t iscsid_config_semaphore; 200 201 extern kmutex_t iscsi_oid_mutex; 202 extern uint32_t iscsi_oid; 203 extern void *iscsi_state; 204 205 /* 206 * NOP delay is used to send a iSCSI NOP (ie. ping) across the 207 * wire to see if the target is still alive. NOPs are only 208 * sent when the RX thread hasn't received anything for the 209 * below amount of time. 210 */ 211 #define ISCSI_DEFAULT_NOP_DELAY 5 /* seconds */ 212 extern int iscsi_nop_delay; 213 /* 214 * If we haven't received anything in a specified period of time 215 * we will stop accepting IO via tran start. This will enable 216 * upper level drivers to see we might be having a problem and 217 * in the case of scsi_vhci will start to route IO down a better 218 * path. 219 */ 220 #define ISCSI_DEFAULT_RX_WINDOW 20 /* seconds */ 221 extern int iscsi_rx_window; 222 /* 223 * If we haven't received anything in a specified period of time 224 * we will stop accepting IO via tran start. This the max limit 225 * when encountered we will start returning a fatal error. 226 */ 227 #define ISCSI_DEFAULT_RX_MAX_WINDOW 180 /* seconds */ 228 extern int iscsi_rx_max_window; 229 230 /* 231 * During iscsi boot, if the boot session has been created, the 232 * initiator hasn't changed the boot lun to be online, we will wait 233 * 180s here for lun online by default. 234 */ 235 #define ISCSI_BOOT_DEFAULT_MAX_DELAY 180 /* seconds */ 236 /* 237 * +--------------------------------------------------------------------+ 238 * | iSCSI Driver Structures | 239 * +--------------------------------------------------------------------+ 240 */ 241 242 /* 243 * iSCSI Auth Information 244 */ 245 typedef struct iscsi_auth { 246 IscsiAuthStringBlock auth_recv_string_block; 247 IscsiAuthStringBlock auth_send_string_block; 248 IscsiAuthLargeBinary auth_recv_binary_block; 249 IscsiAuthLargeBinary auth_send_binary_block; 250 IscsiAuthClient auth_client_block; 251 int num_auth_buffers; 252 IscsiAuthBufferDesc auth_buffers[5]; 253 254 /* 255 * To indicate if bi-directional authentication is enabled. 256 * 0 means uni-directional authentication. 257 * 1 means bi-directional authentication. 258 */ 259 int bidirectional_auth; 260 261 /* Initiator's authentication information. */ 262 char username[iscsiAuthStringMaxLength]; 263 uint8_t password[iscsiAuthStringMaxLength]; 264 int password_length; 265 266 /* Target's authentication information. */ 267 char username_in[iscsiAuthStringMaxLength]; 268 uint8_t password_in[iscsiAuthStringMaxLength]; 269 int password_length_in; 270 } iscsi_auth_t; 271 272 /* 273 * iSCSI Task 274 */ 275 typedef struct iscsi_task { 276 void *t_arg; 277 boolean_t t_blocking; 278 } iscsi_task_t; 279 280 /* 281 * These are all the iscsi_cmd types that we use to track our 282 * commands between queues and actions. 283 */ 284 typedef enum iscsi_cmd_type { 285 ISCSI_CMD_TYPE_SCSI = 1, /* scsi cmd */ 286 ISCSI_CMD_TYPE_R2T, /* r2t */ 287 ISCSI_CMD_TYPE_NOP, /* nop / ping */ 288 ISCSI_CMD_TYPE_ABORT, /* abort */ 289 ISCSI_CMD_TYPE_RESET, /* reset */ 290 ISCSI_CMD_TYPE_LOGOUT, /* logout */ 291 ISCSI_CMD_TYPE_LOGIN, /* login */ 292 ISCSI_CMD_TYPE_TEXT /* text */ 293 } iscsi_cmd_type_t; 294 295 /* 296 * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram) 297 */ 298 typedef enum iscsi_cmd_state { 299 ISCSI_CMD_STATE_FREE, 300 ISCSI_CMD_STATE_PENDING, 301 ISCSI_CMD_STATE_ACTIVE, 302 ISCSI_CMD_STATE_ABORTING, 303 ISCSI_CMD_STATE_COMPLETED 304 } iscsi_cmd_state_t; 305 306 /* 307 * iscsi command events 308 */ 309 typedef enum iscsi_cmd_event { 310 ISCSI_CMD_EVENT_E1, 311 ISCSI_CMD_EVENT_E2, 312 ISCSI_CMD_EVENT_E3, 313 ISCSI_CMD_EVENT_E4, 314 ISCSI_CMD_EVENT_E6, 315 ISCSI_CMD_EVENT_E7, 316 ISCSI_CMD_EVENT_E8 317 } iscsi_cmd_event_t; 318 319 /* 320 * iscsi text command stages - these stages are used by iSCSI text 321 * processing to manage long resonses. 322 */ 323 typedef enum iscsi_cmd_text_stage { 324 ISCSI_CMD_TEXT_INITIAL_REQ, 325 ISCSI_CMD_TEXT_CONTINUATION, 326 ISCSI_CMD_TEXT_FINAL_RSP 327 } iscsi_cmd_text_stage_t; 328 329 /* 330 * iscsi cmd misc flags - bitwise applicable 331 */ 332 #define ISCSI_CMD_MISCFLAG_INTERNAL 0x1 333 #define ISCSI_CMD_MISCFLAG_FREE 0x2 334 #define ISCSI_CMD_MISCFLAG_STUCK 0x4 335 #define ISCSI_CMD_MISCFLAG_XARQ 0x8 336 337 /* 338 * iSCSI cmd/pkt Structure 339 */ 340 typedef struct iscsi_cmd { 341 uint32_t cmd_sig; 342 struct iscsi_cmd *cmd_prev; 343 struct iscsi_cmd *cmd_next; 344 struct iscsi_conn *cmd_conn; 345 346 iscsi_cmd_type_t cmd_type; 347 iscsi_cmd_state_t cmd_state; 348 iscsi_cmd_state_t cmd_prev_state; 349 clock_t cmd_lbolt_pending; 350 clock_t cmd_lbolt_active; 351 clock_t cmd_lbolt_aborting; 352 clock_t cmd_lbolt_timeout; 353 uint8_t cmd_misc_flags; 354 355 union { 356 /* ISCSI_CMD_TYPE_SCSI */ 357 struct { 358 struct scsi_pkt *pkt; 359 struct buf *bp; 360 int cmdlen; 361 int statuslen; 362 size_t data_transferred; 363 364 uint32_t lun; 365 366 /* 367 * If SCSI_CMD_TYPE is in ABORTING_STATE 368 * then the abort_icmdp field will be a pointer 369 * to the abort command chasing this one. 370 */ 371 struct iscsi_cmd *abort_icmdp; 372 /* 373 * pointer to the r2t associated with this 374 * command (if any) 375 */ 376 struct iscsi_cmd *r2t_icmdp; 377 /* 378 * It will be true if this command has 379 * another R2T to handle. 380 */ 381 boolean_t r2t_more; 382 } scsi; 383 /* ISCSI_CMD_TYPE_ABORT */ 384 struct { 385 /* pointer to original iscsi_cmd, for abort */ 386 struct iscsi_cmd *icmdp; 387 } abort; 388 /* ISCSI_CMD_TYPE_RESET */ 389 struct { 390 int level; 391 } reset; 392 /* ISCSI_CMD_TYPE_NOP */ 393 struct { 394 int rsvd; 395 } nop; 396 /* ISCSI_CMD_TYPE_R2T */ 397 struct { 398 struct iscsi_cmd *icmdp; 399 uint32_t offset; 400 uint32_t length; 401 } r2t; 402 /* ISCSI_CMD_TYPE_LOGIN */ 403 struct { 404 int rvsd; 405 } login; 406 /* ISCSI_CMD_TYPE_LOGOUT */ 407 struct { 408 int rsvd; 409 } logout; 410 /* ISCSI_CMD_TYPE_TEXT */ 411 struct { 412 char *buf; 413 int buf_len; 414 uint32_t offset; 415 uint32_t data_len; 416 uint32_t total_rx_len; 417 uint32_t ttt; 418 uint8_t lun[8]; 419 iscsi_cmd_text_stage_t stage; 420 } text; 421 } cmd_un; 422 423 struct iscsi_lun *cmd_lun; /* associated lun */ 424 425 uint32_t cmd_itt; 426 uint32_t cmd_ttt; 427 428 /* 429 * If a data digest error is seem on a data pdu. This flag 430 * will get set. We don't abort the cmd immediately because 431 * we want to read in all the data to get it out of the 432 * stream. Once the completion for the cmd is received we 433 * we will abort the cmd and state no sense data was available. 434 */ 435 boolean_t cmd_crc_error_seen; 436 437 /* 438 * Used to block and wake up caller until action is completed. 439 * This is for ABORT, RESET, and PASSTHRU cmds. 440 */ 441 int cmd_result; 442 int cmd_completed; 443 kmutex_t cmd_mutex; 444 kcondvar_t cmd_completion; 445 446 } iscsi_cmd_t; 447 448 449 /* 450 * iSCSI LUN Structure 451 */ 452 typedef struct iscsi_lun { 453 uint32_t lun_sig; 454 int lun_state; 455 456 struct iscsi_lun *lun_next; /* next lun on this sess. */ 457 struct iscsi_sess *lun_sess; /* parent sess. for lun */ 458 dev_info_t *lun_dip; 459 mdi_pathinfo_t *lun_pip; 460 461 uint16_t lun_num; /* LUN */ 462 uint8_t lun_addr_type; /* LUN addressing type */ 463 uint32_t lun_oid; /* OID */ 464 char *lun_guid; /* GUID */ 465 int lun_guid_size; /* GUID allocation size */ 466 char *lun_addr; /* sess,lun */ 467 time_t lun_time_online; 468 469 uchar_t lun_cap; /* bitmap of scsi caps */ 470 471 uchar_t lun_vid[ISCSI_INQ_VID_BUF_LEN]; /* Vendor ID */ 472 uchar_t lun_pid[ISCSI_INQ_PID_BUF_LEN]; /* Product ID */ 473 } iscsi_lun_t; 474 475 #define ISCSI_LUN_STATE_CLEAR 0 /* used to clear all states */ 476 #define ISCSI_LUN_STATE_OFFLINE 1 477 #define ISCSI_LUN_STATE_ONLINE 2 478 #define ISCSI_LUN_STATE_INVALID 4 /* offline failed */ 479 480 #define ISCSI_LUN_CAP_RESET 0x01 481 482 /* 483 * iscsi_conn_state - (reference iscsi_conn.c for state diagram) 484 */ 485 typedef enum iscsi_conn_state { 486 ISCSI_CONN_STATE_FREE, 487 ISCSI_CONN_STATE_IN_LOGIN, 488 ISCSI_CONN_STATE_LOGGED_IN, 489 ISCSI_CONN_STATE_IN_LOGOUT, 490 ISCSI_CONN_STATE_FAILED, 491 ISCSI_CONN_STATE_POLLING 492 } iscsi_conn_state_t; 493 494 #define ISCSI_CONN_STATE_FULL_FEATURE(state) \ 495 ((state == ISCSI_CONN_STATE_LOGGED_IN) || \ 496 (state == ISCSI_CONN_STATE_IN_LOGOUT)) 497 498 /* 499 * iscsi connection events - (reference iscsi_conn.c for state diagram) 500 */ 501 typedef enum iscsi_conn_event { 502 ISCSI_CONN_EVENT_T1, 503 ISCSI_CONN_EVENT_T5, 504 ISCSI_CONN_EVENT_T7, 505 ISCSI_CONN_EVENT_T8, 506 ISCSI_CONN_EVENT_T9, 507 ISCSI_CONN_EVENT_T11, 508 ISCSI_CONN_EVENT_T12, 509 ISCSI_CONN_EVENT_T13, 510 ISCSI_CONN_EVENT_T14, 511 ISCSI_CONN_EVENT_T15, 512 ISCSI_CONN_EVENT_T17, 513 ISCSI_CONN_EVENT_T30 514 } iscsi_conn_event_t; 515 516 /* 517 * 518 * 519 */ 520 typedef struct iscsi_queue { 521 iscsi_cmd_t *head; 522 iscsi_cmd_t *tail; 523 int count; 524 kmutex_t mutex; 525 } iscsi_queue_t; 526 527 #define ISCSI_CONN_DEFAULT_LOGIN_MIN 0 528 #define ISCSI_CONN_DEFAULT_LOGIN_MAX 180 529 #define ISCSI_CONN_DEFAULT_LOGIN_REDIRECT 10 530 531 typedef union iscsi_sockaddr { 532 struct sockaddr sin; 533 struct sockaddr_in sin4; 534 struct sockaddr_in6 sin6; 535 } iscsi_sockaddr_t; 536 537 #define SIZEOF_SOCKADDR(so) ((so)->sa_family == AF_INET ? \ 538 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)) 539 540 /* 541 * iSCSI Connection Structure 542 */ 543 typedef struct iscsi_conn { 544 uint32_t conn_sig; 545 struct iscsi_conn *conn_next; /* next conn on this sess. */ 546 struct iscsi_sess *conn_sess; /* parent sess. for conn. */ 547 548 iscsi_conn_state_t conn_state; /* cur. conn. driver state */ 549 iscsi_conn_state_t conn_prev_state; /* prev. conn. driver state */ 550 clock_t conn_state_lbolt; 551 /* protects the session state and synchronizes the state machine */ 552 kmutex_t conn_state_mutex; 553 kcondvar_t conn_state_change; 554 boolean_t conn_state_destroy; 555 556 void *conn_socket; /* kernel socket */ 557 558 /* base connection information */ 559 iscsi_sockaddr_t conn_base_addr; 560 561 /* current connection information, may have been redirected */ 562 iscsi_sockaddr_t conn_curr_addr; 563 564 /* current connection information, may have been redirected */ 565 boolean_t conn_bound; 566 iscsi_sockaddr_t conn_bound_addr; 567 568 uint32_t conn_cid; /* CID */ 569 uint32_t conn_oid; /* OID */ 570 571 int conn_current_stage; /* iSCSI login stage */ 572 int conn_next_stage; /* iSCSI login stage */ 573 int conn_partial_response; 574 575 /* 576 * The active queue contains iscsi_cmds that have already 577 * been sent on this connection. Any future responses to 578 * these cmds require alligence to this connection. If there 579 * are issues with these cmds the command may need aborted 580 * depending on the command type, and must be put back into 581 * the session's pending queue or aborted. 582 */ 583 iscsi_queue_t conn_queue_active; 584 585 /* lbolt from the last receive, used for nop processing */ 586 clock_t conn_rx_lbolt; 587 clock_t conn_nop_lbolt; 588 589 iscsi_thread_t *conn_rx_thread; 590 iscsi_thread_t *conn_tx_thread; 591 592 /* 593 * The expstatsn is the command status sn that is expected 594 * next from the target. Command status is carried on a number 595 * of iSCSI PDUs (ex. SCSI Cmd Response, SCSI Data IN with 596 * S-Bit set, ...), not all PDUs. If our expstatsn is different 597 * than the received statsn. Something got out of sync we need to 598 * recover. 599 */ 600 uint32_t conn_expstatsn; 601 uint32_t conn_laststatsn; 602 603 /* active login parameters */ 604 iscsi_login_params_t conn_params; 605 606 /* Statistics */ 607 struct { 608 kstat_t *ks; 609 iscsi_conn_stats_t ks_data; 610 } stats; 611 612 /* 613 * login min and max identify the amount of time 614 * in lbolt that iscsi_start_login() should attempt 615 * to log into a target portal. The login will 616 * delay until the min lbolt has been reached and 617 * will end once max time has been reached. These 618 * values are normally set to the default but can 619 * are also altered by async commands received from 620 * the targetlogin. 621 */ 622 clock_t conn_login_min; 623 clock_t conn_login_max; 624 } iscsi_conn_t; 625 626 627 /* 628 * iscsi_conn_state - (reference iscsi_sess.c for state diagram) 629 */ 630 typedef enum iscsi_sess_state { 631 ISCSI_SESS_STATE_FREE, 632 ISCSI_SESS_STATE_LOGGED_IN, 633 ISCSI_SESS_STATE_FAILED, 634 ISCSI_SESS_STATE_IN_FLUSH, 635 ISCSI_SESS_STATE_FLUSHED 636 } iscsi_sess_state_t; 637 638 #define ISCSI_SESS_STATE_FULL_FEATURE(state) \ 639 ((state == ISCSI_SESS_STATE_LOGGED_IN) || \ 640 (state == ISCSI_SESS_STATE_IN_FLUSH)) 641 642 643 typedef enum iscsi_sess_event { 644 ISCSI_SESS_EVENT_N1, 645 ISCSI_SESS_EVENT_N3, 646 ISCSI_SESS_EVENT_N5, 647 ISCSI_SESS_EVENT_N6, 648 ISCSI_SESS_EVENT_N7 649 } iscsi_sess_event_t; 650 651 typedef enum iscsi_sess_type { 652 ISCSI_SESS_TYPE_NORMAL, 653 ISCSI_SESS_TYPE_DISCOVERY 654 } iscsi_sess_type_t; 655 656 #define SESS_ABORT_TASK_MAX_THREADS 1 657 658 /* Sun's initiator session ID */ 659 #define ISCSI_SUN_ISID_0 0x40 /* ISID - EN format */ 660 #define ISCSI_SUN_ISID_1 0x00 /* Sec B */ 661 #define ISCSI_SUN_ISID_2 0x00 /* Sec B */ 662 #define ISCSI_SUN_ISID_3 0x2A /* Sec C - 42 = Sun's EN */ 663 /* 664 * defines 4-5 are the reserved values. These reserved values 665 * are used as the ISID for an initiator-port in MP-API and used 666 * for the send targets discovery sessions. Byte 5 is overridden 667 * for full feature sessions. The default values of byte 5 for a 668 * full feature session is 0. When MS/T is enabled with more than 669 * one session this byte 5 will increment > 0 up to 670 * ISCSI_MAX_CONFIG_SESSIONS. 671 */ 672 #define ISCSI_SUN_ISID_4 0x00 673 #define ISCSI_SUN_ISID_5 0xFF 674 675 #define ISCSI_DEFAULT_SESS_BOUND B_FALSE 676 #define ISCSI_DEFAULT_SESS_NUM 1 677 678 /* 679 * iSCSI Session(Target) Structure 680 */ 681 typedef struct iscsi_sess { 682 uint32_t sess_sig; 683 684 iscsi_sess_state_t sess_state; 685 iscsi_sess_state_t sess_prev_state; 686 clock_t sess_state_lbolt; 687 /* protects the session state and synchronizes the state machine */ 688 kmutex_t sess_state_mutex; 689 690 /* 691 * Associated target OID. 692 */ 693 uint32_t sess_target_oid; 694 695 /* 696 * Session OID. Used by IMA, interfaces and exported as 697 * TARGET_PROP which is checked by the NDI. In addition 698 * this is used in our tran_lun_init function. 699 */ 700 uint32_t sess_oid; 701 702 struct iscsi_sess *sess_next; 703 struct iscsi_hba *sess_hba; 704 705 /* list of all luns relating to session */ 706 struct iscsi_lun *sess_lun_list; 707 krwlock_t sess_lun_list_rwlock; 708 709 /* list of all connections relating to session */ 710 struct iscsi_conn *sess_conn_list; 711 struct iscsi_conn *sess_conn_list_last_ptr; 712 /* pointer to active connection in session */ 713 struct iscsi_conn *sess_conn_act; 714 krwlock_t sess_conn_list_rwlock; 715 716 /* Connection ID for next connection to be added to session */ 717 uint32_t sess_conn_next_cid; 718 719 /* 720 * last time any connection on this session received 721 * data from the target. 722 */ 723 clock_t sess_rx_lbolt; 724 725 clock_t sess_failure_lbolt; 726 727 int sess_storm_delay; 728 729 /* 730 * sess_cmdsn_mutex protects the cmdsn and itt table/values 731 * Cmdsn isn't that big of a problem yet since we only have 732 * one connection but in the future we will need to ensure 733 * this locking is working so keep the sequence numbers in 734 * sync on the wire. 735 * 736 * We also use this lock to protect the ITT table and it's 737 * values. We need to make sure someone doesn't assign 738 * a duplicate ITT value or cell to a command. Also we 739 * need to make sure when someone is looking up an ITT 740 * that the command is still in that correct queue location. 741 */ 742 kmutex_t sess_cmdsn_mutex; 743 744 /* 745 * iSCSI command sequencing / windowing. The next 746 * command to be sent via the pending queue will 747 * get the sess_cmdsn. If the maxcmdsn is less 748 * than the next cmdsn then the iSCSI window is 749 * closed and this command cannot be sent yet. 750 * Most iscsi cmd responses from the target carry 751 * a new maxcmdsn. If this new maxcmdsn is greater 752 * than the sess_maxcmdsn we will update it's value 753 * and set a timer to fire in one tick and reprocess 754 * the pending queue. 755 * 756 * The expcmdsn. Is the value the target expects 757 * to be sent for my next cmdsn. If the expcmdsn 758 * and the cmdsn get out of sync this could denote 759 * a communication problem. 760 */ 761 uint32_t sess_cmdsn; 762 uint32_t sess_expcmdsn; 763 uint32_t sess_maxcmdsn; 764 765 /* Next Initiator Task Tag (ITT) to use */ 766 uint32_t sess_itt; 767 /* 768 * The session iscsi_cmd table is used to a fast performance 769 * lookup of an ITT to a iscsi_cmd when we receive an iSCSI 770 * PDU from the wire. To reserve a location in the sess_cmd_table 771 * we try the sess_itt % ISCSI_CMD_TABLE_SIZE if this cmd table 772 * cell is already full. Then increament the sess_itt and 773 * try to get the cell position again, repeat until an empty 774 * cell is found. Once an empty cell is found place your 775 * scsi_cmd point into the cell to reserve the location. This 776 * selection process should be done while holding the session's 777 * mutex. 778 */ 779 struct iscsi_cmd *sess_cmd_table[ISCSI_CMD_TABLE_SIZE]; 780 int sess_cmd_table_count; 781 782 /* 783 * The pending queue contains all iscsi_cmds that require an 784 * open MaxCmdSn window to be put on the wire and haven't 785 * been placed on the wire. Once placed on the wire they 786 * will be moved to a connections specific active queue. 787 */ 788 iscsi_queue_t sess_queue_pending; 789 790 iscsi_error_t sess_last_err; 791 792 iscsi_queue_t sess_queue_completion; 793 /* configured login parameters */ 794 iscsi_login_params_t sess_params; 795 796 /* general iSCSI protocol/session info */ 797 uchar_t sess_name[ISCSI_MAX_NAME_LEN]; 798 int sess_name_length; 799 char sess_alias[ISCSI_MAX_NAME_LEN]; 800 int sess_alias_length; 801 iSCSIDiscoveryMethod_t sess_discovered_by; 802 iscsi_sockaddr_t sess_discovered_addr; 803 uchar_t sess_isid[ISCSI_ISID_LEN]; /* Session ID */ 804 uint16_t sess_tsid; /* Target ID */ 805 /* 806 * If the target portal group tag(TPGT) is equal to ISCSI_DEFAULT_TPGT 807 * then the initiator will accept a successful login with any TPGT 808 * specified by the target. If a none default TPGT is configured 809 * then we will only successfully accept a login with that matching 810 * TPGT value. 811 */ 812 int sess_tpgt_conf; 813 /* This field records the negotiated TPGT value, preserved for dtrace */ 814 int sess_tpgt_nego; 815 816 /* 817 * Authentication information. 818 * 819 * DCW: Again IMA seems to take a session view at this 820 * information. 821 */ 822 iscsi_auth_t sess_auth; 823 824 /* Statistics */ 825 struct { 826 kstat_t *ks; 827 iscsi_sess_stats_t ks_data; 828 kstat_t *ks_io; 829 kstat_io_t ks_io_data; 830 kmutex_t ks_io_lock; 831 } stats; 832 833 iscsi_thread_t *sess_ic_thread; 834 boolean_t sess_window_open; 835 boolean_t sess_boot; 836 iscsi_sess_type_t sess_type; 837 838 boolean_t sess_enum_in_progress; 839 840 ddi_taskq_t *sess_taskq; 841 842 iscsi_thread_t *sess_wd_thread; 843 844 } iscsi_sess_t; 845 846 /* 847 * This structure will be used to store sessions to be online 848 * during normal login operation. 849 */ 850 typedef struct iscsi_sess_list { 851 iscsi_sess_t *session; 852 struct iscsi_sess_list *next; 853 } iscsi_sess_list_t; 854 855 /* 856 * iscsi_network 857 */ 858 typedef struct iscsi_network { 859 void* (*socket)(int domain, int, int); 860 int (*bind)(void *, struct sockaddr *, int, int, int); 861 int (*connect)(void *, struct sockaddr *, int, int, int); 862 int (*listen)(void *, int); 863 void* (*accept)(void *, struct sockaddr *, int *); 864 int (*getsockname)(void *, struct sockaddr *, socklen_t *); 865 int (*getsockopt)(void *, int, int, void *, int *, int); 866 int (*setsockopt)(void *, int, int, void *, int); 867 int (*shutdown)(void *, int); 868 void (*close)(void *); 869 870 size_t (*poll)(void *, clock_t); 871 size_t (*sendmsg)(void *, struct msghdr *); 872 size_t (*recvmsg)(void *, struct msghdr *, int); 873 874 iscsi_status_t (*sendpdu)(void *, iscsi_hdr_t *, char *, int); 875 iscsi_status_t (*recvdata)(void *, iscsi_hdr_t *, char *, 876 int, int, int); 877 iscsi_status_t (*recvhdr)(void *, iscsi_hdr_t *, int, int, int); 878 879 struct { 880 int sndbuf; 881 int rcvbuf; 882 int nodelay; 883 int conn_notify_threshold; 884 int conn_abort_threshold; 885 int abort_threshold; 886 } tweaks; 887 } iscsi_network_t; 888 889 #define ISCSI_NET_HEADER_DIGEST 0x00000001 890 #define ISCSI_NET_DATA_DIGEST 0x00000002 891 892 extern iscsi_network_t *iscsi_net; 893 894 /* 895 * If we get bus_config requests in less than 5 seconds 896 * apart skip the name services re-discovery and just 897 * complete the requested logins. This protects against 898 * bus_config storms from stale /dev links. 899 */ 900 #define ISCSI_CONFIG_STORM_DELAY_DEFAULT 5 901 902 /* 903 * iSCSI HBA Structure 904 */ 905 typedef struct iscsi_hba { 906 uint32_t hba_sig; 907 dev_info_t *hba_dip; /* dev info ptr */ 908 scsi_hba_tran_t *hba_tran; /* scsi tran ptr */ 909 910 struct iscsi_sess *hba_sess_list; /* sess. list for hba */ 911 krwlock_t hba_sess_list_rwlock; /* protect sess. list */ 912 913 /* lbolt of the last time we received a config request */ 914 clock_t hba_config_lbolt; 915 /* current number of seconds to protect against bus config storms */ 916 int hba_config_storm_delay; 917 918 /* general iSCSI protocol hba/initiator info */ 919 uchar_t hba_name[ISCSI_MAX_NAME_LEN]; 920 int hba_name_length; 921 uchar_t hba_alias[ISCSI_MAX_NAME_LEN]; 922 int hba_alias_length; 923 924 /* Default SessionID for HBA */ 925 uchar_t hba_isid[ISCSI_ISID_LEN]; 926 927 /* Default HBA wide settings */ 928 iscsi_login_params_t hba_params; 929 930 /* 931 * There's only one HBA and it's set to ISCSI_INITIATOR_OID 932 * (value of 1) at the beginning of time. 933 */ 934 uint32_t hba_oid; 935 936 /* 937 * Keep track of which events have been sent. User daemons request 938 * this information so they don't wait for events which they won't 939 * see. 940 */ 941 kmutex_t hba_discovery_events_mutex; 942 iSCSIDiscoveryMethod_t hba_discovery_events; 943 boolean_t hba_discovery_in_progress; 944 945 boolean_t hba_mpxio_enabled; /* mpxio-enabled */ 946 boolean_t persistent_loaded; /* persistent_loaded */ 947 948 /* 949 * Ensures only one SendTargets operation occurs at a time 950 */ 951 ksema_t hba_sendtgts_semaphore; 952 953 /* 954 * Statistics 955 */ 956 struct { 957 kstat_t *ks; 958 iscsi_hba_stats_t ks_data; 959 } stats; 960 } iscsi_hba_t; 961 962 /* 963 * +--------------------------------------------------------------------+ 964 * | iSCSI prototypes | 965 * +--------------------------------------------------------------------+ 966 */ 967 968 /* iscsi_io.c */ 969 int iscsi_sna_lte(uint32_t n1, uint32_t n2); 970 char *iscsi_get_next_text(char *data, int data_length, char *curr_text); 971 972 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg); 973 void iscsi_tx_thread(iscsi_thread_t *thread, void *arg); 974 void iscsi_rx_thread(iscsi_thread_t *thread, void *arg); 975 void iscsi_wd_thread(iscsi_thread_t *thread, void *arg); 976 977 iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 978 979 void iscsi_handle_abort(void *arg); 980 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level, 981 iscsi_lun_t *ilp); 982 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp); 983 iscsi_status_t iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun, 984 struct uscsi_cmd *ucmdp); 985 iscsi_status_t iscsi_handle_text(iscsi_conn_t *icp, 986 char *buf, uint32_t buf_len, uint32_t data_len, uint32_t *rx_data_len); 987 988 void iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 989 990 /* iscsi_crc.c */ 991 uint32_t iscsi_crc32c(void *address, unsigned long length); 992 uint32_t iscsi_crc32c_continued(void *address, unsigned long length, 993 uint32_t crc); 994 995 /* iscsi_queue.c */ 996 void iscsi_init_queue(iscsi_queue_t *queue); 997 void iscsi_destroy_queue(iscsi_queue_t *queue); 998 void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 999 void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1000 void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 1001 void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 1002 void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1003 iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *); 1004 void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue); 1005 void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **, 1006 iscsi_cmd_t *); 1007 1008 /* iscsi_login.c */ 1009 iscsi_status_t iscsi_login_start(void *arg); 1010 1011 /* iscsi_stats.c */ 1012 boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp); 1013 boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp); 1014 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp); 1015 boolean_t iscsi_sess_kstat_term(struct iscsi_sess *isp); 1016 boolean_t iscsi_conn_kstat_init(struct iscsi_conn *icp); 1017 void iscsi_conn_kstat_term(struct iscsi_conn *icp); 1018 1019 /* iscsi_net.c */ 1020 void iscsi_net_init(); 1021 void iscsi_net_fini(); 1022 1023 /* iscsi_sess.c */ 1024 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp, 1025 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc, 1026 char *target_name, int tpgt, uchar_t isid_lsb, 1027 iscsi_sess_type_t type, uint32_t *oid); 1028 void iscsi_sess_online(void *arg); 1029 int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp); 1030 iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp); 1031 void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event); 1032 char *iscsi_sess_state_str(iscsi_sess_state_t state); 1033 boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp); 1034 iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1035 void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1036 void iscsi_sess_redrive_io(iscsi_sess_t *isp); 1037 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp, 1038 iscsi_sess_t **ispp); 1039 1040 1041 /* iscsi_conn.c */ 1042 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp, 1043 iscsi_conn_t **icpp); 1044 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp); 1045 iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp); 1046 iscsi_status_t iscsi_conn_state_machine(iscsi_conn_t *icp, 1047 iscsi_conn_event_t event); 1048 char *iscsi_conn_state_str(iscsi_conn_state_t state); 1049 void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max); 1050 iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp); 1051 1052 /* iscsi_lun.c */ 1053 iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num, 1054 uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid); 1055 iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, 1056 iscsi_lun_t *ilp); 1057 void iscsi_lun_online(iscsi_hba_t *ihp, 1058 iscsi_lun_t *ilp); 1059 iscsi_status_t iscsi_lun_offline(iscsi_hba_t *ihp, 1060 iscsi_lun_t *ilp, boolean_t lun_free); 1061 1062 /* iscsi_cmd.c */ 1063 void iscsi_cmd_state_machine(iscsi_cmd_t *icmdp, 1064 iscsi_cmd_event_t event, void *arg); 1065 iscsi_cmd_t *iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags); 1066 void iscsi_cmd_free(iscsi_cmd_t *icmdp); 1067 1068 /* iscsi_ioctl.c */ 1069 int iscsi_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 1070 void * iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size); 1071 int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode); 1072 iscsi_conn_list_t *iscsi_ioctl_conn_oid_list_get_copyin(caddr_t, int); 1073 int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *, caddr_t, int); 1074 boolean_t iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp, 1075 iscsi_conn_list_t *cl); 1076 boolean_t iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp); 1077 int iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl); 1078 int iscsi_target_prop_mod(iscsi_hba_t *, iscsi_property_t *, int cmd); 1079 int iscsi_set_params(iscsi_param_set_t *, iscsi_hba_t *, boolean_t); 1080 int iscsi_get_persisted_param(uchar_t *, iscsi_param_get_t *, 1081 iscsi_login_params_t *); 1082 void iscsi_set_default_login_params(iscsi_login_params_t *params); 1083 int iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp, 1084 iscsi_config_sess_t *ics); 1085 int iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp, 1086 iscsi_config_sess_t *ics); 1087 /* ioctls prototypes */ 1088 int iscsi_get_param(iscsi_login_params_t *params, 1089 boolean_t valid_flag, 1090 iscsi_param_get_t *ipgp); 1091 1092 /* iscsid.c */ 1093 boolean_t iscsid_init(iscsi_hba_t *ihp, boolean_t restart); 1094 void iscsid_fini(); 1095 void iscsid_props(iSCSIDiscoveryProperties_t *props); 1096 boolean_t iscsid_enable_discovery(iscsi_hba_t *ihp, 1097 iSCSIDiscoveryMethod_t idm, boolean_t poke); 1098 boolean_t iscsid_disable_discovery(iscsi_hba_t *ihp, 1099 iSCSIDiscoveryMethod_t idm); 1100 void iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method); 1101 void iscsid_do_sendtgts(entry_t *discovery_addr); 1102 void iscsid_do_isns_query_one_server( 1103 iscsi_hba_t *ihp, entry_t *isns_addr); 1104 void iscsid_do_isns_query(iscsi_hba_t *ihp); 1105 void iscsid_config_one(iscsi_hba_t *ihp, 1106 char *name, boolean_t protect); 1107 void iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect); 1108 void iscsid_unconfig_one(iscsi_hba_t *ihp, char *name); 1109 void iscsid_unconfig_all(iscsi_hba_t *ihp); 1110 void isns_scn_callback(void *arg); 1111 boolean_t iscsid_del(iscsi_hba_t *ihp, char *target_name, 1112 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc); 1113 boolean_t iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name, 1114 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc); 1115 void iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port, 1116 struct sockaddr *dst_addr); 1117 boolean_t iscsi_reconfig_boot_sess(iscsi_hba_t *ihp); 1118 boolean_t iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp); 1119 boolean_t iscsi_cmp_boot_ini_name(char *name); 1120 boolean_t iscsi_cmp_boot_tgt_name(char *name); 1121 1122 extern void bcopy(const void *s1, void *s2, size_t n); 1123 extern void bzero(void *s, size_t n); 1124 /* 1125 * Here we need a contract for inet_ntop() and inet_pton() 1126 * in uts/common/inet/ip/inet_ntop.c 1127 */ 1128 extern char *inet_ntop(int af, const void *addr, char *buf, int addrlen); 1129 extern int inet_pton(int af, char *inp, void *outp); 1130 1131 #ifdef __cplusplus 1132 } 1133 #endif 1134 1135 #endif /* _ISCSI_H */ 1136