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 /* 23 * Copyright 2000 by Cisco Systems, Inc. All rights reserved. 24 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 25 * Copyright 2014-2015 Nexenta Systems, Inc. All rights reserved. 26 */ 27 28 #ifndef _ISCSI_H 29 #define _ISCSI_H 30 31 /* 32 * Block comment which describes the contents of this file. 33 */ 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 #include <sys/scsi/scsi.h> 40 #include <sys/ddi.h> 41 #include <sys/sunddi.h> 42 #include <sys/socket.h> 43 #include <sys/kstat.h> 44 #include <sys/sunddi.h> 45 #include <sys/sunmdi.h> 46 #include <sys/mdi_impldefs.h> 47 #include <sys/time.h> 48 #include <sys/nvpair.h> 49 #include <sys/sdt.h> 50 51 #include <sys/iscsi_protocol.h> 52 #include <sys/scsi/adapters/iscsi_if.h> 53 #include <iscsiAuthClient.h> 54 #include <iscsi_stats.h> 55 #include <iscsi_thread.h> 56 #include <sys/idm/idm.h> 57 #include <sys/idm/idm_conn_sm.h> 58 #include <nvfile.h> 59 #include <inet/ip.h> 60 61 #ifndef MIN 62 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 63 #endif 64 65 #ifndef TRUE 66 #define TRUE 1 67 #endif 68 69 #ifndef FALSE 70 #define FALSE 0 71 #endif 72 73 #define LOGIN_PDU_BUFFER_SIZE (16 * 1024) /* move somewhere else */ 74 75 extern boolean_t iscsi_conn_logging; 76 extern boolean_t iscsi_io_logging; 77 extern boolean_t iscsi_login_logging; 78 extern boolean_t iscsi_logging; 79 extern boolean_t iscsi_sess_logging; 80 #define ISCSI_CONN_LOG if (iscsi_conn_logging) cmn_err 81 #define ISCSI_IO_LOG if (iscsi_io_logging) cmn_err 82 #define ISCSI_LOGIN_LOG if (iscsi_login_logging) cmn_err 83 #define ISCSI_LOG if (iscsi_logging) cmn_err 84 #define ISCSI_SESS_LOG if (iscsi_sess_logging) cmn_err 85 86 /* 87 * Name Format of the different Task Queues 88 */ 89 #define ISCSI_SESS_IOTH_NAME_FORMAT "io_thrd_%d.%d" 90 #define ISCSI_SESS_WD_NAME_FORMAT "wd_thrd_%d.%d" 91 #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT "login_taskq_%d.%d" 92 #define ISCSI_SESS_ENUM_TASKQ_NAME_FORMAT "enum_taskq_%d.%d" 93 #define ISCSI_CONN_CN_TASKQ_NAME_FORMAT "conn_cn_taskq_%d.%d.%d" 94 #define ISCSI_CONN_RXTH_NAME_FORMAT "rx_thrd_%d.%d.%d" 95 #define ISCSI_CONN_TXTH_NAME_FORMAT "tx_thrd_%d.%d.%d" 96 97 /* 98 * The iSCSI driver will not build scatter/gather lists (iovec) longer 99 * than the value defined here. Asserts have been include in the code 100 * to check. 101 */ 102 #define ISCSI_MAX_IOVEC 5 103 104 #define ISCSI_DEFAULT_MAX_STORM_DELAY 32 105 106 /* 107 * The SNDBUF and RCVBUF size parameters for the sockets are just a 108 * guess for the time being (I think it is the values used by CISCO 109 * or UNH). Testing will have to be done to figure * out the impact 110 * of these values on performance. 111 */ 112 #define ISCSI_SOCKET_SNDBUF_SIZE (256 * 1024) 113 #define ISCSI_SOCKET_RCVBUF_SIZE (256 * 1024) 114 #define ISCSI_TCP_NODELAY_DEFAULT 0 115 #define ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT 2000 116 #define ISCSI_TCP_CABORT_THRESHOLD_DEFAULT 10000 117 #define ISCSI_TCP_ABORT_THRESHOLD_DEFAULT (30 * 1000) /* milliseconds */ 118 #define ISNS_TCP_ABORT_THRESHOLD_DEFAULT (3 * 1000) /* milliseconds */ 119 120 /* Default values for tunable parameters */ 121 #define ISCSI_DEFAULT_RX_TIMEOUT_VALUE 60 122 #define ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX 180 123 #define ISCSI_DEFAULT_LOGIN_POLLING_DELAY 60 124 125 /* 126 * Convenient short hand defines 127 */ 128 #define TARGET_PROP "target" 129 #define LUN_PROP "lun" 130 #define MDI_GUID "wwn" 131 #define NDI_GUID "client-guid" 132 133 #define ISCSI_SIG_CMD 0x11111111 134 #define ISCSI_SIG_LUN 0x22222222 135 #define ISCSI_SIG_CONN 0x33333333 136 #define ISCSI_SIG_SESS 0x44444444 137 #define ISCSI_SIG_HBA 0x55555555 138 139 #define SENDTARGETS_DISCOVERY "SENDTARGETS_DISCOVERY" 140 141 #define ISCSI_LUN_MASK_MSB 0x00003f00 142 #define ISCSI_LUN_MASK_LSB 0x000000ff 143 #define ISCSI_LUN_MASK (ISCSI_LUN_MASK_MSB | ISCSI_LUN_MASK_LSB) 144 #define ISCSI_LUN_BYTE_COPY(lun, report_lun_data) \ 145 lun[0] = (report_lun_data & ISCSI_LUN_MASK_MSB) >> 8; \ 146 lun[1] = (report_lun_data & ISCSI_LUN_MASK_LSB); 147 /* 148 * Not defined by iSCSI, but used in the login code to 149 * determine when to send the initial Login PDU 150 */ 151 #define ISCSI_INITIAL_LOGIN_STAGE -1 152 153 typedef enum iscsi_status { 154 /* Success */ 155 ISCSI_STATUS_SUCCESS = 0, 156 /* Driver / Kernel / Code error */ 157 ISCSI_STATUS_INTERNAL_ERROR, 158 /* ITT table is already full, unable to reserve slot */ 159 ISCSI_STATUS_ITT_TABLE_FULL, 160 /* Login on connection failed */ 161 ISCSI_STATUS_LOGIN_FAILED, 162 /* No connections are in the LOGGED_IN state */ 163 ISCSI_STATUS_NO_CONN_LOGGED_IN, 164 /* TCP Transfer Error */ 165 ISCSI_STATUS_TCP_TX_ERROR, 166 /* TCP Receive Error */ 167 ISCSI_STATUS_TCP_RX_ERROR, 168 /* iSCSI packet RCV timeout */ 169 ISCSI_STATUS_RX_TIMEOUT, 170 /* iSCSI Header Digest CRC error */ 171 ISCSI_STATUS_HEADER_DIGEST_ERROR, 172 /* iSCSI Data Digest CRC error */ 173 ISCSI_STATUS_DATA_DIGEST_ERROR, 174 /* kmem_alloc failure */ 175 ISCSI_STATUS_ALLOC_FAILURE, 176 /* cmd (tran_abort/reset) failed */ 177 ISCSI_STATUS_CMD_FAILED, 178 /* iSCSI protocol error */ 179 ISCSI_STATUS_PROTOCOL_ERROR, 180 /* iSCSI protocol version mismatch */ 181 ISCSI_STATUS_VERSION_MISMATCH, 182 /* iSCSI login negotiation failed */ 183 ISCSI_STATUS_NEGO_FAIL, 184 /* iSCSI login authentication failed */ 185 ISCSI_STATUS_AUTHENTICATION_FAILED, 186 /* iSCSI login redirection failed */ 187 ISCSI_STATUS_REDIRECTION_FAILED, 188 /* iSCSI uscsi status failure */ 189 ISCSI_STATUS_USCSI_FAILED, 190 /* data received would have overflowed given buffer */ 191 ISCSI_STATUS_DATA_OVERFLOW, 192 /* session/connection needs to shutdown */ 193 ISCSI_STATUS_SHUTDOWN, 194 /* logical unit in use */ 195 ISCSI_STATUS_BUSY, 196 /* Login on connection failed, retries exceeded */ 197 ISCSI_STATUS_LOGIN_TIMED_OUT, 198 /* iSCSI login tpgt negotiation failed */ 199 ISCSI_STATUS_LOGIN_TPGT_NEGO_FAIL 200 } iscsi_status_t; 201 #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS) 202 203 /* SNA32 check value used on increment of CmdSn values */ 204 #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */ 205 206 /* 207 * This is the maximum number of commands that can be outstanding 208 * on a iSCSI session at anyone point in time. 209 */ 210 #define ISCSI_CMD_TABLE_SIZE 1024 211 212 /* Used on connections thread create of receiver thread */ 213 extern pri_t minclsyspri; 214 215 /* 216 * Callers of iscsid_config_one/all must hold this 217 * semaphore across the calls. Otherwise a ndi_devi_enter() 218 * deadlock in the DDI layer may occur. 219 */ 220 extern ksema_t iscsid_config_semaphore; 221 222 extern kmutex_t iscsi_oid_mutex; 223 extern uint32_t iscsi_oid; 224 extern void *iscsi_state; 225 226 /* 227 * NOP delay is used to send a iSCSI NOP (ie. ping) across the 228 * wire to see if the target is still alive. NOPs are only 229 * sent when the RX thread hasn't received anything for the 230 * below amount of time. 231 */ 232 #define ISCSI_DEFAULT_NOP_DELAY 5 /* seconds */ 233 extern int iscsi_nop_delay; 234 /* 235 * If we haven't received anything in a specified period of time 236 * we will stop accepting IO via tran start. This will enable 237 * upper level drivers to see we might be having a problem and 238 * in the case of scsi_vhci will start to route IO down a better 239 * path. 240 */ 241 #define ISCSI_DEFAULT_RX_WINDOW 20 /* seconds */ 242 extern int iscsi_rx_window; 243 /* 244 * If we haven't received anything in a specified period of time 245 * we will stop accepting IO via tran start. This the max limit 246 * when encountered we will start returning a fatal error. 247 */ 248 #define ISCSI_DEFAULT_RX_MAX_WINDOW 180 /* seconds */ 249 extern int iscsi_rx_max_window; 250 251 /* 252 * During iscsi boot, if the boot session has been created, the 253 * initiator hasn't changed the boot lun to be online, we will wait 254 * 180s here for lun online by default. 255 */ 256 #define ISCSI_BOOT_DEFAULT_MAX_DELAY 180 /* seconds */ 257 /* 258 * +--------------------------------------------------------------------+ 259 * | iSCSI Driver Structures | 260 * +--------------------------------------------------------------------+ 261 */ 262 263 /* 264 * iSCSI Auth Information 265 */ 266 typedef struct iscsi_auth { 267 IscsiAuthStringBlock auth_recv_string_block; 268 IscsiAuthStringBlock auth_send_string_block; 269 IscsiAuthLargeBinary auth_recv_binary_block; 270 IscsiAuthLargeBinary auth_send_binary_block; 271 IscsiAuthClient auth_client_block; 272 int num_auth_buffers; 273 IscsiAuthBufferDesc auth_buffers[5]; 274 275 /* 276 * To indicate if bi-directional authentication is enabled. 277 * 0 means uni-directional authentication. 278 * 1 means bi-directional authentication. 279 */ 280 int bidirectional_auth; 281 282 /* Initiator's authentication information. */ 283 char username[iscsiAuthStringMaxLength]; 284 uint8_t password[iscsiAuthStringMaxLength]; 285 int password_length; 286 287 /* Target's authentication information. */ 288 char username_in[iscsiAuthStringMaxLength]; 289 uint8_t password_in[iscsiAuthStringMaxLength]; 290 int password_length_in; 291 } iscsi_auth_t; 292 293 /* 294 * iSCSI Task 295 */ 296 typedef struct iscsi_task { 297 void *t_arg; 298 boolean_t t_blocking; 299 uint32_t t_event_count; 300 } iscsi_task_t; 301 302 /* 303 * These are all the iscsi_cmd types that we use to track our 304 * commands between queues and actions. 305 */ 306 typedef enum iscsi_cmd_type { 307 ISCSI_CMD_TYPE_SCSI = 1, /* scsi cmd */ 308 ISCSI_CMD_TYPE_NOP, /* nop / ping */ 309 ISCSI_CMD_TYPE_ABORT, /* abort */ 310 ISCSI_CMD_TYPE_RESET, /* reset */ 311 ISCSI_CMD_TYPE_LOGOUT, /* logout */ 312 ISCSI_CMD_TYPE_LOGIN, /* login */ 313 ISCSI_CMD_TYPE_TEXT /* text */ 314 } iscsi_cmd_type_t; 315 316 /* 317 * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram) 318 */ 319 typedef enum iscsi_cmd_state { 320 ISCSI_CMD_STATE_FREE = 0, 321 ISCSI_CMD_STATE_PENDING, 322 ISCSI_CMD_STATE_ACTIVE, 323 ISCSI_CMD_STATE_ABORTING, 324 ISCSI_CMD_STATE_IDM_ABORTING, 325 ISCSI_CMD_STATE_COMPLETED, 326 ISCSI_CMD_STATE_MAX 327 } iscsi_cmd_state_t; 328 329 #ifdef ISCSI_CMD_SM_STRINGS 330 static const char *iscsi_cmd_state_names[ISCSI_CMD_STATE_MAX+1] = { 331 "ISCSI_CMD_STATE_FREE", 332 "ISCSI_CMD_STATE_PENDING", 333 "ISCSI_CMD_STATE_ACTIVE", 334 "ISCSI_CMD_STATE_ABORTING", 335 "ISCSI_CMD_STATE_IDM_ABORTING", 336 "ISCSI_CMD_STATE_COMPLETED", 337 "ISCSI_CMD_STATE_MAX" 338 }; 339 #endif 340 341 /* 342 * iscsi command events 343 */ 344 typedef enum iscsi_cmd_event { 345 ISCSI_CMD_EVENT_E1 = 0, 346 ISCSI_CMD_EVENT_E2, 347 ISCSI_CMD_EVENT_E3, 348 ISCSI_CMD_EVENT_E4, 349 ISCSI_CMD_EVENT_E6, 350 ISCSI_CMD_EVENT_E7, 351 ISCSI_CMD_EVENT_E8, 352 ISCSI_CMD_EVENT_E9, 353 ISCSI_CMD_EVENT_E10, 354 ISCSI_CMD_EVENT_MAX 355 } iscsi_cmd_event_t; 356 357 #ifdef ISCSI_CMD_SM_STRINGS 358 static const char *iscsi_cmd_event_names[ISCSI_CMD_EVENT_MAX+1] = { 359 "ISCSI_CMD_EVENT_E1", 360 "ISCSI_CMD_EVENT_E2", 361 "ISCSI_CMD_EVENT_E3", 362 "ISCSI_CMD_EVENT_E4", 363 "ISCSI_CMD_EVENT_E6", 364 "ISCSI_CMD_EVENT_E7", 365 "ISCSI_CMD_EVENT_E8", 366 "ISCSI_CMD_EVENT_E9", 367 "ISCSI_CMD_EVENT_E10", 368 "ISCSI_CMD_EVENT_MAX" 369 }; 370 #endif 371 372 /* 373 * iscsi text command stages - these stages are used by iSCSI text 374 * processing to manage long resonses. 375 */ 376 typedef enum iscsi_cmd_text_stage { 377 ISCSI_CMD_TEXT_INITIAL_REQ = 0, 378 ISCSI_CMD_TEXT_CONTINUATION, 379 ISCSI_CMD_TEXT_FINAL_RSP 380 } iscsi_cmd_text_stage_t; 381 382 /* 383 * iscsi cmd misc flags - bitwise applicable 384 */ 385 #define ISCSI_CMD_MISCFLAG_INTERNAL 0x1 386 #define ISCSI_CMD_MISCFLAG_FREE 0x2 387 #define ISCSI_CMD_MISCFLAG_STUCK 0x4 388 #define ISCSI_CMD_MISCFLAG_XARQ 0x8 389 #define ISCSI_CMD_MISCFLAG_SENT 0x10 390 #define ISCSI_CMD_MISCFLAG_FLUSH 0x20 391 392 /* 393 * 1/2 of a 32 bit number, used for checking CmdSN 394 * wrapped. 395 */ 396 #define ISCSI_CMD_SN_WRAP 0x80000000 397 398 #define ISCSI_CMD_PKT_STAT_INIT 0 399 400 /* 401 * iSCSI cmd/pkt Structure 402 */ 403 typedef struct iscsi_cmd { 404 uint32_t cmd_sig; 405 struct iscsi_cmd *cmd_prev; 406 struct iscsi_cmd *cmd_next; 407 struct iscsi_conn *cmd_conn; 408 409 iscsi_cmd_type_t cmd_type; 410 iscsi_cmd_state_t cmd_state; 411 iscsi_cmd_state_t cmd_prev_state; 412 clock_t cmd_lbolt_pending; 413 clock_t cmd_lbolt_active; 414 clock_t cmd_lbolt_aborting; 415 clock_t cmd_lbolt_idm_aborting; 416 clock_t cmd_lbolt_timeout; 417 uint8_t cmd_misc_flags; 418 idm_task_t *cmd_itp; 419 420 union { 421 /* ISCSI_CMD_TYPE_SCSI */ 422 struct { 423 idm_buf_t *ibp_ibuf; 424 idm_buf_t *ibp_obuf; 425 struct scsi_pkt *pkt; 426 struct buf *bp; 427 int cmdlen; 428 int statuslen; 429 size_t data_transferred; 430 431 uint32_t lun; 432 433 /* 434 * If SCSI_CMD_TYPE is in ABORTING_STATE 435 * then the abort_icmdp field will be a pointer 436 * to the abort command chasing this one. 437 */ 438 struct iscsi_cmd *abort_icmdp; 439 /* 440 * pointer to the r2t associated with this 441 * command (if any) 442 */ 443 struct iscsi_cmd *r2t_icmdp; 444 /* 445 * It will be true if this command has 446 * another R2T to handle. 447 */ 448 boolean_t r2t_more; 449 /* 450 * It is used to record pkt_statistics temporarily. 451 */ 452 uint_t pkt_stat; 453 } scsi; 454 /* ISCSI_CMD_TYPE_ABORT */ 455 struct { 456 /* pointer to original iscsi_cmd, for abort */ 457 struct iscsi_cmd *icmdp; 458 } abort; 459 /* ISCSI_CMD_TYPE_RESET */ 460 struct { 461 int level; 462 uint8_t response; 463 } reset; 464 /* ISCSI_CMD_TYPE_NOP */ 465 struct { 466 int rsvd; 467 } nop; 468 /* ISCSI_CMD_TYPE_R2T */ 469 struct { 470 struct iscsi_cmd *icmdp; 471 uint32_t offset; 472 uint32_t length; 473 } r2t; 474 /* ISCSI_CMD_TYPE_LOGIN */ 475 struct { 476 int rvsd; 477 } login; 478 /* ISCSI_CMD_TYPE_LOGOUT */ 479 struct { 480 int rsvd; 481 } logout; 482 /* ISCSI_CMD_TYPE_TEXT */ 483 struct { 484 char *buf; 485 int buf_len; 486 uint32_t offset; 487 uint32_t data_len; 488 uint32_t total_rx_len; 489 uint32_t ttt; 490 uint8_t lun[8]; 491 iscsi_cmd_text_stage_t stage; 492 } text; 493 } cmd_un; 494 495 struct iscsi_lun *cmd_lun; /* associated lun */ 496 497 uint32_t cmd_itt; 498 uint32_t cmd_ttt; 499 500 /* 501 * If a data digest error is seem on a data pdu. This flag 502 * will get set. We don't abort the cmd immediately because 503 * we want to read in all the data to get it out of the 504 * stream. Once the completion for the cmd is received we 505 * we will abort the cmd and state no sense data was available. 506 */ 507 boolean_t cmd_crc_error_seen; 508 509 /* 510 * Used to block and wake up caller until action is completed. 511 * This is for ABORT, RESET, and PASSTHRU cmds. 512 */ 513 int cmd_result; 514 int cmd_completed; 515 kmutex_t cmd_mutex; 516 kcondvar_t cmd_completion; 517 518 idm_pdu_t cmd_pdu; 519 520 sm_audit_buf_t cmd_state_audit; 521 522 uint32_t cmd_sn; 523 } iscsi_cmd_t; 524 525 526 /* 527 * iSCSI LUN Structure 528 */ 529 typedef struct iscsi_lun { 530 uint32_t lun_sig; 531 int lun_state; 532 533 struct iscsi_lun *lun_next; /* next lun on this sess. */ 534 struct iscsi_sess *lun_sess; /* parent sess. for lun */ 535 dev_info_t *lun_dip; 536 mdi_pathinfo_t *lun_pip; 537 538 uint16_t lun_num; /* LUN */ 539 uint8_t lun_addr_type; /* LUN addressing type */ 540 uint32_t lun_oid; /* OID */ 541 char *lun_guid; /* GUID */ 542 int lun_guid_size; /* GUID allocation size */ 543 char *lun_addr; /* sess,lun */ 544 time_t lun_time_online; 545 546 uchar_t lun_cap; /* bitmap of scsi caps */ 547 548 uchar_t lun_vid[ISCSI_INQ_VID_BUF_LEN]; /* Vendor ID */ 549 uchar_t lun_pid[ISCSI_INQ_PID_BUF_LEN]; /* Product ID */ 550 551 uchar_t lun_type; 552 kmutex_t lun_mutex; 553 int lun_refcnt; 554 } iscsi_lun_t; 555 556 #define ISCSI_LUN_STATE_CLEAR 0 /* used to clear all states */ 557 #define ISCSI_LUN_STATE_OFFLINE 1 558 #define ISCSI_LUN_STATE_ONLINE 2 559 #define ISCSI_LUN_STATE_INVALID 4 /* offline failed */ 560 #define ISCSI_LUN_STATE_BUSY 8 /* logic unit is in reset */ 561 562 #define ISCSI_LUN_CAP_RESET 0x01 563 564 #define ISCSI_SCSI_RESET_SENSE_CODE 0x29 565 #define ISCSI_SCSI_LUNCHANGED_CODE 0x3f 566 567 #define ISCSI_SCSI_LUNCHANGED_ASCQ 0x0e 568 569 /* 570 * 571 * 572 */ 573 typedef struct iscsi_queue { 574 iscsi_cmd_t *head; 575 iscsi_cmd_t *tail; 576 int count; 577 kmutex_t mutex; 578 } iscsi_queue_t; 579 580 #define ISCSI_CONN_DEFAULT_LOGIN_MIN 0 581 #define ISCSI_CONN_DEFAULT_LOGIN_REDIRECT 10 582 583 /* iSCSI tunable Parameters */ 584 typedef struct iscsi_tunable_params { 585 int recv_login_rsp_timeout; /* range: 0 - 60*60 */ 586 int conn_login_max; /* range: 0 - 60*60 */ 587 int polling_login_delay; /* range: 0 - 60*60 */ 588 } iscsi_tunable_params_t; 589 590 typedef union iscsi_sockaddr { 591 struct sockaddr sin; 592 struct sockaddr_in sin4; 593 struct sockaddr_in6 sin6; 594 } iscsi_sockaddr_t; 595 596 #define SIZEOF_SOCKADDR(so) ((so)->sa_family == AF_INET ? \ 597 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)) 598 599 typedef enum { 600 LOGIN_START, 601 LOGIN_READY, 602 LOGIN_TX, 603 LOGIN_RX, 604 LOGIN_ERROR, 605 LOGIN_DONE, 606 LOGIN_FFP, 607 LOGIN_MAX 608 } iscsi_login_state_t; 609 610 #ifdef ISCSI_LOGIN_STATE_NAMES 611 static const char *iscsi_login_state_names[LOGIN_MAX+1] = { 612 "LOGIN_START", 613 "LOGIN_READY", 614 "LOGIN_TX", 615 "LOGIN_RX", 616 "LOGIN_ERROR", 617 "LOGIN_DONE", 618 "LOGIN_FFP", 619 "LOGIN_MAX" 620 }; 621 #endif 622 623 /* 624 * iscsi_conn_state 625 */ 626 typedef enum iscsi_conn_state { 627 ISCSI_CONN_STATE_UNDEFINED = 0, 628 ISCSI_CONN_STATE_FREE, 629 ISCSI_CONN_STATE_IN_LOGIN, 630 ISCSI_CONN_STATE_LOGGED_IN, 631 ISCSI_CONN_STATE_IN_LOGOUT, 632 ISCSI_CONN_STATE_FAILED, 633 ISCSI_CONN_STATE_POLLING, 634 ISCSI_CONN_STATE_MAX 635 } iscsi_conn_state_t; 636 637 #ifdef ISCSI_ICS_NAMES 638 static const char *iscsi_ics_name[ISCSI_CONN_STATE_MAX+1] = { 639 "ISCSI_CONN_STATE_UNDEFINED", 640 "ISCSI_CONN_STATE_FREE", 641 "ISCSI_CONN_STATE_IN_LOGIN", 642 "ISCSI_CONN_STATE_LOGGED_IN", 643 "ISCSI_CONN_STATE_IN_LOGOUT", 644 "ISCSI_CONN_STATE_FAILED", 645 "ISCSI_CONN_STATE_POLLING", 646 "ISCSI_CONN_STATE_MAX" 647 }; 648 #endif 649 650 #define ISCSI_CONN_STATE_FULL_FEATURE(state) \ 651 ((state == ISCSI_CONN_STATE_LOGGED_IN) || \ 652 (state == ISCSI_CONN_STATE_IN_LOGOUT)) 653 654 /* 655 * iSCSI Connection Structure 656 */ 657 typedef struct iscsi_conn { 658 uint32_t conn_sig; 659 struct iscsi_conn *conn_next; /* next conn on this sess. */ 660 struct iscsi_sess *conn_sess; /* parent sess. for conn. */ 661 662 iscsi_conn_state_t conn_state; /* cur. conn. driver state */ 663 iscsi_conn_state_t conn_prev_state; /* prev. conn. driver state */ 664 /* protects the session state and synchronizes the state machine */ 665 kmutex_t conn_state_mutex; 666 kcondvar_t conn_state_change; 667 boolean_t conn_state_destroy; 668 boolean_t conn_state_ffp; 669 boolean_t conn_state_idm_connected; 670 boolean_t conn_async_logout; 671 ddi_taskq_t *conn_cn_taskq; 672 673 idm_conn_t *conn_ic; 674 675 /* base connection information, may have been redirected */ 676 iscsi_sockaddr_t conn_base_addr; 677 678 /* current connection information, may have been redirected */ 679 iscsi_sockaddr_t conn_curr_addr; 680 681 boolean_t conn_bound; 682 iscsi_sockaddr_t conn_bound_addr; 683 684 uint32_t conn_cid; /* CID */ 685 uint32_t conn_oid; /* OID */ 686 687 int conn_current_stage; /* iSCSI login stage */ 688 int conn_next_stage; /* iSCSI login stage */ 689 int conn_partial_response; 690 691 /* 692 * The active queue contains iscsi_cmds that have already 693 * been sent on this connection. Any future responses to 694 * these cmds require alligence to this connection. If there 695 * are issues with these cmds the command may need aborted 696 * depending on the command type, and must be put back into 697 * the session's pending queue or aborted. 698 */ 699 iscsi_queue_t conn_queue_active; 700 iscsi_queue_t conn_queue_idm_aborting; 701 702 /* lbolt from the last receive, used for nop processing */ 703 clock_t conn_rx_lbolt; 704 clock_t conn_nop_lbolt; 705 706 iscsi_thread_t *conn_tx_thread; 707 708 /* 709 * The expstatsn is the command status sn that is expected 710 * next from the target. Command status is carried on a number 711 * of iSCSI PDUs (ex. SCSI Cmd Response, SCSI Data IN with 712 * S-Bit set, ...), not all PDUs. If our expstatsn is different 713 * than the received statsn. Something got out of sync we need to 714 * recover. 715 */ 716 uint32_t conn_expstatsn; 717 uint32_t conn_laststatsn; 718 719 /* active login parameters */ 720 iscsi_login_params_t conn_params; 721 722 /* Statistics */ 723 struct { 724 kstat_t *ks; 725 iscsi_conn_stats_t ks_data; 726 } stats; 727 728 /* 729 * These fields are used to coordinate the asynchronous IDM 730 * PDU operations with the synchronous login code. 731 */ 732 kmutex_t conn_login_mutex; 733 kcondvar_t conn_login_cv; 734 iscsi_login_state_t conn_login_state; 735 iscsi_status_t conn_login_status; 736 iscsi_hdr_t conn_login_resp_hdr; 737 char *conn_login_data; 738 int conn_login_datalen; 739 int conn_login_max_data_length; 740 741 /* 742 * login min and max identify the amount of time 743 * in lbolt that iscsi_start_login() should attempt 744 * to log into a target portal. The login will 745 * delay until the min lbolt has been reached and 746 * will end once max time has been reached. These 747 * values are normally set to the default but can 748 * are also altered by async commands received from 749 * the targetlogin. 750 */ 751 clock_t conn_login_min; 752 clock_t conn_login_max; 753 sm_audit_buf_t conn_state_audit; 754 755 /* active tunable parameters */ 756 iscsi_tunable_params_t conn_tunable_params; 757 boolean_t conn_timeout; 758 } iscsi_conn_t; 759 760 761 /* 762 * iscsi_sess_state - (reference iscsi_sess.c for state diagram) 763 */ 764 typedef enum iscsi_sess_state { 765 ISCSI_SESS_STATE_FREE = 0, 766 ISCSI_SESS_STATE_LOGGED_IN, 767 ISCSI_SESS_STATE_FAILED, 768 ISCSI_SESS_STATE_IN_FLUSH, 769 ISCSI_SESS_STATE_FLUSHED, 770 ISCSI_SESS_STATE_MAX 771 } iscsi_sess_state_t; 772 773 #ifdef ISCSI_SESS_SM_STRINGS 774 static const char *iscsi_sess_state_names[ISCSI_SESS_STATE_MAX+1] = { 775 "ISCSI_SESS_STATE_FREE", 776 "ISCSI_SESS_STATE_LOGGED_IN", 777 "ISCSI_SESS_STATE_FAILED", 778 "ISCSI_SESS_STATE_IN_FLUSH", 779 "ISCSI_SESS_STATE_FLUSHED", 780 "ISCSI_SESS_STATE_MAX" 781 }; 782 #endif 783 784 #define ISCSI_SESS_STATE_FULL_FEATURE(state) \ 785 ((state == ISCSI_SESS_STATE_LOGGED_IN) || \ 786 (state == ISCSI_SESS_STATE_IN_FLUSH)) 787 788 789 typedef enum iscsi_sess_event { 790 ISCSI_SESS_EVENT_N1 = 0, 791 ISCSI_SESS_EVENT_N3, 792 ISCSI_SESS_EVENT_N5, 793 ISCSI_SESS_EVENT_N6, 794 ISCSI_SESS_EVENT_N7, 795 ISCSI_SESS_EVENT_MAX 796 } iscsi_sess_event_t; 797 798 #ifdef ISCSI_SESS_SM_STRINGS 799 static const char *iscsi_sess_event_names[ISCSI_SESS_EVENT_MAX+1] = { 800 "ISCSI_SESS_EVENT_N1", 801 "ISCSI_SESS_EVENT_N3", 802 "ISCSI_SESS_EVENT_N5", 803 "ISCSI_SESS_EVENT_N6", 804 "ISCSI_SESS_EVENT_N7", 805 "ISCSI_SESS_EVENT_MAX" 806 }; 807 #endif 808 809 typedef enum iscsi_sess_type { 810 ISCSI_SESS_TYPE_NORMAL = 0, 811 ISCSI_SESS_TYPE_DISCOVERY 812 } iscsi_sess_type_t; 813 814 #define SESS_ABORT_TASK_MAX_THREADS 1 815 816 /* Sun's initiator session ID */ 817 #define ISCSI_SUN_ISID_0 0x40 /* ISID - EN format */ 818 #define ISCSI_SUN_ISID_1 0x00 /* Sec B */ 819 #define ISCSI_SUN_ISID_2 0x00 /* Sec B */ 820 #define ISCSI_SUN_ISID_3 0x2A /* Sec C - 42 = Sun's EN */ 821 /* 822 * defines 4-5 are the reserved values. These reserved values 823 * are used as the ISID for an initiator-port in MP-API and used 824 * for the send targets discovery sessions. Byte 5 is overridden 825 * for full feature sessions. The default values of byte 5 for a 826 * full feature session is 0. When MS/T is enabled with more than 827 * one session this byte 5 will increment > 0 up to 828 * ISCSI_MAX_CONFIG_SESSIONS. 829 */ 830 #define ISCSI_SUN_ISID_4 0x00 831 #define ISCSI_SUN_ISID_5 0xFF 832 833 #define ISCSI_DEFAULT_SESS_BOUND B_FALSE 834 #define ISCSI_DEFAULT_SESS_NUM 1 835 836 typedef enum iscsi_enum_status { 837 ISCSI_SESS_ENUM_FREE = 0, 838 ISCSI_SESS_ENUM_INPROG, 839 ISCSI_SESS_ENUM_DONE 840 } iscsi_enum_status_t; 841 842 typedef enum iscsi_enum_result { 843 ISCSI_SESS_ENUM_COMPLETE = 0, 844 ISCSI_SESS_ENUM_PARTIAL, 845 ISCSI_SESS_ENUM_IOFAIL, 846 ISCSI_SESS_ENUM_SUBMITTED, 847 ISCSI_SESS_ENUM_SUBFAIL, 848 ISCSI_SESS_ENUM_GONE, 849 ISCSI_SESS_ENUM_TUR_FAIL 850 } iscsi_enum_result_t; 851 852 /* 853 * iSCSI Session(Target) Structure 854 */ 855 typedef struct iscsi_sess { 856 uint32_t sess_sig; 857 858 iscsi_sess_state_t sess_state; 859 iscsi_sess_state_t sess_prev_state; 860 clock_t sess_state_lbolt; 861 /* protects the session state and synchronizes the state machine */ 862 krwlock_t sess_state_rwlock; 863 864 /* 865 * Associated target OID. 866 */ 867 uint32_t sess_target_oid; 868 869 /* 870 * Session OID. Used by IMA, interfaces and exported as 871 * TARGET_PROP which is checked by the NDI. In addition 872 * this is used in our tran_lun_init function. 873 */ 874 uint32_t sess_oid; 875 876 struct iscsi_sess *sess_next; 877 struct iscsi_hba *sess_hba; 878 879 /* list of all luns relating to session */ 880 struct iscsi_lun *sess_lun_list; 881 krwlock_t sess_lun_list_rwlock; 882 883 /* list of all connections relating to session */ 884 struct iscsi_conn *sess_conn_list; 885 struct iscsi_conn *sess_conn_list_last_ptr; 886 /* pointer to active connection in session */ 887 struct iscsi_conn *sess_conn_act; 888 krwlock_t sess_conn_list_rwlock; 889 890 /* Connection ID for next connection to be added to session */ 891 uint32_t sess_conn_next_cid; 892 893 /* 894 * last time any connection on this session received 895 * data from the target. 896 */ 897 clock_t sess_rx_lbolt; 898 899 clock_t sess_failure_lbolt; 900 901 int sess_storm_delay; 902 903 /* 904 * sess_cmdsn_mutex protects the cmdsn and itt table/values 905 * Cmdsn isn't that big of a problem yet since we only have 906 * one connection but in the future we will need to ensure 907 * this locking is working so keep the sequence numbers in 908 * sync on the wire. 909 * 910 * We also use this lock to protect the ITT table and it's 911 * values. We need to make sure someone doesn't assign 912 * a duplicate ITT value or cell to a command. Also we 913 * need to make sure when someone is looking up an ITT 914 * that the command is still in that correct queue location. 915 */ 916 kmutex_t sess_cmdsn_mutex; 917 918 /* 919 * iSCSI command sequencing / windowing. The next 920 * command to be sent via the pending queue will 921 * get the sess_cmdsn. If the maxcmdsn is less 922 * than the next cmdsn then the iSCSI window is 923 * closed and this command cannot be sent yet. 924 * Most iscsi cmd responses from the target carry 925 * a new maxcmdsn. If this new maxcmdsn is greater 926 * than the sess_maxcmdsn we will update it's value 927 * and set a timer to fire in one tick and reprocess 928 * the pending queue. 929 * 930 * The expcmdsn. Is the value the target expects 931 * to be sent for my next cmdsn. If the expcmdsn 932 * and the cmdsn get out of sync this could denote 933 * a communication problem. 934 */ 935 uint32_t sess_cmdsn; 936 uint32_t sess_expcmdsn; 937 uint32_t sess_maxcmdsn; 938 939 /* Next Initiator Task Tag (ITT) to use */ 940 uint32_t sess_itt; 941 /* 942 * The session iscsi_cmd table is used to a fast performance 943 * lookup of an ITT to a iscsi_cmd when we receive an iSCSI 944 * PDU from the wire. To reserve a location in the sess_cmd_table 945 * we try the sess_itt % ISCSI_CMD_TABLE_SIZE if this cmd table 946 * cell is already full. Then increament the sess_itt and 947 * try to get the cell position again, repeat until an empty 948 * cell is found. Once an empty cell is found place your 949 * scsi_cmd point into the cell to reserve the location. This 950 * selection process should be done while holding the session's 951 * mutex. 952 */ 953 struct iscsi_cmd *sess_cmd_table[ISCSI_CMD_TABLE_SIZE]; 954 int sess_cmd_table_count; 955 956 /* 957 * The pending queue contains all iscsi_cmds that require an 958 * open MaxCmdSn window to be put on the wire and haven't 959 * been placed on the wire. Once placed on the wire they 960 * will be moved to a connections specific active queue. 961 */ 962 iscsi_queue_t sess_queue_pending; 963 964 iscsi_error_t sess_last_err; 965 966 iscsi_queue_t sess_queue_completion; 967 /* configured login parameters */ 968 iscsi_login_params_t sess_params; 969 970 /* general iSCSI protocol/session info */ 971 uchar_t sess_name[ISCSI_MAX_NAME_LEN]; 972 int sess_name_length; 973 char sess_alias[ISCSI_MAX_NAME_LEN]; 974 int sess_alias_length; 975 iSCSIDiscoveryMethod_t sess_discovered_by; 976 iscsi_sockaddr_t sess_discovered_addr; 977 uchar_t sess_isid[ISCSI_ISID_LEN]; /* Session ID */ 978 uint16_t sess_tsid; /* Target ID */ 979 /* 980 * If the target portal group tag(TPGT) is equal to ISCSI_DEFAULT_TPGT 981 * then the initiator will accept a successful login with any TPGT 982 * specified by the target. If a none default TPGT is configured 983 * then we will only successfully accept a login with that matching 984 * TPGT value. 985 */ 986 int sess_tpgt_conf; 987 /* This field records the negotiated TPGT value, preserved for dtrace */ 988 int sess_tpgt_nego; 989 990 /* 991 * Authentication information. 992 * 993 * DCW: Again IMA seems to take a session view at this 994 * information. 995 */ 996 iscsi_auth_t sess_auth; 997 998 /* Statistics */ 999 struct { 1000 kstat_t *ks; 1001 iscsi_sess_stats_t ks_data; 1002 kstat_t *ks_io; 1003 kstat_io_t ks_io_data; 1004 kmutex_t ks_io_lock; 1005 } stats; 1006 1007 iscsi_thread_t *sess_ic_thread; 1008 boolean_t sess_window_open; 1009 boolean_t sess_boot; 1010 iscsi_sess_type_t sess_type; 1011 1012 ddi_taskq_t *sess_login_taskq; 1013 1014 iscsi_thread_t *sess_wd_thread; 1015 1016 sm_audit_buf_t sess_state_audit; 1017 1018 kmutex_t sess_reset_mutex; 1019 1020 boolean_t sess_reset_in_progress; 1021 1022 boolean_t sess_boot_nic_reset; 1023 kmutex_t sess_enum_lock; 1024 kcondvar_t sess_enum_cv; 1025 iscsi_enum_status_t sess_enum_status; 1026 iscsi_enum_result_t sess_enum_result; 1027 uint32_t sess_enum_result_count; 1028 ddi_taskq_t *sess_enum_taskq; 1029 1030 kmutex_t sess_state_wmutex; 1031 kcondvar_t sess_state_wcv; 1032 boolean_t sess_state_hasw; 1033 1034 /* to accelerate the state change in case of new event */ 1035 volatile uint32_t sess_state_event_count; 1036 } iscsi_sess_t; 1037 1038 /* 1039 * This structure will be used to store sessions to be online 1040 * during normal login operation. 1041 */ 1042 typedef struct iscsi_sess_list { 1043 iscsi_sess_t *session; 1044 struct iscsi_sess_list *next; 1045 } iscsi_sess_list_t; 1046 1047 /* 1048 * iSCSI client notify task context for deferred IDM notifications processing 1049 */ 1050 typedef struct iscsi_cn_task { 1051 idm_conn_t *ct_ic; 1052 idm_client_notify_t ct_icn; 1053 uintptr_t ct_data; 1054 } iscsi_cn_task_t; 1055 1056 /* 1057 * iscsi_network 1058 */ 1059 typedef struct iscsi_network { 1060 void* (*socket)(int domain, int, int); 1061 int (*bind)(void *, struct sockaddr *, int, int, int); 1062 int (*connect)(void *, struct sockaddr *, int, int, int); 1063 int (*listen)(void *, int); 1064 void* (*accept)(void *, struct sockaddr *, int *); 1065 int (*getsockname)(void *, struct sockaddr *, socklen_t *); 1066 int (*getsockopt)(void *, int, int, void *, int *, int); 1067 int (*setsockopt)(void *, int, int, void *, int); 1068 int (*shutdown)(void *, int); 1069 void (*close)(void *); 1070 1071 size_t (*poll)(void *, clock_t); 1072 size_t (*sendmsg)(void *, struct msghdr *); 1073 size_t (*recvmsg)(void *, struct msghdr *, int); 1074 1075 iscsi_status_t (*sendpdu)(void *, iscsi_hdr_t *, char *, int); 1076 iscsi_status_t (*recvdata)(void *, iscsi_hdr_t *, char *, 1077 int, int, int); 1078 iscsi_status_t (*recvhdr)(void *, iscsi_hdr_t *, int, int, int); 1079 1080 struct { 1081 int sndbuf; 1082 int rcvbuf; 1083 int nodelay; 1084 int conn_notify_threshold; 1085 int conn_abort_threshold; 1086 int abort_threshold; 1087 } tweaks; 1088 } iscsi_network_t; 1089 1090 #define ISCSI_NET_HEADER_DIGEST 0x00000001 1091 #define ISCSI_NET_DATA_DIGEST 0x00000002 1092 1093 extern iscsi_network_t *iscsi_net; 1094 1095 /* 1096 * If we get bus_config requests in less than 5 seconds 1097 * apart skip the name services re-discovery and just 1098 * complete the requested logins. This protects against 1099 * bus_config storms from stale /dev links. 1100 */ 1101 #define ISCSI_CONFIG_STORM_DELAY_DEFAULT 5 1102 1103 /* 1104 * iSCSI HBA Structure 1105 */ 1106 typedef struct iscsi_hba { 1107 uint32_t hba_sig; 1108 dev_info_t *hba_dip; /* dev info ptr */ 1109 scsi_hba_tran_t *hba_tran; /* scsi tran ptr */ 1110 ldi_ident_t hba_li; 1111 1112 struct iscsi_sess *hba_sess_list; /* sess. list for hba */ 1113 krwlock_t hba_sess_list_rwlock; /* protect sess. list */ 1114 1115 /* lbolt of the last time we received a config request */ 1116 clock_t hba_config_lbolt; 1117 /* current number of seconds to protect against bus config storms */ 1118 int hba_config_storm_delay; 1119 1120 /* general iSCSI protocol hba/initiator info */ 1121 uchar_t hba_name[ISCSI_MAX_NAME_LEN]; 1122 int hba_name_length; 1123 uchar_t hba_alias[ISCSI_MAX_NAME_LEN]; 1124 int hba_alias_length; 1125 1126 /* Default SessionID for HBA */ 1127 uchar_t hba_isid[ISCSI_ISID_LEN]; 1128 1129 /* Default HBA wide settings */ 1130 iscsi_login_params_t hba_params; 1131 1132 /* 1133 * There's only one HBA and it's set to ISCSI_INITIATOR_OID 1134 * (value of 1) at the beginning of time. 1135 */ 1136 uint32_t hba_oid; 1137 1138 /* 1139 * Keep track of which events have been sent. User daemons request 1140 * this information so they don't wait for events which they won't 1141 * see. 1142 */ 1143 kmutex_t hba_discovery_events_mutex; 1144 iSCSIDiscoveryMethod_t hba_discovery_events; 1145 boolean_t hba_discovery_in_progress; 1146 1147 boolean_t hba_mpxio_enabled; /* mpxio-enabled */ 1148 /* if the persistent store is loaded */ 1149 boolean_t hba_persistent_loaded; 1150 1151 /* 1152 * Ensures only one SendTargets operation occurs at a time 1153 */ 1154 ksema_t hba_sendtgts_semaphore; 1155 1156 /* 1157 * Statistics 1158 */ 1159 struct { 1160 kstat_t *ks; 1161 iscsi_hba_stats_t ks_data; 1162 } stats; 1163 1164 /* 1165 * track/control the service status and client 1166 * 1167 * service- service online ensures the operational of cli 1168 * - and the availability of iSCSI discovery/devices 1169 * - so obviously offline means the unusable of cli 1170 * - , disabling of all discovery methods and to offline 1171 * - all discovered devices 1172 * 1173 * client - here the client actually means 'exclusive client' 1174 * - for operations these clients take may conflict 1175 * - with the changing of service status and therefore 1176 * - need to be exclusive 1177 * 1178 * The service has three status: 1179 * ISCSI_SERVICE_ENABLED - client is permitted to 1180 * - request service 1181 * 1182 * ISCSI_SERVICE_DISABLED - client is not permitted to 1183 * - request service 1184 * 1185 * ISCSI_SERVICE_TRANSITION - client must wait for 1186 * - one of above two statuses 1187 * 1188 * The hba_service_client_count tracks the number of 1189 * current clients, it increases with new clients and decreases 1190 * with leaving clients. It stops to increase once the 1191 * ISCSI_SERVICE_TRANSITION is set, and causes later clients be 1192 * blocked there. 1193 * 1194 * The status of the service can only be changed when the number 1195 * of current clients reaches zero. 1196 * 1197 * Clients include: 1198 * iscsi_ioctl 1199 * iscsi_tran_bus_config 1200 * iscsi_tran_bus_unconfig 1201 * isns_scn_callback 1202 */ 1203 kmutex_t hba_service_lock; 1204 kcondvar_t hba_service_cv; 1205 uint32_t hba_service_status; 1206 uint32_t hba_service_client_count; 1207 1208 /* Default HBA tunable settings */ 1209 iscsi_tunable_params_t hba_tunable_params; 1210 boolean_t hba_service_status_overwrite; 1211 } iscsi_hba_t; 1212 1213 /* 1214 * +--------------------------------------------------------------------+ 1215 * | iSCSI prototypes | 1216 * +--------------------------------------------------------------------+ 1217 */ 1218 1219 /* IDM client callback entry points */ 1220 idm_rx_pdu_cb_t iscsi_rx_scsi_rsp; 1221 idm_rx_pdu_cb_t iscsi_rx_misc_pdu; 1222 idm_rx_pdu_error_cb_t iscsi_rx_error_pdu; 1223 idm_build_hdr_cb_t iscsi_build_hdr; 1224 idm_task_cb_t iscsi_task_aborted; 1225 idm_client_notify_cb_t iscsi_client_notify; 1226 1227 /* iscsi_io.c */ 1228 int iscsi_sna_lte(uint32_t n1, uint32_t n2); 1229 char *iscsi_get_next_text(char *data, int data_length, char *curr_text); 1230 1231 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg); 1232 void iscsi_tx_thread(iscsi_thread_t *thread, void *arg); 1233 void iscsi_wd_thread(iscsi_thread_t *thread, void *arg); 1234 1235 iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1236 1237 void iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp); 1238 1239 void iscsi_handle_abort(void *arg); 1240 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level, 1241 iscsi_lun_t *ilp); 1242 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp); 1243 iscsi_status_t iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun, 1244 struct uscsi_cmd *ucmdp); 1245 iscsi_status_t iscsi_handle_text(iscsi_conn_t *icp, 1246 char *buf, uint32_t buf_len, uint32_t data_len, uint32_t *rx_data_len); 1247 1248 void iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1249 1250 /* iscsi_crc.c */ 1251 uint32_t iscsi_crc32c(void *address, unsigned long length); 1252 uint32_t iscsi_crc32c_continued(void *address, unsigned long length, 1253 uint32_t crc); 1254 1255 /* iscsi_queue.c */ 1256 void iscsi_init_queue(iscsi_queue_t *queue); 1257 void iscsi_destroy_queue(iscsi_queue_t *queue); 1258 void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1259 void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1260 void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 1261 void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 1262 void iscsi_enqueue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 1263 void iscsi_dequeue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 1264 void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1265 iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *); 1266 void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue); 1267 void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **, 1268 iscsi_cmd_t *); 1269 1270 /* iscsi_login.c */ 1271 void iscsi_login_cb(void *arg); 1272 iscsi_status_t iscsi_login_start(void *arg); 1273 void iscsi_login_update_state(iscsi_conn_t *icp, 1274 iscsi_login_state_t next_state); 1275 void iscsi_login_update_state_locked(iscsi_conn_t *icp, 1276 iscsi_login_state_t next_state); 1277 1278 1279 /* iscsi_stats.c */ 1280 boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp); 1281 boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp); 1282 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp); 1283 boolean_t iscsi_sess_kstat_term(struct iscsi_sess *isp); 1284 boolean_t iscsi_conn_kstat_init(struct iscsi_conn *icp); 1285 void iscsi_conn_kstat_term(struct iscsi_conn *icp); 1286 1287 /* iscsi_net.c */ 1288 void iscsi_net_init(); 1289 void iscsi_net_fini(); 1290 iscsi_status_t iscsi_net_interface(boolean_t reset); 1291 1292 /* iscsi_sess.c */ 1293 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp, 1294 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc, 1295 char *target_name, int tpgt, uchar_t isid_lsb, 1296 iscsi_sess_type_t type, uint32_t *oid); 1297 void iscsi_sess_online(void *arg); 1298 int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp); 1299 iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp); 1300 void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event, 1301 uint32_t event_count); 1302 char *iscsi_sess_state_str(iscsi_sess_state_t state); 1303 boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp); 1304 iscsi_status_t iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp); 1305 void iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp); 1306 iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1307 void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 1308 void iscsi_sess_redrive_io(iscsi_sess_t *isp); 1309 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp, 1310 iscsi_sess_t **ispp); 1311 iscsi_enum_result_t iscsi_sess_enum_request(iscsi_sess_t *isp, 1312 boolean_t wait, uint32_t event_count); 1313 iscsi_enum_result_t iscsi_sess_enum_query(iscsi_sess_t *isp); 1314 void iscsi_sess_enter_state_zone(iscsi_sess_t *isp); 1315 void iscsi_sess_exit_state_zone(iscsi_sess_t *isp); 1316 1317 /* iscsi_conn.c */ 1318 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp, 1319 iscsi_conn_t **icpp); 1320 iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp); 1321 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp); 1322 iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp); 1323 void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max); 1324 iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp); 1325 void iscsi_conn_retry(iscsi_sess_t *isp, iscsi_conn_t *icp); 1326 void iscsi_conn_update_state(iscsi_conn_t *icp, iscsi_conn_state_t next_state); 1327 void iscsi_conn_update_state_locked(iscsi_conn_t *icp, 1328 iscsi_conn_state_t next_state); 1329 1330 /* iscsi_lun.c */ 1331 iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num, 1332 uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid); 1333 void iscsi_lun_hold(iscsi_lun_t *ilp); 1334 void iscsi_lun_rele(iscsi_lun_t *ilp); 1335 iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, iscsi_lun_t *ilp); 1336 void iscsi_lun_online(iscsi_hba_t *ihp, 1337 iscsi_lun_t *ilp); 1338 iscsi_status_t iscsi_lun_offline(iscsi_hba_t *ihp, 1339 iscsi_lun_t *ilp, boolean_t lun_free); 1340 1341 /* iscsi_cmd.c */ 1342 void iscsi_cmd_state_machine(iscsi_cmd_t *icmdp, 1343 iscsi_cmd_event_t event, void *arg); 1344 iscsi_cmd_t *iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags); 1345 void iscsi_cmd_free(iscsi_cmd_t *icmdp); 1346 1347 /* iscsi_ioctl.c */ 1348 void * iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size); 1349 int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode); 1350 iscsi_conn_list_t *iscsi_ioctl_conn_oid_list_get_copyin(caddr_t, int); 1351 int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *, caddr_t, int); 1352 boolean_t iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp, 1353 iscsi_conn_list_t *cl); 1354 boolean_t iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp); 1355 int iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl); 1356 int iscsi_target_prop_mod(iscsi_hba_t *, iscsi_property_t *, int cmd); 1357 int iscsi_set_params(iscsi_param_set_t *, iscsi_hba_t *, boolean_t); 1358 int iscsi_get_persisted_param(uchar_t *, iscsi_param_get_t *, 1359 iscsi_login_params_t *); 1360 void iscsi_set_default_login_params(iscsi_login_params_t *params); 1361 int iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp, 1362 iscsi_config_sess_t *ics); 1363 int iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp, 1364 iscsi_config_sess_t *ics); 1365 int iscsi_ioctl_set_tunable_param(iscsi_hba_t *ihp, 1366 iscsi_tunable_object_t *tpss); 1367 /* ioctls prototypes */ 1368 int iscsi_get_param(iscsi_login_params_t *params, 1369 boolean_t valid_flag, 1370 iscsi_param_get_t *ipgp); 1371 1372 /* iscsid.c */ 1373 boolean_t iscsid_init(iscsi_hba_t *ihp); 1374 boolean_t iscsid_start(iscsi_hba_t *ihp); 1375 boolean_t iscsid_stop(iscsi_hba_t *ihp); 1376 void iscsid_fini(); 1377 void iscsid_props(iSCSIDiscoveryProperties_t *props); 1378 boolean_t iscsid_enable_discovery(iscsi_hba_t *ihp, 1379 iSCSIDiscoveryMethod_t idm, boolean_t poke); 1380 boolean_t iscsid_disable_discovery(iscsi_hba_t *ihp, 1381 iSCSIDiscoveryMethod_t idm); 1382 void iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method); 1383 void iscsid_do_sendtgts(entry_t *discovery_addr); 1384 void iscsid_do_isns_query_one_server( 1385 iscsi_hba_t *ihp, entry_t *isns_addr); 1386 void iscsid_do_isns_query(iscsi_hba_t *ihp); 1387 void iscsid_config_one(iscsi_hba_t *ihp, 1388 char *name, boolean_t protect); 1389 void iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect); 1390 void iscsid_unconfig_one(iscsi_hba_t *ihp, char *name); 1391 void iscsid_unconfig_all(iscsi_hba_t *ihp); 1392 void isns_scn_callback(void *arg); 1393 boolean_t iscsid_del(iscsi_hba_t *ihp, char *target_name, 1394 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc); 1395 boolean_t iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name, 1396 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc); 1397 void iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port, 1398 struct sockaddr *dst_addr); 1399 void iscsid_set_default_initiator_node_settings(iscsi_hba_t *ihp, 1400 boolean_t minimal); 1401 1402 void iscsi_send_sysevent(iscsi_hba_t *ihp, char *eventcalss, 1403 char *subclass, nvlist_t *np); 1404 boolean_t iscsi_reconfig_boot_sess(iscsi_hba_t *ihp); 1405 boolean_t iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp); 1406 boolean_t iscsi_cmp_boot_ini_name(char *name); 1407 boolean_t iscsi_cmp_boot_tgt_name(char *name); 1408 boolean_t iscsi_client_request_service(iscsi_hba_t *ihp); 1409 void iscsi_client_release_service(iscsi_hba_t *ihp); 1410 1411 extern void bcopy(const void *s1, void *s2, size_t n); 1412 extern void bzero(void *s, size_t n); 1413 1414 #ifdef __cplusplus 1415 } 1416 #endif 1417 1418 #endif /* _ISCSI_H */ 1419