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