17836SJohn.Forte@Sun.COM /* 27836SJohn.Forte@Sun.COM * CDDL HEADER START 37836SJohn.Forte@Sun.COM * 47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 77836SJohn.Forte@Sun.COM * 87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 117836SJohn.Forte@Sun.COM * and limitations under the License. 127836SJohn.Forte@Sun.COM * 137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 187836SJohn.Forte@Sun.COM * 197836SJohn.Forte@Sun.COM * CDDL HEADER END 207836SJohn.Forte@Sun.COM */ 217836SJohn.Forte@Sun.COM /* 227836SJohn.Forte@Sun.COM * Copyright 2000 by Cisco Systems, Inc. All rights reserved. 23*12161SJack.Meng@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 247836SJohn.Forte@Sun.COM */ 257836SJohn.Forte@Sun.COM 267836SJohn.Forte@Sun.COM #ifndef _ISCSI_H 277836SJohn.Forte@Sun.COM #define _ISCSI_H 287836SJohn.Forte@Sun.COM 297836SJohn.Forte@Sun.COM /* 307836SJohn.Forte@Sun.COM * Block comment which describes the contents of this file. 317836SJohn.Forte@Sun.COM */ 327836SJohn.Forte@Sun.COM 337836SJohn.Forte@Sun.COM #ifdef __cplusplus 347836SJohn.Forte@Sun.COM extern "C" { 357836SJohn.Forte@Sun.COM #endif 367836SJohn.Forte@Sun.COM 377836SJohn.Forte@Sun.COM #include <sys/scsi/scsi.h> 387836SJohn.Forte@Sun.COM #include <sys/ddi.h> 397836SJohn.Forte@Sun.COM #include <sys/sunddi.h> 407836SJohn.Forte@Sun.COM #include <sys/socket.h> 417836SJohn.Forte@Sun.COM #include <sys/kstat.h> 427836SJohn.Forte@Sun.COM #include <sys/sunddi.h> 437836SJohn.Forte@Sun.COM #include <sys/sunmdi.h> 447836SJohn.Forte@Sun.COM #include <sys/mdi_impldefs.h> 457836SJohn.Forte@Sun.COM #include <sys/time.h> 467836SJohn.Forte@Sun.COM #include <sys/nvpair.h> 477836SJohn.Forte@Sun.COM #include <sys/sdt.h> 487836SJohn.Forte@Sun.COM 499162SPeter.Dunlap@Sun.COM #include <sys/iscsi_protocol.h> 507836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_if.h> 517836SJohn.Forte@Sun.COM #include <iscsiAuthClient.h> 527836SJohn.Forte@Sun.COM #include <iscsi_stats.h> 537836SJohn.Forte@Sun.COM #include <iscsi_thread.h> 549162SPeter.Dunlap@Sun.COM #include <sys/idm/idm.h> 559162SPeter.Dunlap@Sun.COM #include <sys/idm/idm_conn_sm.h> 567836SJohn.Forte@Sun.COM #include <nvfile.h> 577836SJohn.Forte@Sun.COM 587836SJohn.Forte@Sun.COM #ifndef MIN 597836SJohn.Forte@Sun.COM #define MIN(a, b) ((a) < (b) ? (a) : (b)) 607836SJohn.Forte@Sun.COM #endif 617836SJohn.Forte@Sun.COM 627836SJohn.Forte@Sun.COM #ifndef TRUE 637836SJohn.Forte@Sun.COM #define TRUE 1 647836SJohn.Forte@Sun.COM #endif 657836SJohn.Forte@Sun.COM 667836SJohn.Forte@Sun.COM #ifndef FALSE 677836SJohn.Forte@Sun.COM #define FALSE 0 687836SJohn.Forte@Sun.COM #endif 697836SJohn.Forte@Sun.COM 707836SJohn.Forte@Sun.COM #define LOGIN_PDU_BUFFER_SIZE (16 * 1024) /* move somewhere else */ 717836SJohn.Forte@Sun.COM 729162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_conn_logging; 739162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_io_logging; 749162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_login_logging; 759162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_logging; 769162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_sess_logging; 779162SPeter.Dunlap@Sun.COM #define ISCSI_CONN_LOG if (iscsi_conn_logging) cmn_err 789162SPeter.Dunlap@Sun.COM #define ISCSI_IO_LOG if (iscsi_io_logging) cmn_err 799162SPeter.Dunlap@Sun.COM #define ISCSI_LOGIN_LOG if (iscsi_login_logging) cmn_err 809162SPeter.Dunlap@Sun.COM #define ISCSI_LOG if (iscsi_logging) cmn_err 819162SPeter.Dunlap@Sun.COM #define ISCSI_SESS_LOG if (iscsi_sess_logging) cmn_err 829162SPeter.Dunlap@Sun.COM 837836SJohn.Forte@Sun.COM /* 847836SJohn.Forte@Sun.COM * Name Format of the different Task Queues 857836SJohn.Forte@Sun.COM */ 867836SJohn.Forte@Sun.COM #define ISCSI_SESS_IOTH_NAME_FORMAT "io_thrd_%d.%d" 877836SJohn.Forte@Sun.COM #define ISCSI_SESS_WD_NAME_FORMAT "wd_thrd_%d.%d" 887836SJohn.Forte@Sun.COM #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT "login_taskq_%d.%d" 89*12161SJack.Meng@Sun.COM #define ISCSI_SESS_ENUM_TASKQ_NAME_FORMAT "enum_taskq_%d.%d" 909162SPeter.Dunlap@Sun.COM #define ISCSI_CONN_CN_TASKQ_NAME_FORMAT "conn_cn_taskq_%d.%d.%d" 917836SJohn.Forte@Sun.COM #define ISCSI_CONN_RXTH_NAME_FORMAT "rx_thrd_%d.%d.%d" 927836SJohn.Forte@Sun.COM #define ISCSI_CONN_TXTH_NAME_FORMAT "tx_thrd_%d.%d.%d" 937836SJohn.Forte@Sun.COM 947836SJohn.Forte@Sun.COM /* 957836SJohn.Forte@Sun.COM * The iSCSI driver will not build scatter/gather lists (iovec) longer 967836SJohn.Forte@Sun.COM * than the value defined here. Asserts have been include in the code 977836SJohn.Forte@Sun.COM * to check. 987836SJohn.Forte@Sun.COM */ 997836SJohn.Forte@Sun.COM #define ISCSI_MAX_IOVEC 5 1007836SJohn.Forte@Sun.COM 1017836SJohn.Forte@Sun.COM #define ISCSI_DEFAULT_MAX_STORM_DELAY 32 1027836SJohn.Forte@Sun.COM 1037836SJohn.Forte@Sun.COM /* 1047836SJohn.Forte@Sun.COM * The SNDBUF and RCVBUF size parameters for the sockets are just a 1057836SJohn.Forte@Sun.COM * guess for the time being (I think it is the values used by CISCO 1067836SJohn.Forte@Sun.COM * or UNH). Testing will have to be done to figure * out the impact 1077836SJohn.Forte@Sun.COM * of these values on performance. 1087836SJohn.Forte@Sun.COM */ 1097836SJohn.Forte@Sun.COM #define ISCSI_SOCKET_SNDBUF_SIZE (256 * 1024) 1107836SJohn.Forte@Sun.COM #define ISCSI_SOCKET_RCVBUF_SIZE (256 * 1024) 1117836SJohn.Forte@Sun.COM #define ISCSI_TCP_NODELAY_DEFAULT 0 1127836SJohn.Forte@Sun.COM #define ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT 2000 1137836SJohn.Forte@Sun.COM #define ISCSI_TCP_CABORT_THRESHOLD_DEFAULT 10000 1147836SJohn.Forte@Sun.COM #define ISCSI_TCP_ABORT_THRESHOLD_DEFAULT (30 * 1000) /* milliseconds */ 1157836SJohn.Forte@Sun.COM #define ISNS_TCP_ABORT_THRESHOLD_DEFAULT (3 * 1000) /* milliseconds */ 1167836SJohn.Forte@Sun.COM 11710156SZhang.Yi@Sun.COM /* Default values for tunable parameters */ 11810156SZhang.Yi@Sun.COM #define ISCSI_DEFAULT_RX_TIMEOUT_VALUE 60 11910156SZhang.Yi@Sun.COM #define ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX 180 12010156SZhang.Yi@Sun.COM #define ISCSI_DEFAULT_LOGIN_POLLING_DELAY 60 1217836SJohn.Forte@Sun.COM 1227836SJohn.Forte@Sun.COM /* 1237836SJohn.Forte@Sun.COM * Convenient short hand defines 1247836SJohn.Forte@Sun.COM */ 1257836SJohn.Forte@Sun.COM #define TARGET_PROP "target" 1267836SJohn.Forte@Sun.COM #define LUN_PROP "lun" 1277836SJohn.Forte@Sun.COM #define MDI_GUID "wwn" 1287836SJohn.Forte@Sun.COM #define NDI_GUID "client-guid" 1297836SJohn.Forte@Sun.COM 1307836SJohn.Forte@Sun.COM #define ISCSI_SIG_CMD 0x11111111 1317836SJohn.Forte@Sun.COM #define ISCSI_SIG_LUN 0x22222222 1327836SJohn.Forte@Sun.COM #define ISCSI_SIG_CONN 0x33333333 1337836SJohn.Forte@Sun.COM #define ISCSI_SIG_SESS 0x44444444 1347836SJohn.Forte@Sun.COM #define ISCSI_SIG_HBA 0x55555555 1357836SJohn.Forte@Sun.COM 1367836SJohn.Forte@Sun.COM #define SENDTARGETS_DISCOVERY "SENDTARGETS_DISCOVERY" 1377836SJohn.Forte@Sun.COM 1387836SJohn.Forte@Sun.COM #define ISCSI_LUN_MASK_MSB 0x00003f00 1397836SJohn.Forte@Sun.COM #define ISCSI_LUN_MASK_LSB 0x000000ff 14011272SMilos.Muzik@Sun.COM #define ISCSI_LUN_MASK (ISCSI_LUN_MASK_MSB | ISCSI_LUN_MASK_LSB) 1417836SJohn.Forte@Sun.COM #define ISCSI_LUN_BYTE_COPY(lun, report_lun_data) \ 1427836SJohn.Forte@Sun.COM lun[0] = (report_lun_data & ISCSI_LUN_MASK_MSB) >> 8; \ 1437836SJohn.Forte@Sun.COM lun[1] = (report_lun_data & ISCSI_LUN_MASK_LSB); 1447836SJohn.Forte@Sun.COM /* 1457836SJohn.Forte@Sun.COM * Not defined by iSCSI, but used in the login code to 1467836SJohn.Forte@Sun.COM * determine when to send the initial Login PDU 1477836SJohn.Forte@Sun.COM */ 1487836SJohn.Forte@Sun.COM #define ISCSI_INITIAL_LOGIN_STAGE -1 1497836SJohn.Forte@Sun.COM 1507836SJohn.Forte@Sun.COM typedef enum iscsi_status { 1517836SJohn.Forte@Sun.COM /* Success */ 1527836SJohn.Forte@Sun.COM ISCSI_STATUS_SUCCESS = 0, 1537836SJohn.Forte@Sun.COM /* Driver / Kernel / Code error */ 1547836SJohn.Forte@Sun.COM ISCSI_STATUS_INTERNAL_ERROR, 1557836SJohn.Forte@Sun.COM /* ITT table is already full, unable to reserve slot */ 1567836SJohn.Forte@Sun.COM ISCSI_STATUS_ITT_TABLE_FULL, 1577836SJohn.Forte@Sun.COM /* Login on connection failed */ 1587836SJohn.Forte@Sun.COM ISCSI_STATUS_LOGIN_FAILED, 1597836SJohn.Forte@Sun.COM /* No connections are in the LOGGED_IN state */ 1607836SJohn.Forte@Sun.COM ISCSI_STATUS_NO_CONN_LOGGED_IN, 1617836SJohn.Forte@Sun.COM /* TCP Transfer Error */ 1627836SJohn.Forte@Sun.COM ISCSI_STATUS_TCP_TX_ERROR, 1637836SJohn.Forte@Sun.COM /* TCP Receive Error */ 1647836SJohn.Forte@Sun.COM ISCSI_STATUS_TCP_RX_ERROR, 1657836SJohn.Forte@Sun.COM /* iSCSI packet RCV timeout */ 1667836SJohn.Forte@Sun.COM ISCSI_STATUS_RX_TIMEOUT, 1677836SJohn.Forte@Sun.COM /* iSCSI Header Digest CRC error */ 1687836SJohn.Forte@Sun.COM ISCSI_STATUS_HEADER_DIGEST_ERROR, 1697836SJohn.Forte@Sun.COM /* iSCSI Data Digest CRC error */ 1707836SJohn.Forte@Sun.COM ISCSI_STATUS_DATA_DIGEST_ERROR, 1717836SJohn.Forte@Sun.COM /* kmem_alloc failure */ 1727836SJohn.Forte@Sun.COM ISCSI_STATUS_ALLOC_FAILURE, 1737836SJohn.Forte@Sun.COM /* cmd (tran_abort/reset) failed */ 1747836SJohn.Forte@Sun.COM ISCSI_STATUS_CMD_FAILED, 1757836SJohn.Forte@Sun.COM /* iSCSI protocol error */ 1767836SJohn.Forte@Sun.COM ISCSI_STATUS_PROTOCOL_ERROR, 1777836SJohn.Forte@Sun.COM /* iSCSI protocol version mismatch */ 1787836SJohn.Forte@Sun.COM ISCSI_STATUS_VERSION_MISMATCH, 1797836SJohn.Forte@Sun.COM /* iSCSI login negotiation failed */ 1807836SJohn.Forte@Sun.COM ISCSI_STATUS_NEGO_FAIL, 1817836SJohn.Forte@Sun.COM /* iSCSI login authentication failed */ 1827836SJohn.Forte@Sun.COM ISCSI_STATUS_AUTHENTICATION_FAILED, 1837836SJohn.Forte@Sun.COM /* iSCSI login redirection failed */ 1847836SJohn.Forte@Sun.COM ISCSI_STATUS_REDIRECTION_FAILED, 1857836SJohn.Forte@Sun.COM /* iSCSI uscsi status failure */ 1867836SJohn.Forte@Sun.COM ISCSI_STATUS_USCSI_FAILED, 1877836SJohn.Forte@Sun.COM /* data received would have overflowed given buffer */ 1887836SJohn.Forte@Sun.COM ISCSI_STATUS_DATA_OVERFLOW, 1897836SJohn.Forte@Sun.COM /* session/connection needs to shutdown */ 1907836SJohn.Forte@Sun.COM ISCSI_STATUS_SHUTDOWN, 1917836SJohn.Forte@Sun.COM /* logical unit in use */ 1929162SPeter.Dunlap@Sun.COM ISCSI_STATUS_BUSY, 1939162SPeter.Dunlap@Sun.COM /* Login on connection failed, retries exceeded */ 19412001SZhang.Yi@Sun.COM ISCSI_STATUS_LOGIN_TIMED_OUT, 19512001SZhang.Yi@Sun.COM /* iSCSI login tpgt negotiation failed */ 19612001SZhang.Yi@Sun.COM ISCSI_STATUS_LOGIN_TPGT_NEGO_FAIL 1977836SJohn.Forte@Sun.COM } iscsi_status_t; 1987836SJohn.Forte@Sun.COM #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS) 1997836SJohn.Forte@Sun.COM 2007836SJohn.Forte@Sun.COM /* SNA32 check value used on increment of CmdSn values */ 2017836SJohn.Forte@Sun.COM #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */ 2027836SJohn.Forte@Sun.COM 2037836SJohn.Forte@Sun.COM /* 2047836SJohn.Forte@Sun.COM * This is the maximum number of commands that can be outstanding 2057836SJohn.Forte@Sun.COM * on a iSCSI session at anyone point in time. 2067836SJohn.Forte@Sun.COM */ 2077836SJohn.Forte@Sun.COM #define ISCSI_CMD_TABLE_SIZE 1024 2087836SJohn.Forte@Sun.COM 2097836SJohn.Forte@Sun.COM /* Used on connections thread create of receiver thread */ 2107836SJohn.Forte@Sun.COM extern pri_t minclsyspri; 2117836SJohn.Forte@Sun.COM 2127836SJohn.Forte@Sun.COM /* 2137836SJohn.Forte@Sun.COM * Callers of iscsid_config_one/all must hold this 2147836SJohn.Forte@Sun.COM * semaphore across the calls. Otherwise a ndi_devi_enter() 2157836SJohn.Forte@Sun.COM * deadlock in the DDI layer may occur. 2167836SJohn.Forte@Sun.COM */ 2177836SJohn.Forte@Sun.COM extern ksema_t iscsid_config_semaphore; 2187836SJohn.Forte@Sun.COM 2197836SJohn.Forte@Sun.COM extern kmutex_t iscsi_oid_mutex; 2207836SJohn.Forte@Sun.COM extern uint32_t iscsi_oid; 2217836SJohn.Forte@Sun.COM extern void *iscsi_state; 2227836SJohn.Forte@Sun.COM 2237836SJohn.Forte@Sun.COM /* 2247836SJohn.Forte@Sun.COM * NOP delay is used to send a iSCSI NOP (ie. ping) across the 2257836SJohn.Forte@Sun.COM * wire to see if the target is still alive. NOPs are only 2267836SJohn.Forte@Sun.COM * sent when the RX thread hasn't received anything for the 2277836SJohn.Forte@Sun.COM * below amount of time. 2287836SJohn.Forte@Sun.COM */ 2297836SJohn.Forte@Sun.COM #define ISCSI_DEFAULT_NOP_DELAY 5 /* seconds */ 2307836SJohn.Forte@Sun.COM extern int iscsi_nop_delay; 2317836SJohn.Forte@Sun.COM /* 2327836SJohn.Forte@Sun.COM * If we haven't received anything in a specified period of time 2337836SJohn.Forte@Sun.COM * we will stop accepting IO via tran start. This will enable 2347836SJohn.Forte@Sun.COM * upper level drivers to see we might be having a problem and 2357836SJohn.Forte@Sun.COM * in the case of scsi_vhci will start to route IO down a better 2367836SJohn.Forte@Sun.COM * path. 2377836SJohn.Forte@Sun.COM */ 2387836SJohn.Forte@Sun.COM #define ISCSI_DEFAULT_RX_WINDOW 20 /* seconds */ 2397836SJohn.Forte@Sun.COM extern int iscsi_rx_window; 2407836SJohn.Forte@Sun.COM /* 2417836SJohn.Forte@Sun.COM * If we haven't received anything in a specified period of time 2427836SJohn.Forte@Sun.COM * we will stop accepting IO via tran start. This the max limit 2437836SJohn.Forte@Sun.COM * when encountered we will start returning a fatal error. 2447836SJohn.Forte@Sun.COM */ 2457836SJohn.Forte@Sun.COM #define ISCSI_DEFAULT_RX_MAX_WINDOW 180 /* seconds */ 2467836SJohn.Forte@Sun.COM extern int iscsi_rx_max_window; 2477836SJohn.Forte@Sun.COM 2487836SJohn.Forte@Sun.COM /* 2498194SJack.Meng@Sun.COM * During iscsi boot, if the boot session has been created, the 2508194SJack.Meng@Sun.COM * initiator hasn't changed the boot lun to be online, we will wait 2518194SJack.Meng@Sun.COM * 180s here for lun online by default. 2528194SJack.Meng@Sun.COM */ 2538194SJack.Meng@Sun.COM #define ISCSI_BOOT_DEFAULT_MAX_DELAY 180 /* seconds */ 2548194SJack.Meng@Sun.COM /* 2557836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+ 2567836SJohn.Forte@Sun.COM * | iSCSI Driver Structures | 2577836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+ 2587836SJohn.Forte@Sun.COM */ 2597836SJohn.Forte@Sun.COM 2607836SJohn.Forte@Sun.COM /* 2617836SJohn.Forte@Sun.COM * iSCSI Auth Information 2627836SJohn.Forte@Sun.COM */ 2637836SJohn.Forte@Sun.COM typedef struct iscsi_auth { 2647836SJohn.Forte@Sun.COM IscsiAuthStringBlock auth_recv_string_block; 2657836SJohn.Forte@Sun.COM IscsiAuthStringBlock auth_send_string_block; 2667836SJohn.Forte@Sun.COM IscsiAuthLargeBinary auth_recv_binary_block; 2677836SJohn.Forte@Sun.COM IscsiAuthLargeBinary auth_send_binary_block; 2687836SJohn.Forte@Sun.COM IscsiAuthClient auth_client_block; 2697836SJohn.Forte@Sun.COM int num_auth_buffers; 2707836SJohn.Forte@Sun.COM IscsiAuthBufferDesc auth_buffers[5]; 2717836SJohn.Forte@Sun.COM 2727836SJohn.Forte@Sun.COM /* 2737836SJohn.Forte@Sun.COM * To indicate if bi-directional authentication is enabled. 2747836SJohn.Forte@Sun.COM * 0 means uni-directional authentication. 2757836SJohn.Forte@Sun.COM * 1 means bi-directional authentication. 2767836SJohn.Forte@Sun.COM */ 2777836SJohn.Forte@Sun.COM int bidirectional_auth; 2787836SJohn.Forte@Sun.COM 2797836SJohn.Forte@Sun.COM /* Initiator's authentication information. */ 2807836SJohn.Forte@Sun.COM char username[iscsiAuthStringMaxLength]; 2817836SJohn.Forte@Sun.COM uint8_t password[iscsiAuthStringMaxLength]; 2827836SJohn.Forte@Sun.COM int password_length; 2837836SJohn.Forte@Sun.COM 2847836SJohn.Forte@Sun.COM /* Target's authentication information. */ 2857836SJohn.Forte@Sun.COM char username_in[iscsiAuthStringMaxLength]; 2867836SJohn.Forte@Sun.COM uint8_t password_in[iscsiAuthStringMaxLength]; 2877836SJohn.Forte@Sun.COM int password_length_in; 2887836SJohn.Forte@Sun.COM } iscsi_auth_t; 2897836SJohn.Forte@Sun.COM 2907836SJohn.Forte@Sun.COM /* 2917836SJohn.Forte@Sun.COM * iSCSI Task 2927836SJohn.Forte@Sun.COM */ 2937836SJohn.Forte@Sun.COM typedef struct iscsi_task { 2947836SJohn.Forte@Sun.COM void *t_arg; 2957836SJohn.Forte@Sun.COM boolean_t t_blocking; 296*12161SJack.Meng@Sun.COM uint32_t t_event_count; 2977836SJohn.Forte@Sun.COM } iscsi_task_t; 2987836SJohn.Forte@Sun.COM 2997836SJohn.Forte@Sun.COM /* 3007836SJohn.Forte@Sun.COM * These are all the iscsi_cmd types that we use to track our 3017836SJohn.Forte@Sun.COM * commands between queues and actions. 3027836SJohn.Forte@Sun.COM */ 3037836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_type { 3047836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_SCSI = 1, /* scsi cmd */ 3057836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_NOP, /* nop / ping */ 3067836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_ABORT, /* abort */ 3077836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_RESET, /* reset */ 3087836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_LOGOUT, /* logout */ 3097836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_LOGIN, /* login */ 3107836SJohn.Forte@Sun.COM ISCSI_CMD_TYPE_TEXT /* text */ 3117836SJohn.Forte@Sun.COM } iscsi_cmd_type_t; 3127836SJohn.Forte@Sun.COM 3137836SJohn.Forte@Sun.COM /* 3147836SJohn.Forte@Sun.COM * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram) 3157836SJohn.Forte@Sun.COM */ 3167836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_state { 3179162SPeter.Dunlap@Sun.COM ISCSI_CMD_STATE_FREE = 0, 3187836SJohn.Forte@Sun.COM ISCSI_CMD_STATE_PENDING, 3197836SJohn.Forte@Sun.COM ISCSI_CMD_STATE_ACTIVE, 3207836SJohn.Forte@Sun.COM ISCSI_CMD_STATE_ABORTING, 3219162SPeter.Dunlap@Sun.COM ISCSI_CMD_STATE_IDM_ABORTING, 3229162SPeter.Dunlap@Sun.COM ISCSI_CMD_STATE_COMPLETED, 3239162SPeter.Dunlap@Sun.COM ISCSI_CMD_STATE_MAX 3247836SJohn.Forte@Sun.COM } iscsi_cmd_state_t; 3257836SJohn.Forte@Sun.COM 3269162SPeter.Dunlap@Sun.COM #ifdef ISCSI_CMD_SM_STRINGS 3279162SPeter.Dunlap@Sun.COM static const char *iscsi_cmd_state_names[ISCSI_CMD_STATE_MAX+1] = { 3289162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_FREE", 3299162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_PENDING", 3309162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_ACTIVE", 3319162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_ABORTING", 3329162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_IDM_ABORTING", 3339162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_COMPLETED", 3349162SPeter.Dunlap@Sun.COM "ISCSI_CMD_STATE_MAX" 3359162SPeter.Dunlap@Sun.COM }; 3369162SPeter.Dunlap@Sun.COM #endif 3379162SPeter.Dunlap@Sun.COM 3387836SJohn.Forte@Sun.COM /* 3397836SJohn.Forte@Sun.COM * iscsi command events 3407836SJohn.Forte@Sun.COM */ 3417836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_event { 3429162SPeter.Dunlap@Sun.COM ISCSI_CMD_EVENT_E1 = 0, 3437836SJohn.Forte@Sun.COM ISCSI_CMD_EVENT_E2, 3447836SJohn.Forte@Sun.COM ISCSI_CMD_EVENT_E3, 3457836SJohn.Forte@Sun.COM ISCSI_CMD_EVENT_E4, 3467836SJohn.Forte@Sun.COM ISCSI_CMD_EVENT_E6, 3477836SJohn.Forte@Sun.COM ISCSI_CMD_EVENT_E7, 3489162SPeter.Dunlap@Sun.COM ISCSI_CMD_EVENT_E8, 3499162SPeter.Dunlap@Sun.COM ISCSI_CMD_EVENT_E9, 3509162SPeter.Dunlap@Sun.COM ISCSI_CMD_EVENT_E10, 3519162SPeter.Dunlap@Sun.COM ISCSI_CMD_EVENT_MAX 3527836SJohn.Forte@Sun.COM } iscsi_cmd_event_t; 3537836SJohn.Forte@Sun.COM 3549162SPeter.Dunlap@Sun.COM #ifdef ISCSI_CMD_SM_STRINGS 3559162SPeter.Dunlap@Sun.COM static const char *iscsi_cmd_event_names[ISCSI_CMD_EVENT_MAX+1] = { 3569162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E1", 3579162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E2", 3589162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E3", 3599162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E4", 3609162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E6", 3619162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E7", 3629162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E8", 3639162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E9", 3649162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_E10", 3659162SPeter.Dunlap@Sun.COM "ISCSI_CMD_EVENT_MAX" 3669162SPeter.Dunlap@Sun.COM }; 3679162SPeter.Dunlap@Sun.COM #endif 3689162SPeter.Dunlap@Sun.COM 3697836SJohn.Forte@Sun.COM /* 3707836SJohn.Forte@Sun.COM * iscsi text command stages - these stages are used by iSCSI text 3717836SJohn.Forte@Sun.COM * processing to manage long resonses. 3727836SJohn.Forte@Sun.COM */ 3737836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_text_stage { 3749162SPeter.Dunlap@Sun.COM ISCSI_CMD_TEXT_INITIAL_REQ = 0, 3757836SJohn.Forte@Sun.COM ISCSI_CMD_TEXT_CONTINUATION, 3767836SJohn.Forte@Sun.COM ISCSI_CMD_TEXT_FINAL_RSP 3777836SJohn.Forte@Sun.COM } iscsi_cmd_text_stage_t; 3787836SJohn.Forte@Sun.COM 3797836SJohn.Forte@Sun.COM /* 3808231SJack.Meng@Sun.COM * iscsi cmd misc flags - bitwise applicable 3818231SJack.Meng@Sun.COM */ 3828231SJack.Meng@Sun.COM #define ISCSI_CMD_MISCFLAG_INTERNAL 0x1 3838231SJack.Meng@Sun.COM #define ISCSI_CMD_MISCFLAG_FREE 0x2 3848231SJack.Meng@Sun.COM #define ISCSI_CMD_MISCFLAG_STUCK 0x4 3858294SShengliang.Zhang@Sun.COM #define ISCSI_CMD_MISCFLAG_XARQ 0x8 3869780SBing.Zhao@Sun.COM #define ISCSI_CMD_MISCFLAG_SENT 0x10 3879780SBing.Zhao@Sun.COM #define ISCSI_CMD_MISCFLAG_FLUSH 0x20 3889780SBing.Zhao@Sun.COM 3899780SBing.Zhao@Sun.COM /* 3909780SBing.Zhao@Sun.COM * 1/2 of a 32 bit number, used for checking CmdSN 3919780SBing.Zhao@Sun.COM * wrapped. 3929780SBing.Zhao@Sun.COM */ 3939780SBing.Zhao@Sun.COM #define ISCSI_CMD_SN_WRAP 0x80000000 3949780SBing.Zhao@Sun.COM 3959780SBing.Zhao@Sun.COM #define ISCSI_CMD_PKT_STAT_INIT 0 3968231SJack.Meng@Sun.COM 3978231SJack.Meng@Sun.COM /* 3987836SJohn.Forte@Sun.COM * iSCSI cmd/pkt Structure 3997836SJohn.Forte@Sun.COM */ 4007836SJohn.Forte@Sun.COM typedef struct iscsi_cmd { 4017836SJohn.Forte@Sun.COM uint32_t cmd_sig; 4027836SJohn.Forte@Sun.COM struct iscsi_cmd *cmd_prev; 4037836SJohn.Forte@Sun.COM struct iscsi_cmd *cmd_next; 4047836SJohn.Forte@Sun.COM struct iscsi_conn *cmd_conn; 4057836SJohn.Forte@Sun.COM 4067836SJohn.Forte@Sun.COM iscsi_cmd_type_t cmd_type; 4077836SJohn.Forte@Sun.COM iscsi_cmd_state_t cmd_state; 4087836SJohn.Forte@Sun.COM iscsi_cmd_state_t cmd_prev_state; 4097836SJohn.Forte@Sun.COM clock_t cmd_lbolt_pending; 4107836SJohn.Forte@Sun.COM clock_t cmd_lbolt_active; 4117836SJohn.Forte@Sun.COM clock_t cmd_lbolt_aborting; 4129162SPeter.Dunlap@Sun.COM clock_t cmd_lbolt_idm_aborting; 4137836SJohn.Forte@Sun.COM clock_t cmd_lbolt_timeout; 4148231SJack.Meng@Sun.COM uint8_t cmd_misc_flags; 4159162SPeter.Dunlap@Sun.COM idm_task_t *cmd_itp; 4167836SJohn.Forte@Sun.COM 4177836SJohn.Forte@Sun.COM union { 4187836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_SCSI */ 4197836SJohn.Forte@Sun.COM struct { 4209162SPeter.Dunlap@Sun.COM idm_buf_t *ibp_ibuf; 4219162SPeter.Dunlap@Sun.COM idm_buf_t *ibp_obuf; 4227836SJohn.Forte@Sun.COM struct scsi_pkt *pkt; 4237836SJohn.Forte@Sun.COM struct buf *bp; 4247836SJohn.Forte@Sun.COM int cmdlen; 4257836SJohn.Forte@Sun.COM int statuslen; 4267836SJohn.Forte@Sun.COM size_t data_transferred; 4277836SJohn.Forte@Sun.COM 4287836SJohn.Forte@Sun.COM uint32_t lun; 4297836SJohn.Forte@Sun.COM 4307836SJohn.Forte@Sun.COM /* 4317836SJohn.Forte@Sun.COM * If SCSI_CMD_TYPE is in ABORTING_STATE 4327836SJohn.Forte@Sun.COM * then the abort_icmdp field will be a pointer 4337836SJohn.Forte@Sun.COM * to the abort command chasing this one. 4347836SJohn.Forte@Sun.COM */ 4357836SJohn.Forte@Sun.COM struct iscsi_cmd *abort_icmdp; 4367836SJohn.Forte@Sun.COM /* 4377836SJohn.Forte@Sun.COM * pointer to the r2t associated with this 4387836SJohn.Forte@Sun.COM * command (if any) 4397836SJohn.Forte@Sun.COM */ 4407836SJohn.Forte@Sun.COM struct iscsi_cmd *r2t_icmdp; 4418447SBing.Zhao@Sun.COM /* 4428447SBing.Zhao@Sun.COM * It will be true if this command has 4438447SBing.Zhao@Sun.COM * another R2T to handle. 4448447SBing.Zhao@Sun.COM */ 4458447SBing.Zhao@Sun.COM boolean_t r2t_more; 4469780SBing.Zhao@Sun.COM /* 4479780SBing.Zhao@Sun.COM * It is used to record pkt_statistics temporarily. 4489780SBing.Zhao@Sun.COM */ 4499780SBing.Zhao@Sun.COM uint_t pkt_stat; 4507836SJohn.Forte@Sun.COM } scsi; 4517836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_ABORT */ 4527836SJohn.Forte@Sun.COM struct { 4537836SJohn.Forte@Sun.COM /* pointer to original iscsi_cmd, for abort */ 4547836SJohn.Forte@Sun.COM struct iscsi_cmd *icmdp; 4557836SJohn.Forte@Sun.COM } abort; 4567836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_RESET */ 4577836SJohn.Forte@Sun.COM struct { 4587836SJohn.Forte@Sun.COM int level; 4599780SBing.Zhao@Sun.COM uint8_t response; 4607836SJohn.Forte@Sun.COM } reset; 4617836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_NOP */ 4627836SJohn.Forte@Sun.COM struct { 4637836SJohn.Forte@Sun.COM int rsvd; 4647836SJohn.Forte@Sun.COM } nop; 4657836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_R2T */ 4667836SJohn.Forte@Sun.COM struct { 4677836SJohn.Forte@Sun.COM struct iscsi_cmd *icmdp; 4687836SJohn.Forte@Sun.COM uint32_t offset; 4697836SJohn.Forte@Sun.COM uint32_t length; 4707836SJohn.Forte@Sun.COM } r2t; 4717836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_LOGIN */ 4727836SJohn.Forte@Sun.COM struct { 4737836SJohn.Forte@Sun.COM int rvsd; 4747836SJohn.Forte@Sun.COM } login; 4757836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_LOGOUT */ 4767836SJohn.Forte@Sun.COM struct { 4777836SJohn.Forte@Sun.COM int rsvd; 4787836SJohn.Forte@Sun.COM } logout; 4797836SJohn.Forte@Sun.COM /* ISCSI_CMD_TYPE_TEXT */ 4807836SJohn.Forte@Sun.COM struct { 4817836SJohn.Forte@Sun.COM char *buf; 4827836SJohn.Forte@Sun.COM int buf_len; 4837836SJohn.Forte@Sun.COM uint32_t offset; 4847836SJohn.Forte@Sun.COM uint32_t data_len; 4857836SJohn.Forte@Sun.COM uint32_t total_rx_len; 4867836SJohn.Forte@Sun.COM uint32_t ttt; 4877836SJohn.Forte@Sun.COM uint8_t lun[8]; 4887836SJohn.Forte@Sun.COM iscsi_cmd_text_stage_t stage; 4897836SJohn.Forte@Sun.COM } text; 4907836SJohn.Forte@Sun.COM } cmd_un; 4917836SJohn.Forte@Sun.COM 4927836SJohn.Forte@Sun.COM struct iscsi_lun *cmd_lun; /* associated lun */ 4937836SJohn.Forte@Sun.COM 4947836SJohn.Forte@Sun.COM uint32_t cmd_itt; 4957836SJohn.Forte@Sun.COM uint32_t cmd_ttt; 4967836SJohn.Forte@Sun.COM 4977836SJohn.Forte@Sun.COM /* 4987836SJohn.Forte@Sun.COM * If a data digest error is seem on a data pdu. This flag 4997836SJohn.Forte@Sun.COM * will get set. We don't abort the cmd immediately because 5007836SJohn.Forte@Sun.COM * we want to read in all the data to get it out of the 5017836SJohn.Forte@Sun.COM * stream. Once the completion for the cmd is received we 5027836SJohn.Forte@Sun.COM * we will abort the cmd and state no sense data was available. 5037836SJohn.Forte@Sun.COM */ 5047836SJohn.Forte@Sun.COM boolean_t cmd_crc_error_seen; 5057836SJohn.Forte@Sun.COM 5067836SJohn.Forte@Sun.COM /* 5077836SJohn.Forte@Sun.COM * Used to block and wake up caller until action is completed. 5087836SJohn.Forte@Sun.COM * This is for ABORT, RESET, and PASSTHRU cmds. 5097836SJohn.Forte@Sun.COM */ 5107836SJohn.Forte@Sun.COM int cmd_result; 5117836SJohn.Forte@Sun.COM int cmd_completed; 5127836SJohn.Forte@Sun.COM kmutex_t cmd_mutex; 5137836SJohn.Forte@Sun.COM kcondvar_t cmd_completion; 5147836SJohn.Forte@Sun.COM 5159162SPeter.Dunlap@Sun.COM idm_pdu_t cmd_pdu; 5169162SPeter.Dunlap@Sun.COM 5179162SPeter.Dunlap@Sun.COM sm_audit_buf_t cmd_state_audit; 5189780SBing.Zhao@Sun.COM 5199780SBing.Zhao@Sun.COM uint32_t cmd_sn; 5207836SJohn.Forte@Sun.COM } iscsi_cmd_t; 5217836SJohn.Forte@Sun.COM 5227836SJohn.Forte@Sun.COM 5237836SJohn.Forte@Sun.COM /* 5247836SJohn.Forte@Sun.COM * iSCSI LUN Structure 5257836SJohn.Forte@Sun.COM */ 5267836SJohn.Forte@Sun.COM typedef struct iscsi_lun { 5277836SJohn.Forte@Sun.COM uint32_t lun_sig; 5287836SJohn.Forte@Sun.COM int lun_state; 5297836SJohn.Forte@Sun.COM 5307836SJohn.Forte@Sun.COM struct iscsi_lun *lun_next; /* next lun on this sess. */ 5317836SJohn.Forte@Sun.COM struct iscsi_sess *lun_sess; /* parent sess. for lun */ 5327836SJohn.Forte@Sun.COM dev_info_t *lun_dip; 5337836SJohn.Forte@Sun.COM mdi_pathinfo_t *lun_pip; 5347836SJohn.Forte@Sun.COM 5357836SJohn.Forte@Sun.COM uint16_t lun_num; /* LUN */ 5367836SJohn.Forte@Sun.COM uint8_t lun_addr_type; /* LUN addressing type */ 5377836SJohn.Forte@Sun.COM uint32_t lun_oid; /* OID */ 5387836SJohn.Forte@Sun.COM char *lun_guid; /* GUID */ 5397836SJohn.Forte@Sun.COM int lun_guid_size; /* GUID allocation size */ 5407836SJohn.Forte@Sun.COM char *lun_addr; /* sess,lun */ 5417836SJohn.Forte@Sun.COM time_t lun_time_online; 5427836SJohn.Forte@Sun.COM 5437836SJohn.Forte@Sun.COM uchar_t lun_cap; /* bitmap of scsi caps */ 5447836SJohn.Forte@Sun.COM 5457836SJohn.Forte@Sun.COM uchar_t lun_vid[ISCSI_INQ_VID_BUF_LEN]; /* Vendor ID */ 5467836SJohn.Forte@Sun.COM uchar_t lun_pid[ISCSI_INQ_PID_BUF_LEN]; /* Product ID */ 5479371SBing.Zhao@Sun.COM 5489371SBing.Zhao@Sun.COM uchar_t lun_type; 5497836SJohn.Forte@Sun.COM } iscsi_lun_t; 5507836SJohn.Forte@Sun.COM 5519780SBing.Zhao@Sun.COM #define ISCSI_LUN_STATE_CLEAR 0 /* used to clear all states */ 5529780SBing.Zhao@Sun.COM #define ISCSI_LUN_STATE_OFFLINE 1 5539780SBing.Zhao@Sun.COM #define ISCSI_LUN_STATE_ONLINE 2 5549780SBing.Zhao@Sun.COM #define ISCSI_LUN_STATE_INVALID 4 /* offline failed */ 5559780SBing.Zhao@Sun.COM #define ISCSI_LUN_STATE_BUSY 8 /* logic unit is in reset */ 5567836SJohn.Forte@Sun.COM 5579780SBing.Zhao@Sun.COM #define ISCSI_LUN_CAP_RESET 0x01 5589780SBing.Zhao@Sun.COM 5599780SBing.Zhao@Sun.COM #define ISCSI_SCSI_RESET_SENSE_CODE 0x29 560*12161SJack.Meng@Sun.COM #define ISCSI_SCSI_LUNCHANGED_CODE 0x3f 561*12161SJack.Meng@Sun.COM 562*12161SJack.Meng@Sun.COM #define ISCSI_SCSI_LUNCHANGED_ASCQ 0x0e 5637836SJohn.Forte@Sun.COM 5647836SJohn.Forte@Sun.COM /* 5657836SJohn.Forte@Sun.COM * 5667836SJohn.Forte@Sun.COM * 5677836SJohn.Forte@Sun.COM */ 5687836SJohn.Forte@Sun.COM typedef struct iscsi_queue { 5697836SJohn.Forte@Sun.COM iscsi_cmd_t *head; 5707836SJohn.Forte@Sun.COM iscsi_cmd_t *tail; 5717836SJohn.Forte@Sun.COM int count; 5727836SJohn.Forte@Sun.COM kmutex_t mutex; 5737836SJohn.Forte@Sun.COM } iscsi_queue_t; 5747836SJohn.Forte@Sun.COM 5757836SJohn.Forte@Sun.COM #define ISCSI_CONN_DEFAULT_LOGIN_MIN 0 5767836SJohn.Forte@Sun.COM #define ISCSI_CONN_DEFAULT_LOGIN_REDIRECT 10 5777836SJohn.Forte@Sun.COM 57810156SZhang.Yi@Sun.COM /* iSCSI tunable Parameters */ 57910156SZhang.Yi@Sun.COM typedef struct iscsi_tunable_params { 58010156SZhang.Yi@Sun.COM int recv_login_rsp_timeout; /* range: 0 - 60*60 */ 58110156SZhang.Yi@Sun.COM int conn_login_max; /* range: 0 - 60*60 */ 58210156SZhang.Yi@Sun.COM int polling_login_delay; /* range: 0 - 60*60 */ 58310156SZhang.Yi@Sun.COM } iscsi_tunable_params_t; 58410156SZhang.Yi@Sun.COM 5857836SJohn.Forte@Sun.COM typedef union iscsi_sockaddr { 5867836SJohn.Forte@Sun.COM struct sockaddr sin; 5877836SJohn.Forte@Sun.COM struct sockaddr_in sin4; 5887836SJohn.Forte@Sun.COM struct sockaddr_in6 sin6; 5897836SJohn.Forte@Sun.COM } iscsi_sockaddr_t; 5907836SJohn.Forte@Sun.COM 5917836SJohn.Forte@Sun.COM #define SIZEOF_SOCKADDR(so) ((so)->sa_family == AF_INET ? \ 5927836SJohn.Forte@Sun.COM sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)) 5937836SJohn.Forte@Sun.COM 5949162SPeter.Dunlap@Sun.COM typedef enum { 5959162SPeter.Dunlap@Sun.COM LOGIN_START, 5969162SPeter.Dunlap@Sun.COM LOGIN_READY, 5979162SPeter.Dunlap@Sun.COM LOGIN_TX, 5989162SPeter.Dunlap@Sun.COM LOGIN_RX, 5999162SPeter.Dunlap@Sun.COM LOGIN_ERROR, 6009162SPeter.Dunlap@Sun.COM LOGIN_DONE, 6019162SPeter.Dunlap@Sun.COM LOGIN_FFP, 6029162SPeter.Dunlap@Sun.COM LOGIN_MAX 6039162SPeter.Dunlap@Sun.COM } iscsi_login_state_t; 6049162SPeter.Dunlap@Sun.COM 6059162SPeter.Dunlap@Sun.COM #ifdef ISCSI_LOGIN_STATE_NAMES 6069162SPeter.Dunlap@Sun.COM static const char *iscsi_login_state_names[LOGIN_MAX+1] = { 6079162SPeter.Dunlap@Sun.COM "LOGIN_START", 6089162SPeter.Dunlap@Sun.COM "LOGIN_READY", 6099162SPeter.Dunlap@Sun.COM "LOGIN_TX", 6109162SPeter.Dunlap@Sun.COM "LOGIN_RX", 6119162SPeter.Dunlap@Sun.COM "LOGIN_ERROR", 6129162SPeter.Dunlap@Sun.COM "LOGIN_DONE", 6139162SPeter.Dunlap@Sun.COM "LOGIN_FFP", 6149162SPeter.Dunlap@Sun.COM "LOGIN_MAX" 6159162SPeter.Dunlap@Sun.COM }; 6169162SPeter.Dunlap@Sun.COM #endif 6179162SPeter.Dunlap@Sun.COM 6189162SPeter.Dunlap@Sun.COM /* 6199162SPeter.Dunlap@Sun.COM * iscsi_conn_state 6209162SPeter.Dunlap@Sun.COM */ 6219162SPeter.Dunlap@Sun.COM typedef enum iscsi_conn_state { 6229162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_UNDEFINED = 0, 6239162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_FREE, 6249162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_IN_LOGIN, 6259162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_LOGGED_IN, 6269162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_IN_LOGOUT, 6279162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_FAILED, 6289162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_POLLING, 6299162SPeter.Dunlap@Sun.COM ISCSI_CONN_STATE_MAX 6309162SPeter.Dunlap@Sun.COM } iscsi_conn_state_t; 6319162SPeter.Dunlap@Sun.COM 6329162SPeter.Dunlap@Sun.COM #ifdef ISCSI_ICS_NAMES 6339162SPeter.Dunlap@Sun.COM static const char *iscsi_ics_name[ISCSI_CONN_STATE_MAX+1] = { 6349162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_UNDEFINED", 6359162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_FREE", 6369162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_IN_LOGIN", 6379162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_LOGGED_IN", 6389162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_IN_LOGOUT", 6399162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_FAILED", 6409162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_POLLING", 6419162SPeter.Dunlap@Sun.COM "ISCSI_CONN_STATE_MAX" 6429162SPeter.Dunlap@Sun.COM }; 6439162SPeter.Dunlap@Sun.COM #endif 6449162SPeter.Dunlap@Sun.COM 6459162SPeter.Dunlap@Sun.COM #define ISCSI_CONN_STATE_FULL_FEATURE(state) \ 6469162SPeter.Dunlap@Sun.COM ((state == ISCSI_CONN_STATE_LOGGED_IN) || \ 6479162SPeter.Dunlap@Sun.COM (state == ISCSI_CONN_STATE_IN_LOGOUT)) 6489162SPeter.Dunlap@Sun.COM 6497836SJohn.Forte@Sun.COM /* 6507836SJohn.Forte@Sun.COM * iSCSI Connection Structure 6517836SJohn.Forte@Sun.COM */ 6527836SJohn.Forte@Sun.COM typedef struct iscsi_conn { 6537836SJohn.Forte@Sun.COM uint32_t conn_sig; 6547836SJohn.Forte@Sun.COM struct iscsi_conn *conn_next; /* next conn on this sess. */ 6557836SJohn.Forte@Sun.COM struct iscsi_sess *conn_sess; /* parent sess. for conn. */ 6567836SJohn.Forte@Sun.COM 6577836SJohn.Forte@Sun.COM iscsi_conn_state_t conn_state; /* cur. conn. driver state */ 6587836SJohn.Forte@Sun.COM iscsi_conn_state_t conn_prev_state; /* prev. conn. driver state */ 6597836SJohn.Forte@Sun.COM /* protects the session state and synchronizes the state machine */ 6607836SJohn.Forte@Sun.COM kmutex_t conn_state_mutex; 6617836SJohn.Forte@Sun.COM kcondvar_t conn_state_change; 6627836SJohn.Forte@Sun.COM boolean_t conn_state_destroy; 6639162SPeter.Dunlap@Sun.COM boolean_t conn_state_ffp; 6649162SPeter.Dunlap@Sun.COM boolean_t conn_state_idm_connected; 6659162SPeter.Dunlap@Sun.COM boolean_t conn_async_logout; 6669162SPeter.Dunlap@Sun.COM ddi_taskq_t *conn_cn_taskq; 6677836SJohn.Forte@Sun.COM 6689162SPeter.Dunlap@Sun.COM idm_conn_t *conn_ic; 6697836SJohn.Forte@Sun.COM 6709162SPeter.Dunlap@Sun.COM /* base connection information, may have been redirected */ 6717836SJohn.Forte@Sun.COM iscsi_sockaddr_t conn_base_addr; 6727836SJohn.Forte@Sun.COM 6737836SJohn.Forte@Sun.COM /* current connection information, may have been redirected */ 6747836SJohn.Forte@Sun.COM iscsi_sockaddr_t conn_curr_addr; 6757836SJohn.Forte@Sun.COM 6767836SJohn.Forte@Sun.COM boolean_t conn_bound; 6777836SJohn.Forte@Sun.COM iscsi_sockaddr_t conn_bound_addr; 6787836SJohn.Forte@Sun.COM 6797836SJohn.Forte@Sun.COM uint32_t conn_cid; /* CID */ 6807836SJohn.Forte@Sun.COM uint32_t conn_oid; /* OID */ 6817836SJohn.Forte@Sun.COM 6827836SJohn.Forte@Sun.COM int conn_current_stage; /* iSCSI login stage */ 6837836SJohn.Forte@Sun.COM int conn_next_stage; /* iSCSI login stage */ 6847836SJohn.Forte@Sun.COM int conn_partial_response; 6857836SJohn.Forte@Sun.COM 6867836SJohn.Forte@Sun.COM /* 6877836SJohn.Forte@Sun.COM * The active queue contains iscsi_cmds that have already 6887836SJohn.Forte@Sun.COM * been sent on this connection. Any future responses to 6897836SJohn.Forte@Sun.COM * these cmds require alligence to this connection. If there 6907836SJohn.Forte@Sun.COM * are issues with these cmds the command may need aborted 6917836SJohn.Forte@Sun.COM * depending on the command type, and must be put back into 6927836SJohn.Forte@Sun.COM * the session's pending queue or aborted. 6937836SJohn.Forte@Sun.COM */ 6947836SJohn.Forte@Sun.COM iscsi_queue_t conn_queue_active; 6959162SPeter.Dunlap@Sun.COM iscsi_queue_t conn_queue_idm_aborting; 6967836SJohn.Forte@Sun.COM 6977836SJohn.Forte@Sun.COM /* lbolt from the last receive, used for nop processing */ 6987836SJohn.Forte@Sun.COM clock_t conn_rx_lbolt; 6997836SJohn.Forte@Sun.COM clock_t conn_nop_lbolt; 7007836SJohn.Forte@Sun.COM 7017836SJohn.Forte@Sun.COM iscsi_thread_t *conn_tx_thread; 7027836SJohn.Forte@Sun.COM 7037836SJohn.Forte@Sun.COM /* 7047836SJohn.Forte@Sun.COM * The expstatsn is the command status sn that is expected 7057836SJohn.Forte@Sun.COM * next from the target. Command status is carried on a number 7067836SJohn.Forte@Sun.COM * of iSCSI PDUs (ex. SCSI Cmd Response, SCSI Data IN with 7077836SJohn.Forte@Sun.COM * S-Bit set, ...), not all PDUs. If our expstatsn is different 7087836SJohn.Forte@Sun.COM * than the received statsn. Something got out of sync we need to 7097836SJohn.Forte@Sun.COM * recover. 7107836SJohn.Forte@Sun.COM */ 7117836SJohn.Forte@Sun.COM uint32_t conn_expstatsn; 7127836SJohn.Forte@Sun.COM uint32_t conn_laststatsn; 7137836SJohn.Forte@Sun.COM 7147836SJohn.Forte@Sun.COM /* active login parameters */ 7157836SJohn.Forte@Sun.COM iscsi_login_params_t conn_params; 7167836SJohn.Forte@Sun.COM 7177836SJohn.Forte@Sun.COM /* Statistics */ 7187836SJohn.Forte@Sun.COM struct { 7197836SJohn.Forte@Sun.COM kstat_t *ks; 7207836SJohn.Forte@Sun.COM iscsi_conn_stats_t ks_data; 7217836SJohn.Forte@Sun.COM } stats; 7227836SJohn.Forte@Sun.COM 7237836SJohn.Forte@Sun.COM /* 7249162SPeter.Dunlap@Sun.COM * These fields are used to coordinate the asynchronous IDM 7259162SPeter.Dunlap@Sun.COM * PDU operations with the synchronous login code. 7269162SPeter.Dunlap@Sun.COM */ 7279162SPeter.Dunlap@Sun.COM kmutex_t conn_login_mutex; 7289162SPeter.Dunlap@Sun.COM kcondvar_t conn_login_cv; 7299162SPeter.Dunlap@Sun.COM iscsi_login_state_t conn_login_state; 7309162SPeter.Dunlap@Sun.COM iscsi_status_t conn_login_status; 7319162SPeter.Dunlap@Sun.COM iscsi_hdr_t conn_login_resp_hdr; 7329162SPeter.Dunlap@Sun.COM char *conn_login_data; 7339162SPeter.Dunlap@Sun.COM int conn_login_datalen; 7349162SPeter.Dunlap@Sun.COM int conn_login_max_data_length; 7359162SPeter.Dunlap@Sun.COM 7369162SPeter.Dunlap@Sun.COM /* 7377836SJohn.Forte@Sun.COM * login min and max identify the amount of time 7387836SJohn.Forte@Sun.COM * in lbolt that iscsi_start_login() should attempt 7397836SJohn.Forte@Sun.COM * to log into a target portal. The login will 7407836SJohn.Forte@Sun.COM * delay until the min lbolt has been reached and 7417836SJohn.Forte@Sun.COM * will end once max time has been reached. These 7427836SJohn.Forte@Sun.COM * values are normally set to the default but can 7437836SJohn.Forte@Sun.COM * are also altered by async commands received from 7447836SJohn.Forte@Sun.COM * the targetlogin. 7457836SJohn.Forte@Sun.COM */ 7467836SJohn.Forte@Sun.COM clock_t conn_login_min; 7477836SJohn.Forte@Sun.COM clock_t conn_login_max; 7489162SPeter.Dunlap@Sun.COM sm_audit_buf_t conn_state_audit; 74910156SZhang.Yi@Sun.COM 75010156SZhang.Yi@Sun.COM /* active tunable parameters */ 75110156SZhang.Yi@Sun.COM iscsi_tunable_params_t conn_tunable_params; 75210156SZhang.Yi@Sun.COM boolean_t conn_timeout; 7537836SJohn.Forte@Sun.COM } iscsi_conn_t; 7547836SJohn.Forte@Sun.COM 7557836SJohn.Forte@Sun.COM 7567836SJohn.Forte@Sun.COM /* 7579162SPeter.Dunlap@Sun.COM * iscsi_sess_state - (reference iscsi_sess.c for state diagram) 7587836SJohn.Forte@Sun.COM */ 7597836SJohn.Forte@Sun.COM typedef enum iscsi_sess_state { 7609162SPeter.Dunlap@Sun.COM ISCSI_SESS_STATE_FREE = 0, 7617836SJohn.Forte@Sun.COM ISCSI_SESS_STATE_LOGGED_IN, 7627836SJohn.Forte@Sun.COM ISCSI_SESS_STATE_FAILED, 7637836SJohn.Forte@Sun.COM ISCSI_SESS_STATE_IN_FLUSH, 7649162SPeter.Dunlap@Sun.COM ISCSI_SESS_STATE_FLUSHED, 7659162SPeter.Dunlap@Sun.COM ISCSI_SESS_STATE_MAX 7667836SJohn.Forte@Sun.COM } iscsi_sess_state_t; 7677836SJohn.Forte@Sun.COM 7689162SPeter.Dunlap@Sun.COM #ifdef ISCSI_SESS_SM_STRINGS 7699162SPeter.Dunlap@Sun.COM static const char *iscsi_sess_state_names[ISCSI_SESS_STATE_MAX+1] = { 7709162SPeter.Dunlap@Sun.COM "ISCSI_SESS_STATE_FREE", 7719162SPeter.Dunlap@Sun.COM "ISCSI_SESS_STATE_LOGGED_IN", 7729162SPeter.Dunlap@Sun.COM "ISCSI_SESS_STATE_FAILED", 7739162SPeter.Dunlap@Sun.COM "ISCSI_SESS_STATE_IN_FLUSH", 7749162SPeter.Dunlap@Sun.COM "ISCSI_SESS_STATE_FLUSHED", 7759162SPeter.Dunlap@Sun.COM "ISCSI_SESS_STATE_MAX" 7769162SPeter.Dunlap@Sun.COM }; 7779162SPeter.Dunlap@Sun.COM #endif 7789162SPeter.Dunlap@Sun.COM 7797836SJohn.Forte@Sun.COM #define ISCSI_SESS_STATE_FULL_FEATURE(state) \ 7807836SJohn.Forte@Sun.COM ((state == ISCSI_SESS_STATE_LOGGED_IN) || \ 7817836SJohn.Forte@Sun.COM (state == ISCSI_SESS_STATE_IN_FLUSH)) 7827836SJohn.Forte@Sun.COM 7837836SJohn.Forte@Sun.COM 7847836SJohn.Forte@Sun.COM typedef enum iscsi_sess_event { 7859162SPeter.Dunlap@Sun.COM ISCSI_SESS_EVENT_N1 = 0, 7867836SJohn.Forte@Sun.COM ISCSI_SESS_EVENT_N3, 7877836SJohn.Forte@Sun.COM ISCSI_SESS_EVENT_N5, 7887836SJohn.Forte@Sun.COM ISCSI_SESS_EVENT_N6, 7899162SPeter.Dunlap@Sun.COM ISCSI_SESS_EVENT_N7, 7909162SPeter.Dunlap@Sun.COM ISCSI_SESS_EVENT_MAX 7917836SJohn.Forte@Sun.COM } iscsi_sess_event_t; 7927836SJohn.Forte@Sun.COM 7939162SPeter.Dunlap@Sun.COM #ifdef ISCSI_SESS_SM_STRINGS 7949162SPeter.Dunlap@Sun.COM static const char *iscsi_sess_event_names[ISCSI_SESS_EVENT_MAX+1] = { 7959162SPeter.Dunlap@Sun.COM "ISCSI_SESS_EVENT_N1", 7969162SPeter.Dunlap@Sun.COM "ISCSI_SESS_EVENT_N3", 7979162SPeter.Dunlap@Sun.COM "ISCSI_SESS_EVENT_N5", 7989162SPeter.Dunlap@Sun.COM "ISCSI_SESS_EVENT_N6", 7999162SPeter.Dunlap@Sun.COM "ISCSI_SESS_EVENT_N7", 8009162SPeter.Dunlap@Sun.COM "ISCSI_SESS_EVENT_MAX" 8019162SPeter.Dunlap@Sun.COM }; 8029162SPeter.Dunlap@Sun.COM #endif 8039162SPeter.Dunlap@Sun.COM 8047836SJohn.Forte@Sun.COM typedef enum iscsi_sess_type { 8059162SPeter.Dunlap@Sun.COM ISCSI_SESS_TYPE_NORMAL = 0, 8067836SJohn.Forte@Sun.COM ISCSI_SESS_TYPE_DISCOVERY 8077836SJohn.Forte@Sun.COM } iscsi_sess_type_t; 8087836SJohn.Forte@Sun.COM 8097836SJohn.Forte@Sun.COM #define SESS_ABORT_TASK_MAX_THREADS 1 8107836SJohn.Forte@Sun.COM 8117836SJohn.Forte@Sun.COM /* Sun's initiator session ID */ 8127836SJohn.Forte@Sun.COM #define ISCSI_SUN_ISID_0 0x40 /* ISID - EN format */ 8137836SJohn.Forte@Sun.COM #define ISCSI_SUN_ISID_1 0x00 /* Sec B */ 8147836SJohn.Forte@Sun.COM #define ISCSI_SUN_ISID_2 0x00 /* Sec B */ 8157836SJohn.Forte@Sun.COM #define ISCSI_SUN_ISID_3 0x2A /* Sec C - 42 = Sun's EN */ 8167836SJohn.Forte@Sun.COM /* 8177836SJohn.Forte@Sun.COM * defines 4-5 are the reserved values. These reserved values 8187836SJohn.Forte@Sun.COM * are used as the ISID for an initiator-port in MP-API and used 8197836SJohn.Forte@Sun.COM * for the send targets discovery sessions. Byte 5 is overridden 8207836SJohn.Forte@Sun.COM * for full feature sessions. The default values of byte 5 for a 8217836SJohn.Forte@Sun.COM * full feature session is 0. When MS/T is enabled with more than 8227836SJohn.Forte@Sun.COM * one session this byte 5 will increment > 0 up to 8237836SJohn.Forte@Sun.COM * ISCSI_MAX_CONFIG_SESSIONS. 8247836SJohn.Forte@Sun.COM */ 8257836SJohn.Forte@Sun.COM #define ISCSI_SUN_ISID_4 0x00 8267836SJohn.Forte@Sun.COM #define ISCSI_SUN_ISID_5 0xFF 8277836SJohn.Forte@Sun.COM 8287836SJohn.Forte@Sun.COM #define ISCSI_DEFAULT_SESS_BOUND B_FALSE 8297836SJohn.Forte@Sun.COM #define ISCSI_DEFAULT_SESS_NUM 1 8307836SJohn.Forte@Sun.COM 831*12161SJack.Meng@Sun.COM typedef enum iscsi_enum_status { 832*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_FREE = 0, 833*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_INPROG, 834*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_DONE 835*12161SJack.Meng@Sun.COM } iscsi_enum_status_t; 836*12161SJack.Meng@Sun.COM 837*12161SJack.Meng@Sun.COM typedef enum iscsi_enum_result { 838*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_COMPLETE = 0, 839*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_PARTIAL, 840*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_IOFAIL, 841*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_SUBMITTED, 842*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_SUBFAIL, 843*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_GONE, 844*12161SJack.Meng@Sun.COM ISCSI_SESS_ENUM_TUR_FAIL 845*12161SJack.Meng@Sun.COM } iscsi_enum_result_t; 846*12161SJack.Meng@Sun.COM 8477836SJohn.Forte@Sun.COM /* 8487836SJohn.Forte@Sun.COM * iSCSI Session(Target) Structure 8497836SJohn.Forte@Sun.COM */ 8507836SJohn.Forte@Sun.COM typedef struct iscsi_sess { 8517836SJohn.Forte@Sun.COM uint32_t sess_sig; 8527836SJohn.Forte@Sun.COM 8537836SJohn.Forte@Sun.COM iscsi_sess_state_t sess_state; 8547836SJohn.Forte@Sun.COM iscsi_sess_state_t sess_prev_state; 8557836SJohn.Forte@Sun.COM clock_t sess_state_lbolt; 8567836SJohn.Forte@Sun.COM /* protects the session state and synchronizes the state machine */ 857*12161SJack.Meng@Sun.COM krwlock_t sess_state_rwlock; 8587836SJohn.Forte@Sun.COM 8597836SJohn.Forte@Sun.COM /* 8607836SJohn.Forte@Sun.COM * Associated target OID. 8617836SJohn.Forte@Sun.COM */ 8627836SJohn.Forte@Sun.COM uint32_t sess_target_oid; 8637836SJohn.Forte@Sun.COM 8647836SJohn.Forte@Sun.COM /* 8657836SJohn.Forte@Sun.COM * Session OID. Used by IMA, interfaces and exported as 8667836SJohn.Forte@Sun.COM * TARGET_PROP which is checked by the NDI. In addition 8677836SJohn.Forte@Sun.COM * this is used in our tran_lun_init function. 8687836SJohn.Forte@Sun.COM */ 8697836SJohn.Forte@Sun.COM uint32_t sess_oid; 8707836SJohn.Forte@Sun.COM 8717836SJohn.Forte@Sun.COM struct iscsi_sess *sess_next; 8727836SJohn.Forte@Sun.COM struct iscsi_hba *sess_hba; 8737836SJohn.Forte@Sun.COM 8747836SJohn.Forte@Sun.COM /* list of all luns relating to session */ 8757836SJohn.Forte@Sun.COM struct iscsi_lun *sess_lun_list; 8767836SJohn.Forte@Sun.COM krwlock_t sess_lun_list_rwlock; 8777836SJohn.Forte@Sun.COM 8787836SJohn.Forte@Sun.COM /* list of all connections relating to session */ 8797836SJohn.Forte@Sun.COM struct iscsi_conn *sess_conn_list; 8807836SJohn.Forte@Sun.COM struct iscsi_conn *sess_conn_list_last_ptr; 8817836SJohn.Forte@Sun.COM /* pointer to active connection in session */ 8827836SJohn.Forte@Sun.COM struct iscsi_conn *sess_conn_act; 8837836SJohn.Forte@Sun.COM krwlock_t sess_conn_list_rwlock; 8847836SJohn.Forte@Sun.COM 8857836SJohn.Forte@Sun.COM /* Connection ID for next connection to be added to session */ 8867836SJohn.Forte@Sun.COM uint32_t sess_conn_next_cid; 8877836SJohn.Forte@Sun.COM 8887836SJohn.Forte@Sun.COM /* 8897836SJohn.Forte@Sun.COM * last time any connection on this session received 8907836SJohn.Forte@Sun.COM * data from the target. 8917836SJohn.Forte@Sun.COM */ 8927836SJohn.Forte@Sun.COM clock_t sess_rx_lbolt; 8937836SJohn.Forte@Sun.COM 8947836SJohn.Forte@Sun.COM clock_t sess_failure_lbolt; 8957836SJohn.Forte@Sun.COM 8967836SJohn.Forte@Sun.COM int sess_storm_delay; 8977836SJohn.Forte@Sun.COM 8987836SJohn.Forte@Sun.COM /* 8997836SJohn.Forte@Sun.COM * sess_cmdsn_mutex protects the cmdsn and itt table/values 9007836SJohn.Forte@Sun.COM * Cmdsn isn't that big of a problem yet since we only have 9017836SJohn.Forte@Sun.COM * one connection but in the future we will need to ensure 9027836SJohn.Forte@Sun.COM * this locking is working so keep the sequence numbers in 9037836SJohn.Forte@Sun.COM * sync on the wire. 9047836SJohn.Forte@Sun.COM * 9057836SJohn.Forte@Sun.COM * We also use this lock to protect the ITT table and it's 9067836SJohn.Forte@Sun.COM * values. We need to make sure someone doesn't assign 9077836SJohn.Forte@Sun.COM * a duplicate ITT value or cell to a command. Also we 9087836SJohn.Forte@Sun.COM * need to make sure when someone is looking up an ITT 9097836SJohn.Forte@Sun.COM * that the command is still in that correct queue location. 9107836SJohn.Forte@Sun.COM */ 9117836SJohn.Forte@Sun.COM kmutex_t sess_cmdsn_mutex; 9127836SJohn.Forte@Sun.COM 9137836SJohn.Forte@Sun.COM /* 9147836SJohn.Forte@Sun.COM * iSCSI command sequencing / windowing. The next 9157836SJohn.Forte@Sun.COM * command to be sent via the pending queue will 9167836SJohn.Forte@Sun.COM * get the sess_cmdsn. If the maxcmdsn is less 9177836SJohn.Forte@Sun.COM * than the next cmdsn then the iSCSI window is 9187836SJohn.Forte@Sun.COM * closed and this command cannot be sent yet. 9197836SJohn.Forte@Sun.COM * Most iscsi cmd responses from the target carry 9207836SJohn.Forte@Sun.COM * a new maxcmdsn. If this new maxcmdsn is greater 9217836SJohn.Forte@Sun.COM * than the sess_maxcmdsn we will update it's value 9227836SJohn.Forte@Sun.COM * and set a timer to fire in one tick and reprocess 9237836SJohn.Forte@Sun.COM * the pending queue. 9247836SJohn.Forte@Sun.COM * 9257836SJohn.Forte@Sun.COM * The expcmdsn. Is the value the target expects 9267836SJohn.Forte@Sun.COM * to be sent for my next cmdsn. If the expcmdsn 9277836SJohn.Forte@Sun.COM * and the cmdsn get out of sync this could denote 9287836SJohn.Forte@Sun.COM * a communication problem. 9297836SJohn.Forte@Sun.COM */ 9307836SJohn.Forte@Sun.COM uint32_t sess_cmdsn; 9317836SJohn.Forte@Sun.COM uint32_t sess_expcmdsn; 9327836SJohn.Forte@Sun.COM uint32_t sess_maxcmdsn; 9337836SJohn.Forte@Sun.COM 9347836SJohn.Forte@Sun.COM /* Next Initiator Task Tag (ITT) to use */ 9357836SJohn.Forte@Sun.COM uint32_t sess_itt; 9367836SJohn.Forte@Sun.COM /* 9377836SJohn.Forte@Sun.COM * The session iscsi_cmd table is used to a fast performance 9387836SJohn.Forte@Sun.COM * lookup of an ITT to a iscsi_cmd when we receive an iSCSI 9397836SJohn.Forte@Sun.COM * PDU from the wire. To reserve a location in the sess_cmd_table 9407836SJohn.Forte@Sun.COM * we try the sess_itt % ISCSI_CMD_TABLE_SIZE if this cmd table 9417836SJohn.Forte@Sun.COM * cell is already full. Then increament the sess_itt and 9427836SJohn.Forte@Sun.COM * try to get the cell position again, repeat until an empty 9437836SJohn.Forte@Sun.COM * cell is found. Once an empty cell is found place your 9447836SJohn.Forte@Sun.COM * scsi_cmd point into the cell to reserve the location. This 9457836SJohn.Forte@Sun.COM * selection process should be done while holding the session's 9467836SJohn.Forte@Sun.COM * mutex. 9477836SJohn.Forte@Sun.COM */ 9487836SJohn.Forte@Sun.COM struct iscsi_cmd *sess_cmd_table[ISCSI_CMD_TABLE_SIZE]; 9497836SJohn.Forte@Sun.COM int sess_cmd_table_count; 9507836SJohn.Forte@Sun.COM 9517836SJohn.Forte@Sun.COM /* 9527836SJohn.Forte@Sun.COM * The pending queue contains all iscsi_cmds that require an 9537836SJohn.Forte@Sun.COM * open MaxCmdSn window to be put on the wire and haven't 9547836SJohn.Forte@Sun.COM * been placed on the wire. Once placed on the wire they 9557836SJohn.Forte@Sun.COM * will be moved to a connections specific active queue. 9567836SJohn.Forte@Sun.COM */ 9577836SJohn.Forte@Sun.COM iscsi_queue_t sess_queue_pending; 9587836SJohn.Forte@Sun.COM 9597836SJohn.Forte@Sun.COM iscsi_error_t sess_last_err; 9607836SJohn.Forte@Sun.COM 9617836SJohn.Forte@Sun.COM iscsi_queue_t sess_queue_completion; 9627836SJohn.Forte@Sun.COM /* configured login parameters */ 9637836SJohn.Forte@Sun.COM iscsi_login_params_t sess_params; 9647836SJohn.Forte@Sun.COM 9657836SJohn.Forte@Sun.COM /* general iSCSI protocol/session info */ 9667836SJohn.Forte@Sun.COM uchar_t sess_name[ISCSI_MAX_NAME_LEN]; 9677836SJohn.Forte@Sun.COM int sess_name_length; 9687836SJohn.Forte@Sun.COM char sess_alias[ISCSI_MAX_NAME_LEN]; 9697836SJohn.Forte@Sun.COM int sess_alias_length; 9707836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t sess_discovered_by; 9717836SJohn.Forte@Sun.COM iscsi_sockaddr_t sess_discovered_addr; 9727836SJohn.Forte@Sun.COM uchar_t sess_isid[ISCSI_ISID_LEN]; /* Session ID */ 9737836SJohn.Forte@Sun.COM uint16_t sess_tsid; /* Target ID */ 9747836SJohn.Forte@Sun.COM /* 9757836SJohn.Forte@Sun.COM * If the target portal group tag(TPGT) is equal to ISCSI_DEFAULT_TPGT 9767836SJohn.Forte@Sun.COM * then the initiator will accept a successful login with any TPGT 9777836SJohn.Forte@Sun.COM * specified by the target. If a none default TPGT is configured 9787836SJohn.Forte@Sun.COM * then we will only successfully accept a login with that matching 9797836SJohn.Forte@Sun.COM * TPGT value. 9807836SJohn.Forte@Sun.COM */ 9817836SJohn.Forte@Sun.COM int sess_tpgt_conf; 9827836SJohn.Forte@Sun.COM /* This field records the negotiated TPGT value, preserved for dtrace */ 9837836SJohn.Forte@Sun.COM int sess_tpgt_nego; 9847836SJohn.Forte@Sun.COM 9857836SJohn.Forte@Sun.COM /* 9867836SJohn.Forte@Sun.COM * Authentication information. 9877836SJohn.Forte@Sun.COM * 9887836SJohn.Forte@Sun.COM * DCW: Again IMA seems to take a session view at this 9897836SJohn.Forte@Sun.COM * information. 9907836SJohn.Forte@Sun.COM */ 9917836SJohn.Forte@Sun.COM iscsi_auth_t sess_auth; 9927836SJohn.Forte@Sun.COM 9937836SJohn.Forte@Sun.COM /* Statistics */ 9947836SJohn.Forte@Sun.COM struct { 9957836SJohn.Forte@Sun.COM kstat_t *ks; 9967836SJohn.Forte@Sun.COM iscsi_sess_stats_t ks_data; 9977836SJohn.Forte@Sun.COM kstat_t *ks_io; 9987836SJohn.Forte@Sun.COM kstat_io_t ks_io_data; 9997836SJohn.Forte@Sun.COM kmutex_t ks_io_lock; 10007836SJohn.Forte@Sun.COM } stats; 10017836SJohn.Forte@Sun.COM 10027836SJohn.Forte@Sun.COM iscsi_thread_t *sess_ic_thread; 10037836SJohn.Forte@Sun.COM boolean_t sess_window_open; 10048194SJack.Meng@Sun.COM boolean_t sess_boot; 10057836SJohn.Forte@Sun.COM iscsi_sess_type_t sess_type; 10067836SJohn.Forte@Sun.COM 1007*12161SJack.Meng@Sun.COM ddi_taskq_t *sess_login_taskq; 10087836SJohn.Forte@Sun.COM 10097836SJohn.Forte@Sun.COM iscsi_thread_t *sess_wd_thread; 10107836SJohn.Forte@Sun.COM 10119162SPeter.Dunlap@Sun.COM sm_audit_buf_t sess_state_audit; 10129780SBing.Zhao@Sun.COM 10139780SBing.Zhao@Sun.COM kmutex_t sess_reset_mutex; 10149780SBing.Zhao@Sun.COM 10159780SBing.Zhao@Sun.COM boolean_t sess_reset_in_progress; 101611424SJack.Meng@Sun.COM 101711424SJack.Meng@Sun.COM boolean_t sess_boot_nic_reset; 1018*12161SJack.Meng@Sun.COM kmutex_t sess_enum_lock; 1019*12161SJack.Meng@Sun.COM kcondvar_t sess_enum_cv; 1020*12161SJack.Meng@Sun.COM iscsi_enum_status_t sess_enum_status; 1021*12161SJack.Meng@Sun.COM iscsi_enum_result_t sess_enum_result; 1022*12161SJack.Meng@Sun.COM uint32_t sess_enum_result_count; 1023*12161SJack.Meng@Sun.COM ddi_taskq_t *sess_enum_taskq; 1024*12161SJack.Meng@Sun.COM 1025*12161SJack.Meng@Sun.COM kmutex_t sess_state_wmutex; 1026*12161SJack.Meng@Sun.COM kcondvar_t sess_state_wcv; 1027*12161SJack.Meng@Sun.COM boolean_t sess_state_hasw; 1028*12161SJack.Meng@Sun.COM 1029*12161SJack.Meng@Sun.COM /* to accelerate the state change in case of new event */ 1030*12161SJack.Meng@Sun.COM volatile uint32_t sess_state_event_count; 10317836SJohn.Forte@Sun.COM } iscsi_sess_t; 10327836SJohn.Forte@Sun.COM 10338488SBing.Zhao@Sun.COM /* 10348488SBing.Zhao@Sun.COM * This structure will be used to store sessions to be online 10358488SBing.Zhao@Sun.COM * during normal login operation. 10368488SBing.Zhao@Sun.COM */ 10378488SBing.Zhao@Sun.COM typedef struct iscsi_sess_list { 10388488SBing.Zhao@Sun.COM iscsi_sess_t *session; 10398488SBing.Zhao@Sun.COM struct iscsi_sess_list *next; 10408488SBing.Zhao@Sun.COM } iscsi_sess_list_t; 10417836SJohn.Forte@Sun.COM 10427836SJohn.Forte@Sun.COM /* 10439162SPeter.Dunlap@Sun.COM * iSCSI client notify task context for deferred IDM notifications processing 10449162SPeter.Dunlap@Sun.COM */ 10459162SPeter.Dunlap@Sun.COM typedef struct iscsi_cn_task { 10469162SPeter.Dunlap@Sun.COM idm_conn_t *ct_ic; 10479162SPeter.Dunlap@Sun.COM idm_client_notify_t ct_icn; 10489162SPeter.Dunlap@Sun.COM uintptr_t ct_data; 10499162SPeter.Dunlap@Sun.COM } iscsi_cn_task_t; 10509162SPeter.Dunlap@Sun.COM 10519162SPeter.Dunlap@Sun.COM /* 10527836SJohn.Forte@Sun.COM * iscsi_network 10537836SJohn.Forte@Sun.COM */ 10547836SJohn.Forte@Sun.COM typedef struct iscsi_network { 10557836SJohn.Forte@Sun.COM void* (*socket)(int domain, int, int); 10567836SJohn.Forte@Sun.COM int (*bind)(void *, struct sockaddr *, int, int, int); 10577836SJohn.Forte@Sun.COM int (*connect)(void *, struct sockaddr *, int, int, int); 10587836SJohn.Forte@Sun.COM int (*listen)(void *, int); 10597836SJohn.Forte@Sun.COM void* (*accept)(void *, struct sockaddr *, int *); 10608348SEric.Yu@Sun.COM int (*getsockname)(void *, struct sockaddr *, socklen_t *); 10617836SJohn.Forte@Sun.COM int (*getsockopt)(void *, int, int, void *, int *, int); 10627836SJohn.Forte@Sun.COM int (*setsockopt)(void *, int, int, void *, int); 10637836SJohn.Forte@Sun.COM int (*shutdown)(void *, int); 10647836SJohn.Forte@Sun.COM void (*close)(void *); 10657836SJohn.Forte@Sun.COM 10667836SJohn.Forte@Sun.COM size_t (*poll)(void *, clock_t); 10677836SJohn.Forte@Sun.COM size_t (*sendmsg)(void *, struct msghdr *); 10687836SJohn.Forte@Sun.COM size_t (*recvmsg)(void *, struct msghdr *, int); 10697836SJohn.Forte@Sun.COM 10707836SJohn.Forte@Sun.COM iscsi_status_t (*sendpdu)(void *, iscsi_hdr_t *, char *, int); 10717836SJohn.Forte@Sun.COM iscsi_status_t (*recvdata)(void *, iscsi_hdr_t *, char *, 10727836SJohn.Forte@Sun.COM int, int, int); 10737836SJohn.Forte@Sun.COM iscsi_status_t (*recvhdr)(void *, iscsi_hdr_t *, int, int, int); 10747836SJohn.Forte@Sun.COM 10757836SJohn.Forte@Sun.COM struct { 10767836SJohn.Forte@Sun.COM int sndbuf; 10777836SJohn.Forte@Sun.COM int rcvbuf; 10787836SJohn.Forte@Sun.COM int nodelay; 10797836SJohn.Forte@Sun.COM int conn_notify_threshold; 10807836SJohn.Forte@Sun.COM int conn_abort_threshold; 10817836SJohn.Forte@Sun.COM int abort_threshold; 10827836SJohn.Forte@Sun.COM } tweaks; 10837836SJohn.Forte@Sun.COM } iscsi_network_t; 10847836SJohn.Forte@Sun.COM 10857836SJohn.Forte@Sun.COM #define ISCSI_NET_HEADER_DIGEST 0x00000001 10867836SJohn.Forte@Sun.COM #define ISCSI_NET_DATA_DIGEST 0x00000002 10877836SJohn.Forte@Sun.COM 10887836SJohn.Forte@Sun.COM extern iscsi_network_t *iscsi_net; 10897836SJohn.Forte@Sun.COM 10907836SJohn.Forte@Sun.COM /* 10917836SJohn.Forte@Sun.COM * If we get bus_config requests in less than 5 seconds 10927836SJohn.Forte@Sun.COM * apart skip the name services re-discovery and just 10937836SJohn.Forte@Sun.COM * complete the requested logins. This protects against 10947836SJohn.Forte@Sun.COM * bus_config storms from stale /dev links. 10957836SJohn.Forte@Sun.COM */ 10967836SJohn.Forte@Sun.COM #define ISCSI_CONFIG_STORM_DELAY_DEFAULT 5 10977836SJohn.Forte@Sun.COM 10987836SJohn.Forte@Sun.COM /* 10997836SJohn.Forte@Sun.COM * iSCSI HBA Structure 11007836SJohn.Forte@Sun.COM */ 11017836SJohn.Forte@Sun.COM typedef struct iscsi_hba { 11027836SJohn.Forte@Sun.COM uint32_t hba_sig; 11037836SJohn.Forte@Sun.COM dev_info_t *hba_dip; /* dev info ptr */ 11047836SJohn.Forte@Sun.COM scsi_hba_tran_t *hba_tran; /* scsi tran ptr */ 11059162SPeter.Dunlap@Sun.COM ldi_ident_t hba_li; 11067836SJohn.Forte@Sun.COM 11077836SJohn.Forte@Sun.COM struct iscsi_sess *hba_sess_list; /* sess. list for hba */ 11087836SJohn.Forte@Sun.COM krwlock_t hba_sess_list_rwlock; /* protect sess. list */ 11097836SJohn.Forte@Sun.COM 11107836SJohn.Forte@Sun.COM /* lbolt of the last time we received a config request */ 11117836SJohn.Forte@Sun.COM clock_t hba_config_lbolt; 11127836SJohn.Forte@Sun.COM /* current number of seconds to protect against bus config storms */ 11137836SJohn.Forte@Sun.COM int hba_config_storm_delay; 11147836SJohn.Forte@Sun.COM 11157836SJohn.Forte@Sun.COM /* general iSCSI protocol hba/initiator info */ 11167836SJohn.Forte@Sun.COM uchar_t hba_name[ISCSI_MAX_NAME_LEN]; 11177836SJohn.Forte@Sun.COM int hba_name_length; 11187836SJohn.Forte@Sun.COM uchar_t hba_alias[ISCSI_MAX_NAME_LEN]; 11197836SJohn.Forte@Sun.COM int hba_alias_length; 11207836SJohn.Forte@Sun.COM 11217836SJohn.Forte@Sun.COM /* Default SessionID for HBA */ 11227836SJohn.Forte@Sun.COM uchar_t hba_isid[ISCSI_ISID_LEN]; 11237836SJohn.Forte@Sun.COM 11247836SJohn.Forte@Sun.COM /* Default HBA wide settings */ 11257836SJohn.Forte@Sun.COM iscsi_login_params_t hba_params; 11267836SJohn.Forte@Sun.COM 11277836SJohn.Forte@Sun.COM /* 11287836SJohn.Forte@Sun.COM * There's only one HBA and it's set to ISCSI_INITIATOR_OID 11297836SJohn.Forte@Sun.COM * (value of 1) at the beginning of time. 11307836SJohn.Forte@Sun.COM */ 11317836SJohn.Forte@Sun.COM uint32_t hba_oid; 11327836SJohn.Forte@Sun.COM 11337836SJohn.Forte@Sun.COM /* 11347836SJohn.Forte@Sun.COM * Keep track of which events have been sent. User daemons request 11357836SJohn.Forte@Sun.COM * this information so they don't wait for events which they won't 11367836SJohn.Forte@Sun.COM * see. 11377836SJohn.Forte@Sun.COM */ 11387836SJohn.Forte@Sun.COM kmutex_t hba_discovery_events_mutex; 11397836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t hba_discovery_events; 11407836SJohn.Forte@Sun.COM boolean_t hba_discovery_in_progress; 11417836SJohn.Forte@Sun.COM 11427836SJohn.Forte@Sun.COM boolean_t hba_mpxio_enabled; /* mpxio-enabled */ 11439201SJack.Meng@Sun.COM /* if the persistent store is loaded */ 11449201SJack.Meng@Sun.COM boolean_t hba_persistent_loaded; 11457836SJohn.Forte@Sun.COM 11467836SJohn.Forte@Sun.COM /* 11477836SJohn.Forte@Sun.COM * Ensures only one SendTargets operation occurs at a time 11487836SJohn.Forte@Sun.COM */ 11497836SJohn.Forte@Sun.COM ksema_t hba_sendtgts_semaphore; 11507836SJohn.Forte@Sun.COM 11517836SJohn.Forte@Sun.COM /* 11527836SJohn.Forte@Sun.COM * Statistics 11537836SJohn.Forte@Sun.COM */ 11547836SJohn.Forte@Sun.COM struct { 11557836SJohn.Forte@Sun.COM kstat_t *ks; 11567836SJohn.Forte@Sun.COM iscsi_hba_stats_t ks_data; 11577836SJohn.Forte@Sun.COM } stats; 11589201SJack.Meng@Sun.COM 11599201SJack.Meng@Sun.COM /* 11609201SJack.Meng@Sun.COM * track/control the service status and client 11619201SJack.Meng@Sun.COM * 11629201SJack.Meng@Sun.COM * service- service online ensures the operational of cli 11639201SJack.Meng@Sun.COM * - and the availability of iSCSI discovery/devices 11649201SJack.Meng@Sun.COM * - so obviously offline means the unusable of cli 11659201SJack.Meng@Sun.COM * - , disabling of all discovery methods and to offline 11669201SJack.Meng@Sun.COM * - all discovered devices 11679201SJack.Meng@Sun.COM * 11689201SJack.Meng@Sun.COM * client - here the client actually means 'exclusive client' 11699201SJack.Meng@Sun.COM * - for operations these clients take may conflict 11709201SJack.Meng@Sun.COM * - with the changing of service status and therefore 11719201SJack.Meng@Sun.COM * - need to be exclusive 11729201SJack.Meng@Sun.COM * 11739201SJack.Meng@Sun.COM * The service has three status: 11749201SJack.Meng@Sun.COM * ISCSI_SERVICE_ENABLED - client is permitted to 11759201SJack.Meng@Sun.COM * - request service 11769201SJack.Meng@Sun.COM * 11779201SJack.Meng@Sun.COM * ISCSI_SERVICE_DISABLED - client is not permitted to 11789201SJack.Meng@Sun.COM * - request service 11799201SJack.Meng@Sun.COM * 11809201SJack.Meng@Sun.COM * ISCSI_SERVICE_TRANSITION - client must wait for 11819201SJack.Meng@Sun.COM * - one of above two statuses 11829201SJack.Meng@Sun.COM * 11839201SJack.Meng@Sun.COM * The hba_service_client_count tracks the number of 11849201SJack.Meng@Sun.COM * current clients, it increases with new clients and decreases 11859201SJack.Meng@Sun.COM * with leaving clients. It stops to increase once the 11869201SJack.Meng@Sun.COM * ISCSI_SERVICE_TRANSITION is set, and causes later clients be 11879201SJack.Meng@Sun.COM * blocked there. 11889201SJack.Meng@Sun.COM * 11899201SJack.Meng@Sun.COM * The status of the service can only be changed when the number 11909201SJack.Meng@Sun.COM * of current clients reaches zero. 11919201SJack.Meng@Sun.COM * 11929201SJack.Meng@Sun.COM * Clients include: 11939201SJack.Meng@Sun.COM * iscsi_ioctl 11949201SJack.Meng@Sun.COM * iscsi_tran_bus_config 11959201SJack.Meng@Sun.COM * iscsi_tran_bus_unconfig 11969201SJack.Meng@Sun.COM * isns_scn_callback 11979201SJack.Meng@Sun.COM */ 11989201SJack.Meng@Sun.COM kmutex_t hba_service_lock; 11999201SJack.Meng@Sun.COM kcondvar_t hba_service_cv; 12009201SJack.Meng@Sun.COM uint32_t hba_service_status; 12019201SJack.Meng@Sun.COM uint32_t hba_service_client_count; 120210156SZhang.Yi@Sun.COM 120310156SZhang.Yi@Sun.COM /* Default HBA tunable settings */ 120410156SZhang.Yi@Sun.COM iscsi_tunable_params_t hba_tunable_params; 120510185SJack.Meng@Sun.COM boolean_t hba_service_status_overwrite; 12067836SJohn.Forte@Sun.COM } iscsi_hba_t; 12077836SJohn.Forte@Sun.COM 12087836SJohn.Forte@Sun.COM /* 12097836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+ 12107836SJohn.Forte@Sun.COM * | iSCSI prototypes | 12117836SJohn.Forte@Sun.COM * +--------------------------------------------------------------------+ 12127836SJohn.Forte@Sun.COM */ 12137836SJohn.Forte@Sun.COM 12149162SPeter.Dunlap@Sun.COM /* IDM client callback entry points */ 12159162SPeter.Dunlap@Sun.COM idm_rx_pdu_cb_t iscsi_rx_scsi_rsp; 12169162SPeter.Dunlap@Sun.COM idm_rx_pdu_cb_t iscsi_rx_misc_pdu; 12179162SPeter.Dunlap@Sun.COM idm_rx_pdu_error_cb_t iscsi_rx_error_pdu; 12189162SPeter.Dunlap@Sun.COM idm_build_hdr_cb_t iscsi_build_hdr; 12199162SPeter.Dunlap@Sun.COM idm_task_cb_t iscsi_task_aborted; 12209162SPeter.Dunlap@Sun.COM idm_client_notify_cb_t iscsi_client_notify; 12219162SPeter.Dunlap@Sun.COM 12227836SJohn.Forte@Sun.COM /* iscsi_io.c */ 12237836SJohn.Forte@Sun.COM int iscsi_sna_lte(uint32_t n1, uint32_t n2); 12247836SJohn.Forte@Sun.COM char *iscsi_get_next_text(char *data, int data_length, char *curr_text); 12257836SJohn.Forte@Sun.COM 12267836SJohn.Forte@Sun.COM void iscsi_ic_thread(iscsi_thread_t *thread, void *arg); 12277836SJohn.Forte@Sun.COM void iscsi_tx_thread(iscsi_thread_t *thread, void *arg); 12287836SJohn.Forte@Sun.COM void iscsi_wd_thread(iscsi_thread_t *thread, void *arg); 12297836SJohn.Forte@Sun.COM 12307836SJohn.Forte@Sun.COM iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 12317836SJohn.Forte@Sun.COM 12329162SPeter.Dunlap@Sun.COM void iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp); 12339162SPeter.Dunlap@Sun.COM 12347836SJohn.Forte@Sun.COM void iscsi_handle_abort(void *arg); 12357836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level, 12367836SJohn.Forte@Sun.COM iscsi_lun_t *ilp); 12377836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp); 12387836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun, 12397836SJohn.Forte@Sun.COM struct uscsi_cmd *ucmdp); 12407836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_text(iscsi_conn_t *icp, 12417836SJohn.Forte@Sun.COM char *buf, uint32_t buf_len, uint32_t data_len, uint32_t *rx_data_len); 12427836SJohn.Forte@Sun.COM 12437836SJohn.Forte@Sun.COM void iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 12447836SJohn.Forte@Sun.COM 12457836SJohn.Forte@Sun.COM /* iscsi_crc.c */ 12467836SJohn.Forte@Sun.COM uint32_t iscsi_crc32c(void *address, unsigned long length); 12477836SJohn.Forte@Sun.COM uint32_t iscsi_crc32c_continued(void *address, unsigned long length, 12487836SJohn.Forte@Sun.COM uint32_t crc); 12497836SJohn.Forte@Sun.COM 12507836SJohn.Forte@Sun.COM /* iscsi_queue.c */ 12517836SJohn.Forte@Sun.COM void iscsi_init_queue(iscsi_queue_t *queue); 12527836SJohn.Forte@Sun.COM void iscsi_destroy_queue(iscsi_queue_t *queue); 12537836SJohn.Forte@Sun.COM void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 12547836SJohn.Forte@Sun.COM void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 12557836SJohn.Forte@Sun.COM void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 12567836SJohn.Forte@Sun.COM void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 12579162SPeter.Dunlap@Sun.COM void iscsi_enqueue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 12589162SPeter.Dunlap@Sun.COM void iscsi_dequeue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); 12597836SJohn.Forte@Sun.COM void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 12607836SJohn.Forte@Sun.COM iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *); 12617836SJohn.Forte@Sun.COM void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue); 12627836SJohn.Forte@Sun.COM void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **, 12637836SJohn.Forte@Sun.COM iscsi_cmd_t *); 12647836SJohn.Forte@Sun.COM 12657836SJohn.Forte@Sun.COM /* iscsi_login.c */ 12667836SJohn.Forte@Sun.COM iscsi_status_t iscsi_login_start(void *arg); 12679162SPeter.Dunlap@Sun.COM void iscsi_login_update_state(iscsi_conn_t *icp, 12689162SPeter.Dunlap@Sun.COM iscsi_login_state_t next_state); 12699162SPeter.Dunlap@Sun.COM void iscsi_login_update_state_locked(iscsi_conn_t *icp, 12709162SPeter.Dunlap@Sun.COM iscsi_login_state_t next_state); 12719162SPeter.Dunlap@Sun.COM 12727836SJohn.Forte@Sun.COM 12737836SJohn.Forte@Sun.COM /* iscsi_stats.c */ 12747836SJohn.Forte@Sun.COM boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp); 12757836SJohn.Forte@Sun.COM boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp); 12767836SJohn.Forte@Sun.COM boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp); 12777836SJohn.Forte@Sun.COM boolean_t iscsi_sess_kstat_term(struct iscsi_sess *isp); 12787836SJohn.Forte@Sun.COM boolean_t iscsi_conn_kstat_init(struct iscsi_conn *icp); 12797836SJohn.Forte@Sun.COM void iscsi_conn_kstat_term(struct iscsi_conn *icp); 12807836SJohn.Forte@Sun.COM 12817836SJohn.Forte@Sun.COM /* iscsi_net.c */ 12827836SJohn.Forte@Sun.COM void iscsi_net_init(); 12837836SJohn.Forte@Sun.COM void iscsi_net_fini(); 128411424SJack.Meng@Sun.COM iscsi_status_t iscsi_net_interface(boolean_t reset); 12857836SJohn.Forte@Sun.COM 12867836SJohn.Forte@Sun.COM /* iscsi_sess.c */ 12877836SJohn.Forte@Sun.COM iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp, 12887836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc, 12897836SJohn.Forte@Sun.COM char *target_name, int tpgt, uchar_t isid_lsb, 12907836SJohn.Forte@Sun.COM iscsi_sess_type_t type, uint32_t *oid); 12918488SBing.Zhao@Sun.COM void iscsi_sess_online(void *arg); 12927836SJohn.Forte@Sun.COM int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp); 12937836SJohn.Forte@Sun.COM iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp); 1294*12161SJack.Meng@Sun.COM void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event, 1295*12161SJack.Meng@Sun.COM uint32_t event_count); 12967836SJohn.Forte@Sun.COM char *iscsi_sess_state_str(iscsi_sess_state_t state); 12977836SJohn.Forte@Sun.COM boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp); 12989162SPeter.Dunlap@Sun.COM iscsi_status_t iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp); 12999162SPeter.Dunlap@Sun.COM void iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp); 13007836SJohn.Forte@Sun.COM iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 13017836SJohn.Forte@Sun.COM void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); 13027836SJohn.Forte@Sun.COM void iscsi_sess_redrive_io(iscsi_sess_t *isp); 13037836SJohn.Forte@Sun.COM int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp, 1304*12161SJack.Meng@Sun.COM iscsi_sess_t **ispp); 1305*12161SJack.Meng@Sun.COM iscsi_enum_result_t iscsi_sess_enum_request(iscsi_sess_t *isp, 1306*12161SJack.Meng@Sun.COM boolean_t wait, uint32_t event_count); 1307*12161SJack.Meng@Sun.COM iscsi_enum_result_t iscsi_sess_enum_query(iscsi_sess_t *isp); 1308*12161SJack.Meng@Sun.COM void iscsi_sess_enter_state_zone(iscsi_sess_t *isp); 1309*12161SJack.Meng@Sun.COM void iscsi_sess_exit_state_zone(iscsi_sess_t *isp); 13107836SJohn.Forte@Sun.COM 13117836SJohn.Forte@Sun.COM /* iscsi_conn.c */ 13127836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp, 13137836SJohn.Forte@Sun.COM iscsi_conn_t **icpp); 13149162SPeter.Dunlap@Sun.COM iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp); 13157836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp); 13167836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp); 13177836SJohn.Forte@Sun.COM void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max); 13187836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp); 13199162SPeter.Dunlap@Sun.COM void iscsi_conn_retry(iscsi_sess_t *isp, iscsi_conn_t *icp); 13209162SPeter.Dunlap@Sun.COM void iscsi_conn_update_state(iscsi_conn_t *icp, iscsi_conn_state_t next_state); 13219162SPeter.Dunlap@Sun.COM void iscsi_conn_update_state_locked(iscsi_conn_t *icp, 13229162SPeter.Dunlap@Sun.COM iscsi_conn_state_t next_state); 13237836SJohn.Forte@Sun.COM 13247836SJohn.Forte@Sun.COM /* iscsi_lun.c */ 13257836SJohn.Forte@Sun.COM iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num, 13267836SJohn.Forte@Sun.COM uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid); 13277836SJohn.Forte@Sun.COM iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, 13287836SJohn.Forte@Sun.COM iscsi_lun_t *ilp); 13297836SJohn.Forte@Sun.COM void iscsi_lun_online(iscsi_hba_t *ihp, 13307836SJohn.Forte@Sun.COM iscsi_lun_t *ilp); 13317836SJohn.Forte@Sun.COM iscsi_status_t iscsi_lun_offline(iscsi_hba_t *ihp, 13327836SJohn.Forte@Sun.COM iscsi_lun_t *ilp, boolean_t lun_free); 13337836SJohn.Forte@Sun.COM 13347836SJohn.Forte@Sun.COM /* iscsi_cmd.c */ 13357836SJohn.Forte@Sun.COM void iscsi_cmd_state_machine(iscsi_cmd_t *icmdp, 13367836SJohn.Forte@Sun.COM iscsi_cmd_event_t event, void *arg); 13377836SJohn.Forte@Sun.COM iscsi_cmd_t *iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags); 13387836SJohn.Forte@Sun.COM void iscsi_cmd_free(iscsi_cmd_t *icmdp); 13397836SJohn.Forte@Sun.COM 13407836SJohn.Forte@Sun.COM /* iscsi_ioctl.c */ 13417836SJohn.Forte@Sun.COM void * iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size); 13427836SJohn.Forte@Sun.COM int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode); 13437836SJohn.Forte@Sun.COM iscsi_conn_list_t *iscsi_ioctl_conn_oid_list_get_copyin(caddr_t, int); 13447836SJohn.Forte@Sun.COM int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *, caddr_t, int); 13457836SJohn.Forte@Sun.COM boolean_t iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp, 13467836SJohn.Forte@Sun.COM iscsi_conn_list_t *cl); 13477836SJohn.Forte@Sun.COM boolean_t iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp); 13487836SJohn.Forte@Sun.COM int iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl); 13497836SJohn.Forte@Sun.COM int iscsi_target_prop_mod(iscsi_hba_t *, iscsi_property_t *, int cmd); 13507836SJohn.Forte@Sun.COM int iscsi_set_params(iscsi_param_set_t *, iscsi_hba_t *, boolean_t); 13517836SJohn.Forte@Sun.COM int iscsi_get_persisted_param(uchar_t *, iscsi_param_get_t *, 13527836SJohn.Forte@Sun.COM iscsi_login_params_t *); 13537836SJohn.Forte@Sun.COM void iscsi_set_default_login_params(iscsi_login_params_t *params); 13547836SJohn.Forte@Sun.COM int iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp, 13557836SJohn.Forte@Sun.COM iscsi_config_sess_t *ics); 13567836SJohn.Forte@Sun.COM int iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp, 13577836SJohn.Forte@Sun.COM iscsi_config_sess_t *ics); 135810156SZhang.Yi@Sun.COM int iscsi_ioctl_set_tunable_param(iscsi_hba_t *ihp, 135910156SZhang.Yi@Sun.COM iscsi_tunable_object_t *tpss); 13607836SJohn.Forte@Sun.COM /* ioctls prototypes */ 13617836SJohn.Forte@Sun.COM int iscsi_get_param(iscsi_login_params_t *params, 13627836SJohn.Forte@Sun.COM boolean_t valid_flag, 13637836SJohn.Forte@Sun.COM iscsi_param_get_t *ipgp); 13647836SJohn.Forte@Sun.COM 13657836SJohn.Forte@Sun.COM /* iscsid.c */ 13669201SJack.Meng@Sun.COM boolean_t iscsid_init(iscsi_hba_t *ihp); 13679201SJack.Meng@Sun.COM boolean_t iscsid_start(iscsi_hba_t *ihp); 13689201SJack.Meng@Sun.COM boolean_t iscsid_stop(iscsi_hba_t *ihp); 13697836SJohn.Forte@Sun.COM void iscsid_fini(); 13707836SJohn.Forte@Sun.COM void iscsid_props(iSCSIDiscoveryProperties_t *props); 13717836SJohn.Forte@Sun.COM boolean_t iscsid_enable_discovery(iscsi_hba_t *ihp, 13727836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t idm, boolean_t poke); 13737836SJohn.Forte@Sun.COM boolean_t iscsid_disable_discovery(iscsi_hba_t *ihp, 13747836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t idm); 13757836SJohn.Forte@Sun.COM void iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method); 13767836SJohn.Forte@Sun.COM void iscsid_do_sendtgts(entry_t *discovery_addr); 13777836SJohn.Forte@Sun.COM void iscsid_do_isns_query_one_server( 13787836SJohn.Forte@Sun.COM iscsi_hba_t *ihp, entry_t *isns_addr); 13797836SJohn.Forte@Sun.COM void iscsid_do_isns_query(iscsi_hba_t *ihp); 13807836SJohn.Forte@Sun.COM void iscsid_config_one(iscsi_hba_t *ihp, 13817836SJohn.Forte@Sun.COM char *name, boolean_t protect); 13827836SJohn.Forte@Sun.COM void iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect); 13837836SJohn.Forte@Sun.COM void iscsid_unconfig_one(iscsi_hba_t *ihp, char *name); 13847836SJohn.Forte@Sun.COM void iscsid_unconfig_all(iscsi_hba_t *ihp); 13857836SJohn.Forte@Sun.COM void isns_scn_callback(void *arg); 13867836SJohn.Forte@Sun.COM boolean_t iscsid_del(iscsi_hba_t *ihp, char *target_name, 13877836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc); 13887836SJohn.Forte@Sun.COM boolean_t iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name, 13897836SJohn.Forte@Sun.COM iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc); 13907836SJohn.Forte@Sun.COM void iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port, 13917836SJohn.Forte@Sun.COM struct sockaddr *dst_addr); 13929429SJack.Meng@Sun.COM void iscsid_set_default_initiator_node_settings(iscsi_hba_t *ihp, 13939429SJack.Meng@Sun.COM boolean_t minimal); 13949429SJack.Meng@Sun.COM 13959371SBing.Zhao@Sun.COM void iscsi_send_sysevent(iscsi_hba_t *ihp, char *eventcalss, 13969371SBing.Zhao@Sun.COM char *subclass, nvlist_t *np); 13978194SJack.Meng@Sun.COM boolean_t iscsi_reconfig_boot_sess(iscsi_hba_t *ihp); 13988194SJack.Meng@Sun.COM boolean_t iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp); 13998194SJack.Meng@Sun.COM boolean_t iscsi_cmp_boot_ini_name(char *name); 14008194SJack.Meng@Sun.COM boolean_t iscsi_cmp_boot_tgt_name(char *name); 14019201SJack.Meng@Sun.COM boolean_t iscsi_client_request_service(iscsi_hba_t *ihp); 14029201SJack.Meng@Sun.COM void iscsi_client_release_service(iscsi_hba_t *ihp); 14037836SJohn.Forte@Sun.COM 14047836SJohn.Forte@Sun.COM extern void bcopy(const void *s1, void *s2, size_t n); 14057836SJohn.Forte@Sun.COM extern void bzero(void *s, size_t n); 14067836SJohn.Forte@Sun.COM /* 14077836SJohn.Forte@Sun.COM * Here we need a contract for inet_ntop() and inet_pton() 14087836SJohn.Forte@Sun.COM * in uts/common/inet/ip/inet_ntop.c 14097836SJohn.Forte@Sun.COM */ 14107836SJohn.Forte@Sun.COM extern char *inet_ntop(int af, const void *addr, char *buf, int addrlen); 14117836SJohn.Forte@Sun.COM extern int inet_pton(int af, char *inp, void *outp); 14127836SJohn.Forte@Sun.COM 14137836SJohn.Forte@Sun.COM #ifdef __cplusplus 14147836SJohn.Forte@Sun.COM } 14157836SJohn.Forte@Sun.COM #endif 14167836SJohn.Forte@Sun.COM 14177836SJohn.Forte@Sun.COM #endif /* _ISCSI_H */ 1418