xref: /titanic_50/usr/src/uts/common/io/idm/idm.c (revision a69116193464f859a8b27a2db19ad330ce163a55)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #include <sys/cpuvar.h>
26 #include <sys/conf.h>
27 #include <sys/file.h>
28 #include <sys/ddi.h>
29 #include <sys/sunddi.h>
30 #include <sys/modctl.h>
31 
32 #include <sys/socket.h>
33 #include <sys/strsubr.h>
34 #include <sys/sysmacros.h>
35 
36 #include <sys/socketvar.h>
37 #include <netinet/in.h>
38 
39 #include <sys/idm/idm.h>
40 #include <sys/idm/idm_so.h>
41 
42 #define	IDM_NAME_VERSION	"iSCSI Data Mover"
43 
44 extern struct mod_ops mod_miscops;
45 extern struct mod_ops mod_miscops;
46 
47 static struct modlmisc modlmisc = {
48 	&mod_miscops,	/* Type of module */
49 	IDM_NAME_VERSION
50 };
51 
52 static struct modlinkage modlinkage = {
53 	MODREV_1, (void *)&modlmisc, NULL
54 };
55 
56 extern void idm_wd_thread(void *arg);
57 
58 static int _idm_init(void);
59 static int _idm_fini(void);
60 static void idm_buf_bind_in_locked(idm_task_t *idt, idm_buf_t *buf);
61 static void idm_buf_bind_out_locked(idm_task_t *idt, idm_buf_t *buf);
62 static void idm_buf_unbind_in_locked(idm_task_t *idt, idm_buf_t *buf);
63 static void idm_buf_unbind_out_locked(idm_task_t *idt, idm_buf_t *buf);
64 static void idm_task_abort_one(idm_conn_t *ic, idm_task_t *idt,
65     idm_abort_type_t abort_type);
66 static void idm_task_aborted(idm_task_t *idt, idm_status_t status);
67 static idm_pdu_t *idm_pdu_alloc_common(uint_t hdrlen, uint_t datalen,
68     int sleepflag);
69 
70 boolean_t idm_conn_logging = 0;
71 boolean_t idm_svc_logging = 0;
72 #ifdef DEBUG
73 boolean_t idm_pattern_checking = 1;
74 #else
75 boolean_t idm_pattern_checking = 0;
76 #endif
77 
78 /*
79  * Potential tuneable for the maximum number of tasks.  Default to
80  * IDM_TASKIDS_MAX
81  */
82 
83 uint32_t	idm_max_taskids = IDM_TASKIDS_MAX;
84 
85 /*
86  * Global list of transport handles
87  *   These are listed in preferential order, so we can simply take the
88  *   first "it_conn_is_capable" hit. Note also that the order maps to
89  *   the order of the idm_transport_type_t list.
90  */
91 idm_transport_t idm_transport_list[] = {
92 
93 	/* iSER on InfiniBand transport handle */
94 	{IDM_TRANSPORT_TYPE_ISER,	/* type */
95 	"/devices/ib/iser@0:iser",	/* device path */
96 	NULL,				/* LDI handle */
97 	NULL,				/* transport ops */
98 	NULL},				/* transport caps */
99 
100 	/* IDM native sockets transport handle */
101 	{IDM_TRANSPORT_TYPE_SOCKETS,	/* type */
102 	NULL,				/* device path */
103 	NULL,				/* LDI handle */
104 	NULL,				/* transport ops */
105 	NULL}				/* transport caps */
106 
107 };
108 
109 int
110 _init(void)
111 {
112 	int rc;
113 
114 	if ((rc = _idm_init()) != 0) {
115 		return (rc);
116 	}
117 
118 	return (mod_install(&modlinkage));
119 }
120 
121 int
122 _fini(void)
123 {
124 	int rc;
125 
126 	if ((rc = _idm_fini()) != 0) {
127 		return (rc);
128 	}
129 
130 	if ((rc = mod_remove(&modlinkage)) != 0) {
131 		return (rc);
132 	}
133 
134 	return (rc);
135 }
136 
137 int
138 _info(struct modinfo *modinfop)
139 {
140 	return (mod_info(&modlinkage, modinfop));
141 }
142 
143 /*
144  * idm_transport_register()
145  *
146  * Provides a mechanism for an IDM transport driver to register its
147  * transport ops and caps with the IDM kernel module. Invoked during
148  * a transport driver's attach routine.
149  */
150 idm_status_t
151 idm_transport_register(idm_transport_attr_t *attr)
152 {
153 	ASSERT(attr->it_ops != NULL);
154 	ASSERT(attr->it_caps != NULL);
155 
156 	switch (attr->type) {
157 	/* All known non-native transports here; for now, iSER */
158 	case IDM_TRANSPORT_TYPE_ISER:
159 		idm_transport_list[attr->type].it_ops	= attr->it_ops;
160 		idm_transport_list[attr->type].it_caps	= attr->it_caps;
161 		return (IDM_STATUS_SUCCESS);
162 
163 	default:
164 		cmn_err(CE_NOTE, "idm: unknown transport type (0x%x) in "
165 		    "idm_transport_register", attr->type);
166 		return (IDM_STATUS_SUCCESS);
167 	}
168 }
169 
170 /*
171  * idm_ini_conn_create
172  *
173  * This function is invoked by the iSCSI layer to create a connection context.
174  * This does not actually establish the socket connection.
175  *
176  * cr - Connection request parameters
177  * new_con - Output parameter that contains the new request if successful
178  *
179  */
180 idm_status_t
181 idm_ini_conn_create(idm_conn_req_t *cr, idm_conn_t **new_con)
182 {
183 	idm_transport_t		*it;
184 	idm_conn_t		*ic;
185 	int			rc;
186 
187 	it = idm_transport_lookup(cr);
188 
189 retry:
190 	ic = idm_conn_create_common(CONN_TYPE_INI, it->it_type,
191 	    &cr->icr_conn_ops);
192 
193 	bcopy(&cr->cr_ini_dst_addr, &ic->ic_ini_dst_addr,
194 	    sizeof (cr->cr_ini_dst_addr));
195 
196 	/* create the transport-specific connection components */
197 	rc = it->it_ops->it_ini_conn_create(cr, ic);
198 	if (rc != IDM_STATUS_SUCCESS) {
199 		/* cleanup the failed connection */
200 		idm_conn_destroy_common(ic);
201 
202 		/*
203 		 * It is possible for an IB client to connect to
204 		 * an ethernet-only client via an IB-eth gateway.
205 		 * Therefore, if we are attempting to use iSER and
206 		 * fail, retry with sockets before ultimately
207 		 * failing the connection.
208 		 */
209 		if (it->it_type == IDM_TRANSPORT_TYPE_ISER) {
210 			it = &idm_transport_list[IDM_TRANSPORT_TYPE_SOCKETS];
211 			goto retry;
212 		}
213 
214 		return (IDM_STATUS_FAIL);
215 	}
216 
217 	*new_con = ic;
218 
219 	mutex_enter(&idm.idm_global_mutex);
220 	list_insert_tail(&idm.idm_ini_conn_list, ic);
221 	mutex_exit(&idm.idm_global_mutex);
222 
223 	return (IDM_STATUS_SUCCESS);
224 }
225 
226 /*
227  * idm_ini_conn_destroy
228  *
229  * Releases any resources associated with the connection.  This is the
230  * complement to idm_ini_conn_create.
231  * ic - idm_conn_t structure representing the relevant connection
232  *
233  */
234 void
235 idm_ini_conn_destroy_task(void *ic_void)
236 {
237 	idm_conn_t *ic = ic_void;
238 
239 	ic->ic_transport_ops->it_ini_conn_destroy(ic);
240 	idm_conn_destroy_common(ic);
241 }
242 
243 void
244 idm_ini_conn_destroy(idm_conn_t *ic)
245 {
246 	/*
247 	 * It's reasonable for the initiator to call idm_ini_conn_destroy
248 	 * from within the context of the CN_CONNECT_DESTROY notification.
249 	 * That's a problem since we want to destroy the taskq for the
250 	 * state machine associated with the connection.  Remove the
251 	 * connection from the list right away then handle the remaining
252 	 * work via the idm_global_taskq.
253 	 */
254 	mutex_enter(&idm.idm_global_mutex);
255 	list_remove(&idm.idm_ini_conn_list, ic);
256 	mutex_exit(&idm.idm_global_mutex);
257 
258 	if (taskq_dispatch(idm.idm_global_taskq,
259 	    &idm_ini_conn_destroy_task, ic, TQ_SLEEP) == NULL) {
260 		cmn_err(CE_WARN,
261 		    "idm_ini_conn_destroy: Couldn't dispatch task");
262 	}
263 }
264 
265 /*
266  * idm_ini_conn_connect
267  *
268  * Establish connection to the remote system identified in idm_conn_t.
269  * The connection parameters including the remote IP address were established
270  * in the call to idm_ini_conn_create.  The IDM state machine will
271  * perform client notifications as necessary to prompt the initiator through
272  * the login process.  IDM also keeps a timer running so that if the login
273  * process doesn't complete in a timely manner it will fail.
274  *
275  * ic - idm_conn_t structure representing the relevant connection
276  *
277  * Returns success if the connection was established, otherwise some kind
278  * of meaningful error code.
279  *
280  * Upon return the login has either failed or is loggin in (ffp)
281  */
282 idm_status_t
283 idm_ini_conn_connect(idm_conn_t *ic)
284 {
285 	idm_status_t	rc;
286 
287 	rc = idm_conn_sm_init(ic);
288 	if (rc != IDM_STATUS_SUCCESS) {
289 		return (ic->ic_conn_sm_status);
290 	}
291 
292 	/* Hold connection until we return */
293 	idm_conn_hold(ic);
294 
295 	/* Kick state machine */
296 	idm_conn_event(ic, CE_CONNECT_REQ, NULL);
297 
298 	/* Wait for login flag */
299 	mutex_enter(&ic->ic_state_mutex);
300 	while (!(ic->ic_state_flags & CF_LOGIN_READY) &&
301 	    !(ic->ic_state_flags & CF_ERROR)) {
302 		cv_wait(&ic->ic_state_cv, &ic->ic_state_mutex);
303 	}
304 
305 	/*
306 	 * The CN_READY_TO_LOGIN and/or the CN_CONNECT_FAIL call to
307 	 * idm_notify_client has already been generated by the idm conn
308 	 * state machine.  If connection fails any time after this
309 	 * check, we will detect it in iscsi_login.
310 	 */
311 	if (ic->ic_state_flags & CF_ERROR) {
312 		rc = ic->ic_conn_sm_status;
313 	}
314 	mutex_exit(&ic->ic_state_mutex);
315 	idm_conn_rele(ic);
316 
317 	return (rc);
318 }
319 
320 /*
321  * idm_ini_conn_disconnect
322  *
323  * Forces a connection (previously established using idm_ini_conn_connect)
324  * to perform a controlled shutdown, cleaning up any outstanding requests.
325  *
326  * ic - idm_conn_t structure representing the relevant connection
327  *
328  * This is asynchronous and will return before the connection is properly
329  * shutdown
330  */
331 /* ARGSUSED */
332 void
333 idm_ini_conn_disconnect(idm_conn_t *ic)
334 {
335 	idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL);
336 }
337 
338 /*
339  * idm_ini_conn_disconnect_wait
340  *
341  * Forces a connection (previously established using idm_ini_conn_connect)
342  * to perform a controlled shutdown.  Blocks until the connection is
343  * disconnected.
344  *
345  * ic - idm_conn_t structure representing the relevant connection
346  */
347 /* ARGSUSED */
348 void
349 idm_ini_conn_disconnect_sync(idm_conn_t *ic)
350 {
351 	mutex_enter(&ic->ic_state_mutex);
352 	if ((ic->ic_state != CS_S9_INIT_ERROR) &&
353 	    (ic->ic_state != CS_S11_COMPLETE)) {
354 		idm_conn_event_locked(ic, CE_TRANSPORT_FAIL, NULL, CT_NONE);
355 		while ((ic->ic_state != CS_S9_INIT_ERROR) &&
356 		    (ic->ic_state != CS_S11_COMPLETE))
357 			cv_wait(&ic->ic_state_cv, &ic->ic_state_mutex);
358 	}
359 	mutex_exit(&ic->ic_state_mutex);
360 }
361 
362 /*
363  * idm_tgt_svc_create
364  *
365  * The target calls this service to obtain a service context for each available
366  * transport, starting a service of each type related to the IP address and port
367  * passed. The idm_svc_req_t contains the service parameters.
368  */
369 idm_status_t
370 idm_tgt_svc_create(idm_svc_req_t *sr, idm_svc_t **new_svc)
371 {
372 	idm_transport_type_t	type;
373 	idm_transport_t		*it;
374 	idm_svc_t		*is;
375 	int			rc;
376 
377 	*new_svc = NULL;
378 	is = kmem_zalloc(sizeof (idm_svc_t), KM_SLEEP);
379 
380 	/* Initialize transport-agnostic components of the service handle */
381 	is->is_svc_req = *sr;
382 	mutex_init(&is->is_mutex, NULL, MUTEX_DEFAULT, NULL);
383 	cv_init(&is->is_cv, NULL, CV_DEFAULT, NULL);
384 	mutex_init(&is->is_count_mutex, NULL, MUTEX_DEFAULT, NULL);
385 	cv_init(&is->is_count_cv, NULL, CV_DEFAULT, NULL);
386 	idm_refcnt_init(&is->is_refcnt, is);
387 
388 	/*
389 	 * Make sure all available transports are setup.  We call this now
390 	 * instead of at initialization time in case IB has become available
391 	 * since we started (hotplug, etc).
392 	 */
393 	idm_transport_setup(sr->sr_li, B_FALSE);
394 
395 	/*
396 	 * Loop through the transports, configuring the transport-specific
397 	 * components of each one.
398 	 */
399 	for (type = 0; type < IDM_TRANSPORT_NUM_TYPES; type++) {
400 
401 		it = &idm_transport_list[type];
402 		/*
403 		 * If it_ops is NULL then the transport is unconfigured
404 		 * and we shouldn't try to start the service.
405 		 */
406 		if (it->it_ops == NULL) {
407 			continue;
408 		}
409 
410 		rc = it->it_ops->it_tgt_svc_create(sr, is);
411 		if (rc != IDM_STATUS_SUCCESS) {
412 			/* Teardown any configured services */
413 			while (type--) {
414 				it = &idm_transport_list[type];
415 				if (it->it_ops == NULL) {
416 					continue;
417 				}
418 				it->it_ops->it_tgt_svc_destroy(is);
419 			}
420 			/* Free the svc context and return */
421 			kmem_free(is, sizeof (idm_svc_t));
422 			return (rc);
423 		}
424 	}
425 
426 	*new_svc = is;
427 
428 	mutex_enter(&idm.idm_global_mutex);
429 	list_insert_tail(&idm.idm_tgt_svc_list, is);
430 	mutex_exit(&idm.idm_global_mutex);
431 
432 	return (IDM_STATUS_SUCCESS);
433 }
434 
435 /*
436  * idm_tgt_svc_destroy
437  *
438  * is - idm_svc_t returned by the call to idm_tgt_svc_create
439  *
440  * Cleanup any resources associated with the idm_svc_t.
441  */
442 void
443 idm_tgt_svc_destroy(idm_svc_t *is)
444 {
445 	idm_transport_type_t	type;
446 	idm_transport_t		*it;
447 
448 	mutex_enter(&idm.idm_global_mutex);
449 	/* remove this service from the global list */
450 	list_remove(&idm.idm_tgt_svc_list, is);
451 	/* wakeup any waiters for service change */
452 	cv_broadcast(&idm.idm_tgt_svc_cv);
453 	mutex_exit(&idm.idm_global_mutex);
454 
455 	/* teardown each transport-specific service */
456 	for (type = 0; type < IDM_TRANSPORT_NUM_TYPES; type++) {
457 		it = &idm_transport_list[type];
458 		if (it->it_ops == NULL) {
459 			continue;
460 		}
461 
462 		it->it_ops->it_tgt_svc_destroy(is);
463 	}
464 
465 	/* tear down the svc resources */
466 	idm_refcnt_destroy(&is->is_refcnt);
467 	cv_destroy(&is->is_count_cv);
468 	mutex_destroy(&is->is_count_mutex);
469 	cv_destroy(&is->is_cv);
470 	mutex_destroy(&is->is_mutex);
471 
472 	/* free the svc handle */
473 	kmem_free(is, sizeof (idm_svc_t));
474 }
475 
476 void
477 idm_tgt_svc_hold(idm_svc_t *is)
478 {
479 	idm_refcnt_hold(&is->is_refcnt);
480 }
481 
482 void
483 idm_tgt_svc_rele_and_destroy(idm_svc_t *is)
484 {
485 	idm_refcnt_rele_and_destroy(&is->is_refcnt,
486 	    (idm_refcnt_cb_t *)&idm_tgt_svc_destroy);
487 }
488 
489 /*
490  * idm_tgt_svc_online
491  *
492  * is - idm_svc_t returned by the call to idm_tgt_svc_create
493  *
494  * Online each transport service, as we want this target to be accessible
495  * via any configured transport.
496  *
497  * When the initiator establishes a new connection to the target, IDM will
498  * call the "new connect" callback defined in the idm_svc_req_t structure
499  * and it will pass an idm_conn_t structure representing that new connection.
500  */
501 idm_status_t
502 idm_tgt_svc_online(idm_svc_t *is)
503 {
504 
505 	idm_transport_type_t	type, last_type;
506 	idm_transport_t		*it;
507 	int			rc = IDM_STATUS_SUCCESS;
508 
509 	mutex_enter(&is->is_mutex);
510 	if (is->is_online == 0) {
511 		/* Walk through each of the transports and online them */
512 		for (type = 0; type < IDM_TRANSPORT_NUM_TYPES; type++) {
513 			it = &idm_transport_list[type];
514 			if (it->it_ops == NULL) {
515 				/* transport is not registered */
516 				continue;
517 			}
518 
519 			mutex_exit(&is->is_mutex);
520 			rc = it->it_ops->it_tgt_svc_online(is);
521 			mutex_enter(&is->is_mutex);
522 			if (rc != IDM_STATUS_SUCCESS) {
523 				last_type = type;
524 				break;
525 			}
526 		}
527 		if (rc != IDM_STATUS_SUCCESS) {
528 			/*
529 			 * The last transport failed to online.
530 			 * Offline any transport onlined above and
531 			 * do not online the target.
532 			 */
533 			for (type = 0; type < last_type; type++) {
534 				it = &idm_transport_list[type];
535 				if (it->it_ops == NULL) {
536 					/* transport is not registered */
537 					continue;
538 				}
539 
540 				mutex_exit(&is->is_mutex);
541 				it->it_ops->it_tgt_svc_offline(is);
542 				mutex_enter(&is->is_mutex);
543 			}
544 		} else {
545 			/* Target service now online */
546 			is->is_online = 1;
547 		}
548 	} else {
549 		/* Target service already online, just bump the count */
550 		is->is_online++;
551 	}
552 	mutex_exit(&is->is_mutex);
553 
554 	return (rc);
555 }
556 
557 /*
558  * idm_tgt_svc_offline
559  *
560  * is - idm_svc_t returned by the call to idm_tgt_svc_create
561  *
562  * Shutdown any online target services.
563  */
564 void
565 idm_tgt_svc_offline(idm_svc_t *is)
566 {
567 	idm_transport_type_t	type;
568 	idm_transport_t		*it;
569 
570 	mutex_enter(&is->is_mutex);
571 	is->is_online--;
572 	if (is->is_online == 0) {
573 		/* Walk through each of the transports and offline them */
574 		for (type = 0; type < IDM_TRANSPORT_NUM_TYPES; type++) {
575 			it = &idm_transport_list[type];
576 			if (it->it_ops == NULL) {
577 				/* transport is not registered */
578 				continue;
579 			}
580 
581 			mutex_exit(&is->is_mutex);
582 			it->it_ops->it_tgt_svc_offline(is);
583 			mutex_enter(&is->is_mutex);
584 		}
585 	}
586 	mutex_exit(&is->is_mutex);
587 }
588 
589 /*
590  * idm_tgt_svc_lookup
591  *
592  * Lookup a service instance listening on the specified port
593  */
594 
595 idm_svc_t *
596 idm_tgt_svc_lookup(uint16_t port)
597 {
598 	idm_svc_t *result;
599 
600 retry:
601 	mutex_enter(&idm.idm_global_mutex);
602 	for (result = list_head(&idm.idm_tgt_svc_list);
603 	    result != NULL;
604 	    result = list_next(&idm.idm_tgt_svc_list, result)) {
605 		if (result->is_svc_req.sr_port == port) {
606 			if (result->is_online == 0) {
607 				/*
608 				 * A service exists on this port, but it
609 				 * is going away, wait for it to cleanup.
610 				 */
611 				cv_wait(&idm.idm_tgt_svc_cv,
612 				    &idm.idm_global_mutex);
613 				mutex_exit(&idm.idm_global_mutex);
614 				goto retry;
615 			}
616 			idm_tgt_svc_hold(result);
617 			mutex_exit(&idm.idm_global_mutex);
618 			return (result);
619 		}
620 	}
621 	mutex_exit(&idm.idm_global_mutex);
622 
623 	return (NULL);
624 }
625 
626 /*
627  * idm_negotiate_key_values()
628  * Give IDM level a chance to negotiate any login parameters it should own.
629  *  -- leave unhandled parameters alone on request_nvl
630  *  -- move all handled parameters to response_nvl with an appropriate response
631  *  -- also add an entry to negotiated_nvl for any accepted parameters
632  */
633 kv_status_t
634 idm_negotiate_key_values(idm_conn_t *ic, nvlist_t *request_nvl,
635     nvlist_t *response_nvl, nvlist_t *negotiated_nvl)
636 {
637 	ASSERT(ic->ic_transport_ops != NULL);
638 	return (ic->ic_transport_ops->it_negotiate_key_values(ic,
639 	    request_nvl, response_nvl, negotiated_nvl));
640 }
641 
642 /*
643  * idm_notice_key_values()
644  * Activate at the IDM level any parameters that have been negotiated.
645  * Passes the set of key value pairs to the transport for activation.
646  * This will be invoked as the connection is entering full-feature mode.
647  */
648 void
649 idm_notice_key_values(idm_conn_t *ic, nvlist_t *negotiated_nvl)
650 {
651 	ASSERT(ic->ic_transport_ops != NULL);
652 	ic->ic_transport_ops->it_notice_key_values(ic, negotiated_nvl);
653 }
654 
655 /*
656  * idm_declare_key_values()
657  * Activate an operational set of declarative parameters from the config_nvl,
658  * and return the selected values in the outgoing_nvl.
659  */
660 kv_status_t
661 idm_declare_key_values(idm_conn_t *ic, nvlist_t *config_nvl,
662     nvlist_t *outgoing_nvl)
663 {
664 	ASSERT(ic->ic_transport_ops != NULL);
665 	return (ic->ic_transport_ops->it_declare_key_values(ic, config_nvl,
666 	    outgoing_nvl));
667 }
668 
669 /*
670  * idm_buf_tx_to_ini
671  *
672  * This is IDM's implementation of the 'Put_Data' operational primitive.
673  *
674  * This function is invoked by a target iSCSI layer to request its local
675  * Datamover layer to transmit the Data-In PDU to the peer iSCSI layer
676  * on the remote iSCSI node. The I/O buffer represented by 'idb' is
677  * transferred to the initiator associated with task 'idt'. The connection
678  * info, contents of the Data-In PDU header, the DataDescriptorIn, BHS,
679  * and the callback (idb->idb_buf_cb) at transfer completion are
680  * provided as input.
681  *
682  * This data transfer takes place transparently to the remote iSCSI layer,
683  * i.e. without its participation.
684  *
685  * Using sockets, IDM implements the data transfer by segmenting the data
686  * buffer into appropriately sized iSCSI PDUs and transmitting them to the
687  * initiator. iSER performs the transfer using RDMA write.
688  *
689  */
690 idm_status_t
691 idm_buf_tx_to_ini(idm_task_t *idt, idm_buf_t *idb,
692     uint32_t offset, uint32_t xfer_len,
693     idm_buf_cb_t idb_buf_cb, void *cb_arg)
694 {
695 	idm_status_t rc;
696 
697 	idb->idb_bufoffset = offset;
698 	idb->idb_xfer_len = xfer_len;
699 	idb->idb_buf_cb = idb_buf_cb;
700 	idb->idb_cb_arg = cb_arg;
701 	gethrestime(&idb->idb_xfer_start);
702 
703 	/*
704 	 * Buffer should not contain the pattern.  If the pattern is
705 	 * present then we've been asked to transmit initialized data
706 	 */
707 	IDM_BUFPAT_CHECK(idb, xfer_len, BP_CHECK_ASSERT);
708 
709 	mutex_enter(&idt->idt_mutex);
710 	switch (idt->idt_state) {
711 	case TASK_ACTIVE:
712 		idt->idt_tx_to_ini_start++;
713 		idm_task_hold(idt);
714 		idm_buf_bind_in_locked(idt, idb);
715 		idb->idb_in_transport = B_TRUE;
716 		rc = (*idt->idt_ic->ic_transport_ops->it_buf_tx_to_ini)
717 		    (idt, idb);
718 		return (rc);
719 
720 	case TASK_SUSPENDING:
721 	case TASK_SUSPENDED:
722 		/*
723 		 * Bind buffer but don't start a transfer since the task
724 		 * is suspended
725 		 */
726 		idm_buf_bind_in_locked(idt, idb);
727 		mutex_exit(&idt->idt_mutex);
728 		return (IDM_STATUS_SUCCESS);
729 
730 	case TASK_ABORTING:
731 	case TASK_ABORTED:
732 		/*
733 		 * Once the task is aborted, any buffers added to the
734 		 * idt_inbufv will never get cleaned up, so just return
735 		 * SUCCESS.  The buffer should get cleaned up by the
736 		 * client or framework once task_aborted has completed.
737 		 */
738 		mutex_exit(&idt->idt_mutex);
739 		return (IDM_STATUS_SUCCESS);
740 
741 	default:
742 		ASSERT(0);
743 		break;
744 	}
745 	mutex_exit(&idt->idt_mutex);
746 
747 	return (IDM_STATUS_FAIL);
748 }
749 
750 /*
751  * idm_buf_rx_from_ini
752  *
753  * This is IDM's implementation of the 'Get_Data' operational primitive.
754  *
755  * This function is invoked by a target iSCSI layer to request its local
756  * Datamover layer to retrieve certain data identified by the R2T PDU from the
757  * peer iSCSI layer on the remote node. The retrieved Data-Out PDU will be
758  * mapped to the respective buffer by the task tags (ITT & TTT).
759  * The connection information, contents of an R2T PDU, DataDescriptor, BHS, and
760  * the callback (idb->idb_buf_cb) notification for data transfer completion are
761  * are provided as input.
762  *
763  * When an iSCSI node sends an R2T PDU to its local Datamover layer, the local
764  * Datamover layer, the local and remote Datamover layers transparently bring
765  * about the data transfer requested by the R2T PDU, without the participation
766  * of the iSCSI layers.
767  *
768  * Using sockets, IDM transmits an R2T PDU for each buffer and the rx_data_out()
769  * assembles the Data-Out PDUs into the buffer. iSER uses RDMA read.
770  *
771  */
772 idm_status_t
773 idm_buf_rx_from_ini(idm_task_t *idt, idm_buf_t *idb,
774     uint32_t offset, uint32_t xfer_len,
775     idm_buf_cb_t idb_buf_cb, void *cb_arg)
776 {
777 	idm_status_t rc;
778 
779 	idb->idb_bufoffset = offset;
780 	idb->idb_xfer_len = xfer_len;
781 	idb->idb_buf_cb = idb_buf_cb;
782 	idb->idb_cb_arg = cb_arg;
783 	gethrestime(&idb->idb_xfer_start);
784 
785 	/*
786 	 * "In" buf list is for "Data In" PDU's, "Out" buf list is for
787 	 * "Data Out" PDU's
788 	 */
789 	mutex_enter(&idt->idt_mutex);
790 	switch (idt->idt_state) {
791 	case TASK_ACTIVE:
792 		idt->idt_rx_from_ini_start++;
793 		idm_task_hold(idt);
794 		idm_buf_bind_out_locked(idt, idb);
795 		idb->idb_in_transport = B_TRUE;
796 		rc = (*idt->idt_ic->ic_transport_ops->it_buf_rx_from_ini)
797 		    (idt, idb);
798 		return (rc);
799 	case TASK_SUSPENDING:
800 	case TASK_SUSPENDED:
801 	case TASK_ABORTING:
802 	case TASK_ABORTED:
803 		/*
804 		 * Bind buffer but don't start a transfer since the task
805 		 * is suspended
806 		 */
807 		idm_buf_bind_out_locked(idt, idb);
808 		mutex_exit(&idt->idt_mutex);
809 		return (IDM_STATUS_SUCCESS);
810 	default:
811 		ASSERT(0);
812 		break;
813 	}
814 	mutex_exit(&idt->idt_mutex);
815 
816 	return (IDM_STATUS_FAIL);
817 }
818 
819 /*
820  * idm_buf_tx_to_ini_done
821  *
822  * The transport calls this after it has completed a transfer requested by
823  * a call to transport_buf_tx_to_ini
824  *
825  * Caller holds idt->idt_mutex, idt->idt_mutex is released before returning.
826  * idt may be freed after the call to idb->idb_buf_cb.
827  */
828 void
829 idm_buf_tx_to_ini_done(idm_task_t *idt, idm_buf_t *idb, idm_status_t status)
830 {
831 	ASSERT(mutex_owned(&idt->idt_mutex));
832 	idb->idb_in_transport = B_FALSE;
833 	idb->idb_tx_thread = B_FALSE;
834 	idt->idt_tx_to_ini_done++;
835 	gethrestime(&idb->idb_xfer_done);
836 
837 	/*
838 	 * idm_refcnt_rele may cause TASK_SUSPENDING --> TASK_SUSPENDED or
839 	 * TASK_ABORTING --> TASK_ABORTED transistion if the refcount goes
840 	 * to 0.
841 	 */
842 	idm_task_rele(idt);
843 	idb->idb_status = status;
844 
845 	switch (idt->idt_state) {
846 	case TASK_ACTIVE:
847 		idt->idt_ic->ic_timestamp = ddi_get_lbolt();
848 		idm_buf_unbind_in_locked(idt, idb);
849 		mutex_exit(&idt->idt_mutex);
850 		(*idb->idb_buf_cb)(idb, status);
851 		return;
852 	case TASK_SUSPENDING:
853 	case TASK_SUSPENDED:
854 	case TASK_ABORTING:
855 	case TASK_ABORTED:
856 		/*
857 		 * To keep things simple we will ignore the case where the
858 		 * transfer was successful and leave all buffers bound to the
859 		 * task.  This allows us to also ignore the case where we've
860 		 * been asked to abort a task but the last transfer of the
861 		 * task has completed.  IDM has no idea whether this was, in
862 		 * fact, the last transfer of the task so it would be difficult
863 		 * to handle this case.  Everything should get sorted out again
864 		 * after task reassignment is complete.
865 		 *
866 		 * In the case of TASK_ABORTING we could conceivably call the
867 		 * buffer callback here but the timing of when the client's
868 		 * client_task_aborted callback is invoked vs. when the client's
869 		 * buffer callback gets invoked gets sticky.  We don't want
870 		 * the client to here from us again after the call to
871 		 * client_task_aborted() but we don't want to give it a bunch
872 		 * of failed buffer transfers until we've called
873 		 * client_task_aborted().  Instead we'll just leave all the
874 		 * buffers bound and allow the client to cleanup.
875 		 */
876 		break;
877 	default:
878 		ASSERT(0);
879 	}
880 	mutex_exit(&idt->idt_mutex);
881 }
882 
883 /*
884  * idm_buf_rx_from_ini_done
885  *
886  * The transport calls this after it has completed a transfer requested by
887  * a call totransport_buf_tx_to_ini
888  *
889  * Caller holds idt->idt_mutex, idt->idt_mutex is released before returning.
890  * idt may be freed after the call to idb->idb_buf_cb.
891  */
892 void
893 idm_buf_rx_from_ini_done(idm_task_t *idt, idm_buf_t *idb, idm_status_t status)
894 {
895 	ASSERT(mutex_owned(&idt->idt_mutex));
896 	idb->idb_in_transport = B_FALSE;
897 	idt->idt_rx_from_ini_done++;
898 	gethrestime(&idb->idb_xfer_done);
899 
900 	/*
901 	 * idm_refcnt_rele may cause TASK_SUSPENDING --> TASK_SUSPENDED or
902 	 * TASK_ABORTING --> TASK_ABORTED transistion if the refcount goes
903 	 * to 0.
904 	 */
905 	idm_task_rele(idt);
906 	idb->idb_status = status;
907 
908 	if (status == IDM_STATUS_SUCCESS) {
909 		/*
910 		 * Buffer should not contain the pattern.  If it does then
911 		 * we did not get the data from the remote host.
912 		 */
913 		IDM_BUFPAT_CHECK(idb, idb->idb_xfer_len, BP_CHECK_ASSERT);
914 	}
915 
916 	switch (idt->idt_state) {
917 	case TASK_ACTIVE:
918 		idt->idt_ic->ic_timestamp = ddi_get_lbolt();
919 		idm_buf_unbind_out_locked(idt, idb);
920 		mutex_exit(&idt->idt_mutex);
921 		(*idb->idb_buf_cb)(idb, status);
922 		return;
923 	case TASK_SUSPENDING:
924 	case TASK_SUSPENDED:
925 	case TASK_ABORTING:
926 	case TASK_ABORTED:
927 		/*
928 		 * To keep things simple we will ignore the case where the
929 		 * transfer was successful and leave all buffers bound to the
930 		 * task.  This allows us to also ignore the case where we've
931 		 * been asked to abort a task but the last transfer of the
932 		 * task has completed.  IDM has no idea whether this was, in
933 		 * fact, the last transfer of the task so it would be difficult
934 		 * to handle this case.  Everything should get sorted out again
935 		 * after task reassignment is complete.
936 		 *
937 		 * In the case of TASK_ABORTING we could conceivably call the
938 		 * buffer callback here but the timing of when the client's
939 		 * client_task_aborted callback is invoked vs. when the client's
940 		 * buffer callback gets invoked gets sticky.  We don't want
941 		 * the client to here from us again after the call to
942 		 * client_task_aborted() but we don't want to give it a bunch
943 		 * of failed buffer transfers until we've called
944 		 * client_task_aborted().  Instead we'll just leave all the
945 		 * buffers bound and allow the client to cleanup.
946 		 */
947 		break;
948 	default:
949 		ASSERT(0);
950 	}
951 	mutex_exit(&idt->idt_mutex);
952 }
953 
954 /*
955  * idm_buf_alloc
956  *
957  * Allocates a buffer handle and registers it for use with the transport
958  * layer. If a buffer is not passed on bufptr, the buffer will be allocated
959  * as well as the handle.
960  *
961  * ic		- connection on which the buffer will be transferred
962  * bufptr	- allocate memory for buffer if NULL, else assign to buffer
963  * buflen	- length of buffer
964  *
965  * Returns idm_buf_t handle if successful, otherwise NULL
966  */
967 idm_buf_t *
968 idm_buf_alloc(idm_conn_t *ic, void *bufptr, uint64_t buflen)
969 {
970 	idm_buf_t	*buf = NULL;
971 	int		rc;
972 
973 	ASSERT(ic != NULL);
974 	ASSERT(idm.idm_buf_cache != NULL);
975 	ASSERT(buflen > 0);
976 
977 	/* Don't allocate new buffers if we are not in FFP */
978 	mutex_enter(&ic->ic_state_mutex);
979 	if (!ic->ic_ffp) {
980 		mutex_exit(&ic->ic_state_mutex);
981 		return (NULL);
982 	}
983 
984 
985 	idm_conn_hold(ic);
986 	mutex_exit(&ic->ic_state_mutex);
987 
988 	buf = kmem_cache_alloc(idm.idm_buf_cache, KM_NOSLEEP);
989 	if (buf == NULL) {
990 		idm_conn_rele(ic);
991 		return (NULL);
992 	}
993 
994 	buf->idb_ic		= ic;
995 	buf->idb_buflen		= buflen;
996 	buf->idb_exp_offset	= 0;
997 	buf->idb_bufoffset	= 0;
998 	buf->idb_xfer_len 	= 0;
999 	buf->idb_magic		= IDM_BUF_MAGIC;
1000 	buf->idb_in_transport	= B_FALSE;
1001 	buf->idb_bufbcopy	= B_FALSE;
1002 
1003 	/*
1004 	 * If bufptr is NULL, we have an implicit request to allocate
1005 	 * memory for this IDM buffer handle and register it for use
1006 	 * with the transport. To simplify this, and to give more freedom
1007 	 * to the transport layer for it's own buffer management, both of
1008 	 * these actions will take place in the transport layer.
1009 	 * If bufptr is set, then the caller has allocated memory (or more
1010 	 * likely it's been passed from an upper layer), and we need only
1011 	 * register the buffer for use with the transport layer.
1012 	 */
1013 	if (bufptr == NULL) {
1014 		/*
1015 		 * Allocate a buffer from the transport layer (which
1016 		 * will also register the buffer for use).
1017 		 */
1018 		rc = ic->ic_transport_ops->it_buf_alloc(buf, buflen);
1019 		if (rc != 0) {
1020 			idm_conn_rele(ic);
1021 			kmem_cache_free(idm.idm_buf_cache, buf);
1022 			return (NULL);
1023 		}
1024 		/* Set the bufalloc'd flag */
1025 		buf->idb_bufalloc = B_TRUE;
1026 	} else {
1027 		/*
1028 		 * For large transfers, Set the passed bufptr into
1029 		 * the buf handle, and register the handle with the
1030 		 * transport layer. As memory registration with the
1031 		 * transport layer is a time/cpu intensive operation,
1032 		 * for small transfers (up to a pre-defined bcopy
1033 		 * threshold), use pre-registered memory buffers
1034 		 * and bcopy data at the appropriate time.
1035 		 */
1036 		buf->idb_buf = bufptr;
1037 
1038 		rc = ic->ic_transport_ops->it_buf_setup(buf);
1039 		if (rc != 0) {
1040 			idm_conn_rele(ic);
1041 			kmem_cache_free(idm.idm_buf_cache, buf);
1042 			return (NULL);
1043 		}
1044 		/*
1045 		 * The transport layer is now expected to set the idb_bufalloc
1046 		 * correctly to indicate if resources have been allocated.
1047 		 */
1048 	}
1049 
1050 	IDM_BUFPAT_SET(buf);
1051 
1052 	return (buf);
1053 }
1054 
1055 /*
1056  * idm_buf_free
1057  *
1058  * Release a buffer handle along with the associated buffer that was allocated
1059  * or assigned with idm_buf_alloc
1060  */
1061 void
1062 idm_buf_free(idm_buf_t *buf)
1063 {
1064 	idm_conn_t *ic = buf->idb_ic;
1065 
1066 
1067 	buf->idb_task_binding	= NULL;
1068 
1069 	if (buf->idb_bufalloc) {
1070 		ic->ic_transport_ops->it_buf_free(buf);
1071 	} else {
1072 		ic->ic_transport_ops->it_buf_teardown(buf);
1073 	}
1074 	kmem_cache_free(idm.idm_buf_cache, buf);
1075 	idm_conn_rele(ic);
1076 }
1077 
1078 /*
1079  * idm_buf_bind_in
1080  *
1081  * This function associates a buffer with a task. This is only for use by the
1082  * iSCSI initiator that will have only one buffer per transfer direction
1083  *
1084  */
1085 void
1086 idm_buf_bind_in(idm_task_t *idt, idm_buf_t *buf)
1087 {
1088 	mutex_enter(&idt->idt_mutex);
1089 	idm_buf_bind_in_locked(idt, buf);
1090 	mutex_exit(&idt->idt_mutex);
1091 }
1092 
1093 static void
1094 idm_buf_bind_in_locked(idm_task_t *idt, idm_buf_t *buf)
1095 {
1096 	buf->idb_task_binding = idt;
1097 	buf->idb_ic = idt->idt_ic;
1098 	idm_listbuf_insert(&idt->idt_inbufv, buf);
1099 }
1100 
1101 void
1102 idm_buf_bind_out(idm_task_t *idt, idm_buf_t *buf)
1103 {
1104 	/*
1105 	 * For small transfers, the iSER transport delegates the IDM
1106 	 * layer to bcopy the SCSI Write data for faster IOPS.
1107 	 */
1108 	if (buf->idb_bufbcopy == B_TRUE) {
1109 
1110 		bcopy(buf->idb_bufptr, buf->idb_buf, buf->idb_buflen);
1111 	}
1112 	mutex_enter(&idt->idt_mutex);
1113 	idm_buf_bind_out_locked(idt, buf);
1114 	mutex_exit(&idt->idt_mutex);
1115 }
1116 
1117 static void
1118 idm_buf_bind_out_locked(idm_task_t *idt, idm_buf_t *buf)
1119 {
1120 	buf->idb_task_binding = idt;
1121 	buf->idb_ic = idt->idt_ic;
1122 	idm_listbuf_insert(&idt->idt_outbufv, buf);
1123 }
1124 
1125 void
1126 idm_buf_unbind_in(idm_task_t *idt, idm_buf_t *buf)
1127 {
1128 	/*
1129 	 * For small transfers, the iSER transport delegates the IDM
1130 	 * layer to bcopy the SCSI Read data into the read buufer
1131 	 * for faster IOPS.
1132 	 */
1133 	if (buf->idb_bufbcopy == B_TRUE) {
1134 		bcopy(buf->idb_buf, buf->idb_bufptr, buf->idb_buflen);
1135 	}
1136 	mutex_enter(&idt->idt_mutex);
1137 	idm_buf_unbind_in_locked(idt, buf);
1138 	mutex_exit(&idt->idt_mutex);
1139 }
1140 
1141 static void
1142 idm_buf_unbind_in_locked(idm_task_t *idt, idm_buf_t *buf)
1143 {
1144 	list_remove(&idt->idt_inbufv, buf);
1145 }
1146 
1147 void
1148 idm_buf_unbind_out(idm_task_t *idt, idm_buf_t *buf)
1149 {
1150 	mutex_enter(&idt->idt_mutex);
1151 	idm_buf_unbind_out_locked(idt, buf);
1152 	mutex_exit(&idt->idt_mutex);
1153 }
1154 
1155 static void
1156 idm_buf_unbind_out_locked(idm_task_t *idt, idm_buf_t *buf)
1157 {
1158 	list_remove(&idt->idt_outbufv, buf);
1159 }
1160 
1161 /*
1162  * idm_buf_find() will lookup the idm_buf_t based on the relative offset in the
1163  * iSCSI PDU
1164  */
1165 idm_buf_t *
1166 idm_buf_find(void *lbuf, size_t data_offset)
1167 {
1168 	idm_buf_t	*idb;
1169 	list_t		*lst = (list_t *)lbuf;
1170 
1171 	/* iterate through the list to find the buffer */
1172 	for (idb = list_head(lst); idb != NULL; idb = list_next(lst, idb)) {
1173 
1174 		ASSERT((idb->idb_ic->ic_conn_type == CONN_TYPE_TGT) ||
1175 		    (idb->idb_bufoffset == 0));
1176 
1177 		if ((data_offset >= idb->idb_bufoffset) &&
1178 		    (data_offset < (idb->idb_bufoffset + idb->idb_buflen))) {
1179 
1180 			return (idb);
1181 		}
1182 	}
1183 
1184 	return (NULL);
1185 }
1186 
1187 void
1188 idm_bufpat_set(idm_buf_t *idb)
1189 {
1190 	idm_bufpat_t	*bufpat;
1191 	int		len, i;
1192 
1193 	len = idb->idb_buflen;
1194 	len = (len / sizeof (idm_bufpat_t)) * sizeof (idm_bufpat_t);
1195 
1196 	bufpat = idb->idb_buf;
1197 	for (i = 0; i < len; i += sizeof (idm_bufpat_t)) {
1198 		bufpat->bufpat_idb = idb;
1199 		bufpat->bufpat_bufmagic = IDM_BUF_MAGIC;
1200 		bufpat->bufpat_offset = i;
1201 		bufpat++;
1202 	}
1203 }
1204 
1205 boolean_t
1206 idm_bufpat_check(idm_buf_t *idb, int check_len, idm_bufpat_check_type_t type)
1207 {
1208 	idm_bufpat_t	*bufpat;
1209 	int		len, i;
1210 
1211 	len = (type == BP_CHECK_QUICK) ? sizeof (idm_bufpat_t) : check_len;
1212 	len = (len / sizeof (idm_bufpat_t)) * sizeof (idm_bufpat_t);
1213 	ASSERT(len <= idb->idb_buflen);
1214 	bufpat = idb->idb_buf;
1215 
1216 	/*
1217 	 * Don't check the pattern in buffers that came from outside IDM
1218 	 * (these will be buffers from the initiator that we opted not
1219 	 * to double-buffer)
1220 	 */
1221 	if (!idb->idb_bufalloc)
1222 		return (B_FALSE);
1223 
1224 	/*
1225 	 * Return true if we find the pattern anywhere in the buffer
1226 	 */
1227 	for (i = 0; i < len; i += sizeof (idm_bufpat_t)) {
1228 		if (BUFPAT_MATCH(bufpat, idb)) {
1229 			IDM_CONN_LOG(CE_WARN, "idm_bufpat_check found: "
1230 			    "idb %p bufpat %p "
1231 			    "bufpat_idb=%p bufmagic=%08x offset=%08x",
1232 			    (void *)idb, (void *)bufpat, bufpat->bufpat_idb,
1233 			    bufpat->bufpat_bufmagic, bufpat->bufpat_offset);
1234 			DTRACE_PROBE2(bufpat__pattern__found,
1235 			    idm_buf_t *, idb, idm_bufpat_t *, bufpat);
1236 			if (type == BP_CHECK_ASSERT) {
1237 				ASSERT(0);
1238 			}
1239 			return (B_TRUE);
1240 		}
1241 		bufpat++;
1242 	}
1243 
1244 	return (B_FALSE);
1245 }
1246 
1247 /*
1248  * idm_task_alloc
1249  *
1250  * This function will allocate a idm_task_t structure. A task tag is also
1251  * generated and saved in idt_tt. The task is not active.
1252  */
1253 idm_task_t *
1254 idm_task_alloc(idm_conn_t *ic)
1255 {
1256 	idm_task_t	*idt;
1257 
1258 	ASSERT(ic != NULL);
1259 
1260 	/* Don't allocate new tasks if we are not in FFP */
1261 	if (!ic->ic_ffp) {
1262 		return (NULL);
1263 	}
1264 	idt = kmem_cache_alloc(idm.idm_task_cache, KM_NOSLEEP);
1265 	if (idt == NULL) {
1266 		return (NULL);
1267 	}
1268 
1269 	ASSERT(list_is_empty(&idt->idt_inbufv));
1270 	ASSERT(list_is_empty(&idt->idt_outbufv));
1271 
1272 	mutex_enter(&ic->ic_state_mutex);
1273 	if (!ic->ic_ffp) {
1274 		mutex_exit(&ic->ic_state_mutex);
1275 		kmem_cache_free(idm.idm_task_cache, idt);
1276 		return (NULL);
1277 	}
1278 	idm_conn_hold(ic);
1279 	mutex_exit(&ic->ic_state_mutex);
1280 
1281 	idt->idt_state		= TASK_IDLE;
1282 	idt->idt_ic		= ic;
1283 	idt->idt_private 	= NULL;
1284 	idt->idt_exp_datasn	= 0;
1285 	idt->idt_exp_rttsn	= 0;
1286 	idt->idt_flags		= 0;
1287 	return (idt);
1288 }
1289 
1290 /*
1291  * idm_task_start
1292  *
1293  * Mark the task active and initialize some stats. The caller
1294  * sets up the idm_task_t structure with a prior call to idm_task_alloc().
1295  * The task service does not function as a task/work engine, it is the
1296  * responsibility of the initiator to start the data transfer and free the
1297  * resources.
1298  */
1299 void
1300 idm_task_start(idm_task_t *idt, uintptr_t handle)
1301 {
1302 	ASSERT(idt != NULL);
1303 
1304 	/* mark the task as ACTIVE */
1305 	idt->idt_state = TASK_ACTIVE;
1306 	idt->idt_client_handle = handle;
1307 	idt->idt_tx_to_ini_start = idt->idt_tx_to_ini_done =
1308 	    idt->idt_rx_from_ini_start = idt->idt_rx_from_ini_done =
1309 	    idt->idt_tx_bytes = idt->idt_rx_bytes = 0;
1310 }
1311 
1312 /*
1313  * idm_task_done
1314  *
1315  * This function sets the state to indicate that the task is no longer active.
1316  */
1317 void
1318 idm_task_done(idm_task_t *idt)
1319 {
1320 	ASSERT(idt != NULL);
1321 
1322 	mutex_enter(&idt->idt_mutex);
1323 	idt->idt_state = TASK_IDLE;
1324 	mutex_exit(&idt->idt_mutex);
1325 
1326 	/*
1327 	 * Although unlikely it is possible for a reference to come in after
1328 	 * the client has decided the task is over but before we've marked
1329 	 * the task idle.  One specific unavoidable scenario is the case where
1330 	 * received PDU with the matching ITT/TTT results in a successful
1331 	 * lookup of this task.  We are at the mercy of the remote node in
1332 	 * that case so we need to handle it.  Now that the task state
1333 	 * has changed no more references will occur so a simple call to
1334 	 * idm_refcnt_wait_ref should deal with the situation.
1335 	 */
1336 	idm_refcnt_wait_ref(&idt->idt_refcnt);
1337 	idm_refcnt_reset(&idt->idt_refcnt);
1338 }
1339 
1340 /*
1341  * idm_task_free
1342  *
1343  * This function will free the Task Tag and the memory allocated for the task
1344  * idm_task_done should be called prior to this call
1345  */
1346 void
1347 idm_task_free(idm_task_t *idt)
1348 {
1349 	idm_conn_t *ic;
1350 
1351 	ASSERT(idt != NULL);
1352 	ASSERT(idt->idt_refcnt.ir_refcnt == 0);
1353 	ASSERT(idt->idt_state == TASK_IDLE);
1354 
1355 	ic = idt->idt_ic;
1356 
1357 	/*
1358 	 * It's possible for items to still be in the idt_inbufv list if
1359 	 * they were added after idm_free_task_rsrc was called.  We rely on
1360 	 * STMF to free all buffers associated with the task however STMF
1361 	 * doesn't know that we have this reference to the buffers.
1362 	 * Use list_create so that we don't end up with stale references
1363 	 * to these buffers.
1364 	 */
1365 	list_create(&idt->idt_inbufv, sizeof (idm_buf_t),
1366 	    offsetof(idm_buf_t, idb_buflink));
1367 	list_create(&idt->idt_outbufv, sizeof (idm_buf_t),
1368 	    offsetof(idm_buf_t, idb_buflink));
1369 
1370 	kmem_cache_free(idm.idm_task_cache, idt);
1371 
1372 	idm_conn_rele(ic);
1373 }
1374 
1375 /*
1376  * idm_task_find_common
1377  *	common code for idm_task_find() and idm_task_find_and_complete()
1378  */
1379 /*ARGSUSED*/
1380 static idm_task_t *
1381 idm_task_find_common(idm_conn_t *ic, uint32_t itt, uint32_t ttt,
1382     boolean_t complete)
1383 {
1384 	uint32_t	tt, client_handle;
1385 	idm_task_t	*idt;
1386 
1387 	/*
1388 	 * Must match both itt and ttt.  The table is indexed by itt
1389 	 * for initiator connections and ttt for target connections.
1390 	 */
1391 	if (IDM_CONN_ISTGT(ic)) {
1392 		tt = ttt;
1393 		client_handle = itt;
1394 	} else {
1395 		tt = itt;
1396 		client_handle = ttt;
1397 	}
1398 
1399 	rw_enter(&idm.idm_taskid_table_lock, RW_READER);
1400 	if (tt >= idm.idm_taskid_max) {
1401 		rw_exit(&idm.idm_taskid_table_lock);
1402 		return (NULL);
1403 	}
1404 
1405 	idt = idm.idm_taskid_table[tt];
1406 
1407 	if (idt != NULL) {
1408 		mutex_enter(&idt->idt_mutex);
1409 		if ((idt->idt_state != TASK_ACTIVE) ||
1410 		    (idt->idt_ic != ic) ||
1411 		    (IDM_CONN_ISTGT(ic) &&
1412 		    (idt->idt_client_handle != client_handle))) {
1413 			/*
1414 			 * Task doesn't match or task is aborting and
1415 			 * we don't want any more references.
1416 			 */
1417 			if ((idt->idt_ic != ic) &&
1418 			    (idt->idt_state == TASK_ACTIVE) &&
1419 			    (IDM_CONN_ISINI(ic) || idt->idt_client_handle ==
1420 			    client_handle)) {
1421 				IDM_CONN_LOG(CE_WARN,
1422 				"idm_task_find: wrong connection %p != %p",
1423 				    (void *)ic, (void *)idt->idt_ic);
1424 			}
1425 			mutex_exit(&idt->idt_mutex);
1426 			rw_exit(&idm.idm_taskid_table_lock);
1427 			return (NULL);
1428 		}
1429 		idm_task_hold(idt);
1430 		/*
1431 		 * Set the task state to TASK_COMPLETE so it can no longer
1432 		 * be found or aborted.
1433 		 */
1434 		if (B_TRUE == complete)
1435 			idt->idt_state = TASK_COMPLETE;
1436 		mutex_exit(&idt->idt_mutex);
1437 	}
1438 	rw_exit(&idm.idm_taskid_table_lock);
1439 
1440 	return (idt);
1441 }
1442 
1443 /*
1444  * This function looks up a task by task tag.
1445  */
1446 idm_task_t *
1447 idm_task_find(idm_conn_t *ic, uint32_t itt, uint32_t ttt)
1448 {
1449 	return (idm_task_find_common(ic, itt, ttt, B_FALSE));
1450 }
1451 
1452 /*
1453  * This function looks up a task by task tag. If found, the task state
1454  * is atomically set to TASK_COMPLETE so it can longer be found or aborted.
1455  */
1456 idm_task_t *
1457 idm_task_find_and_complete(idm_conn_t *ic, uint32_t itt, uint32_t ttt)
1458 {
1459 	return (idm_task_find_common(ic, itt, ttt, B_TRUE));
1460 }
1461 
1462 /*
1463  * idm_task_find_by_handle
1464  *
1465  * This function looks up a task by the client-private idt_client_handle.
1466  *
1467  * This function should NEVER be called in the performance path.  It is
1468  * intended strictly for error recovery/task management.
1469  */
1470 /*ARGSUSED*/
1471 void *
1472 idm_task_find_by_handle(idm_conn_t *ic, uintptr_t handle)
1473 {
1474 	idm_task_t	*idt = NULL;
1475 	int		idx = 0;
1476 
1477 	rw_enter(&idm.idm_taskid_table_lock, RW_READER);
1478 
1479 	for (idx = 0; idx < idm.idm_taskid_max; idx++) {
1480 		idt = idm.idm_taskid_table[idx];
1481 
1482 		if (idt == NULL)
1483 			continue;
1484 
1485 		mutex_enter(&idt->idt_mutex);
1486 
1487 		if (idt->idt_state != TASK_ACTIVE) {
1488 			/*
1489 			 * Task is either in suspend, abort, or already
1490 			 * complete.
1491 			 */
1492 			mutex_exit(&idt->idt_mutex);
1493 			continue;
1494 		}
1495 
1496 		if (idt->idt_client_handle == handle) {
1497 			idm_task_hold(idt);
1498 			mutex_exit(&idt->idt_mutex);
1499 			break;
1500 		}
1501 
1502 		mutex_exit(&idt->idt_mutex);
1503 	}
1504 
1505 	rw_exit(&idm.idm_taskid_table_lock);
1506 
1507 	if ((idt == NULL) || (idx == idm.idm_taskid_max))
1508 		return (NULL);
1509 
1510 	return (idt->idt_private);
1511 }
1512 
1513 void
1514 idm_task_hold(idm_task_t *idt)
1515 {
1516 	idm_refcnt_hold(&idt->idt_refcnt);
1517 }
1518 
1519 void
1520 idm_task_rele(idm_task_t *idt)
1521 {
1522 	idm_refcnt_rele(&idt->idt_refcnt);
1523 }
1524 
1525 void
1526 idm_task_abort(idm_conn_t *ic, idm_task_t *idt, idm_abort_type_t abort_type)
1527 {
1528 	idm_task_t	*task;
1529 	int		idx;
1530 
1531 	/*
1532 	 * Passing NULL as the task indicates that all tasks
1533 	 * for this connection should be aborted.
1534 	 */
1535 	if (idt == NULL) {
1536 		/*
1537 		 * Only the connection state machine should ask for
1538 		 * all tasks to abort and this should never happen in FFP.
1539 		 */
1540 		ASSERT(!ic->ic_ffp);
1541 		rw_enter(&idm.idm_taskid_table_lock, RW_READER);
1542 		for (idx = 0; idx < idm.idm_taskid_max; idx++) {
1543 			task = idm.idm_taskid_table[idx];
1544 			if (task == NULL)
1545 				continue;
1546 			mutex_enter(&task->idt_mutex);
1547 			if ((task->idt_state != TASK_IDLE) &&
1548 			    (task->idt_state != TASK_COMPLETE) &&
1549 			    (task->idt_ic == ic)) {
1550 				rw_exit(&idm.idm_taskid_table_lock);
1551 				idm_task_abort_one(ic, task, abort_type);
1552 				rw_enter(&idm.idm_taskid_table_lock, RW_READER);
1553 			} else
1554 				mutex_exit(&task->idt_mutex);
1555 		}
1556 		rw_exit(&idm.idm_taskid_table_lock);
1557 	} else {
1558 		mutex_enter(&idt->idt_mutex);
1559 		idm_task_abort_one(ic, idt, abort_type);
1560 	}
1561 }
1562 
1563 static void
1564 idm_task_abort_unref_cb(void *ref)
1565 {
1566 	idm_task_t *idt = ref;
1567 
1568 	mutex_enter(&idt->idt_mutex);
1569 	switch (idt->idt_state) {
1570 	case TASK_SUSPENDING:
1571 		idt->idt_state = TASK_SUSPENDED;
1572 		mutex_exit(&idt->idt_mutex);
1573 		idm_task_aborted(idt, IDM_STATUS_SUSPENDED);
1574 		return;
1575 	case TASK_ABORTING:
1576 		idt->idt_state = TASK_ABORTED;
1577 		mutex_exit(&idt->idt_mutex);
1578 		idm_task_aborted(idt, IDM_STATUS_ABORTED);
1579 		return;
1580 	default:
1581 		mutex_exit(&idt->idt_mutex);
1582 		ASSERT(0);
1583 		break;
1584 	}
1585 }
1586 
1587 /*
1588  * Abort the idm task.
1589  *    Caller must hold the task mutex, which will be released before return
1590  */
1591 static void
1592 idm_task_abort_one(idm_conn_t *ic, idm_task_t *idt, idm_abort_type_t abort_type)
1593 {
1594 	/* Caller must hold connection mutex */
1595 	ASSERT(mutex_owned(&idt->idt_mutex));
1596 	switch (idt->idt_state) {
1597 	case TASK_ACTIVE:
1598 		switch (abort_type) {
1599 		case AT_INTERNAL_SUSPEND:
1600 			/* Call transport to release any resources */
1601 			idt->idt_state = TASK_SUSPENDING;
1602 			mutex_exit(&idt->idt_mutex);
1603 			ic->ic_transport_ops->it_free_task_rsrc(idt);
1604 
1605 			/*
1606 			 * Wait for outstanding references.  When all
1607 			 * references are released the callback will call
1608 			 * idm_task_aborted().
1609 			 */
1610 			idm_refcnt_async_wait_ref(&idt->idt_refcnt,
1611 			    &idm_task_abort_unref_cb);
1612 			return;
1613 		case AT_INTERNAL_ABORT:
1614 		case AT_TASK_MGMT_ABORT:
1615 			idt->idt_state = TASK_ABORTING;
1616 			mutex_exit(&idt->idt_mutex);
1617 			ic->ic_transport_ops->it_free_task_rsrc(idt);
1618 
1619 			/*
1620 			 * Wait for outstanding references.  When all
1621 			 * references are released the callback will call
1622 			 * idm_task_aborted().
1623 			 */
1624 			idm_refcnt_async_wait_ref(&idt->idt_refcnt,
1625 			    &idm_task_abort_unref_cb);
1626 			return;
1627 		default:
1628 			ASSERT(0);
1629 		}
1630 		break;
1631 	case TASK_SUSPENDING:
1632 		/* Already called transport_free_task_rsrc(); */
1633 		switch (abort_type) {
1634 		case AT_INTERNAL_SUSPEND:
1635 			/* Already doing it */
1636 			break;
1637 		case AT_INTERNAL_ABORT:
1638 		case AT_TASK_MGMT_ABORT:
1639 			idt->idt_state = TASK_ABORTING;
1640 			break;
1641 		default:
1642 			ASSERT(0);
1643 		}
1644 		break;
1645 	case TASK_SUSPENDED:
1646 		/* Already called transport_free_task_rsrc(); */
1647 		switch (abort_type) {
1648 		case AT_INTERNAL_SUSPEND:
1649 			/* Already doing it */
1650 			break;
1651 		case AT_INTERNAL_ABORT:
1652 		case AT_TASK_MGMT_ABORT:
1653 			idt->idt_state = TASK_ABORTING;
1654 			mutex_exit(&idt->idt_mutex);
1655 
1656 			/*
1657 			 * We could probably call idm_task_aborted directly
1658 			 * here but we may be holding the conn lock. It's
1659 			 * easier to just switch contexts.  Even though
1660 			 * we shouldn't really have any references we'll
1661 			 * set the state to TASK_ABORTING instead of
1662 			 * TASK_ABORTED so we can use the same code path.
1663 			 */
1664 			idm_refcnt_async_wait_ref(&idt->idt_refcnt,
1665 			    &idm_task_abort_unref_cb);
1666 			return;
1667 		default:
1668 			ASSERT(0);
1669 		}
1670 		break;
1671 	case TASK_ABORTING:
1672 	case TASK_ABORTED:
1673 		switch (abort_type) {
1674 		case AT_INTERNAL_SUSPEND:
1675 			/* We're already past this point... */
1676 		case AT_INTERNAL_ABORT:
1677 		case AT_TASK_MGMT_ABORT:
1678 			/* Already doing it */
1679 			break;
1680 		default:
1681 			ASSERT(0);
1682 		}
1683 		break;
1684 	case TASK_COMPLETE:
1685 		/*
1686 		 * In this case, let it go.  The status has already been
1687 		 * sent (which may or may not get successfully transmitted)
1688 		 * and we don't want to end up in a race between completing
1689 		 * the status PDU and marking the task suspended.
1690 		 */
1691 		break;
1692 	default:
1693 		ASSERT(0);
1694 	}
1695 	mutex_exit(&idt->idt_mutex);
1696 }
1697 
1698 static void
1699 idm_task_aborted(idm_task_t *idt, idm_status_t status)
1700 {
1701 	(*idt->idt_ic->ic_conn_ops.icb_task_aborted)(idt, status);
1702 }
1703 
1704 /*
1705  * idm_pdu_tx
1706  *
1707  * This is IDM's implementation of the 'Send_Control' operational primitive.
1708  * This function is invoked by an initiator iSCSI layer requesting the transfer
1709  * of a iSCSI command PDU or a target iSCSI layer requesting the transfer of a
1710  * iSCSI response PDU. The PDU will be transmitted as-is by the local Datamover
1711  * layer to the peer iSCSI layer in the remote iSCSI node. The connection info
1712  * and iSCSI PDU-specific qualifiers namely BHS, AHS, DataDescriptor and Size
1713  * are provided as input.
1714  *
1715  */
1716 void
1717 idm_pdu_tx(idm_pdu_t *pdu)
1718 {
1719 	idm_conn_t		*ic = pdu->isp_ic;
1720 	iscsi_async_evt_hdr_t	*async_evt;
1721 
1722 	/*
1723 	 * If we are in full-featured mode then route SCSI-related
1724 	 * commands to the appropriate function vector without checking
1725 	 * the connection state.  We will only be in full-feature mode
1726 	 * when we are in an acceptable state for SCSI PDU's.
1727 	 *
1728 	 * We also need to ensure that there are no PDU events outstanding
1729 	 * on the state machine.  Any non-SCSI PDU's received in full-feature
1730 	 * mode will result in PDU events and until these have been handled
1731 	 * we need to route all PDU's through the state machine as PDU
1732 	 * events to maintain ordering.
1733 	 *
1734 	 * Note that IDM cannot enter FFP mode until it processes in
1735 	 * its state machine the last xmit of the login process.
1736 	 * Hence, checking the IDM_PDU_LOGIN_TX flag here would be
1737 	 * superfluous.
1738 	 */
1739 	mutex_enter(&ic->ic_state_mutex);
1740 	if (ic->ic_ffp && (ic->ic_pdu_events == 0)) {
1741 		mutex_exit(&ic->ic_state_mutex);
1742 		switch (IDM_PDU_OPCODE(pdu)) {
1743 		case ISCSI_OP_SCSI_RSP:
1744 			/* Target only */
1745 			DTRACE_ISCSI_2(scsi__response, idm_conn_t *, ic,
1746 			    iscsi_scsi_rsp_hdr_t *,
1747 			    (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr);
1748 			idm_pdu_tx_forward(ic, pdu);
1749 			return;
1750 		case ISCSI_OP_SCSI_TASK_MGT_RSP:
1751 			/* Target only */
1752 			DTRACE_ISCSI_2(task__response, idm_conn_t *, ic,
1753 			    iscsi_text_rsp_hdr_t *,
1754 			    (iscsi_text_rsp_hdr_t *)pdu->isp_hdr);
1755 			idm_pdu_tx_forward(ic, pdu);
1756 			return;
1757 		case ISCSI_OP_SCSI_DATA_RSP:
1758 			/* Target only */
1759 			DTRACE_ISCSI_2(data__send, idm_conn_t *, ic,
1760 			    iscsi_data_rsp_hdr_t *,
1761 			    (iscsi_data_rsp_hdr_t *)pdu->isp_hdr);
1762 			idm_pdu_tx_forward(ic, pdu);
1763 			return;
1764 		case ISCSI_OP_RTT_RSP:
1765 			/* Target only */
1766 			DTRACE_ISCSI_2(data__request, idm_conn_t *, ic,
1767 			    iscsi_rtt_hdr_t *,
1768 			    (iscsi_rtt_hdr_t *)pdu->isp_hdr);
1769 			idm_pdu_tx_forward(ic, pdu);
1770 			return;
1771 		case ISCSI_OP_NOOP_IN:
1772 			/* Target only */
1773 			DTRACE_ISCSI_2(nop__send, idm_conn_t *, ic,
1774 			    iscsi_nop_in_hdr_t *,
1775 			    (iscsi_nop_in_hdr_t *)pdu->isp_hdr);
1776 			idm_pdu_tx_forward(ic, pdu);
1777 			return;
1778 		case ISCSI_OP_TEXT_RSP:
1779 			/* Target only */
1780 			DTRACE_ISCSI_2(text__response, idm_conn_t *, ic,
1781 			    iscsi_text_rsp_hdr_t *,
1782 			    (iscsi_text_rsp_hdr_t *)pdu->isp_hdr);
1783 			idm_pdu_tx_forward(ic, pdu);
1784 			return;
1785 		case ISCSI_OP_TEXT_CMD:
1786 		case ISCSI_OP_NOOP_OUT:
1787 		case ISCSI_OP_SCSI_CMD:
1788 		case ISCSI_OP_SCSI_DATA:
1789 		case ISCSI_OP_SCSI_TASK_MGT_MSG:
1790 			/* Initiator only */
1791 			idm_pdu_tx_forward(ic, pdu);
1792 			return;
1793 		default:
1794 			break;
1795 		}
1796 
1797 		mutex_enter(&ic->ic_state_mutex);
1798 	}
1799 
1800 	/*
1801 	 * Any PDU's processed outside of full-feature mode and non-SCSI
1802 	 * PDU's in full-feature mode are handled by generating an
1803 	 * event to the connection state machine.  The state machine
1804 	 * will validate the PDU against the current state and either
1805 	 * transmit the PDU if the opcode is allowed or handle an
1806 	 * error if the PDU is not allowed.
1807 	 *
1808 	 * This code-path will also generate any events that are implied
1809 	 * by the PDU opcode.  For example a "login response" with success
1810 	 * status generates a CE_LOGOUT_SUCCESS_SND event.
1811 	 */
1812 	switch (IDM_PDU_OPCODE(pdu)) {
1813 	case ISCSI_OP_LOGIN_CMD:
1814 		idm_conn_tx_pdu_event(ic, CE_LOGIN_SND, (uintptr_t)pdu);
1815 		break;
1816 	case ISCSI_OP_LOGIN_RSP:
1817 		DTRACE_ISCSI_2(login__response, idm_conn_t *, ic,
1818 		    iscsi_login_rsp_hdr_t *,
1819 		    (iscsi_login_rsp_hdr_t *)pdu->isp_hdr);
1820 		idm_parse_login_rsp(ic, pdu, /* Is RX */ B_FALSE);
1821 		break;
1822 	case ISCSI_OP_LOGOUT_CMD:
1823 		idm_parse_logout_req(ic, pdu, /* Is RX */ B_FALSE);
1824 		break;
1825 	case ISCSI_OP_LOGOUT_RSP:
1826 		DTRACE_ISCSI_2(logout__response, idm_conn_t *, ic,
1827 		    iscsi_logout_rsp_hdr_t *,
1828 		    (iscsi_logout_rsp_hdr_t *)pdu->isp_hdr);
1829 		idm_parse_logout_rsp(ic, pdu, /* Is RX */ B_FALSE);
1830 		break;
1831 	case ISCSI_OP_ASYNC_EVENT:
1832 		DTRACE_ISCSI_2(async__send, idm_conn_t *, ic,
1833 		    iscsi_async_evt_hdr_t *,
1834 		    (iscsi_async_evt_hdr_t *)pdu->isp_hdr);
1835 		async_evt = (iscsi_async_evt_hdr_t *)pdu->isp_hdr;
1836 		switch (async_evt->async_event) {
1837 		case ISCSI_ASYNC_EVENT_REQUEST_LOGOUT:
1838 			idm_conn_tx_pdu_event(ic, CE_ASYNC_LOGOUT_SND,
1839 			    (uintptr_t)pdu);
1840 			break;
1841 		case ISCSI_ASYNC_EVENT_DROPPING_CONNECTION:
1842 			idm_conn_tx_pdu_event(ic, CE_ASYNC_DROP_CONN_SND,
1843 			    (uintptr_t)pdu);
1844 			break;
1845 		case ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS:
1846 			idm_conn_tx_pdu_event(ic, CE_ASYNC_DROP_ALL_CONN_SND,
1847 			    (uintptr_t)pdu);
1848 			break;
1849 		case ISCSI_ASYNC_EVENT_SCSI_EVENT:
1850 		case ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION:
1851 		default:
1852 			idm_conn_tx_pdu_event(ic, CE_MISC_TX,
1853 			    (uintptr_t)pdu);
1854 			break;
1855 		}
1856 		break;
1857 	case ISCSI_OP_SCSI_RSP:
1858 		/* Target only */
1859 		DTRACE_ISCSI_2(scsi__response, idm_conn_t *, ic,
1860 		    iscsi_scsi_rsp_hdr_t *,
1861 		    (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr);
1862 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1863 		break;
1864 	case ISCSI_OP_SCSI_TASK_MGT_RSP:
1865 		/* Target only */
1866 		DTRACE_ISCSI_2(task__response, idm_conn_t *, ic,
1867 		    iscsi_scsi_task_mgt_rsp_hdr_t *,
1868 		    (iscsi_scsi_task_mgt_rsp_hdr_t *)pdu->isp_hdr);
1869 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1870 		break;
1871 	case ISCSI_OP_SCSI_DATA_RSP:
1872 		/* Target only */
1873 		DTRACE_ISCSI_2(data__send, idm_conn_t *, ic,
1874 		    iscsi_data_rsp_hdr_t *,
1875 		    (iscsi_data_rsp_hdr_t *)pdu->isp_hdr);
1876 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1877 		break;
1878 	case ISCSI_OP_RTT_RSP:
1879 		/* Target only */
1880 		DTRACE_ISCSI_2(data__request, idm_conn_t *, ic,
1881 		    iscsi_rtt_hdr_t *,
1882 		    (iscsi_rtt_hdr_t *)pdu->isp_hdr);
1883 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1884 		break;
1885 	case ISCSI_OP_NOOP_IN:
1886 		/* Target only */
1887 		DTRACE_ISCSI_2(nop__send, idm_conn_t *, ic,
1888 		    iscsi_nop_in_hdr_t *,
1889 		    (iscsi_nop_in_hdr_t *)pdu->isp_hdr);
1890 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1891 		break;
1892 	case ISCSI_OP_TEXT_RSP:
1893 		/* Target only */
1894 		DTRACE_ISCSI_2(text__response, idm_conn_t *, ic,
1895 		    iscsi_text_rsp_hdr_t *,
1896 		    (iscsi_text_rsp_hdr_t *)pdu->isp_hdr);
1897 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1898 		break;
1899 		/* Initiator only */
1900 	case ISCSI_OP_SCSI_CMD:
1901 	case ISCSI_OP_SCSI_TASK_MGT_MSG:
1902 	case ISCSI_OP_SCSI_DATA:
1903 	case ISCSI_OP_NOOP_OUT:
1904 	case ISCSI_OP_TEXT_CMD:
1905 	case ISCSI_OP_SNACK_CMD:
1906 	case ISCSI_OP_REJECT_MSG:
1907 	default:
1908 		/*
1909 		 * Connection state machine will validate these PDU's against
1910 		 * the current state.  A PDU not allowed in the current
1911 		 * state will cause a protocol error.
1912 		 */
1913 		idm_conn_tx_pdu_event(ic, CE_MISC_TX, (uintptr_t)pdu);
1914 		break;
1915 	}
1916 	mutex_exit(&ic->ic_state_mutex);
1917 }
1918 
1919 /*
1920  * Common allocation of a PDU along with memory for header and data.
1921  */
1922 static idm_pdu_t *
1923 idm_pdu_alloc_common(uint_t hdrlen, uint_t datalen, int sleepflag)
1924 {
1925 	idm_pdu_t *result;
1926 
1927 	/*
1928 	 * IDM clients should cache these structures for performance
1929 	 * critical paths.  We can't cache effectively in IDM because we
1930 	 * don't know the correct header and data size.
1931 	 *
1932 	 * Valid header length is assumed to be hdrlen and valid data
1933 	 * length is assumed to be datalen.  isp_hdrlen and isp_datalen
1934 	 * can be adjusted after the PDU is returned if necessary.
1935 	 */
1936 	result = kmem_zalloc(sizeof (idm_pdu_t) + hdrlen + datalen, sleepflag);
1937 	if (result != NULL) {
1938 		/* For idm_pdu_free sanity check */
1939 		result->isp_flags |= IDM_PDU_ALLOC;
1940 		/* pointer arithmetic */
1941 		result->isp_hdr = (iscsi_hdr_t *)(result + 1);
1942 		result->isp_hdrlen = hdrlen;
1943 		result->isp_hdrbuflen = hdrlen;
1944 		result->isp_transport_hdrlen = 0;
1945 		if (datalen != 0)
1946 			result->isp_data = (uint8_t *)result->isp_hdr + hdrlen;
1947 		result->isp_datalen = datalen;
1948 		result->isp_databuflen = datalen;
1949 		result->isp_magic = IDM_PDU_MAGIC;
1950 	}
1951 
1952 	return (result);
1953 }
1954 
1955 /*
1956  * Typical idm_pdu_alloc invocation, will block for resources.
1957  */
1958 idm_pdu_t *
1959 idm_pdu_alloc(uint_t hdrlen, uint_t datalen)
1960 {
1961 	return (idm_pdu_alloc_common(hdrlen, datalen, KM_SLEEP));
1962 }
1963 
1964 /*
1965  * Non-blocking idm_pdu_alloc implementation, returns NULL if resources
1966  * are not available.  Needed for transport-layer allocations which may
1967  * be invoking in interrupt context.
1968  */
1969 idm_pdu_t *
1970 idm_pdu_alloc_nosleep(uint_t hdrlen, uint_t datalen)
1971 {
1972 	return (idm_pdu_alloc_common(hdrlen, datalen, KM_NOSLEEP));
1973 }
1974 
1975 /*
1976  * Free a PDU previously allocated with idm_pdu_alloc() including any
1977  * header and data space allocated as part of the original request.
1978  * Additional memory regions referenced by subsequent modification of
1979  * the isp_hdr and/or isp_data fields will not be freed.
1980  */
1981 void
1982 idm_pdu_free(idm_pdu_t *pdu)
1983 {
1984 	/* Make sure the structure was allocated using idm_pdu_alloc() */
1985 	ASSERT(pdu->isp_flags & IDM_PDU_ALLOC);
1986 	kmem_free(pdu,
1987 	    sizeof (idm_pdu_t) + pdu->isp_hdrbuflen + pdu->isp_databuflen);
1988 }
1989 
1990 /*
1991  * Initialize the connection, private and callback fields in a PDU.
1992  */
1993 void
1994 idm_pdu_init(idm_pdu_t *pdu, idm_conn_t *ic, void *private, idm_pdu_cb_t *cb)
1995 {
1996 	/*
1997 	 * idm_pdu_complete() will call idm_pdu_free if the callback is
1998 	 * NULL.  This will only work if the PDU was originally allocated
1999 	 * with idm_pdu_alloc().
2000 	 */
2001 	ASSERT((pdu->isp_flags & IDM_PDU_ALLOC) ||
2002 	    (cb != NULL));
2003 	pdu->isp_magic = IDM_PDU_MAGIC;
2004 	pdu->isp_ic = ic;
2005 	pdu->isp_private = private;
2006 	pdu->isp_callback = cb;
2007 }
2008 
2009 /*
2010  * Initialize the header and header length field.  This function should
2011  * not be used to adjust the header length in a buffer allocated via
2012  * pdu_pdu_alloc since it overwrites the existing header pointer.
2013  */
2014 void
2015 idm_pdu_init_hdr(idm_pdu_t *pdu, uint8_t *hdr, uint_t hdrlen)
2016 {
2017 	pdu->isp_hdr = (iscsi_hdr_t *)((void *)hdr);
2018 	pdu->isp_hdrlen = hdrlen;
2019 }
2020 
2021 /*
2022  * Initialize the data and data length fields.  This function should
2023  * not be used to adjust the data length of a buffer allocated via
2024  * idm_pdu_alloc since it overwrites the existing data pointer.
2025  */
2026 void
2027 idm_pdu_init_data(idm_pdu_t *pdu, uint8_t *data, uint_t datalen)
2028 {
2029 	pdu->isp_data = data;
2030 	pdu->isp_datalen = datalen;
2031 }
2032 
2033 void
2034 idm_pdu_complete(idm_pdu_t *pdu, idm_status_t status)
2035 {
2036 	if (pdu->isp_callback) {
2037 		pdu->isp_status = status;
2038 		(*pdu->isp_callback)(pdu, status);
2039 	} else {
2040 		idm_pdu_free(pdu);
2041 	}
2042 }
2043 
2044 /*
2045  * State machine auditing
2046  */
2047 
2048 void
2049 idm_sm_audit_init(sm_audit_buf_t *audit_buf)
2050 {
2051 	bzero(audit_buf, sizeof (sm_audit_buf_t));
2052 	audit_buf->sab_max_index = SM_AUDIT_BUF_MAX_REC - 1;
2053 }
2054 
2055 static
2056 sm_audit_record_t *
2057 idm_sm_audit_common(sm_audit_buf_t *audit_buf, sm_audit_record_type_t r_type,
2058     sm_audit_sm_type_t sm_type,
2059     int current_state)
2060 {
2061 	sm_audit_record_t *sar;
2062 
2063 	sar = audit_buf->sab_records;
2064 	sar += audit_buf->sab_index;
2065 	audit_buf->sab_index++;
2066 	audit_buf->sab_index &= audit_buf->sab_max_index;
2067 
2068 	sar->sar_type = r_type;
2069 	gethrestime(&sar->sar_timestamp);
2070 	sar->sar_sm_type = sm_type;
2071 	sar->sar_state = current_state;
2072 
2073 	return (sar);
2074 }
2075 
2076 void
2077 idm_sm_audit_event(sm_audit_buf_t *audit_buf,
2078     sm_audit_sm_type_t sm_type, int current_state,
2079     int event, uintptr_t event_info)
2080 {
2081 	sm_audit_record_t *sar;
2082 
2083 	sar = idm_sm_audit_common(audit_buf, SAR_STATE_EVENT,
2084 	    sm_type, current_state);
2085 	sar->sar_event = event;
2086 	sar->sar_event_info = event_info;
2087 }
2088 
2089 void
2090 idm_sm_audit_state_change(sm_audit_buf_t *audit_buf,
2091     sm_audit_sm_type_t sm_type, int current_state, int new_state)
2092 {
2093 	sm_audit_record_t *sar;
2094 
2095 	sar = idm_sm_audit_common(audit_buf, SAR_STATE_CHANGE,
2096 	    sm_type, current_state);
2097 	sar->sar_new_state = new_state;
2098 }
2099 
2100 
2101 /*
2102  * Object reference tracking
2103  */
2104 
2105 void
2106 idm_refcnt_init(idm_refcnt_t *refcnt, void *referenced_obj)
2107 {
2108 	bzero(refcnt, sizeof (*refcnt));
2109 	idm_refcnt_reset(refcnt);
2110 	refcnt->ir_referenced_obj = referenced_obj;
2111 	bzero(&refcnt->ir_audit_buf, sizeof (refcnt_audit_buf_t));
2112 	refcnt->ir_audit_buf.anb_max_index = REFCNT_AUDIT_BUF_MAX_REC - 1;
2113 	mutex_init(&refcnt->ir_mutex, NULL, MUTEX_DEFAULT, NULL);
2114 	cv_init(&refcnt->ir_cv, NULL, CV_DEFAULT, NULL);
2115 }
2116 
2117 void
2118 idm_refcnt_destroy(idm_refcnt_t *refcnt)
2119 {
2120 	/*
2121 	 * Grab the mutex to there are no other lingering threads holding
2122 	 * the mutex before we destroy it (e.g. idm_refcnt_rele just after
2123 	 * the refcnt goes to zero if ir_waiting == REF_WAIT_ASYNC)
2124 	 */
2125 	mutex_enter(&refcnt->ir_mutex);
2126 	ASSERT(refcnt->ir_refcnt == 0);
2127 	cv_destroy(&refcnt->ir_cv);
2128 	mutex_destroy(&refcnt->ir_mutex);
2129 }
2130 
2131 void
2132 idm_refcnt_reset(idm_refcnt_t *refcnt)
2133 {
2134 	refcnt->ir_waiting = REF_NOWAIT;
2135 	refcnt->ir_refcnt = 0;
2136 }
2137 
2138 void
2139 idm_refcnt_hold(idm_refcnt_t *refcnt)
2140 {
2141 	/*
2142 	 * Nothing should take a hold on an object after a call to
2143 	 * idm_refcnt_wait_ref or idm_refcnd_async_wait_ref
2144 	 */
2145 	ASSERT(refcnt->ir_waiting == REF_NOWAIT);
2146 
2147 	mutex_enter(&refcnt->ir_mutex);
2148 	refcnt->ir_refcnt++;
2149 	REFCNT_AUDIT(refcnt);
2150 	mutex_exit(&refcnt->ir_mutex);
2151 }
2152 
2153 static void
2154 idm_refcnt_unref_task(void *refcnt_void)
2155 {
2156 	idm_refcnt_t *refcnt = refcnt_void;
2157 
2158 	REFCNT_AUDIT(refcnt);
2159 	(*refcnt->ir_cb)(refcnt->ir_referenced_obj);
2160 }
2161 
2162 void
2163 idm_refcnt_rele(idm_refcnt_t *refcnt)
2164 {
2165 	mutex_enter(&refcnt->ir_mutex);
2166 	ASSERT(refcnt->ir_refcnt > 0);
2167 	refcnt->ir_refcnt--;
2168 	REFCNT_AUDIT(refcnt);
2169 	if (refcnt->ir_waiting == REF_NOWAIT) {
2170 		/* No one is waiting on this object */
2171 		mutex_exit(&refcnt->ir_mutex);
2172 		return;
2173 	}
2174 
2175 	/*
2176 	 * Someone is waiting for this object to go idle so check if
2177 	 * refcnt is 0.  Waiting on an object then later grabbing another
2178 	 * reference is not allowed so we don't need to handle that case.
2179 	 */
2180 	if (refcnt->ir_refcnt == 0) {
2181 		if (refcnt->ir_waiting == REF_WAIT_ASYNC) {
2182 			if (taskq_dispatch(idm.idm_global_taskq,
2183 			    &idm_refcnt_unref_task, refcnt, TQ_SLEEP) == NULL) {
2184 				cmn_err(CE_WARN,
2185 				    "idm_refcnt_rele: Couldn't dispatch task");
2186 			}
2187 		} else if (refcnt->ir_waiting == REF_WAIT_SYNC) {
2188 			cv_signal(&refcnt->ir_cv);
2189 		}
2190 	}
2191 	mutex_exit(&refcnt->ir_mutex);
2192 }
2193 
2194 void
2195 idm_refcnt_rele_and_destroy(idm_refcnt_t *refcnt, idm_refcnt_cb_t *cb_func)
2196 {
2197 	mutex_enter(&refcnt->ir_mutex);
2198 	ASSERT(refcnt->ir_refcnt > 0);
2199 	refcnt->ir_refcnt--;
2200 	REFCNT_AUDIT(refcnt);
2201 
2202 	/*
2203 	 * Someone is waiting for this object to go idle so check if
2204 	 * refcnt is 0.  Waiting on an object then later grabbing another
2205 	 * reference is not allowed so we don't need to handle that case.
2206 	 */
2207 	if (refcnt->ir_refcnt == 0) {
2208 		refcnt->ir_cb = cb_func;
2209 		refcnt->ir_waiting = REF_WAIT_ASYNC;
2210 		if (taskq_dispatch(idm.idm_global_taskq,
2211 		    &idm_refcnt_unref_task, refcnt, TQ_SLEEP) == NULL) {
2212 			cmn_err(CE_WARN,
2213 			    "idm_refcnt_rele: Couldn't dispatch task");
2214 		}
2215 	}
2216 	mutex_exit(&refcnt->ir_mutex);
2217 }
2218 
2219 void
2220 idm_refcnt_wait_ref(idm_refcnt_t *refcnt)
2221 {
2222 	mutex_enter(&refcnt->ir_mutex);
2223 	refcnt->ir_waiting = REF_WAIT_SYNC;
2224 	REFCNT_AUDIT(refcnt);
2225 	while (refcnt->ir_refcnt != 0)
2226 		cv_wait(&refcnt->ir_cv, &refcnt->ir_mutex);
2227 	mutex_exit(&refcnt->ir_mutex);
2228 }
2229 
2230 void
2231 idm_refcnt_async_wait_ref(idm_refcnt_t *refcnt, idm_refcnt_cb_t *cb_func)
2232 {
2233 	mutex_enter(&refcnt->ir_mutex);
2234 	refcnt->ir_waiting = REF_WAIT_ASYNC;
2235 	refcnt->ir_cb = cb_func;
2236 	REFCNT_AUDIT(refcnt);
2237 	/*
2238 	 * It's possible we don't have any references.  To make things easier
2239 	 * on the caller use a taskq to call the callback instead of
2240 	 * calling it synchronously
2241 	 */
2242 	if (refcnt->ir_refcnt == 0) {
2243 		if (taskq_dispatch(idm.idm_global_taskq,
2244 		    &idm_refcnt_unref_task, refcnt, TQ_SLEEP) == NULL) {
2245 			cmn_err(CE_WARN,
2246 			    "idm_refcnt_async_wait_ref: "
2247 			    "Couldn't dispatch task");
2248 		}
2249 	}
2250 	mutex_exit(&refcnt->ir_mutex);
2251 }
2252 
2253 void
2254 idm_refcnt_destroy_unref_obj(idm_refcnt_t *refcnt,
2255     idm_refcnt_cb_t *cb_func)
2256 {
2257 	mutex_enter(&refcnt->ir_mutex);
2258 	if (refcnt->ir_refcnt == 0) {
2259 		mutex_exit(&refcnt->ir_mutex);
2260 		(*cb_func)(refcnt->ir_referenced_obj);
2261 		return;
2262 	}
2263 	mutex_exit(&refcnt->ir_mutex);
2264 }
2265 
2266 void
2267 idm_conn_hold(idm_conn_t *ic)
2268 {
2269 	idm_refcnt_hold(&ic->ic_refcnt);
2270 }
2271 
2272 void
2273 idm_conn_rele(idm_conn_t *ic)
2274 {
2275 	idm_refcnt_rele(&ic->ic_refcnt);
2276 }
2277 
2278 void
2279 idm_conn_set_target_name(idm_conn_t *ic, char *target_name)
2280 {
2281 	(void) strlcpy(ic->ic_target_name, target_name, ISCSI_MAX_NAME_LEN + 1);
2282 }
2283 
2284 void
2285 idm_conn_set_initiator_name(idm_conn_t *ic, char *initiator_name)
2286 {
2287 	(void) strlcpy(ic->ic_initiator_name, initiator_name,
2288 	    ISCSI_MAX_NAME_LEN + 1);
2289 }
2290 
2291 void
2292 idm_conn_set_isid(idm_conn_t *ic, uint8_t isid[ISCSI_ISID_LEN])
2293 {
2294 	(void) snprintf(ic->ic_isid, ISCSI_MAX_ISID_LEN + 1,
2295 	    "%02x%02x%02x%02x%02x%02x",
2296 	    isid[0], isid[1], isid[2], isid[3], isid[4], isid[5]);
2297 }
2298 
2299 static int
2300 _idm_init(void)
2301 {
2302 	/* Initialize the rwlock for the taskid table */
2303 	rw_init(&idm.idm_taskid_table_lock, NULL, RW_DRIVER, NULL);
2304 
2305 	/* Initialize the global mutex and taskq */
2306 	mutex_init(&idm.idm_global_mutex, NULL, MUTEX_DEFAULT, NULL);
2307 
2308 	cv_init(&idm.idm_tgt_svc_cv, NULL, CV_DEFAULT, NULL);
2309 	cv_init(&idm.idm_wd_cv, NULL, CV_DEFAULT, NULL);
2310 
2311 	/*
2312 	 * The maximum allocation needs to be high here since there can be
2313 	 * many concurrent tasks using the global taskq.
2314 	 */
2315 	idm.idm_global_taskq = taskq_create("idm_global_taskq", 1, minclsyspri,
2316 	    128, 16384, TASKQ_PREPOPULATE);
2317 	if (idm.idm_global_taskq == NULL) {
2318 		cv_destroy(&idm.idm_wd_cv);
2319 		cv_destroy(&idm.idm_tgt_svc_cv);
2320 		mutex_destroy(&idm.idm_global_mutex);
2321 		rw_destroy(&idm.idm_taskid_table_lock);
2322 		return (ENOMEM);
2323 	}
2324 
2325 	/* Start watchdog thread */
2326 	idm.idm_wd_thread = thread_create(NULL, 0,
2327 	    idm_wd_thread, NULL, 0, &p0, TS_RUN, minclsyspri);
2328 	if (idm.idm_wd_thread == NULL) {
2329 		/* Couldn't create the watchdog thread */
2330 		taskq_destroy(idm.idm_global_taskq);
2331 		cv_destroy(&idm.idm_wd_cv);
2332 		cv_destroy(&idm.idm_tgt_svc_cv);
2333 		mutex_destroy(&idm.idm_global_mutex);
2334 		rw_destroy(&idm.idm_taskid_table_lock);
2335 		return (ENOMEM);
2336 	}
2337 
2338 	/* Pause until the watchdog thread is running */
2339 	mutex_enter(&idm.idm_global_mutex);
2340 	while (!idm.idm_wd_thread_running)
2341 		cv_wait(&idm.idm_wd_cv, &idm.idm_global_mutex);
2342 	mutex_exit(&idm.idm_global_mutex);
2343 
2344 	/*
2345 	 * Allocate the task ID table and set "next" to 0.
2346 	 */
2347 
2348 	idm.idm_taskid_max = idm_max_taskids;
2349 	idm.idm_taskid_table = (idm_task_t **)
2350 	    kmem_zalloc(idm.idm_taskid_max * sizeof (idm_task_t *), KM_SLEEP);
2351 	idm.idm_taskid_next = 0;
2352 
2353 	/* Create the global buffer and task kmem caches */
2354 	idm.idm_buf_cache = kmem_cache_create("idm_buf_cache",
2355 	    sizeof (idm_buf_t), 8, NULL, NULL, NULL, NULL, NULL, KM_SLEEP);
2356 
2357 	/*
2358 	 * Note, we're explicitly allocating an additional iSER header-
2359 	 * sized chunk for each of these elements. See idm_task_constructor().
2360 	 */
2361 	idm.idm_task_cache = kmem_cache_create("idm_task_cache",
2362 	    sizeof (idm_task_t) + IDM_TRANSPORT_HEADER_LENGTH, 8,
2363 	    &idm_task_constructor, &idm_task_destructor,
2364 	    NULL, NULL, NULL, KM_SLEEP);
2365 
2366 	/* Create the service and connection context lists */
2367 	list_create(&idm.idm_tgt_svc_list, sizeof (idm_svc_t),
2368 	    offsetof(idm_svc_t, is_list_node));
2369 	list_create(&idm.idm_tgt_conn_list, sizeof (idm_conn_t),
2370 	    offsetof(idm_conn_t, ic_list_node));
2371 	list_create(&idm.idm_ini_conn_list, sizeof (idm_conn_t),
2372 	    offsetof(idm_conn_t, ic_list_node));
2373 
2374 	/* Initialize the native sockets transport */
2375 	idm_so_init(&idm_transport_list[IDM_TRANSPORT_TYPE_SOCKETS]);
2376 
2377 	/* Create connection ID pool */
2378 	(void) idm_idpool_create(&idm.idm_conn_id_pool);
2379 
2380 	return (DDI_SUCCESS);
2381 }
2382 
2383 static int
2384 _idm_fini(void)
2385 {
2386 	if (!list_is_empty(&idm.idm_ini_conn_list) ||
2387 	    !list_is_empty(&idm.idm_tgt_conn_list) ||
2388 	    !list_is_empty(&idm.idm_tgt_svc_list)) {
2389 		return (EBUSY);
2390 	}
2391 
2392 	mutex_enter(&idm.idm_global_mutex);
2393 	idm.idm_wd_thread_running = B_FALSE;
2394 	cv_signal(&idm.idm_wd_cv);
2395 	mutex_exit(&idm.idm_global_mutex);
2396 
2397 	thread_join(idm.idm_wd_thread_did);
2398 
2399 	idm_idpool_destroy(&idm.idm_conn_id_pool);
2400 
2401 	/* Close any LDI handles we have open on transport drivers */
2402 	mutex_enter(&idm.idm_global_mutex);
2403 	idm_transport_teardown();
2404 	mutex_exit(&idm.idm_global_mutex);
2405 
2406 	/* Teardown the native sockets transport */
2407 	idm_so_fini();
2408 
2409 	list_destroy(&idm.idm_ini_conn_list);
2410 	list_destroy(&idm.idm_tgt_conn_list);
2411 	list_destroy(&idm.idm_tgt_svc_list);
2412 	kmem_cache_destroy(idm.idm_task_cache);
2413 	kmem_cache_destroy(idm.idm_buf_cache);
2414 	kmem_free(idm.idm_taskid_table,
2415 	    idm.idm_taskid_max * sizeof (idm_task_t *));
2416 	mutex_destroy(&idm.idm_global_mutex);
2417 	cv_destroy(&idm.idm_wd_cv);
2418 	cv_destroy(&idm.idm_tgt_svc_cv);
2419 	rw_destroy(&idm.idm_taskid_table_lock);
2420 
2421 	return (0);
2422 }
2423