45 #include <sys/mdi_impldefs.h> |
45 #include <sys/mdi_impldefs.h> |
46 #include <sys/time.h> |
46 #include <sys/time.h> |
47 #include <sys/nvpair.h> |
47 #include <sys/nvpair.h> |
48 #include <sys/sdt.h> |
48 #include <sys/sdt.h> |
49 |
49 |
|
50 #include <sys/iscsi_protocol.h> |
50 #include <sys/scsi/adapters/iscsi_if.h> |
51 #include <sys/scsi/adapters/iscsi_if.h> |
51 #include <sys/iscsi_protocol.h> |
|
52 #include <iscsiAuthClient.h> |
52 #include <iscsiAuthClient.h> |
53 #include <iscsi_stats.h> |
53 #include <iscsi_stats.h> |
54 #include <iscsi_thread.h> |
54 #include <iscsi_thread.h> |
|
55 #include <sys/idm/idm.h> |
|
56 #include <sys/idm/idm_conn_sm.h> |
55 #include <nvfile.h> |
57 #include <nvfile.h> |
56 |
58 |
57 #ifndef MIN |
59 #ifndef MIN |
58 #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
60 #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
59 #endif |
61 #endif |
66 #define FALSE 0 |
68 #define FALSE 0 |
67 #endif |
69 #endif |
68 |
70 |
69 #define LOGIN_PDU_BUFFER_SIZE (16 * 1024) /* move somewhere else */ |
71 #define LOGIN_PDU_BUFFER_SIZE (16 * 1024) /* move somewhere else */ |
70 |
72 |
|
73 extern boolean_t iscsi_conn_logging; |
|
74 extern boolean_t iscsi_io_logging; |
|
75 extern boolean_t iscsi_login_logging; |
|
76 extern boolean_t iscsi_logging; |
|
77 extern boolean_t iscsi_sess_logging; |
|
78 #define ISCSI_CONN_LOG if (iscsi_conn_logging) cmn_err |
|
79 #define ISCSI_IO_LOG if (iscsi_io_logging) cmn_err |
|
80 #define ISCSI_LOGIN_LOG if (iscsi_login_logging) cmn_err |
|
81 #define ISCSI_LOG if (iscsi_logging) cmn_err |
|
82 #define ISCSI_SESS_LOG if (iscsi_sess_logging) cmn_err |
|
83 |
71 /* |
84 /* |
72 * Name Format of the different Task Queues |
85 * Name Format of the different Task Queues |
73 */ |
86 */ |
74 #define ISCSI_SESS_IOTH_NAME_FORMAT "io_thrd_%d.%d" |
87 #define ISCSI_SESS_IOTH_NAME_FORMAT "io_thrd_%d.%d" |
75 #define ISCSI_SESS_WD_NAME_FORMAT "wd_thrd_%d.%d" |
88 #define ISCSI_SESS_WD_NAME_FORMAT "wd_thrd_%d.%d" |
76 #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT "login_taskq_%d.%d" |
89 #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT "login_taskq_%d.%d" |
|
90 #define ISCSI_CONN_CN_TASKQ_NAME_FORMAT "conn_cn_taskq_%d.%d.%d" |
77 #define ISCSI_CONN_RXTH_NAME_FORMAT "rx_thrd_%d.%d.%d" |
91 #define ISCSI_CONN_RXTH_NAME_FORMAT "rx_thrd_%d.%d.%d" |
78 #define ISCSI_CONN_TXTH_NAME_FORMAT "tx_thrd_%d.%d.%d" |
92 #define ISCSI_CONN_TXTH_NAME_FORMAT "tx_thrd_%d.%d.%d" |
79 |
93 |
80 /* |
94 /* |
81 * The iSCSI driver will not build scatter/gather lists (iovec) longer |
95 * The iSCSI driver will not build scatter/gather lists (iovec) longer |
173 /* data received would have overflowed given buffer */ |
187 /* data received would have overflowed given buffer */ |
174 ISCSI_STATUS_DATA_OVERFLOW, |
188 ISCSI_STATUS_DATA_OVERFLOW, |
175 /* session/connection needs to shutdown */ |
189 /* session/connection needs to shutdown */ |
176 ISCSI_STATUS_SHUTDOWN, |
190 ISCSI_STATUS_SHUTDOWN, |
177 /* logical unit in use */ |
191 /* logical unit in use */ |
178 ISCSI_STATUS_BUSY |
192 ISCSI_STATUS_BUSY, |
|
193 /* Login on connection failed, retries exceeded */ |
|
194 ISCSI_STATUS_LOGIN_TIMED_OUT |
179 } iscsi_status_t; |
195 } iscsi_status_t; |
180 #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS) |
196 #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS) |
181 |
197 |
182 /* SNA32 check value used on increment of CmdSn values */ |
198 /* SNA32 check value used on increment of CmdSn values */ |
183 #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */ |
199 #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */ |
281 * These are all the iscsi_cmd types that we use to track our |
297 * These are all the iscsi_cmd types that we use to track our |
282 * commands between queues and actions. |
298 * commands between queues and actions. |
283 */ |
299 */ |
284 typedef enum iscsi_cmd_type { |
300 typedef enum iscsi_cmd_type { |
285 ISCSI_CMD_TYPE_SCSI = 1, /* scsi cmd */ |
301 ISCSI_CMD_TYPE_SCSI = 1, /* scsi cmd */ |
286 ISCSI_CMD_TYPE_R2T, /* r2t */ |
|
287 ISCSI_CMD_TYPE_NOP, /* nop / ping */ |
302 ISCSI_CMD_TYPE_NOP, /* nop / ping */ |
288 ISCSI_CMD_TYPE_ABORT, /* abort */ |
303 ISCSI_CMD_TYPE_ABORT, /* abort */ |
289 ISCSI_CMD_TYPE_RESET, /* reset */ |
304 ISCSI_CMD_TYPE_RESET, /* reset */ |
290 ISCSI_CMD_TYPE_LOGOUT, /* logout */ |
305 ISCSI_CMD_TYPE_LOGOUT, /* logout */ |
291 ISCSI_CMD_TYPE_LOGIN, /* login */ |
306 ISCSI_CMD_TYPE_LOGIN, /* login */ |
294 |
309 |
295 /* |
310 /* |
296 * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram) |
311 * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram) |
297 */ |
312 */ |
298 typedef enum iscsi_cmd_state { |
313 typedef enum iscsi_cmd_state { |
299 ISCSI_CMD_STATE_FREE, |
314 ISCSI_CMD_STATE_FREE = 0, |
300 ISCSI_CMD_STATE_PENDING, |
315 ISCSI_CMD_STATE_PENDING, |
301 ISCSI_CMD_STATE_ACTIVE, |
316 ISCSI_CMD_STATE_ACTIVE, |
302 ISCSI_CMD_STATE_ABORTING, |
317 ISCSI_CMD_STATE_ABORTING, |
303 ISCSI_CMD_STATE_COMPLETED |
318 ISCSI_CMD_STATE_IDM_ABORTING, |
|
319 ISCSI_CMD_STATE_COMPLETED, |
|
320 ISCSI_CMD_STATE_MAX |
304 } iscsi_cmd_state_t; |
321 } iscsi_cmd_state_t; |
305 |
322 |
|
323 #ifdef ISCSI_CMD_SM_STRINGS |
|
324 static const char *iscsi_cmd_state_names[ISCSI_CMD_STATE_MAX+1] = { |
|
325 "ISCSI_CMD_STATE_FREE", |
|
326 "ISCSI_CMD_STATE_PENDING", |
|
327 "ISCSI_CMD_STATE_ACTIVE", |
|
328 "ISCSI_CMD_STATE_ABORTING", |
|
329 "ISCSI_CMD_STATE_IDM_ABORTING", |
|
330 "ISCSI_CMD_STATE_COMPLETED", |
|
331 "ISCSI_CMD_STATE_MAX" |
|
332 }; |
|
333 #endif |
|
334 |
306 /* |
335 /* |
307 * iscsi command events |
336 * iscsi command events |
308 */ |
337 */ |
309 typedef enum iscsi_cmd_event { |
338 typedef enum iscsi_cmd_event { |
310 ISCSI_CMD_EVENT_E1, |
339 ISCSI_CMD_EVENT_E1 = 0, |
311 ISCSI_CMD_EVENT_E2, |
340 ISCSI_CMD_EVENT_E2, |
312 ISCSI_CMD_EVENT_E3, |
341 ISCSI_CMD_EVENT_E3, |
313 ISCSI_CMD_EVENT_E4, |
342 ISCSI_CMD_EVENT_E4, |
314 ISCSI_CMD_EVENT_E6, |
343 ISCSI_CMD_EVENT_E6, |
315 ISCSI_CMD_EVENT_E7, |
344 ISCSI_CMD_EVENT_E7, |
316 ISCSI_CMD_EVENT_E8 |
345 ISCSI_CMD_EVENT_E8, |
|
346 ISCSI_CMD_EVENT_E9, |
|
347 ISCSI_CMD_EVENT_E10, |
|
348 ISCSI_CMD_EVENT_MAX |
317 } iscsi_cmd_event_t; |
349 } iscsi_cmd_event_t; |
|
350 |
|
351 #ifdef ISCSI_CMD_SM_STRINGS |
|
352 static const char *iscsi_cmd_event_names[ISCSI_CMD_EVENT_MAX+1] = { |
|
353 "ISCSI_CMD_EVENT_E1", |
|
354 "ISCSI_CMD_EVENT_E2", |
|
355 "ISCSI_CMD_EVENT_E3", |
|
356 "ISCSI_CMD_EVENT_E4", |
|
357 "ISCSI_CMD_EVENT_E6", |
|
358 "ISCSI_CMD_EVENT_E7", |
|
359 "ISCSI_CMD_EVENT_E8", |
|
360 "ISCSI_CMD_EVENT_E9", |
|
361 "ISCSI_CMD_EVENT_E10", |
|
362 "ISCSI_CMD_EVENT_MAX" |
|
363 }; |
|
364 #endif |
318 |
365 |
319 /* |
366 /* |
320 * iscsi text command stages - these stages are used by iSCSI text |
367 * iscsi text command stages - these stages are used by iSCSI text |
321 * processing to manage long resonses. |
368 * processing to manage long resonses. |
322 */ |
369 */ |
323 typedef enum iscsi_cmd_text_stage { |
370 typedef enum iscsi_cmd_text_stage { |
324 ISCSI_CMD_TEXT_INITIAL_REQ, |
371 ISCSI_CMD_TEXT_INITIAL_REQ = 0, |
325 ISCSI_CMD_TEXT_CONTINUATION, |
372 ISCSI_CMD_TEXT_CONTINUATION, |
326 ISCSI_CMD_TEXT_FINAL_RSP |
373 ISCSI_CMD_TEXT_FINAL_RSP |
327 } iscsi_cmd_text_stage_t; |
374 } iscsi_cmd_text_stage_t; |
328 |
375 |
329 /* |
376 /* |
347 iscsi_cmd_state_t cmd_state; |
394 iscsi_cmd_state_t cmd_state; |
348 iscsi_cmd_state_t cmd_prev_state; |
395 iscsi_cmd_state_t cmd_prev_state; |
349 clock_t cmd_lbolt_pending; |
396 clock_t cmd_lbolt_pending; |
350 clock_t cmd_lbolt_active; |
397 clock_t cmd_lbolt_active; |
351 clock_t cmd_lbolt_aborting; |
398 clock_t cmd_lbolt_aborting; |
|
399 clock_t cmd_lbolt_idm_aborting; |
352 clock_t cmd_lbolt_timeout; |
400 clock_t cmd_lbolt_timeout; |
353 uint8_t cmd_misc_flags; |
401 uint8_t cmd_misc_flags; |
|
402 idm_task_t *cmd_itp; |
354 |
403 |
355 union { |
404 union { |
356 /* ISCSI_CMD_TYPE_SCSI */ |
405 /* ISCSI_CMD_TYPE_SCSI */ |
357 struct { |
406 struct { |
|
407 idm_buf_t *ibp_ibuf; |
|
408 idm_buf_t *ibp_obuf; |
358 struct scsi_pkt *pkt; |
409 struct scsi_pkt *pkt; |
359 struct buf *bp; |
410 struct buf *bp; |
360 int cmdlen; |
411 int cmdlen; |
361 int statuslen; |
412 int statuslen; |
362 size_t data_transferred; |
413 size_t data_transferred; |
478 #define ISCSI_LUN_STATE_INVALID 4 /* offline failed */ |
532 #define ISCSI_LUN_STATE_INVALID 4 /* offline failed */ |
479 |
533 |
480 #define ISCSI_LUN_CAP_RESET 0x01 |
534 #define ISCSI_LUN_CAP_RESET 0x01 |
481 |
535 |
482 /* |
536 /* |
483 * iscsi_conn_state - (reference iscsi_conn.c for state diagram) |
|
484 */ |
|
485 typedef enum iscsi_conn_state { |
|
486 ISCSI_CONN_STATE_FREE, |
|
487 ISCSI_CONN_STATE_IN_LOGIN, |
|
488 ISCSI_CONN_STATE_LOGGED_IN, |
|
489 ISCSI_CONN_STATE_IN_LOGOUT, |
|
490 ISCSI_CONN_STATE_FAILED, |
|
491 ISCSI_CONN_STATE_POLLING |
|
492 } iscsi_conn_state_t; |
|
493 |
|
494 #define ISCSI_CONN_STATE_FULL_FEATURE(state) \ |
|
495 ((state == ISCSI_CONN_STATE_LOGGED_IN) || \ |
|
496 (state == ISCSI_CONN_STATE_IN_LOGOUT)) |
|
497 |
|
498 /* |
|
499 * iscsi connection events - (reference iscsi_conn.c for state diagram) |
|
500 */ |
|
501 typedef enum iscsi_conn_event { |
|
502 ISCSI_CONN_EVENT_T1, |
|
503 ISCSI_CONN_EVENT_T5, |
|
504 ISCSI_CONN_EVENT_T7, |
|
505 ISCSI_CONN_EVENT_T8, |
|
506 ISCSI_CONN_EVENT_T9, |
|
507 ISCSI_CONN_EVENT_T11, |
|
508 ISCSI_CONN_EVENT_T12, |
|
509 ISCSI_CONN_EVENT_T13, |
|
510 ISCSI_CONN_EVENT_T14, |
|
511 ISCSI_CONN_EVENT_T15, |
|
512 ISCSI_CONN_EVENT_T17, |
|
513 ISCSI_CONN_EVENT_T30 |
|
514 } iscsi_conn_event_t; |
|
515 |
|
516 /* |
|
517 * |
537 * |
518 * |
538 * |
519 */ |
539 */ |
520 typedef struct iscsi_queue { |
540 typedef struct iscsi_queue { |
521 iscsi_cmd_t *head; |
541 iscsi_cmd_t *head; |
535 } iscsi_sockaddr_t; |
555 } iscsi_sockaddr_t; |
536 |
556 |
537 #define SIZEOF_SOCKADDR(so) ((so)->sa_family == AF_INET ? \ |
557 #define SIZEOF_SOCKADDR(so) ((so)->sa_family == AF_INET ? \ |
538 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)) |
558 sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)) |
539 |
559 |
|
560 typedef enum { |
|
561 LOGIN_START, |
|
562 LOGIN_READY, |
|
563 LOGIN_TX, |
|
564 LOGIN_RX, |
|
565 LOGIN_ERROR, |
|
566 LOGIN_DONE, |
|
567 LOGIN_FFP, |
|
568 LOGIN_MAX |
|
569 } iscsi_login_state_t; |
|
570 |
|
571 #ifdef ISCSI_LOGIN_STATE_NAMES |
|
572 static const char *iscsi_login_state_names[LOGIN_MAX+1] = { |
|
573 "LOGIN_START", |
|
574 "LOGIN_READY", |
|
575 "LOGIN_TX", |
|
576 "LOGIN_RX", |
|
577 "LOGIN_ERROR", |
|
578 "LOGIN_DONE", |
|
579 "LOGIN_FFP", |
|
580 "LOGIN_MAX" |
|
581 }; |
|
582 #endif |
|
583 |
|
584 /* |
|
585 * iscsi_conn_state |
|
586 */ |
|
587 typedef enum iscsi_conn_state { |
|
588 ISCSI_CONN_STATE_UNDEFINED = 0, |
|
589 ISCSI_CONN_STATE_FREE, |
|
590 ISCSI_CONN_STATE_IN_LOGIN, |
|
591 ISCSI_CONN_STATE_LOGGED_IN, |
|
592 ISCSI_CONN_STATE_IN_LOGOUT, |
|
593 ISCSI_CONN_STATE_FAILED, |
|
594 ISCSI_CONN_STATE_POLLING, |
|
595 ISCSI_CONN_STATE_MAX |
|
596 } iscsi_conn_state_t; |
|
597 |
|
598 #ifdef ISCSI_ICS_NAMES |
|
599 static const char *iscsi_ics_name[ISCSI_CONN_STATE_MAX+1] = { |
|
600 "ISCSI_CONN_STATE_UNDEFINED", |
|
601 "ISCSI_CONN_STATE_FREE", |
|
602 "ISCSI_CONN_STATE_IN_LOGIN", |
|
603 "ISCSI_CONN_STATE_LOGGED_IN", |
|
604 "ISCSI_CONN_STATE_IN_LOGOUT", |
|
605 "ISCSI_CONN_STATE_FAILED", |
|
606 "ISCSI_CONN_STATE_POLLING", |
|
607 "ISCSI_CONN_STATE_MAX" |
|
608 }; |
|
609 #endif |
|
610 |
|
611 #define ISCSI_CONN_STATE_FULL_FEATURE(state) \ |
|
612 ((state == ISCSI_CONN_STATE_LOGGED_IN) || \ |
|
613 (state == ISCSI_CONN_STATE_IN_LOGOUT)) |
|
614 |
540 /* |
615 /* |
541 * iSCSI Connection Structure |
616 * iSCSI Connection Structure |
542 */ |
617 */ |
543 typedef struct iscsi_conn { |
618 typedef struct iscsi_conn { |
544 uint32_t conn_sig; |
619 uint32_t conn_sig; |
545 struct iscsi_conn *conn_next; /* next conn on this sess. */ |
620 struct iscsi_conn *conn_next; /* next conn on this sess. */ |
546 struct iscsi_sess *conn_sess; /* parent sess. for conn. */ |
621 struct iscsi_sess *conn_sess; /* parent sess. for conn. */ |
547 |
622 |
548 iscsi_conn_state_t conn_state; /* cur. conn. driver state */ |
623 iscsi_conn_state_t conn_state; /* cur. conn. driver state */ |
549 iscsi_conn_state_t conn_prev_state; /* prev. conn. driver state */ |
624 iscsi_conn_state_t conn_prev_state; /* prev. conn. driver state */ |
550 clock_t conn_state_lbolt; |
|
551 /* protects the session state and synchronizes the state machine */ |
625 /* protects the session state and synchronizes the state machine */ |
552 kmutex_t conn_state_mutex; |
626 kmutex_t conn_state_mutex; |
553 kcondvar_t conn_state_change; |
627 kcondvar_t conn_state_change; |
554 boolean_t conn_state_destroy; |
628 boolean_t conn_state_destroy; |
555 |
629 boolean_t conn_state_ffp; |
556 void *conn_socket; /* kernel socket */ |
630 boolean_t conn_state_idm_connected; |
557 |
631 boolean_t conn_async_logout; |
558 /* base connection information */ |
632 ddi_taskq_t *conn_cn_taskq; |
|
633 |
|
634 idm_conn_t *conn_ic; |
|
635 |
|
636 /* base connection information, may have been redirected */ |
559 iscsi_sockaddr_t conn_base_addr; |
637 iscsi_sockaddr_t conn_base_addr; |
560 |
638 |
561 /* current connection information, may have been redirected */ |
639 /* current connection information, may have been redirected */ |
562 iscsi_sockaddr_t conn_curr_addr; |
640 iscsi_sockaddr_t conn_curr_addr; |
563 |
641 |
564 /* current connection information, may have been redirected */ |
|
565 boolean_t conn_bound; |
642 boolean_t conn_bound; |
566 iscsi_sockaddr_t conn_bound_addr; |
643 iscsi_sockaddr_t conn_bound_addr; |
567 |
644 |
568 uint32_t conn_cid; /* CID */ |
645 uint32_t conn_cid; /* CID */ |
569 uint32_t conn_oid; /* OID */ |
646 uint32_t conn_oid; /* OID */ |
579 * are issues with these cmds the command may need aborted |
656 * are issues with these cmds the command may need aborted |
580 * depending on the command type, and must be put back into |
657 * depending on the command type, and must be put back into |
581 * the session's pending queue or aborted. |
658 * the session's pending queue or aborted. |
582 */ |
659 */ |
583 iscsi_queue_t conn_queue_active; |
660 iscsi_queue_t conn_queue_active; |
|
661 iscsi_queue_t conn_queue_idm_aborting; |
584 |
662 |
585 /* lbolt from the last receive, used for nop processing */ |
663 /* lbolt from the last receive, used for nop processing */ |
586 clock_t conn_rx_lbolt; |
664 clock_t conn_rx_lbolt; |
587 clock_t conn_nop_lbolt; |
665 clock_t conn_nop_lbolt; |
588 |
666 |
589 iscsi_thread_t *conn_rx_thread; |
|
590 iscsi_thread_t *conn_tx_thread; |
667 iscsi_thread_t *conn_tx_thread; |
591 |
668 |
592 /* |
669 /* |
593 * The expstatsn is the command status sn that is expected |
670 * The expstatsn is the command status sn that is expected |
594 * next from the target. Command status is carried on a number |
671 * next from the target. Command status is carried on a number |
606 /* Statistics */ |
683 /* Statistics */ |
607 struct { |
684 struct { |
608 kstat_t *ks; |
685 kstat_t *ks; |
609 iscsi_conn_stats_t ks_data; |
686 iscsi_conn_stats_t ks_data; |
610 } stats; |
687 } stats; |
|
688 |
|
689 /* |
|
690 * These fields are used to coordinate the asynchronous IDM |
|
691 * PDU operations with the synchronous login code. |
|
692 */ |
|
693 kmutex_t conn_login_mutex; |
|
694 kcondvar_t conn_login_cv; |
|
695 iscsi_login_state_t conn_login_state; |
|
696 iscsi_status_t conn_login_status; |
|
697 iscsi_hdr_t conn_login_resp_hdr; |
|
698 char *conn_login_data; |
|
699 int conn_login_datalen; |
|
700 int conn_login_max_data_length; |
611 |
701 |
612 /* |
702 /* |
613 * login min and max identify the amount of time |
703 * login min and max identify the amount of time |
614 * in lbolt that iscsi_start_login() should attempt |
704 * in lbolt that iscsi_start_login() should attempt |
615 * to log into a target portal. The login will |
705 * to log into a target portal. The login will |
619 * are also altered by async commands received from |
709 * are also altered by async commands received from |
620 * the targetlogin. |
710 * the targetlogin. |
621 */ |
711 */ |
622 clock_t conn_login_min; |
712 clock_t conn_login_min; |
623 clock_t conn_login_max; |
713 clock_t conn_login_max; |
|
714 sm_audit_buf_t conn_state_audit; |
624 } iscsi_conn_t; |
715 } iscsi_conn_t; |
625 |
716 |
626 |
717 |
627 /* |
718 /* |
628 * iscsi_conn_state - (reference iscsi_sess.c for state diagram) |
719 * iscsi_sess_state - (reference iscsi_sess.c for state diagram) |
629 */ |
720 */ |
630 typedef enum iscsi_sess_state { |
721 typedef enum iscsi_sess_state { |
631 ISCSI_SESS_STATE_FREE, |
722 ISCSI_SESS_STATE_FREE = 0, |
632 ISCSI_SESS_STATE_LOGGED_IN, |
723 ISCSI_SESS_STATE_LOGGED_IN, |
633 ISCSI_SESS_STATE_FAILED, |
724 ISCSI_SESS_STATE_FAILED, |
634 ISCSI_SESS_STATE_IN_FLUSH, |
725 ISCSI_SESS_STATE_IN_FLUSH, |
635 ISCSI_SESS_STATE_FLUSHED |
726 ISCSI_SESS_STATE_FLUSHED, |
|
727 ISCSI_SESS_STATE_MAX |
636 } iscsi_sess_state_t; |
728 } iscsi_sess_state_t; |
|
729 |
|
730 #ifdef ISCSI_SESS_SM_STRINGS |
|
731 static const char *iscsi_sess_state_names[ISCSI_SESS_STATE_MAX+1] = { |
|
732 "ISCSI_SESS_STATE_FREE", |
|
733 "ISCSI_SESS_STATE_LOGGED_IN", |
|
734 "ISCSI_SESS_STATE_FAILED", |
|
735 "ISCSI_SESS_STATE_IN_FLUSH", |
|
736 "ISCSI_SESS_STATE_FLUSHED", |
|
737 "ISCSI_SESS_STATE_MAX" |
|
738 }; |
|
739 #endif |
637 |
740 |
638 #define ISCSI_SESS_STATE_FULL_FEATURE(state) \ |
741 #define ISCSI_SESS_STATE_FULL_FEATURE(state) \ |
639 ((state == ISCSI_SESS_STATE_LOGGED_IN) || \ |
742 ((state == ISCSI_SESS_STATE_LOGGED_IN) || \ |
640 (state == ISCSI_SESS_STATE_IN_FLUSH)) |
743 (state == ISCSI_SESS_STATE_IN_FLUSH)) |
641 |
744 |
642 |
745 |
643 typedef enum iscsi_sess_event { |
746 typedef enum iscsi_sess_event { |
644 ISCSI_SESS_EVENT_N1, |
747 ISCSI_SESS_EVENT_N1 = 0, |
645 ISCSI_SESS_EVENT_N3, |
748 ISCSI_SESS_EVENT_N3, |
646 ISCSI_SESS_EVENT_N5, |
749 ISCSI_SESS_EVENT_N5, |
647 ISCSI_SESS_EVENT_N6, |
750 ISCSI_SESS_EVENT_N6, |
648 ISCSI_SESS_EVENT_N7 |
751 ISCSI_SESS_EVENT_N7, |
|
752 ISCSI_SESS_EVENT_MAX |
649 } iscsi_sess_event_t; |
753 } iscsi_sess_event_t; |
650 |
754 |
|
755 #ifdef ISCSI_SESS_SM_STRINGS |
|
756 static const char *iscsi_sess_event_names[ISCSI_SESS_EVENT_MAX+1] = { |
|
757 "ISCSI_SESS_EVENT_N1", |
|
758 "ISCSI_SESS_EVENT_N3", |
|
759 "ISCSI_SESS_EVENT_N5", |
|
760 "ISCSI_SESS_EVENT_N6", |
|
761 "ISCSI_SESS_EVENT_N7", |
|
762 "ISCSI_SESS_EVENT_MAX" |
|
763 }; |
|
764 #endif |
|
765 |
651 typedef enum iscsi_sess_type { |
766 typedef enum iscsi_sess_type { |
652 ISCSI_SESS_TYPE_NORMAL, |
767 ISCSI_SESS_TYPE_NORMAL = 0, |
653 ISCSI_SESS_TYPE_DISCOVERY |
768 ISCSI_SESS_TYPE_DISCOVERY |
654 } iscsi_sess_type_t; |
769 } iscsi_sess_type_t; |
655 |
770 |
656 #define SESS_ABORT_TASK_MAX_THREADS 1 |
771 #define SESS_ABORT_TASK_MAX_THREADS 1 |
657 |
772 |
839 |
954 |
840 ddi_taskq_t *sess_taskq; |
955 ddi_taskq_t *sess_taskq; |
841 |
956 |
842 iscsi_thread_t *sess_wd_thread; |
957 iscsi_thread_t *sess_wd_thread; |
843 |
958 |
|
959 sm_audit_buf_t sess_state_audit; |
844 } iscsi_sess_t; |
960 } iscsi_sess_t; |
845 |
961 |
846 /* |
962 /* |
847 * This structure will be used to store sessions to be online |
963 * This structure will be used to store sessions to be online |
848 * during normal login operation. |
964 * during normal login operation. |
849 */ |
965 */ |
850 typedef struct iscsi_sess_list { |
966 typedef struct iscsi_sess_list { |
851 iscsi_sess_t *session; |
967 iscsi_sess_t *session; |
852 struct iscsi_sess_list *next; |
968 struct iscsi_sess_list *next; |
853 } iscsi_sess_list_t; |
969 } iscsi_sess_list_t; |
|
970 |
|
971 /* |
|
972 * iSCSI client notify task context for deferred IDM notifications processing |
|
973 */ |
|
974 typedef struct iscsi_cn_task { |
|
975 idm_conn_t *ct_ic; |
|
976 idm_client_notify_t ct_icn; |
|
977 uintptr_t ct_data; |
|
978 } iscsi_cn_task_t; |
854 |
979 |
855 /* |
980 /* |
856 * iscsi_network |
981 * iscsi_network |
857 */ |
982 */ |
858 typedef struct iscsi_network { |
983 typedef struct iscsi_network { |
963 * +--------------------------------------------------------------------+ |
1089 * +--------------------------------------------------------------------+ |
964 * | iSCSI prototypes | |
1090 * | iSCSI prototypes | |
965 * +--------------------------------------------------------------------+ |
1091 * +--------------------------------------------------------------------+ |
966 */ |
1092 */ |
967 |
1093 |
|
1094 /* IDM client callback entry points */ |
|
1095 idm_rx_pdu_cb_t iscsi_rx_scsi_rsp; |
|
1096 idm_rx_pdu_cb_t iscsi_rx_misc_pdu; |
|
1097 idm_rx_pdu_error_cb_t iscsi_rx_error_pdu; |
|
1098 idm_build_hdr_cb_t iscsi_build_hdr; |
|
1099 idm_task_cb_t iscsi_task_aborted; |
|
1100 idm_client_notify_cb_t iscsi_client_notify; |
|
1101 |
968 /* iscsi_io.c */ |
1102 /* iscsi_io.c */ |
969 int iscsi_sna_lte(uint32_t n1, uint32_t n2); |
1103 int iscsi_sna_lte(uint32_t n1, uint32_t n2); |
970 char *iscsi_get_next_text(char *data, int data_length, char *curr_text); |
1104 char *iscsi_get_next_text(char *data, int data_length, char *curr_text); |
971 |
1105 |
972 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg); |
1106 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg); |
973 void iscsi_tx_thread(iscsi_thread_t *thread, void *arg); |
1107 void iscsi_tx_thread(iscsi_thread_t *thread, void *arg); |
974 void iscsi_rx_thread(iscsi_thread_t *thread, void *arg); |
|
975 void iscsi_wd_thread(iscsi_thread_t *thread, void *arg); |
1108 void iscsi_wd_thread(iscsi_thread_t *thread, void *arg); |
976 |
1109 |
977 iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1110 iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
|
1111 |
|
1112 void iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp); |
978 |
1113 |
979 void iscsi_handle_abort(void *arg); |
1114 void iscsi_handle_abort(void *arg); |
980 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level, |
1115 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level, |
981 iscsi_lun_t *ilp); |
1116 iscsi_lun_t *ilp); |
982 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp); |
1117 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp); |
997 void iscsi_destroy_queue(iscsi_queue_t *queue); |
1132 void iscsi_destroy_queue(iscsi_queue_t *queue); |
998 void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1133 void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
999 void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1134 void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1000 void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); |
1135 void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); |
1001 void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); |
1136 void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); |
|
1137 void iscsi_enqueue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); |
|
1138 void iscsi_dequeue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp); |
1002 void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1139 void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1003 iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *); |
1140 iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *); |
1004 void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue); |
1141 void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue); |
1005 void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **, |
1142 void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **, |
1006 iscsi_cmd_t *); |
1143 iscsi_cmd_t *); |
1007 |
1144 |
1008 /* iscsi_login.c */ |
1145 /* iscsi_login.c */ |
1009 iscsi_status_t iscsi_login_start(void *arg); |
1146 iscsi_status_t iscsi_login_start(void *arg); |
|
1147 void iscsi_login_update_state(iscsi_conn_t *icp, |
|
1148 iscsi_login_state_t next_state); |
|
1149 void iscsi_login_update_state_locked(iscsi_conn_t *icp, |
|
1150 iscsi_login_state_t next_state); |
|
1151 |
1010 |
1152 |
1011 /* iscsi_stats.c */ |
1153 /* iscsi_stats.c */ |
1012 boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp); |
1154 boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp); |
1013 boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp); |
1155 boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp); |
1014 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp); |
1156 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp); |
1017 void iscsi_conn_kstat_term(struct iscsi_conn *icp); |
1159 void iscsi_conn_kstat_term(struct iscsi_conn *icp); |
1018 |
1160 |
1019 /* iscsi_net.c */ |
1161 /* iscsi_net.c */ |
1020 void iscsi_net_init(); |
1162 void iscsi_net_init(); |
1021 void iscsi_net_fini(); |
1163 void iscsi_net_fini(); |
|
1164 iscsi_status_t iscsi_net_interface(); |
1022 |
1165 |
1023 /* iscsi_sess.c */ |
1166 /* iscsi_sess.c */ |
1024 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp, |
1167 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp, |
1025 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc, |
1168 iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc, |
1026 char *target_name, int tpgt, uchar_t isid_lsb, |
1169 char *target_name, int tpgt, uchar_t isid_lsb, |
1029 int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp); |
1172 int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp); |
1030 iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp); |
1173 iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp); |
1031 void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event); |
1174 void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event); |
1032 char *iscsi_sess_state_str(iscsi_sess_state_t state); |
1175 char *iscsi_sess_state_str(iscsi_sess_state_t state); |
1033 boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp); |
1176 boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp); |
|
1177 iscsi_status_t iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp); |
|
1178 void iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp); |
1034 iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1179 iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1035 void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1180 void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp); |
1036 void iscsi_sess_redrive_io(iscsi_sess_t *isp); |
1181 void iscsi_sess_redrive_io(iscsi_sess_t *isp); |
1037 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp, |
1182 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp, |
1038 iscsi_sess_t **ispp); |
1183 iscsi_sess_t **ispp); |
1039 |
1184 |
1040 |
1185 |
1041 /* iscsi_conn.c */ |
1186 /* iscsi_conn.c */ |
1042 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp, |
1187 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp, |
1043 iscsi_conn_t **icpp); |
1188 iscsi_conn_t **icpp); |
|
1189 iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp); |
1044 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp); |
1190 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp); |
1045 iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp); |
1191 iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp); |
1046 iscsi_status_t iscsi_conn_state_machine(iscsi_conn_t *icp, |
|
1047 iscsi_conn_event_t event); |
|
1048 char *iscsi_conn_state_str(iscsi_conn_state_t state); |
|
1049 void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max); |
1192 void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max); |
1050 iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp); |
1193 iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp); |
|
1194 void iscsi_conn_retry(iscsi_sess_t *isp, iscsi_conn_t *icp); |
|
1195 void iscsi_conn_update_state(iscsi_conn_t *icp, iscsi_conn_state_t next_state); |
|
1196 void iscsi_conn_update_state_locked(iscsi_conn_t *icp, |
|
1197 iscsi_conn_state_t next_state); |
1051 |
1198 |
1052 /* iscsi_lun.c */ |
1199 /* iscsi_lun.c */ |
1053 iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num, |
1200 iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num, |
1054 uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid); |
1201 uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid); |
1055 iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, |
1202 iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, |