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