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