xref: /netbsd-src/sys/dev/iscsi/iscsi_ioctl.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /*	$NetBSD: iscsi_ioctl.c,v 1.33 2022/09/13 13:09:16 mlelstv Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Wasabi Systems, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "iscsi_globals.h"
33 
34 #include <sys/file.h>
35 #include <sys/filedesc.h>
36 #include <sys/proc.h>
37 #include <sys/kmem.h>
38 
39 static kmutex_t iscsi_cleanup_mtx;
40 static kcondvar_t iscsi_cleanup_cv;
41 static kcondvar_t iscsi_event_cv;
42 static struct lwp *iscsi_cleanproc = NULL;
43 
44 static uint16_t current_id = 0;	/* Global session ID counter */
45 
46 /* list of event handlers */
47 static event_handler_list_t event_handlers =
48 	TAILQ_HEAD_INITIALIZER(event_handlers);
49 
50 static connection_list_t iscsi_timeout_conn_list =
51 	TAILQ_HEAD_INITIALIZER(iscsi_timeout_conn_list);
52 
53 static ccb_list_t iscsi_timeout_ccb_list =
54 	TAILQ_HEAD_INITIALIZER(iscsi_timeout_ccb_list);
55 
56 static session_list_t iscsi_cleanups_list =
57 	TAILQ_HEAD_INITIALIZER(iscsi_cleanups_list);
58 
59 static connection_list_t iscsi_cleanupc_list =
60 	TAILQ_HEAD_INITIALIZER(iscsi_cleanupc_list);
61 
62 static uint32_t handler_id = 0;	/* Handler ID counter */
63 
64 /* -------------------------------------------------------------------------- */
65 
66 /* Event management functions */
67 
68 /*
69  * find_handler:
70  *    Search the event handler list for the given ID.
71  *
72  *    Parameter:
73  *          id    The handler ID.
74  *
75  *    Returns:
76  *          Pointer to handler if found, else NULL.
77  */
78 
79 
80 static event_handler_t *
81 find_handler(uint32_t id)
82 {
83 	event_handler_t *curr;
84 
85 	KASSERT(mutex_owned(&iscsi_cleanup_mtx));
86 
87 	TAILQ_FOREACH(curr, &event_handlers, evh_link)
88 		if (curr->evh_id == id)
89 			break;
90 
91 	return curr;
92 }
93 
94 
95 /*
96  * register_event:
97  *    Create event handler entry, return ID.
98  *
99  *    Parameter:
100  *          par   The parameter.
101  */
102 
103 static void
104 register_event(iscsi_register_event_parameters_t *par)
105 {
106 	event_handler_t *handler;
107 	int was_empty;
108 
109 	handler = malloc(sizeof(event_handler_t), M_DEVBUF, M_WAITOK | M_ZERO);
110 	if (handler == NULL) {
111 		DEBOUT(("No mem for event handler\n"));
112 		par->status = ISCSI_STATUS_NO_RESOURCES;
113 		return;
114 	}
115 
116 	TAILQ_INIT(&handler->evh_events);
117 
118 	mutex_enter(&iscsi_cleanup_mtx);
119 	/* create a unique ID */
120 	do {
121 		++handler_id;
122 	} while (!handler_id || find_handler(handler_id) != NULL);
123 	par->event_id = handler->evh_id = handler_id;
124 
125 	was_empty = TAILQ_FIRST(&event_handlers) == NULL;
126 	TAILQ_INSERT_TAIL(&event_handlers, handler, evh_link);
127 	if (was_empty)
128 		iscsi_notify_cleanup();
129 	mutex_exit(&iscsi_cleanup_mtx);
130 
131 	par->status = ISCSI_STATUS_SUCCESS;
132 	DEB(5, ("Register Event OK, ID %d\n", par->event_id));
133 }
134 
135 
136 /*
137  * deregister_event:
138  *    Destroy handler entry and any waiting events, wake up waiter.
139  *
140  *    Parameter:
141  *          par   The parameter.
142  */
143 
144 static void
145 deregister_event(iscsi_register_event_parameters_t *par)
146 {
147 	event_handler_t *handler;
148 	event_t *evt;
149 
150 	mutex_enter(&iscsi_cleanup_mtx);
151 	handler = find_handler(par->event_id);
152 	if (handler == NULL) {
153 		mutex_exit(&iscsi_cleanup_mtx);
154 		DEB(1, ("Deregister Event ID %d not found\n", par->event_id));
155 		par->status = ISCSI_STATUS_INVALID_EVENT_ID;
156 		return;
157 	}
158 
159 	TAILQ_REMOVE(&event_handlers, handler, evh_link);
160 	if (handler->evh_waiter != NULL) {
161 		handler->evh_waiter->status = ISCSI_STATUS_EVENT_DEREGISTERED;
162 		cv_broadcast(&iscsi_event_cv);
163 	}
164 
165 	while ((evt = TAILQ_FIRST(&handler->evh_events)) != NULL) {
166 		TAILQ_REMOVE(&handler->evh_events, evt, ev_link);
167 		free(evt, M_TEMP);
168 	}
169 	mutex_exit(&iscsi_cleanup_mtx);
170 
171 	free(handler, M_DEVBUF);
172 	par->status = ISCSI_STATUS_SUCCESS;
173 	DEB(5, ("Deregister Event ID %d complete\n", par->event_id));
174 }
175 
176 
177 /*
178  * check_event:
179  *    Return first queued event. Optionally wait for arrival of event.
180  *
181  *    Parameter:
182  *          par   The parameter.
183  *          wait  Wait for event if true
184  */
185 
186 static void
187 check_event(iscsi_wait_event_parameters_t *par, bool wait)
188 {
189 	event_handler_t *handler;
190 	event_t *evt;
191 	int rc;
192 
193 	mutex_enter(&iscsi_cleanup_mtx);
194 	handler = find_handler(par->event_id);
195 	if (handler == NULL) {
196 		mutex_exit(&iscsi_cleanup_mtx);
197 		DEBOUT(("Wait Event ID %d not found\n", par->event_id));
198 		par->status = ISCSI_STATUS_INVALID_EVENT_ID;
199 		return;
200 	}
201 	if (handler->evh_waiter != NULL) {
202 		mutex_exit(&iscsi_cleanup_mtx);
203 		DEBOUT(("Wait Event ID %d already waiting\n", par->event_id));
204 		par->status = ISCSI_STATUS_EVENT_WAITING;
205 		return;
206 	}
207 	par->status = ISCSI_STATUS_SUCCESS;
208 	DEB(99, ("Wait Event ID %d\n", par->event_id));
209 
210 	do {
211 		evt = TAILQ_FIRST(&handler->evh_events);
212 		if (evt != NULL) {
213 			TAILQ_REMOVE(&handler->evh_events, evt, ev_link);
214 		} else {
215 			if (!wait) {
216 				par->status = ISCSI_STATUS_LIST_EMPTY;
217 				return;
218 			}
219 			if (par->status != ISCSI_STATUS_SUCCESS) {
220 				return;
221 			}
222 			handler->evh_waiter = par;
223 			rc = cv_wait_sig(&iscsi_event_cv, &iscsi_cleanup_mtx);
224 			if (rc) {
225 				mutex_exit(&iscsi_cleanup_mtx);
226 				par->status = ISCSI_STATUS_LIST_EMPTY;
227 				return;
228 			}
229 		}
230 	} while (evt == NULL);
231 	mutex_exit(&iscsi_cleanup_mtx);
232 
233 	par->connection_id = evt->ev_connection_id;
234 	par->session_id = evt->ev_session_id;
235 	par->event_kind = evt->ev_event_kind;
236 	par->reason = evt->ev_reason;
237 
238 	free(evt, M_TEMP);
239 }
240 
241 /*
242  * add_event
243  *    Adds an event entry to each registered handler queue.
244  *    Note that events are simply duplicated because we expect the number of
245  *    handlers to be very small, usually 1 (the daemon).
246  *
247  *    Parameters:
248  *       kind     The event kind
249  *       sid      The ID of the affected session
250  *       cid      The ID of the affected connection
251  *       reason   The reason code
252  */
253 
254 void
255 add_event(iscsi_event_t kind, uint32_t sid, uint32_t cid, uint32_t reason)
256 {
257 	event_handler_t *curr;
258 	event_t *evt;
259 
260 	DEB(9, ("Add_event kind %d, sid %d, cid %d, reason %d\n",
261 		kind, sid, cid, reason));
262 
263 	mutex_enter(&iscsi_cleanup_mtx);
264 	TAILQ_FOREACH(curr, &event_handlers, evh_link) {
265 		evt = malloc(sizeof(*evt), M_TEMP, M_NOWAIT);
266 		if (evt == NULL) {
267 			DEBOUT(("Cannot allocate event\n"));
268 			break;
269 		}
270 		evt->ev_event_kind = kind;
271 		evt->ev_session_id = sid;
272 		evt->ev_connection_id = cid;
273 		evt->ev_reason = reason;
274 
275 		TAILQ_INSERT_TAIL(&curr->evh_events, evt, ev_link);
276 		if (curr->evh_waiter != NULL) {
277 			curr->evh_waiter = NULL;
278 			cv_broadcast(&iscsi_event_cv);
279 		}
280 	}
281 	mutex_exit(&iscsi_cleanup_mtx);
282 }
283 
284 
285 /*
286  * check_event_handlers
287  *    Checks for dead event handlers. A dead event handler would deplete
288  *    memory over time, so we have to make sure someone at the other
289  *    end is actively monitoring events.
290  *    This function is called every 30 seconds or so (less frequent if there
291  *    is other activity for the cleanup thread to deal with) to go through
292  *    the list of handlers and check whether the first element in the event
293  *    list has changed at all. If not, the event is deregistered.
294  *    Note that this will not detect dead handlers if no events are pending,
295  *    but we don't care as long as events don't accumulate in the list.
296  *
297  */
298 
299 static void
300 check_event_handlers(void)
301 {
302 	event_handler_t *curr, *next;
303 	event_t *evt;
304 
305 	KASSERT(mutex_owned(&iscsi_cleanup_mtx));
306 
307 	for (curr = TAILQ_FIRST(&event_handlers); curr != NULL; curr = next) {
308 		next = TAILQ_NEXT(curr, evh_link);
309 		evt = TAILQ_FIRST(&curr->evh_events);
310 
311 		if (evt != NULL && evt == curr->evh_first_in_list) {
312 			DEBOUT(("Found Dead Event Handler %d, removing\n", curr->evh_id));
313 
314 			TAILQ_REMOVE(&event_handlers, curr, evh_link);
315 			while ((evt = TAILQ_FIRST(&curr->evh_events)) != NULL) {
316 				TAILQ_REMOVE(&curr->evh_events, evt, ev_link);
317 				free(evt, M_TEMP);
318 			}
319 			free(curr, M_DEVBUF);
320 		} else
321 			curr->evh_first_in_list = evt;
322 	}
323 }
324 
325 
326 /* -------------------------------------------------------------------------- */
327 
328 /*
329  * get_socket:
330  *    Get the file pointer from the socket handle passed into login.
331  *
332  *    Parameter:
333  *          fdes     IN: The socket handle
334  *          fpp      OUT: The pointer to the resulting file pointer
335  *
336  *    Returns:    0 on success, else an error code.
337  *
338  */
339 
340 static int
341 get_socket(int fdes, struct file **fpp)
342 {
343 	struct file *fp;
344 
345 	if ((fp = fd_getfile(fdes)) == NULL) {
346 		return EBADF;
347 	}
348 	if (fp->f_type != DTYPE_SOCKET) {
349 		return ENOTSOCK;
350 	}
351 
352 	/* Add the reference */
353 	mutex_enter(&fp->f_lock);
354 	fp->f_count++;
355 	mutex_exit(&fp->f_lock);
356 
357 	*fpp = fp;
358 	return 0;
359 }
360 
361 /*
362  * release_socket:
363  *    Release the file pointer from the socket handle passed into login.
364  *
365  *    Parameter:
366  *          fp       IN: The pointer to the resulting file pointer
367  *
368  */
369 
370 static void
371 release_socket(struct file *fp)
372 {
373 	/* Add the reference */
374 	mutex_enter(&fp->f_lock);
375 	fp->f_count--;
376 	mutex_exit(&fp->f_lock);
377 }
378 
379 
380 /*
381  * find_session:
382  *    Find a session by ID.
383  *
384  *    Parameter:  the session ID
385  *
386  *    Returns:    The pointer to the session (or NULL if not found)
387  */
388 
389 session_t *
390 find_session(uint32_t id)
391 {
392 	session_t *sess;
393 
394 	KASSERT(mutex_owned(&iscsi_cleanup_mtx));
395 
396 	TAILQ_FOREACH(sess, &iscsi_sessions, s_sessions)
397 		if (sess->s_id == id) {
398 			break;
399 		}
400 	return sess;
401 }
402 
403 
404 /*
405  * find_connection:
406  *    Find a connection by ID.
407  *
408  *    Parameter:  the session pointer and the connection ID
409  *
410  *    Returns:    The pointer to the connection (or NULL if not found)
411  */
412 
413 connection_t *
414 find_connection(session_t *sess, uint32_t id)
415 {
416 	connection_t *conn;
417 
418 	KASSERT(mutex_owned(&iscsi_cleanup_mtx));
419 
420 	TAILQ_FOREACH(conn, &sess->s_conn_list, c_connections)
421 		if (conn->c_id == id) {
422 			break;
423 		}
424 	return conn;
425 }
426 
427 /*
428  * ref_session:
429  *    Reference a session
430  *
431  *    Session cannot be release until reference count reaches zero
432  *
433  *    Returns: 1 if reference counter would overflow
434  */
435 
436 int
437 ref_session(session_t *sess)
438 {
439 	int rc = 1;
440 
441 	mutex_enter(&iscsi_cleanup_mtx);
442 	KASSERT(sess != NULL);
443 	if (sess->s_refcount <= CCBS_PER_SESSION) {
444 		sess->s_refcount++;
445 		rc = 0;
446 	}
447 	mutex_exit(&iscsi_cleanup_mtx);
448 
449 	return rc;
450 }
451 
452 /*
453  * unref_session:
454  *    Unreference a session
455  *
456  *    Release session reference, trigger cleanup
457  */
458 
459 void
460 unref_session(session_t *session)
461 {
462 
463 	mutex_enter(&iscsi_cleanup_mtx);
464 	KASSERT(session != NULL);
465 	KASSERT(session->s_refcount > 0);
466 	if (--session->s_refcount == 0)
467 		cv_broadcast(&session->s_sess_cv);
468 	mutex_exit(&iscsi_cleanup_mtx);
469 }
470 
471 
472 /*
473  * kill_connection:
474  *    Terminate the connection as gracefully as possible.
475  *
476  *    Parameter:
477  *		conn		The connection to terminate
478  *		status		The status code for the connection's "terminating" field
479  *		logout		The logout reason code
480  *		recover	Attempt to recover connection
481  */
482 
483 void
484 kill_connection(connection_t *conn, uint32_t status, int logout, bool recover)
485 {
486 	session_t *sess = conn->c_session;
487 	int terminating;
488 
489 	DEBC(conn, 1, ("Kill_connection: terminating=%d, status=%d, logout=%d, "
490 			   "state=%d\n",
491 			   conn->c_terminating, status, logout, conn->c_state));
492 
493 	mutex_enter(&iscsi_cleanup_mtx);
494 	if (recover &&
495 	    !conn->c_destroy &&
496 	    conn->c_recover > MAX_RECOVERY_ATTEMPTS) {
497 		DEBC(conn, 1, ("Kill_connection: Too many recovery attempts, "
498 		               "destroying\n"));
499 		conn->c_destroy = TRUE;
500 	}
501 
502 	if (!recover || conn->c_destroy) {
503 
504 		if (conn->c_in_session) {
505 			conn->c_in_session = FALSE;
506 			TAILQ_REMOVE(&sess->s_conn_list, conn, c_connections);
507 			sess->s_mru_connection = TAILQ_FIRST(&sess->s_conn_list);
508 		}
509 
510 		if (!conn->c_destroy) {
511 			DEBC(conn, 1, ("Kill_connection setting destroy flag\n"));
512 			conn->c_destroy = TRUE;
513 		}
514 	}
515 
516 	terminating = conn->c_terminating;
517 	if (!terminating)
518 		conn->c_terminating = status;
519 
520 	/* Don't recurse */
521 	if (terminating) {
522 		mutex_exit(&iscsi_cleanup_mtx);
523 
524 		KASSERT(conn->c_state != ST_FULL_FEATURE);
525 		DEBC(conn, 1, ("Kill_connection exiting (already terminating)\n"));
526 		goto done;
527 	}
528 
529 	if (conn->c_state == ST_FULL_FEATURE) {
530 		sess->s_active_connections--;
531 		conn->c_state = ST_WINDING_DOWN;
532 
533 		/* If this is the last connection and ERL < 2, reset TSIH */
534 		if (!sess->s_active_connections && sess->s_ErrorRecoveryLevel < 2)
535 			sess->s_TSIH = 0;
536 
537 		/* Don't try to log out if the socket is broken or we're in the middle */
538 		/* of logging in */
539 		if (logout >= 0) {
540 			if (sess->s_ErrorRecoveryLevel < 2 &&
541 			    logout == RECOVER_CONNECTION) {
542 				logout = LOGOUT_CONNECTION;
543 			}
544 			if (!sess->s_active_connections &&
545 			    logout == LOGOUT_CONNECTION) {
546 				logout = LOGOUT_SESSION;
547 			}
548 			mutex_exit(&iscsi_cleanup_mtx);
549 
550 			DEBC(conn, 1, ("Send_logout for reason %d\n", logout));
551 
552 			connection_timeout_start(conn, CONNECTION_TIMEOUT);
553 
554 			if (!send_logout(conn, conn, logout, FALSE)) {
555 				conn->c_terminating = ISCSI_STATUS_SUCCESS;
556 				return;
557 			}
558 			/*
559 			 * if the logout request was successfully sent,
560 			 * the logout response handler will do the rest
561 			 * of the termination processing. If the logout
562 			 * doesn't get a response, we'll get back in here
563 			 * once the timeout hits.
564 			 */
565 
566 			mutex_enter(&iscsi_cleanup_mtx);
567 		}
568 
569 	}
570 
571 	conn->c_state = ST_SETTLING;
572 	mutex_exit(&iscsi_cleanup_mtx);
573 
574 done:
575 	/* let send thread take over next step of cleanup */
576 	mutex_enter(&conn->c_lock);
577 	cv_broadcast(&conn->c_conn_cv);
578 	mutex_exit(&conn->c_lock);
579 
580 	DEBC(conn, 5, ("kill_connection returns\n"));
581 }
582 
583 
584 /*
585  * kill_session:
586  *    Terminate the session as gracefully as possible.
587  *
588  *    Parameter:
589  *		session		Session to terminate
590  *		status		The status code for the termination
591  *		logout		The logout reason code
592 
593  */
594 
595 void
596 kill_session(uint32_t sid, uint32_t status, int logout, bool recover)
597 {
598 	session_t *sess;
599 	connection_t *conn;
600 
601 	DEB(1, ("ISCSI: kill_session %d, status %d, logout %d, recover %d\n",
602 			sid, status, logout, recover));
603 
604 	mutex_enter(&iscsi_cleanup_mtx);
605 
606 	sess = find_session(sid);
607 	if (sess == NULL) {
608 		mutex_exit(&iscsi_cleanup_mtx);
609 
610 		DEB(5, ("Session %u already gone\n", sid));
611 		return;
612 	}
613 
614 	if (sess->s_terminating) {
615 		mutex_exit(&iscsi_cleanup_mtx);
616 
617 		DEB(5, ("Session is being killed with status %d\n",sess->s_terminating));
618 		return;
619 	}
620 
621 	/*
622 	 * don't do anything if session isn't established yet, termination will be
623 	 * handled elsewhere
624 	 */
625 	if (sess->s_sessions.tqe_next == NULL && sess->s_sessions.tqe_prev == NULL) {
626 		mutex_exit(&iscsi_cleanup_mtx);
627 
628 		DEB(5, ("Session is being killed which is not yet established\n"));
629 		return;
630 	}
631 
632 	if (recover) {
633 		mutex_exit(&iscsi_cleanup_mtx);
634 
635 		/*
636 		 * Only recover when there's just one active connection left.
637 		 * Otherwise we get in all sorts of timing problems, and it doesn't
638 		 * make much sense anyway to recover when the other side has
639 		 * requested that we kill a multipathed session.
640 		 */
641 		if (sess->s_active_connections == 1) {
642 			conn = assign_connection(sess, FALSE);
643 			if (conn != NULL)
644 				kill_connection(conn, status, logout, TRUE);
645 		}
646 		return;
647 	}
648 
649 	if (sess->s_refcount > 0) {
650 		mutex_exit(&iscsi_cleanup_mtx);
651 
652 		DEB(5, ("Session is being killed while in use (refcnt = %d)\n",
653 			sess->s_refcount));
654 		return;
655 	}
656 
657 	/* Remove session from global list */
658 	sess->s_terminating = status;
659 	TAILQ_REMOVE(&iscsi_sessions, sess, s_sessions);
660 	sess->s_sessions.tqe_next = NULL;
661 	sess->s_sessions.tqe_prev = NULL;
662 
663 	/*
664 	 * If all connections are already gone, trigger cleanup
665 	 * otherwise, the last connection will do this
666 	 */
667 	if (sess->s_active_connections == 0)
668 		iscsi_notify_cleanup();
669 
670 	mutex_exit(&iscsi_cleanup_mtx);
671 
672 	/* kill all connections */
673 	while ((conn = TAILQ_FIRST(&sess->s_conn_list)) != NULL) {
674 		kill_connection(conn, status, logout, FALSE);
675 		logout = NO_LOGOUT;
676 	}
677 }
678 
679 
680 /*
681  * create_connection:
682  *    Create and init the necessary framework for a connection:
683  *       Take over userland socket
684  *       Alloc the connection structure itself
685  *       Copy connection parameters
686  *       Create the send and receive threads
687  *       And finally, log in.
688  *
689  *    Parameter:
690  *          par      IN/OUT: The login parameters
691  *          session  IN: The owning session
692  *          l        IN: The lwp pointer of the caller
693  *
694  *    Returns:    0 on success
695  *                >0 on failure, connection structure deleted
696  *                <0 on failure, connection is still terminating
697  */
698 
699 static int
700 create_connection(iscsi_login_parameters_t *par, session_t *sess,
701 				  struct lwp *l)
702 {
703 	connection_t *conn;
704 	int rc;
705 
706 	DEB(1, ("Create Connection for Session %d\n", sess->s_id));
707 
708 	if (sess->s_MaxConnections &&
709 	    sess->s_active_connections >= sess->s_MaxConnections) {
710 		DEBOUT(("Too many connections (max = %d, curr = %d)\n",
711 				sess->s_MaxConnections, sess->s_active_connections));
712 		/* Always close descriptor */
713 		fd_close(par->socket);
714 
715 		par->status = ISCSI_STATUS_MAXED_CONNECTIONS;
716 		return EIO;
717 	}
718 
719 	conn = malloc(sizeof(*conn), M_DEVBUF, M_WAITOK | M_ZERO);
720 	if (conn == NULL) {
721 		DEBOUT(("No mem for connection\n"));
722 
723 		/* Always close descriptor */
724 		fd_close(par->socket);
725 
726 		par->status = ISCSI_STATUS_NO_RESOURCES;
727 		return EIO;
728 	}
729 
730 	rc = get_socket(par->socket, &conn->c_sock);
731 	fd_close(par->socket);
732 
733 	if (rc) {
734 		DEBOUT(("Invalid socket %d\n", par->socket));
735 
736 		callout_destroy(&conn->c_timeout);
737 		rw_destroy(&conn->c_sock_rw);
738 		cv_destroy(&conn->c_idle_cv);
739 		cv_destroy(&conn->c_ccb_cv);
740 		cv_destroy(&conn->c_pdu_cv);
741 		cv_destroy(&conn->c_conn_cv);
742 		mutex_destroy(&conn->c_lock);
743 		free(conn, M_DEVBUF);
744 		par->status = ISCSI_STATUS_INVALID_SOCKET;
745 		return rc;
746 	}
747 
748 	DEBC(conn, 1, ("get_socket: par_sock=%d, fdesc=%p\n",
749 			par->socket, conn->c_sock));
750 
751 	mutex_enter(&iscsi_cleanup_mtx);
752 	/* create a unique ID */
753 	do {
754 		++sess->s_conn_id;
755 	} while (!sess->s_conn_id ||
756 		 find_connection(sess, sess->s_conn_id) != NULL);
757 	par->connection_id = conn->c_id = sess->s_conn_id;
758 	mutex_exit(&iscsi_cleanup_mtx);
759 	DEB(99, ("Connection ID = %d\n", conn->c_id));
760 
761 	conn->c_session = sess;
762 
763 	TAILQ_INIT(&conn->c_ccbs_waiting);
764 	TAILQ_INIT(&conn->c_pdus_to_send);
765 	TAILQ_INIT(&conn->c_pdu_pool);
766 
767 	mutex_init(&conn->c_lock, MUTEX_DEFAULT, IPL_BIO);
768 	cv_init(&conn->c_conn_cv, "conn");
769 	cv_init(&conn->c_pdu_cv, "pdupool");
770 	cv_init(&conn->c_ccb_cv, "ccbwait");
771 	cv_init(&conn->c_idle_cv, "idle");
772 	rw_init(&conn->c_sock_rw);
773 
774 	callout_init(&conn->c_timeout, CALLOUT_MPSAFE);
775 	callout_setfunc(&conn->c_timeout, connection_timeout_co, conn);
776 	conn->c_idle_timeout_val = CONNECTION_IDLE_TIMEOUT;
777 
778 	init_sernum(&conn->c_StatSN_buf);
779 	create_pdus(conn);
780 
781 	conn->c_threadobj = l;
782 	conn->c_login_par = par;
783 
784 	DEB(5, ("Creating receive thread\n"));
785 	if ((rc = kthread_create(PRI_BIO, KTHREAD_MPSAFE, NULL, iscsi_rcv_thread,
786 				conn, &conn->c_rcvproc,
787 				"ConnRcv")) != 0) {
788 		DEBOUT(("Can't create rcv thread (rc %d)\n", rc));
789 
790 		release_socket(conn->c_sock);
791 		rw_destroy(&conn->c_sock_rw);
792 		callout_destroy(&conn->c_timeout);
793 		cv_destroy(&conn->c_idle_cv);
794 		cv_destroy(&conn->c_ccb_cv);
795 		cv_destroy(&conn->c_pdu_cv);
796 		cv_destroy(&conn->c_conn_cv);
797 		mutex_destroy(&conn->c_lock);
798 		free(conn, M_DEVBUF);
799 		par->status = ISCSI_STATUS_NO_RESOURCES;
800 		return rc;
801 	}
802 	DEB(5, ("Creating send thread\n"));
803 	if ((rc = kthread_create(PRI_BIO, KTHREAD_MPSAFE, NULL, iscsi_send_thread,
804 				conn, &conn->c_sendproc,
805 				"ConnSend")) != 0) {
806 		DEBOUT(("Can't create send thread (rc %d)\n", rc));
807 
808 		conn->c_terminating = ISCSI_STATUS_NO_RESOURCES;
809 
810 		/*
811 		 * We must close the socket here to force the receive
812 		 * thread to wake up
813 		 */
814 		DEBC(conn, 1, ("Closing Socket %p\n", conn->c_sock));
815 		mutex_enter(&conn->c_sock->f_lock);
816 		conn->c_sock->f_count += 1;
817 		mutex_exit(&conn->c_sock->f_lock);
818 		closef(conn->c_sock);
819 
820 		/* give receive thread time to exit */
821 		kpause("settle", false, 2 * hz, NULL);
822 
823 		release_socket(conn->c_sock);
824 		callout_destroy(&conn->c_timeout);
825 		rw_destroy(&conn->c_sock_rw);
826 		cv_destroy(&conn->c_idle_cv);
827 		cv_destroy(&conn->c_ccb_cv);
828 		cv_destroy(&conn->c_pdu_cv);
829 		cv_destroy(&conn->c_conn_cv);
830 		mutex_destroy(&conn->c_lock);
831 		free(conn, M_DEVBUF);
832 		par->status = ISCSI_STATUS_NO_RESOURCES;
833 		return rc;
834 	}
835 
836 	/*
837 	 * At this point, each thread will tie 'sock' into its own file descriptor
838 	 * tables w/o increasing the use count - they will inherit the use
839 	 * increments performed in get_socket().
840 	 */
841 
842 	if ((rc = send_login(conn)) != 0) {
843 		DEBC(conn, 0, ("Login failed (rc %d)\n", rc));
844 		/* Don't attempt to recover, there seems to be something amiss */
845 		kill_connection(conn, rc, NO_LOGOUT, FALSE);
846 		par->status = rc;
847 		return -1;
848 	}
849 
850 	mutex_enter(&iscsi_cleanup_mtx);
851 	if (sess->s_terminating) {
852 		mutex_exit(&iscsi_cleanup_mtx);
853 		DEBC(conn, 0, ("Session terminating\n"));
854 		kill_connection(conn, rc, NO_LOGOUT, FALSE);
855 		par->status = sess->s_terminating;
856 		return -1;
857 	}
858 	conn->c_state = ST_FULL_FEATURE;
859 	TAILQ_INSERT_TAIL(&sess->s_conn_list, conn, c_connections);
860 	conn->c_in_session = TRUE;
861 	sess->s_total_connections++;
862 	sess->s_active_connections++;
863 	sess->s_mru_connection = conn;
864 	mutex_exit(&iscsi_cleanup_mtx);
865 
866 	DEBC(conn, 5, ("Connection created successfully!\n"));
867 	return 0;
868 }
869 
870 
871 /*
872  * recreate_connection:
873  *    Revive dead connection
874  *
875  *    Parameter:
876  *          par      IN/OUT: The login parameters
877  *          conn     IN: The connection
878  *          l        IN: The lwp pointer of the caller
879  *
880  *    Returns:    0 on success
881  *                >0 on failure, connection structure deleted
882  *                <0 on failure, connection is still terminating
883  */
884 
885 static int
886 recreate_connection(iscsi_login_parameters_t *par, session_t *sess,
887 					connection_t *conn, struct lwp *l)
888 {
889 	int rc;
890 	ccb_t *ccb;
891 	ccb_list_t old_waiting;
892 	pdu_t *pdu;
893 	uint32_t sn;
894 
895 	DEB(1, ("ReCreate Connection %d for Session %d, ERL=%d\n",
896 		conn->c_id, conn->c_session->s_id,
897 		conn->c_session->s_ErrorRecoveryLevel));
898 
899 	if (sess->s_MaxConnections &&
900 	    sess->s_active_connections >= sess->s_MaxConnections) {
901 		DEBOUT(("Too many connections (max = %d, curr = %d)\n",
902 			sess->s_MaxConnections, sess->s_active_connections));
903 
904 		/* Always close the desecriptor */
905 		fd_close(par->socket);
906 
907 		par->status = ISCSI_STATUS_MAXED_CONNECTIONS;
908 		return EIO;
909 	}
910 
911 	rw_enter(&conn->c_sock_rw, RW_WRITER);
912 	if (conn->c_sock != NULL) {
913 		closef(conn->c_sock);
914 		conn->c_sock = NULL;
915 	}
916 	rc = get_socket(par->socket, &conn->c_sock);
917 	rw_exit(&conn->c_sock_rw);
918 	fd_close(par->socket);
919 
920 	if (rc) {
921 		DEBOUT(("Invalid socket %d\n", par->socket));
922 		par->status = ISCSI_STATUS_INVALID_SOCKET;
923 		return rc;
924 	}
925 
926 	DEBC(conn, 1, ("get_socket: par_sock=%d, fdesc=%p\n",
927 			par->socket, conn->c_sock));
928 
929 	conn->c_threadobj = l;
930 	conn->c_login_par = par;
931 	conn->c_terminating = ISCSI_STATUS_SUCCESS;
932 	conn->c_recover++;
933 	conn->c_num_timeouts = 0;
934 	conn->c_state = ST_SEC_NEG;
935 	conn->c_HeaderDigest = 0;
936 	conn->c_DataDigest = 0;
937 
938 	sess->s_active_connections++;
939 
940 	TAILQ_INIT(&old_waiting);
941 
942 	mutex_enter(&conn->c_lock);
943 	while ((ccb = TAILQ_FIRST(&conn->c_ccbs_waiting)) != NULL) {
944 		suspend_ccb(ccb, FALSE);
945 		TAILQ_INSERT_TAIL(&old_waiting, ccb, ccb_chain);
946 	}
947 	init_sernum(&conn->c_StatSN_buf);
948 	cv_broadcast(&conn->c_idle_cv);
949 	mutex_exit(&conn->c_lock);
950 
951 	if ((rc = send_login(conn)) != 0) {
952 		DEBC(conn, 0, ("Re-Login failed (rc %d)\n", rc));
953 		while ((ccb = TAILQ_FIRST(&old_waiting)) != NULL) {
954 			TAILQ_REMOVE(&old_waiting, ccb, ccb_chain);
955 			wake_ccb(ccb, rc);
956 		}
957 		/* Don't attempt to recover, there seems to be something amiss */
958 		kill_connection(conn, rc, NO_LOGOUT, FALSE);
959 		par->status = rc;
960 		return -1;
961 	}
962 
963 	DEBC(conn, 9, ("Re-Login successful\n"));
964 	par->status = ISCSI_STATUS_SUCCESS;
965 
966 	conn->c_state = ST_FULL_FEATURE;
967 	sess->s_mru_connection = conn;
968 
969 	while ((ccb = TAILQ_FIRST(&old_waiting)) != NULL) {
970 		TAILQ_REMOVE(&old_waiting, ccb, ccb_chain);
971 		mutex_enter(&conn->c_lock);
972 		suspend_ccb(ccb, TRUE);
973 		mutex_exit(&conn->c_lock);
974 
975 		rc = send_task_management(conn, ccb, NULL, TASK_REASSIGN);
976 		/* if we get an error on reassign, restart the original request */
977 		if (rc && ccb->ccb_pdu_waiting != NULL) {
978 			mutex_enter(&sess->s_lock);
979 			if (sn_a_lt_b(ccb->ccb_CmdSN, sess->s_ExpCmdSN)) {
980 				pdu = ccb->ccb_pdu_waiting;
981 				sn = get_sernum(sess, pdu);
982 
983 				/* update CmdSN */
984 				DEBC(conn, 0, ("Resend ccb %p (%d) - updating CmdSN old %u, new %u\n",
985 					   ccb, rc, ccb->ccb_CmdSN, sn));
986 				ccb->ccb_CmdSN = sn;
987 				pdu->pdu_hdr.pduh_p.command.CmdSN = htonl(ccb->ccb_CmdSN);
988 			} else {
989 				DEBC(conn, 0, ("Resend ccb %p (%d) - CmdSN %u\n",
990 					   ccb, rc, ccb->ccb_CmdSN));
991 			}
992 			mutex_exit(&sess->s_lock);
993 			resend_pdu(ccb);
994 		} else {
995 			DEBC(conn, 0, ("Resend ccb %p (%d) CmdSN %u - reassigned\n",
996 				ccb, rc, ccb->ccb_CmdSN));
997 			ccb_timeout_start(ccb, COMMAND_TIMEOUT);
998 		}
999 	}
1000 
1001 	mutex_enter(&sess->s_lock);
1002 	cv_broadcast(&sess->s_sess_cv);
1003 	mutex_exit(&sess->s_lock);
1004 
1005 	DEBC(conn, 0, ("Connection ReCreated successfully - status %d\n",
1006 						 par->status));
1007 
1008 	return 0;
1009 }
1010 
1011 /* -------------------------------------------------------------------------- */
1012 
1013 /*
1014  * check_login_pars:
1015  *    Check the parameters passed into login/add_connection
1016  *    for validity and consistency.
1017  *
1018  *    Parameter:
1019  *          par      The login parameters
1020  *
1021  *    Returns:    0 on success, else an error code.
1022  */
1023 
1024 static int
1025 check_login_pars(iscsi_login_parameters_t *par)
1026 {
1027 	int i, n;
1028 
1029 	if (par->is_present.auth_info) {
1030 		/* check consistency of authentication parameters */
1031 
1032 		if (par->auth_info.auth_number > ISCSI_AUTH_OPTIONS) {
1033 			DEBOUT(("Auth number invalid: %d\n", par->auth_info.auth_number));
1034 			return ISCSI_STATUS_PARAMETER_INVALID;
1035 		}
1036 
1037 		if (par->auth_info.auth_number > 2) {
1038 			DEBOUT(("Auth number invalid: %d\n", par->auth_info.auth_number));
1039 			return ISCSI_STATUS_NOTIMPL;
1040 		}
1041 
1042 		for (i = 0, n = 0; i < par->auth_info.auth_number; i++) {
1043 #if 0
1044 			if (par->auth_info.auth_type[i] < ISCSI_AUTH_None) {
1045 				DEBOUT(("Auth type invalid: %d\n",
1046 						par->auth_info.auth_type[i]));
1047 				return ISCSI_STATUS_PARAMETER_INVALID;
1048 			}
1049 #endif
1050 			if (par->auth_info.auth_type[i] > ISCSI_AUTH_CHAP) {
1051 				DEBOUT(("Auth type invalid: %d\n",
1052 						par->auth_info.auth_type[i]));
1053 				return ISCSI_STATUS_NOTIMPL;
1054 			}
1055 			n = max(n, par->auth_info.auth_type[i]);
1056 		}
1057 		if (n) {
1058 			if (!par->is_present.password ||
1059 				(par->auth_info.mutual_auth &&
1060 				 !par->is_present.target_password)) {
1061 				DEBOUT(("Password missing\n"));
1062 				return ISCSI_STATUS_PARAMETER_MISSING;
1063 			}
1064 			/* Note: Default for user-name is initiator name */
1065 		}
1066 	}
1067 	if (par->login_type != ISCSI_LOGINTYPE_DISCOVERY &&
1068 	    !par->is_present.TargetName) {
1069 		DEBOUT(("Target name missing, login type %d\n", par->login_type));
1070 		return ISCSI_STATUS_PARAMETER_MISSING;
1071 	}
1072 	if (par->is_present.MaxRecvDataSegmentLength) {
1073 		if (par->MaxRecvDataSegmentLength < 512 ||
1074 			par->MaxRecvDataSegmentLength > 0xffffff) {
1075 			DEBOUT(("MaxRecvDataSegmentLength invalid: %d\n",
1076 					par->MaxRecvDataSegmentLength));
1077 			return ISCSI_STATUS_PARAMETER_INVALID;
1078 		}
1079 	}
1080 	return 0;
1081 }
1082 
1083 
1084 /*
1085  * login:
1086  *    Handle the login ioctl - Create a session:
1087  *       Alloc the session structure
1088  *       Copy session parameters
1089  *       And call create_connection to establish the connection.
1090  *
1091  *    Parameter:
1092  *          par      IN/OUT: The login parameters
1093  *          l        IN: The lwp pointer of the caller
1094  */
1095 
1096 static void
1097 login(iscsi_login_parameters_t *par, struct lwp *l, device_t dev)
1098 {
1099 	session_t *sess;
1100 	int rc;
1101 
1102 	DEB(99, ("ISCSI: login\n"));
1103 
1104 	if (!iscsi_InitiatorName[0]) {
1105 		DEB(1, ("No Initiator Name\n"));
1106 		par->status = ISCSI_STATUS_NO_INITIATOR_NAME;
1107 		return;
1108 	}
1109 
1110 	if ((par->status = check_login_pars(par)) != 0)
1111 		return;
1112 
1113 	/* alloc the session */
1114 	sess = malloc(sizeof(*sess), M_DEVBUF, M_WAITOK | M_ZERO);
1115 	if (sess == NULL) {
1116 		DEBOUT(("No mem for session\n"));
1117 		par->status = ISCSI_STATUS_NO_RESOURCES;
1118 		return;
1119 	}
1120 	TAILQ_INIT(&sess->s_conn_list);
1121 	TAILQ_INIT(&sess->s_ccb_pool);
1122 
1123 	mutex_init(&sess->s_lock, MUTEX_DEFAULT, IPL_BIO);
1124 	cv_init(&sess->s_sess_cv, "session");
1125 	cv_init(&sess->s_ccb_cv, "ccb");
1126 
1127 	mutex_enter(&iscsi_cleanup_mtx);
1128 	/* create a unique ID */
1129 	do {
1130 		++current_id;
1131 	} while (!current_id || find_session(current_id) != NULL);
1132 	par->session_id = sess->s_id = current_id;
1133 	mutex_exit(&iscsi_cleanup_mtx);
1134 
1135 	create_ccbs(sess);
1136 	sess->s_login_type = par->login_type;
1137 	sess->s_CmdSN = 1;
1138 
1139 	if ((rc = create_connection(par, sess, l)) != 0) {
1140 		if (rc > 0) {
1141 			destroy_ccbs(sess);
1142 			cv_destroy(&sess->s_ccb_cv);
1143 			cv_destroy(&sess->s_sess_cv);
1144 			mutex_destroy(&sess->s_lock);
1145 			free(sess, M_DEVBUF);
1146 		}
1147 		return;
1148 	}
1149 
1150 	mutex_enter(&iscsi_cleanup_mtx);
1151 	TAILQ_INSERT_HEAD(&iscsi_sessions, sess, s_sessions);
1152 	mutex_exit(&iscsi_cleanup_mtx);
1153 
1154 	/* Session established, map LUNs? */
1155 	if (par->login_type == ISCSI_LOGINTYPE_MAP) {
1156 		copyinstr(par->TargetName, sess->s_tgtname,
1157 		    sizeof(sess->s_tgtname), NULL);
1158 		DEB(1, ("Login: map session %d\n", sess->s_id));
1159 		if (!map_session(sess, dev)) {
1160 			DEB(1, ("Login: map session %d failed\n", sess->s_id));
1161 			kill_session(par->session_id, ISCSI_STATUS_MAP_FAILED,
1162 					LOGOUT_SESSION, FALSE);
1163 			par->status = ISCSI_STATUS_MAP_FAILED;
1164 			return;
1165 		}
1166 	}
1167 }
1168 
1169 
1170 /*
1171  * logout:
1172  *    Handle the logout ioctl - Kill a session.
1173  *
1174  *    Parameter:
1175  *          par      IN/OUT: The login parameters
1176  */
1177 
1178 static void
1179 logout(iscsi_logout_parameters_t *par)
1180 {
1181 	session_t *session;
1182 
1183 	DEB(5, ("ISCSI: logout session %d\n", par->session_id));
1184 
1185 	mutex_enter(&iscsi_cleanup_mtx);
1186 	if ((session = find_session(par->session_id)) == NULL) {
1187 		mutex_exit(&iscsi_cleanup_mtx);
1188 		DEBOUT(("Session %d not found\n", par->session_id));
1189 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1190 		return;
1191 	}
1192 	mutex_exit(&iscsi_cleanup_mtx);
1193 	/* If the session exists, this always succeeds */
1194 	par->status = ISCSI_STATUS_SUCCESS;
1195 
1196 	kill_session(par->session_id,
1197 	    ISCSI_STATUS_LOGOUT, LOGOUT_SESSION,
1198 	    FALSE);
1199 }
1200 
1201 
1202 /*
1203  * add_connection:
1204  *    Handle the add_connection ioctl.
1205  *
1206  *    Parameter:
1207  *          par      IN/OUT: The login parameters
1208  *          l        IN: The lwp pointer of the caller
1209  */
1210 
1211 static int
1212 add_connection(iscsi_login_parameters_t *par, struct lwp *l)
1213 {
1214 	session_t *session;
1215 
1216 	DEB(5, ("ISCSI: add_connection to session %d\n", par->session_id));
1217 
1218 	mutex_enter(&iscsi_cleanup_mtx);
1219 	if ((session = find_session(par->session_id)) == NULL) {
1220 		mutex_exit(&iscsi_cleanup_mtx);
1221 		DEBOUT(("Session %d not found\n", par->session_id));
1222 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1223 		return -1;
1224 	}
1225 	mutex_exit(&iscsi_cleanup_mtx);
1226 
1227 	par->status = check_login_pars(par);
1228 	if (par->status)
1229 		return -1;
1230 
1231 	return create_connection(par, session, l);
1232 }
1233 
1234 
1235 /*
1236  * remove_connection:
1237  *    Handle the remove_connection ioctl.
1238  *
1239  *    Parameter:
1240  *          par      IN/OUT: The remove parameters
1241  */
1242 
1243 static void
1244 remove_connection(iscsi_remove_parameters_t *par)
1245 {
1246 	connection_t *conn;
1247 	session_t *session;
1248 
1249 	DEB(5, ("ISCSI: remove_connection %d from session %d\n",
1250 			par->connection_id, par->session_id));
1251 
1252 	mutex_enter(&iscsi_cleanup_mtx);
1253 	if ((session = find_session(par->session_id)) == NULL) {
1254 		mutex_exit(&iscsi_cleanup_mtx);
1255 		DEBOUT(("Session %d not found\n", par->session_id));
1256 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1257 		return;
1258 	}
1259 
1260 	if ((conn = find_connection(session, par->connection_id)) == NULL) {
1261 		mutex_exit(&iscsi_cleanup_mtx);
1262 		DEBOUT(("Connection %d not found in session %d\n",
1263 				par->connection_id, par->session_id));
1264 
1265 		par->status = ISCSI_STATUS_INVALID_CONNECTION_ID;
1266 	} else {
1267 		mutex_exit(&iscsi_cleanup_mtx);
1268 		kill_connection(conn, ISCSI_STATUS_LOGOUT, LOGOUT_CONNECTION,
1269 					FALSE);
1270 		par->status = ISCSI_STATUS_SUCCESS;
1271 	}
1272 }
1273 
1274 
1275 /*
1276  * restore_connection:
1277  *    Handle the restore_connection ioctl.
1278  *
1279  *    Parameter:
1280  *          par      IN/OUT: The login parameters
1281  *          l        IN: The lwp pointer of the caller
1282  */
1283 
1284 static void
1285 restore_connection(iscsi_login_parameters_t *par, struct lwp *l)
1286 {
1287 	session_t *sess;
1288 	connection_t *conn;
1289 
1290 	DEB(1, ("ISCSI: restore_connection %d of session %d\n",
1291 			par->connection_id, par->session_id));
1292 
1293 	mutex_enter(&iscsi_cleanup_mtx);
1294 	if ((sess = find_session(par->session_id)) == NULL) {
1295 		mutex_exit(&iscsi_cleanup_mtx);
1296 		DEBOUT(("Session %d not found\n", par->session_id));
1297 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1298 		return;
1299 	}
1300 	if ((conn = find_connection(sess, par->connection_id)) == NULL) {
1301 		mutex_exit(&iscsi_cleanup_mtx);
1302 		DEBOUT(("Connection %d not found in session %d\n",
1303 				par->connection_id, par->session_id));
1304 		par->status = ISCSI_STATUS_INVALID_CONNECTION_ID;
1305 		return;
1306 	}
1307 	if (!conn->c_terminating) {
1308 		mutex_exit(&iscsi_cleanup_mtx);
1309 		DEBC(conn, 0, ("Connection is alive\n"));
1310 		par->status = ISCSI_STATUS_SUCCESS;
1311 		return;
1312 	}
1313 	mutex_exit(&iscsi_cleanup_mtx);
1314 
1315 	if ((par->status = check_login_pars(par)) == 0) {
1316 		recreate_connection(par, sess, conn, l);
1317 	}
1318 }
1319 
1320 
1321 #ifndef ISCSI_MINIMAL
1322 
1323 /*
1324  * io_command:
1325  *    Handle the io_command ioctl.
1326  *
1327  *    Parameter:
1328  *          par      IN/OUT: The iocommand parameters
1329  *          l        IN: The lwp pointer of the caller
1330  */
1331 
1332 static void
1333 io_command(iscsi_iocommand_parameters_t *par, struct lwp *l)
1334 {
1335 	uint32_t datalen = par->req.datalen;
1336 	session_t *session;
1337 	void *kbuf = NULL;
1338 	int error;
1339 
1340 	DEB(9, ("ISCSI: io_command, SID=%d, lun=%" PRIu64 "\n", par->session_id, par->lun));
1341 	mutex_enter(&iscsi_cleanup_mtx);
1342 	if ((session = find_session(par->session_id)) == NULL) {
1343 		mutex_exit(&iscsi_cleanup_mtx);
1344 		DEBOUT(("Session %d not found\n", par->session_id));
1345 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1346 		return;
1347 	}
1348 	mutex_exit(&iscsi_cleanup_mtx);
1349 
1350 	par->req.senselen_used = 0;
1351 	par->req.datalen_used = 0;
1352 	par->req.error = 0;
1353 	par->req.status = 0;
1354 	par->req.retsts = SCCMD_UNKNOWN;	/* init to failure code */
1355 
1356 	if (par->req.cmdlen > 16 || par->req.senselen > sizeof(par->req.sense)) {
1357 		par->status = ISCSI_STATUS_PARAMETER_INVALID;
1358 		return;
1359 	}
1360 
1361 	if (datalen) {
1362 		/* Arbitrarily limit datalen to 8k. */
1363 		if (datalen > 8192) {
1364 			par->status = ISCSI_STATUS_PARAMETER_INVALID;
1365 			return;
1366 		}
1367 		kbuf = kmem_zalloc(datalen, KM_SLEEP);
1368 		if ((par->req.flags & SCCMD_WRITE) != 0) {
1369 			error = copyin(par->req.databuf, kbuf, datalen);
1370 			if (error) {
1371 				kmem_free(kbuf, datalen);
1372 				par->status = ISCSI_STATUS_PARAMETER_INVALID;
1373 				return;
1374 			}
1375 		}
1376 	}
1377 	par->status = send_io_command(session, par->lun, &par->req,
1378 								  par->options.immediate, par->connection_id);
1379 
1380 	if (kbuf) {
1381 		if ((par->req.flags & SCCMD_READ) != 0) {
1382 			(void) copyout(kbuf, par->req.databuf, datalen);
1383 		}
1384 		kmem_free(kbuf, datalen);
1385 	}
1386 	switch (par->status) {
1387 	case ISCSI_STATUS_SUCCESS:
1388 		par->req.retsts = SCCMD_OK;
1389 		break;
1390 
1391 	case ISCSI_STATUS_TARGET_BUSY:
1392 		par->req.retsts = SCCMD_BUSY;
1393 		break;
1394 
1395 	case ISCSI_STATUS_TIMEOUT:
1396 	case ISCSI_STATUS_SOCKET_ERROR:
1397 		par->req.retsts = SCCMD_TIMEOUT;
1398 		break;
1399 
1400 	default:
1401 		par->req.retsts = (par->req.senselen_used) ? SCCMD_SENSE
1402 												   : SCCMD_UNKNOWN;
1403 		break;
1404 	}
1405 }
1406 #endif
1407 
1408 /*
1409  * send_targets:
1410  *    Handle the send_targets ioctl.
1411  *    Note: If the passed buffer is too small to hold the complete response,
1412  *    the response is kept in the session structure so it can be
1413  *    retrieved with the next call to this function without having to go to
1414  *    the target again. Once the complete response has been retrieved, it
1415  *    is discarded.
1416  *
1417  *    Parameter:
1418  *          par      IN/OUT: The send_targets parameters
1419  */
1420 
1421 static void
1422 send_targets(iscsi_send_targets_parameters_t *par)
1423 {
1424 	int rc;
1425 	uint32_t rlen, cplen;
1426 	session_t *sess;
1427 
1428 	mutex_enter(&iscsi_cleanup_mtx);
1429 	if ((sess = find_session(par->session_id)) == NULL) {
1430 		mutex_exit(&iscsi_cleanup_mtx);
1431 		DEBOUT(("Session %d not found\n", par->session_id));
1432 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1433 		return;
1434 	}
1435 	mutex_exit(&iscsi_cleanup_mtx);
1436 
1437 	DEB(9, ("ISCSI: send_targets, rsp_size=%d; Saved list: %p\n",
1438 			par->response_size, sess->s_target_list));
1439 
1440 	if (sess->s_target_list == NULL) {
1441 		rc = send_send_targets(sess, par->key);
1442 		if (rc) {
1443 			par->status = rc;
1444 			return;
1445 		}
1446 	}
1447 	rlen = sess->s_target_list_len;
1448 	par->response_total = rlen;
1449 	cplen = min(par->response_size, rlen);
1450 	if (cplen) {
1451 		copyout(sess->s_target_list, par->response_buffer, cplen);
1452 	}
1453 	par->response_used = cplen;
1454 
1455 	/* If all of the response was copied, don't keep it around */
1456 	if (rlen && par->response_used == rlen) {
1457 		free(sess->s_target_list, M_TEMP);
1458 		sess->s_target_list = NULL;
1459 	}
1460 
1461 	par->status = ISCSI_STATUS_SUCCESS;
1462 }
1463 
1464 
1465 /*
1466  * set_node_name:
1467  *    Handle the set_node_name ioctl.
1468  *
1469  *    Parameter:
1470  *          par      IN/OUT: The set_node_name parameters
1471  */
1472 
1473 static void
1474 set_node_name(iscsi_set_node_name_parameters_t *par)
1475 {
1476 
1477 	if (strlen(par->InitiatorName) >= ISCSI_STRING_LENGTH ||
1478 		strlen(par->InitiatorAlias) >= ISCSI_STRING_LENGTH) {
1479 		DEBOUT(("*** set_node_name string too long!\n"));
1480 		par->status = ISCSI_STATUS_PARAMETER_INVALID;
1481 		return;
1482 	}
1483 	strlcpy(iscsi_InitiatorName, par->InitiatorName, sizeof(iscsi_InitiatorName));
1484 	strlcpy(iscsi_InitiatorAlias, par->InitiatorAlias, sizeof(iscsi_InitiatorAlias));
1485 	memcpy(&iscsi_InitiatorISID, par->ISID, 6);
1486 	DEB(5, ("ISCSI: set_node_name, ISID A=%x, B=%x, C=%x, D=%x\n",
1487 			iscsi_InitiatorISID.ISID_A, iscsi_InitiatorISID.ISID_B,
1488 			iscsi_InitiatorISID.ISID_C, iscsi_InitiatorISID.ISID_D));
1489 
1490 	if (!iscsi_InitiatorISID.ISID_A && !iscsi_InitiatorISID.ISID_B &&
1491 		!iscsi_InitiatorISID.ISID_C && !iscsi_InitiatorISID.ISID_D) {
1492 		iscsi_InitiatorISID.ISID_A = T_FORMAT_EN;
1493 		iscsi_InitiatorISID.ISID_B = htons(0x1);
1494 		iscsi_InitiatorISID.ISID_C = 0x37;
1495 		iscsi_InitiatorISID.ISID_D = 0;
1496 	}
1497 
1498 	par->status = ISCSI_STATUS_SUCCESS;
1499 }
1500 
1501 
1502 /*
1503  * connection_status:
1504  *    Handle the connection_status ioctl.
1505  *
1506  *    Parameter:
1507  *          par      IN/OUT: The status parameters
1508  */
1509 
1510 static void
1511 connection_status(iscsi_conn_status_parameters_t *par)
1512 {
1513 	connection_t *conn;
1514 	session_t *sess;
1515 
1516 	mutex_enter(&iscsi_cleanup_mtx);
1517 	if ((sess = find_session(par->session_id)) == NULL) {
1518 		mutex_exit(&iscsi_cleanup_mtx);
1519 		par->status = ISCSI_STATUS_INVALID_SESSION_ID;
1520 		return;
1521 	}
1522 
1523 	if (par->connection_id) {
1524 		conn = find_connection(sess, par->connection_id);
1525 	} else {
1526 		conn = TAILQ_FIRST(&sess->s_conn_list);
1527 	}
1528 	par->status = (conn == NULL) ? ISCSI_STATUS_INVALID_CONNECTION_ID :
1529 					ISCSI_STATUS_SUCCESS;
1530 	mutex_exit(&iscsi_cleanup_mtx);
1531 	DEB(9, ("ISCSI: connection_status, session %d connection %d --> %d\n",
1532 			par->session_id, par->connection_id, par->status));
1533 }
1534 
1535 
1536 /*
1537  * get_version:
1538  *    Handle the get_version ioctl.
1539  *
1540  *    Parameter:
1541  *          par      IN/OUT: The version parameters
1542  */
1543 
1544 static void
1545 get_version(iscsi_get_version_parameters_t *par)
1546 {
1547 	par->status = ISCSI_STATUS_SUCCESS;
1548 	par->interface_version = INTERFACE_VERSION;
1549 	par->major = VERSION_MAJOR;
1550 	par->minor = VERSION_MINOR;
1551 	strlcpy(par->version_string, VERSION_STRING,
1552 		sizeof(par->version_string));
1553 }
1554 
1555 
1556 /* -------------------------------------------------------------------- */
1557 
1558 /*
1559  * kill_all_sessions:
1560  *    Terminate all sessions (called when the driver unloads).
1561  */
1562 
1563 int
1564 kill_all_sessions(void)
1565 {
1566 	session_t *sess;
1567 	int rc = 0;
1568 	uint32_t sid;
1569 
1570 	mutex_enter(&iscsi_cleanup_mtx);
1571 	while ((sess = TAILQ_FIRST(&iscsi_sessions)) != NULL) {
1572 		sid = sess->s_id;
1573 		mutex_exit(&iscsi_cleanup_mtx);
1574 		kill_session(sid, ISCSI_STATUS_DRIVER_UNLOAD, LOGOUT_SESSION,
1575 				FALSE);
1576 		mutex_enter(&iscsi_cleanup_mtx);
1577 	}
1578 	if (TAILQ_FIRST(&iscsi_sessions) != NULL) {
1579 		DEBOUT(("Failed to kill all sessions\n"));
1580 		rc = EBUSY;
1581 	}
1582 	mutex_exit(&iscsi_cleanup_mtx);
1583 
1584 	return rc;
1585 }
1586 
1587 /*
1588  * handle_connection_error:
1589  *    Deal with a problem during send or receive.
1590  *
1591  *    Parameter:
1592  *       conn        The connection the problem is associated with
1593  *       status      The status code to insert into any unfinished CCBs
1594  *       dologout    Whether Logout should be attempted
1595  */
1596 
1597 void
1598 handle_connection_error(connection_t *conn, uint32_t status, int dologout)
1599 {
1600 	DEBC(conn, 0, ("*** Connection Error, status=%d, logout=%d, state=%d\n",
1601 				   status, dologout, conn->c_state));
1602 
1603 	if (!conn->c_terminating && conn->c_state <= ST_LOGOUT_SENT) {
1604 		/* if we get an error while winding down, escalate it */
1605 		if (dologout >= 0 && conn->c_state >= ST_WINDING_DOWN) {
1606 			dologout = NO_LOGOUT;
1607 		}
1608 		kill_connection(conn, status, dologout, TRUE);
1609 	}
1610 }
1611 
1612 /*
1613  * remove a connection from session and add to the cleanup list
1614  */
1615 void
1616 add_connection_cleanup(connection_t *conn)
1617 {
1618 	session_t *sess = NULL;
1619 
1620 	mutex_enter(&iscsi_cleanup_mtx);
1621 	if (conn->c_in_session) {
1622 		sess = conn->c_session;
1623 		conn->c_in_session = FALSE;
1624 		conn->c_session = NULL;
1625 		TAILQ_REMOVE(&sess->s_conn_list, conn, c_connections);
1626 		sess->s_mru_connection = TAILQ_FIRST(&sess->s_conn_list);
1627 	}
1628 	TAILQ_INSERT_TAIL(&iscsi_cleanupc_list, conn, c_connections);
1629 	iscsi_notify_cleanup();
1630 	mutex_exit(&iscsi_cleanup_mtx);
1631 }
1632 
1633 /*
1634  * callout wrappers for timeouts, the work is done by the cleanup thread
1635  */
1636 void
1637 connection_timeout_co(void *par)
1638 {
1639 	connection_t *conn = par;
1640 
1641 	mutex_enter(&iscsi_cleanup_mtx);
1642 	conn->c_timedout = TOUT_QUEUED;
1643 	TAILQ_INSERT_TAIL(&iscsi_timeout_conn_list, conn, c_tchain);
1644 	iscsi_notify_cleanup();
1645 	mutex_exit(&iscsi_cleanup_mtx);
1646 }
1647 
1648 void
1649 connection_timeout_start(connection_t *conn, int ticks)
1650 {
1651 	mutex_enter(&iscsi_cleanup_mtx);
1652 	if (conn->c_timedout != TOUT_QUEUED) {
1653 		conn->c_timedout = TOUT_ARMED;
1654 		callout_schedule(&conn->c_timeout, ticks);
1655 	}
1656 	mutex_exit(&iscsi_cleanup_mtx);
1657 }
1658 
1659 void
1660 connection_timeout_stop(connection_t *conn)
1661 {
1662 	callout_stop(&conn->c_timeout);
1663 	mutex_enter(&iscsi_cleanup_mtx);
1664 	if (conn->c_timedout == TOUT_QUEUED) {
1665 		TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, c_tchain);
1666 		conn->c_timedout = TOUT_NONE;
1667 	}
1668 	if (curlwp != iscsi_cleanproc) {
1669 		while (conn->c_timedout == TOUT_BUSY)
1670 			kpause("connbusy", false, 1, &iscsi_cleanup_mtx);
1671 	}
1672 	mutex_exit(&iscsi_cleanup_mtx);
1673 }
1674 
1675 void
1676 ccb_timeout_co(void *par)
1677 {
1678 	ccb_t *ccb = par;
1679 
1680 	mutex_enter(&iscsi_cleanup_mtx);
1681 	ccb->ccb_timedout = TOUT_QUEUED;
1682 	TAILQ_INSERT_TAIL(&iscsi_timeout_ccb_list, ccb, ccb_tchain);
1683 	iscsi_notify_cleanup();
1684 	mutex_exit(&iscsi_cleanup_mtx);
1685 }
1686 
1687 void
1688 ccb_timeout_start(ccb_t *ccb, int ticks)
1689 {
1690 	mutex_enter(&iscsi_cleanup_mtx);
1691 	if (ccb->ccb_timedout != TOUT_QUEUED) {
1692 		ccb->ccb_timedout = TOUT_ARMED;
1693 		callout_schedule(&ccb->ccb_timeout, ticks);
1694 	}
1695 	mutex_exit(&iscsi_cleanup_mtx);
1696 }
1697 
1698 void
1699 ccb_timeout_stop(ccb_t *ccb)
1700 {
1701 	callout_stop(&ccb->ccb_timeout);
1702 	mutex_enter(&iscsi_cleanup_mtx);
1703 	if (ccb->ccb_timedout == TOUT_QUEUED) {
1704 		TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, ccb_tchain);
1705 		ccb->ccb_timedout = TOUT_NONE;
1706 	}
1707 	if (curlwp != iscsi_cleanproc) {
1708 		while (ccb->ccb_timedout == TOUT_BUSY)
1709 			kpause("ccbbusy", false, 1, &iscsi_cleanup_mtx);
1710 	}
1711 	mutex_exit(&iscsi_cleanup_mtx);
1712 }
1713 
1714 /*
1715  * iscsi_cleanup_thread
1716  *    Global thread to handle connection and session cleanup after termination.
1717  */
1718 
1719 static void
1720 iscsi_cleanup_thread(void *par)
1721 {
1722 	int s, rc;
1723 	session_t *sess, *nxts;
1724 	connection_t *conn, *nxtc;
1725 	ccb_t *ccb;
1726 
1727 	mutex_enter(&iscsi_cleanup_mtx);
1728 	while (iscsi_num_send_threads || !iscsi_detaching ||
1729 	       !TAILQ_EMPTY(&iscsi_cleanupc_list) || !TAILQ_EMPTY(&iscsi_cleanups_list)) {
1730 		TAILQ_FOREACH_SAFE(conn, &iscsi_cleanupc_list, c_connections, nxtc) {
1731 
1732 			TAILQ_REMOVE(&iscsi_cleanupc_list, conn, c_connections);
1733 			mutex_exit(&iscsi_cleanup_mtx);
1734 
1735 			sess = conn->c_session;
1736 
1737 			/*
1738 			 * This implies that connection cleanup only runs when
1739 			 * the send/recv threads have been killed
1740 			 */
1741 			DEBC(conn, 5, ("Cleanup: Waiting for threads to exit\n"));
1742 			while (conn->c_sendproc || conn->c_rcvproc)
1743 				kpause("threads", false, hz, NULL);
1744 
1745 			for (s=1; conn->c_usecount > 0 && s < 3; ++s)
1746 				kpause("usecount", false, hz, NULL);
1747 
1748 			if (conn->c_usecount > 0) {
1749 				DEBC(conn, 5, ("Cleanup: %d CCBs busy\n", conn->c_usecount));
1750 				/* retry later */
1751 				mutex_enter(&iscsi_cleanup_mtx);
1752 				TAILQ_INSERT_HEAD(&iscsi_cleanupc_list, conn, c_connections);
1753 				continue;
1754 			}
1755 
1756 			KASSERT(!conn->c_in_session);
1757 
1758 			callout_halt(&conn->c_timeout, NULL);
1759 			closef(conn->c_sock);
1760 			callout_destroy(&conn->c_timeout);
1761 			rw_destroy(&conn->c_sock_rw);
1762 			cv_destroy(&conn->c_idle_cv);
1763 			cv_destroy(&conn->c_ccb_cv);
1764 			cv_destroy(&conn->c_pdu_cv);
1765 			cv_destroy(&conn->c_conn_cv);
1766 			mutex_destroy(&conn->c_lock);
1767 			free(conn, M_DEVBUF);
1768 
1769 			mutex_enter(&iscsi_cleanup_mtx);
1770 
1771 			if (--sess->s_total_connections == 0) {
1772 				DEB(1, ("Cleanup: session %d\n", sess->s_id));
1773 				if (!sess->s_terminating) {
1774 					sess->s_terminating = ISCSI_CONNECTION_TERMINATED;
1775 					KASSERT(sess->s_sessions.tqe_prev != NULL);
1776 					TAILQ_REMOVE(&iscsi_sessions, sess, s_sessions);
1777 					sess->s_sessions.tqe_next = NULL;
1778 					sess->s_sessions.tqe_prev = NULL;
1779 				}
1780 				KASSERT(sess->s_sessions.tqe_prev == NULL);
1781 				TAILQ_INSERT_HEAD(&iscsi_cleanups_list, sess, s_sessions);
1782 			}
1783 		}
1784 
1785 		TAILQ_FOREACH_SAFE(sess, &iscsi_cleanups_list, s_sessions, nxts) {
1786 			if (sess->s_refcount > 0)
1787 				continue;
1788 			TAILQ_REMOVE(&iscsi_cleanups_list, sess, s_sessions);
1789 			sess->s_sessions.tqe_next = NULL;
1790 			sess->s_sessions.tqe_prev = NULL;
1791 			mutex_exit(&iscsi_cleanup_mtx);
1792 
1793 			DEB(1, ("Cleanup: Unmap session %d\n", sess->s_id));
1794 			if (unmap_session(sess) == 0) {
1795 				DEB(1, ("Cleanup: Unmap session %d failed\n", sess->s_id));
1796 				mutex_enter(&iscsi_cleanup_mtx);
1797 				TAILQ_INSERT_HEAD(&iscsi_cleanups_list, sess, s_sessions);
1798 				continue;
1799 			}
1800 
1801 			if (sess->s_target_list != NULL)
1802 				free(sess->s_target_list, M_TEMP);
1803 
1804 			/* notify event handlers of session shutdown */
1805 			add_event(ISCSI_SESSION_TERMINATED, sess->s_id, 0, sess->s_terminating);
1806 			DEB(1, ("Cleanup: session ended %d\n", sess->s_id));
1807 
1808 			destroy_ccbs(sess);
1809 			cv_destroy(&sess->s_ccb_cv);
1810 			cv_destroy(&sess->s_sess_cv);
1811 			mutex_destroy(&sess->s_lock);
1812 			free(sess, M_DEVBUF);
1813 
1814 			mutex_enter(&iscsi_cleanup_mtx);
1815 		}
1816 
1817 		/* handle ccb timeouts */
1818 		while ((ccb = TAILQ_FIRST(&iscsi_timeout_ccb_list)) != NULL) {
1819 			TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, ccb_tchain);
1820 			KASSERT(ccb->ccb_timedout == TOUT_QUEUED);
1821 			ccb->ccb_timedout = TOUT_BUSY;
1822 			mutex_exit(&iscsi_cleanup_mtx);
1823 			ccb_timeout(ccb);
1824 			mutex_enter(&iscsi_cleanup_mtx);
1825 			if (ccb->ccb_timedout == TOUT_BUSY)
1826 				ccb->ccb_timedout = TOUT_NONE;
1827 		}
1828 
1829 		/* handle connection timeouts */
1830 		while ((conn = TAILQ_FIRST(&iscsi_timeout_conn_list)) != NULL) {
1831 			TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, c_tchain);
1832 			KASSERT(conn->c_timedout == TOUT_QUEUED);
1833 			conn->c_timedout = TOUT_BUSY;
1834 			mutex_exit(&iscsi_cleanup_mtx);
1835 			connection_timeout(conn);
1836 			mutex_enter(&iscsi_cleanup_mtx);
1837 			if (conn->c_timedout == TOUT_BUSY)
1838 				conn->c_timedout = TOUT_NONE;
1839 		}
1840 
1841 		/* Go to sleep, but wake up every 30 seconds to
1842 		 * check for dead event handlers */
1843 		rc = cv_timedwait(&iscsi_cleanup_cv, &iscsi_cleanup_mtx,
1844 			(TAILQ_FIRST(&event_handlers)) ? 120 * hz : 0);
1845 
1846 		/* if timed out, not woken up */
1847 		if (rc == EWOULDBLOCK)
1848 			check_event_handlers();
1849 	}
1850 	mutex_exit(&iscsi_cleanup_mtx);
1851 
1852 	add_event(ISCSI_DRIVER_TERMINATING, 0, 0, ISCSI_STATUS_DRIVER_UNLOAD);
1853 
1854 	/*
1855 	 * Wait for all event handlers to deregister, but don't wait more
1856 	 * than 1 minute (assume registering app has died if it takes longer).
1857 	 */
1858 	mutex_enter(&iscsi_cleanup_mtx);
1859 	for (s = 0; TAILQ_FIRST(&event_handlers) != NULL && s < 60; s++)
1860 		kpause("waiteventclr", true, hz, &iscsi_cleanup_mtx);
1861 	mutex_exit(&iscsi_cleanup_mtx);
1862 
1863 	iscsi_cleanproc = NULL;
1864 	DEB(5, ("Cleanup thread exits\n"));
1865 	kthread_exit(0);
1866 }
1867 
1868 void
1869 iscsi_init_cleanup(void)
1870 {
1871 
1872 	mutex_init(&iscsi_cleanup_mtx, MUTEX_DEFAULT, IPL_BIO);
1873 	cv_init(&iscsi_cleanup_cv, "cleanup");
1874 	cv_init(&iscsi_event_cv, "iscsievtwait");
1875 
1876 	if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, iscsi_cleanup_thread,
1877 	    NULL, &iscsi_cleanproc, "iscsi_cleanup") != 0) {
1878 		panic("Can't create cleanup thread!");
1879 	}
1880 }
1881 
1882 int
1883 iscsi_destroy_cleanup(void)
1884 {
1885 
1886 	iscsi_detaching = true;
1887 	mutex_enter(&iscsi_cleanup_mtx);
1888 	while (iscsi_cleanproc != NULL) {
1889 		iscsi_notify_cleanup();
1890 		kpause("detach_wait", false, hz, &iscsi_cleanup_mtx);
1891 	}
1892 	mutex_exit(&iscsi_cleanup_mtx);
1893 
1894 	cv_destroy(&iscsi_event_cv);
1895 	cv_destroy(&iscsi_cleanup_cv);
1896 	mutex_destroy(&iscsi_cleanup_mtx);
1897 
1898 	return 0;
1899 }
1900 
1901 void
1902 iscsi_notify_cleanup(void)
1903 {
1904 	KASSERT(mutex_owned(&iscsi_cleanup_mtx));
1905 
1906 	cv_signal(&iscsi_cleanup_cv);
1907 }
1908 
1909 
1910 /* -------------------------------------------------------------------- */
1911 
1912 /*
1913  * iscsi_ioctl:
1914  *    Driver ioctl entry.
1915  *
1916  *    Parameter:
1917  *       file     File structure
1918  *       cmd      The ioctl Command
1919  *       addr     IN/OUT: The command parameter
1920  *       flag     Flags (ignored)
1921  *       l        IN: The lwp object of the caller
1922  */
1923 
1924 int
1925 iscsiioctl(struct file *fp, u_long cmd, void *addr)
1926 {
1927 	struct lwp *l = curlwp;
1928 	struct iscsifd *d = fp->f_iscsi;
1929 
1930 	DEB(1, ("ISCSI Ioctl cmd = %x\n", (int) cmd));
1931 
1932 	switch (cmd) {
1933 	case ISCSI_GET_VERSION:
1934 		get_version((iscsi_get_version_parameters_t *) addr);
1935 		break;
1936 
1937 	case ISCSI_LOGIN:
1938 		login((iscsi_login_parameters_t *) addr, l, d->fd_dev);
1939 		break;
1940 
1941 	case ISCSI_ADD_CONNECTION:
1942 		add_connection((iscsi_login_parameters_t *) addr, l);
1943 		break;
1944 
1945 	case ISCSI_RESTORE_CONNECTION:
1946 		restore_connection((iscsi_login_parameters_t *) addr, l);
1947 		break;
1948 
1949 	case ISCSI_LOGOUT:
1950 		logout((iscsi_logout_parameters_t *) addr);
1951 		break;
1952 
1953 	case ISCSI_REMOVE_CONNECTION:
1954 		remove_connection((iscsi_remove_parameters_t *) addr);
1955 		break;
1956 
1957 #ifndef ISCSI_MINIMAL
1958 	case ISCSI_IO_COMMAND:
1959 		io_command((iscsi_iocommand_parameters_t *) addr, l);
1960 		break;
1961 #endif
1962 
1963 	case ISCSI_SEND_TARGETS:
1964 		send_targets((iscsi_send_targets_parameters_t *) addr);
1965 		break;
1966 
1967 	case ISCSI_SET_NODE_NAME:
1968 		set_node_name((iscsi_set_node_name_parameters_t *) addr);
1969 		break;
1970 
1971 	case ISCSI_CONNECTION_STATUS:
1972 		connection_status((iscsi_conn_status_parameters_t *) addr);
1973 		break;
1974 
1975 	case ISCSI_REGISTER_EVENT:
1976 		register_event((iscsi_register_event_parameters_t *) addr);
1977 		break;
1978 
1979 	case ISCSI_DEREGISTER_EVENT:
1980 		deregister_event((iscsi_register_event_parameters_t *) addr);
1981 		break;
1982 
1983 	case ISCSI_WAIT_EVENT:
1984 		check_event((iscsi_wait_event_parameters_t *) addr, TRUE);
1985 		break;
1986 
1987 	case ISCSI_POLL_EVENT:
1988 		check_event((iscsi_wait_event_parameters_t *) addr, FALSE);
1989 		break;
1990 
1991 	default:
1992 		DEBOUT(("Invalid IO-Control Code\n"));
1993 		return ENOTTY;
1994 	}
1995 
1996     /*
1997      * NOTE: We return 0 even if the function fails as long as the ioctl code
1998      * is good, so the status code is copied back to the caller.
1999 	 */
2000 	return 0;
2001 }
2002