xref: /illumos-gate/usr/src/uts/common/io/comstar/port/srpt/srpt_stp.c (revision cd3e933325e68e23516a196a8fea7f49b1e497c3)
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 /*
23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /*
27  * SCSI Target Port I/F for Solaris SCSI RDMA Protocol Target (SRP)
28  * port provider module for the COMSTAR framework.
29  */
30 
31 #include <sys/cpuvar.h>
32 #include <sys/types.h>
33 #include <sys/conf.h>
34 #include <sys/stat.h>
35 #include <sys/file.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/modctl.h>
39 #include <sys/sysmacros.h>
40 #include <sys/sdt.h>
41 #include <sys/taskq.h>
42 #include <sys/atomic.h>
43 
44 #include <sys/stmf.h>
45 #include <sys/stmf_ioctl.h>
46 #include <sys/portif.h>
47 
48 #include <sys/ib/mgt/ibdma/ibdma.h>
49 
50 #include "srp.h"
51 #include "srpt_impl.h"
52 #include "srpt_cm.h"
53 #include "srpt_ioc.h"
54 #include "srpt_ch.h"
55 #include "srpt_stp.h"
56 
57 extern srpt_ctxt_t	*srpt_ctxt;
58 extern uint32_t		srpt_iu_size;
59 
60 /*
61  * STMF LPort Interface Prototypes
62  */
63 static stmf_status_t srpt_stp_xfer_data(struct scsi_task *task,
64 	struct stmf_data_buf *dbuf, uint32_t ioflags);
65 stmf_status_t srpt_stp_send_status(struct scsi_task *task,
66 	uint32_t ioflags);
67 static void srpt_stp_task_free(struct scsi_task *task);
68 static stmf_status_t srpt_stp_abort(struct stmf_local_port *lport,
69 	int abort_cmd, void *arg, uint32_t flags);
70 static void srpt_stp_task_poll(struct scsi_task *task);
71 static void srpt_stp_ctl(struct stmf_local_port *lport,
72 	int cmd, void *arg);
73 static stmf_status_t srpt_stp_info(uint32_t cmd,
74 	struct stmf_local_port *lport, void *arg, uint8_t *buf,
75 	uint32_t *bufsizep);
76 static void srpt_stp_event_handler(struct stmf_local_port *lport,
77 	int eventid, void *arg, uint32_t flags);
78 
79 static void srpt_format_login_rsp(srp_login_req_t *req,
80 	srp_login_rsp_t *rsp, uint8_t flags);
81 static void srpt_format_login_rej(srp_login_req_t *req,
82 	srp_login_rej_t *rej, uint32_t reason);
83 
84 static scsi_devid_desc_t *srpt_stp_alloc_scsi_devid_desc(uint64_t guid);
85 static void srpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd);
86 
87 extern uint16_t srpt_send_msg_depth;
88 
89 /*
90  * srpt_stp_start_srp() - Start SRP service
91  *
92  * Enable the SRP service for the specified SCSI Target Port.
93  */
94 int
95 srpt_stp_start_srp(srpt_target_port_t *tgt)
96 {
97 	ibt_status_t		status;
98 	ibdma_status_t		dma_status;
99 	int			port;
100 	srpt_ioc_t		*ioc;
101 
102 	if (tgt == NULL) {
103 		SRPT_DPRINTF_L1("stp_start_srp, NULL SCSI target port");
104 		return (IBT_FAILURE);
105 	}
106 
107 	if (tgt->tp_ioc == NULL) {
108 		SRPT_DPRINTF_L1("stp_start_srp, SCSI target port NULL"
109 		    " IOC pointer");
110 		return (IBT_FAILURE);
111 	}
112 	ioc = tgt->tp_ioc;
113 
114 	SRPT_DPRINTF_L2("stp_start_srp, register SRP service for"
115 	    " svc_id (%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
116 	status = ibt_register_service(srpt_ctxt->sc_ibt_hdl,
117 	    &tgt->tp_ibt_svc_desc, tgt->tp_ibt_svc_id, 1,
118 	    &tgt->tp_ibt_svc_hdl, NULL);
119 	if (status != IBT_SUCCESS) {
120 		tgt->tp_ibt_svc_hdl = NULL;
121 		SRPT_DPRINTF_L1("stp_start_srp, SRP service creation err (%d)",
122 		    status);
123 		return (status);
124 	}
125 
126 	/*
127 	 * Bind the service associated with the SCSI target port to
128 	 * each active port of the I/O Controller.
129 	 */
130 	for (port = 0; port < ioc->ioc_attr.hca_nports; port++) {
131 		status = srpt_ioc_svc_bind(tgt, port+1);
132 		if (status != IBT_SUCCESS &&
133 		    status != IBT_HCA_PORT_NOT_ACTIVE) {
134 			SRPT_DPRINTF_L1("start_srp, Unable to bind"
135 			    " service (%d)", status);
136 			goto srp_start_err;
137 		}
138 	}
139 
140 	/* don't online if we have no active ports */
141 	if (tgt->tp_num_active_ports == 0) {
142 		SRPT_DPRINTF_L2("start_srp, no ports active for svc_id %016llx",
143 		    (u_longlong_t)tgt->tp_ibt_svc_id);
144 		status = IBT_HCA_PORT_NOT_ACTIVE;
145 		goto srp_start_err;
146 	}
147 
148 	tgt->tp_srp_enabled = 1;
149 
150 	/*
151 	 * Calculate the new I/O Controller profile and either update the
152 	 * profile if previously registered or register it with the IB
153 	 * Device Management Agent.
154 	 */
155 	SRPT_DPRINTF_L3("start_srp, update I/O Controller profile (%016llx)",
156 	    (u_longlong_t)ioc->ioc_guid);
157 
158 	srpt_ioc_init_profile(ioc);
159 	if (ioc->ioc_ibdma_hdl == NULL) {
160 		ioc->ioc_ibdma_hdl =
161 		    srpt_ctxt->sc_ibdma_ops.ibdma_register(ioc->ioc_guid,
162 		    &ioc->ioc_profile, &ioc->ioc_svc);
163 		if (ioc->ioc_ibdma_hdl == NULL) {
164 			SRPT_DPRINTF_L1("start_srp, Unable to register"
165 			    " I/O Profile for svc_id %016llx",
166 			    (u_longlong_t)tgt->tp_ibt_svc_id);
167 			status = IBT_FAILURE;
168 			goto srp_start_err;
169 		}
170 	} else {
171 		dma_status =
172 		    srpt_ctxt->sc_ibdma_ops.ibdma_update(ioc->ioc_ibdma_hdl,
173 		    &ioc->ioc_profile, &ioc->ioc_svc);
174 		if (dma_status != IBDMA_SUCCESS) {
175 			SRPT_DPRINTF_L1("start_srp, Unable to update I/O"
176 			    " Profile for svc_id %016llxi (%d)",
177 			    (u_longlong_t)tgt->tp_ibt_svc_id, dma_status);
178 			status = IBT_FAILURE;
179 			goto srp_start_err;
180 		}
181 	}
182 
183 	return (IBT_SUCCESS);
184 
185 srp_start_err:
186 	tgt->tp_srp_enabled = 0;
187 	srpt_ioc_svc_unbind_all(tgt);
188 	tgt->tp_num_active_ports = 0;
189 	if (tgt->tp_ibt_svc_hdl != NULL) {
190 		(void) ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
191 		    tgt->tp_ibt_svc_hdl);
192 		tgt->tp_ibt_svc_hdl = NULL;
193 	}
194 	return (status);
195 }
196 
197 /*
198  * srpt_stp_stop_srp() - Stop SRP service.
199  *
200  * Disable the SRP service on the specified SCSI Target Port.
201  */
202 void
203 srpt_stp_stop_srp(srpt_target_port_t *tgt)
204 {
205 	ibt_status_t		status;
206 	ibdma_status_t		dma_status;
207 	srpt_ioc_t		*ioc;
208 	srpt_channel_t		*ch;
209 
210 	if (tgt == NULL) {
211 		SRPT_DPRINTF_L2("stp_stop_srp, NULL SCSI Target Port"
212 		    " specified");
213 		return;
214 	}
215 
216 	if (tgt->tp_ioc == NULL) {
217 		SRPT_DPRINTF_L2("stp_stop_srp, bad Target, IOC NULL");
218 		return;
219 	}
220 	ioc = tgt->tp_ioc;
221 
222 	/*
223 	 * Update the I/O Controller profile to remove the SRP service
224 	 * for this SCSI target port.
225 	 */
226 	tgt->tp_srp_enabled = 0;
227 
228 	if (ioc->ioc_ibdma_hdl != NULL) {
229 		SRPT_DPRINTF_L3("stp_stop_srp, update I/O Controller"
230 		    " profile (%016llx)", (u_longlong_t)ioc->ioc_guid);
231 		srpt_ioc_init_profile(ioc);
232 
233 		if (ioc->ioc_profile.ioc_service_entries == 0) {
234 			SRPT_DPRINTF_L3("stp_stop_srp, no services active"
235 			    " unregister IOC profile");
236 			srpt_ctxt->sc_ibdma_ops.ibdma_unregister(
237 			    ioc->ioc_ibdma_hdl);
238 			ioc->ioc_ibdma_hdl = NULL;
239 		} else {
240 			dma_status = srpt_ctxt->sc_ibdma_ops.ibdma_update(
241 			    ioc->ioc_ibdma_hdl, &ioc->ioc_profile,
242 			    &ioc->ioc_svc);
243 			if (dma_status != IBDMA_SUCCESS) {
244 				SRPT_DPRINTF_L1("stp_stop_srp, Unable to"
245 				    " update I/O Profile (%d)", dma_status);
246 				return;
247 			}
248 		}
249 	}
250 
251 	/*
252 	 * Unbind the SRP service associated with the SCSI target port
253 	 * from all of the I/O Controller physical ports.
254 	 */
255 	SRPT_DPRINTF_L2("stp_stop_srp, unbind and de-register service"
256 	    "(%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
257 	if (tgt->tp_ibt_svc_hdl != NULL) {
258 		srpt_ioc_svc_unbind_all(tgt);
259 	}
260 
261 	if (tgt->tp_ibt_svc_hdl != NULL) {
262 		status = ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
263 		    tgt->tp_ibt_svc_hdl);
264 		if (status != IBT_SUCCESS) {
265 			SRPT_DPRINTF_L1("stp_stop_srp, de-register service"
266 			    " error(%d)", status);
267 		}
268 		tgt->tp_ibt_svc_hdl = NULL;
269 	}
270 
271 	/*
272 	 * SRP service is now off-line for this SCSI Target Port.
273 	 * We force a disconnect (i.e. SRP Target Logout) for any
274 	 * active SRP logins.
275 	 */
276 	mutex_enter(&tgt->tp_ch_list_lock);
277 	ch = list_head(&tgt->tp_ch_list);
278 	while (ch != NULL) {
279 		SRPT_DPRINTF_L3("stp_stop_srp, disconnect ch(%p)",
280 		    (void *)ch);
281 		srpt_ch_disconnect(ch);
282 		ch = list_next(&tgt->tp_ch_list, ch);
283 	}
284 	mutex_exit(&tgt->tp_ch_list_lock);
285 
286 	/*
287 	 * wait for all sessions to terminate before returning
288 	 */
289 	mutex_enter(&tgt->tp_sess_list_lock);
290 	while (!list_is_empty(&tgt->tp_sess_list)) {
291 		cv_wait(&tgt->tp_sess_complete, &tgt->tp_sess_list_lock);
292 	}
293 	mutex_exit(&tgt->tp_sess_list_lock);
294 }
295 
296 /*
297  * srpt_stp_alloc_port() - Allocate SCSI Target Port
298  */
299 srpt_target_port_t *
300 srpt_stp_alloc_port(srpt_ioc_t *ioc, ib_guid_t guid)
301 {
302 	stmf_status_t		status;
303 	srpt_target_port_t	*tgt;
304 	stmf_local_port_t	*lport;
305 	uint64_t		temp;
306 
307 	if (ioc == NULL) {
308 		SRPT_DPRINTF_L1("stp_alloc_port, NULL I/O Controller");
309 		return (NULL);
310 	}
311 
312 	SRPT_DPRINTF_L3("stp_alloc_port, allocate STMF local port");
313 	lport = stmf_alloc(STMF_STRUCT_STMF_LOCAL_PORT, sizeof (*tgt), 0);
314 	if (lport == NULL) {
315 		SRPT_DPRINTF_L1("tgt_alloc_port, stmf_alloc failed");
316 		return (NULL);
317 	}
318 
319 	tgt = lport->lport_port_private;
320 	ASSERT(tgt != NULL);
321 
322 	mutex_init(&tgt->tp_lock, NULL, MUTEX_DRIVER, NULL);
323 
324 	mutex_init(&tgt->tp_ch_list_lock, NULL, MUTEX_DRIVER, NULL);
325 	cv_init(&tgt->tp_offline_complete, NULL, CV_DRIVER, NULL);
326 	list_create(&tgt->tp_ch_list, sizeof (srpt_channel_t),
327 	    offsetof(srpt_channel_t, ch_stp_node));
328 
329 	mutex_init(&tgt->tp_sess_list_lock, NULL, MUTEX_DRIVER, NULL);
330 	cv_init(&tgt->tp_sess_complete, NULL, CV_DRIVER, NULL);
331 	list_create(&tgt->tp_sess_list, sizeof (srpt_session_t),
332 	    offsetof(srpt_session_t, ss_node));
333 
334 	tgt->tp_state	 = SRPT_TGT_STATE_OFFLINE;
335 	tgt->tp_drv_disabled  = 0;
336 	tgt->tp_srp_enabled   = 0;
337 	tgt->tp_lport	 = lport;
338 	tgt->tp_ioc	   = ioc;
339 	tgt->tp_ibt_svc_id = guid;
340 	tgt->tp_ibt_svc_desc.sd_handler = srpt_cm_hdlr;
341 	tgt->tp_ibt_svc_desc.sd_flags   = IBT_SRV_NO_FLAGS;
342 	temp = h2b64(tgt->tp_ibt_svc_id);
343 	bcopy(&temp, &tgt->tp_srp_port_id[0], 8);
344 	temp = h2b64(tgt->tp_ioc->ioc_guid);
345 	bcopy(&temp, &tgt->tp_srp_port_id[8], 8);
346 
347 	tgt->tp_nports  = ioc->ioc_attr.hca_nports;
348 	tgt->tp_hw_port =
349 	    kmem_zalloc(sizeof (srpt_hw_port_t) * tgt->tp_nports, KM_SLEEP);
350 	tgt->tp_num_active_ports = 0;
351 	tgt->tp_requested_state = SRPT_TGT_STATE_OFFLINE;
352 
353 	tgt->tp_scsi_devid = srpt_stp_alloc_scsi_devid_desc(tgt->tp_ibt_svc_id);
354 
355 	lport->lport_id = tgt->tp_scsi_devid;
356 	lport->lport_pp = srpt_ctxt->sc_pp;
357 	lport->lport_ds	= ioc->ioc_stmf_ds;
358 	lport->lport_xfer_data	= &srpt_stp_xfer_data;
359 	lport->lport_send_status = &srpt_stp_send_status;
360 	lport->lport_task_free	= &srpt_stp_task_free;
361 	lport->lport_abort	= &srpt_stp_abort;
362 	lport->lport_abort_timeout = 300;	/* 5 minutes */
363 	lport->lport_task_poll	= &srpt_stp_task_poll;
364 	lport->lport_ctl	= &srpt_stp_ctl;
365 	lport->lport_info	= &srpt_stp_info;
366 	lport->lport_event_handler = &srpt_stp_event_handler;
367 
368 	/* set up as alua participating port */
369 	stmf_set_port_alua(lport);
370 
371 	SRPT_DPRINTF_L3("stp_alloc_port, register STMF LPORT");
372 
373 retry_registration:
374 	status = stmf_register_local_port(lport);
375 	if (status == STMF_SUCCESS) {
376 		SRPT_DPRINTF_L3("stp_alloc_port, LPORT successfully"
377 		    " registered");
378 		return (tgt);
379 	}
380 
381 	if (status == STMF_BUSY) {
382 		/*
383 		 * This is only done on an administrative thread of
384 		 * execution so it is ok to take a while.
385 		 */
386 		SRPT_DPRINTF_L3("stp_alloc_port, delaying");
387 		delay(2 * drv_usectohz(1000000));
388 		goto retry_registration;
389 	}
390 	SRPT_DPRINTF_L1("stp_alloc_port, STMF register local port err(0x%llx)",
391 	    (u_longlong_t)status);
392 
393 	SRPT_DPRINTF_L3("stp_alloc_port, free STMF local port");
394 	cv_destroy(&tgt->tp_offline_complete);
395 	mutex_destroy(&tgt->tp_ch_list_lock);
396 	mutex_destroy(&tgt->tp_lock);
397 	if (tgt->tp_hw_port) {
398 		kmem_free(tgt->tp_hw_port,
399 		    sizeof (srpt_hw_port_t) * tgt->tp_nports);
400 	}
401 	if (tgt->tp_scsi_devid) {
402 		srpt_stp_free_scsi_devid_desc(tgt->tp_scsi_devid);
403 	}
404 
405 	stmf_free(lport);
406 
407 	return (NULL);
408 }
409 
410 /*
411  * srpt_stp_free_port() - Free SCSI Target Port
412  */
413 stmf_status_t
414 srpt_stp_free_port(srpt_target_port_t *tgt)
415 {
416 	ASSERT(tgt != NULL);
417 	ASSERT(list_is_empty(&tgt->tp_sess_list));
418 	ASSERT(list_is_empty(&tgt->tp_ch_list));
419 
420 	list_destroy(&tgt->tp_ch_list);
421 	list_destroy(&tgt->tp_sess_list);
422 
423 	cv_destroy(&tgt->tp_sess_complete);
424 	cv_destroy(&tgt->tp_offline_complete);
425 
426 	mutex_destroy(&tgt->tp_sess_list_lock);
427 	mutex_destroy(&tgt->tp_ch_list_lock);
428 	mutex_destroy(&tgt->tp_lock);
429 
430 
431 	SRPT_DPRINTF_L3("stp_free_port, free STMF local port");
432 	if (tgt->tp_hw_port) {
433 		kmem_free(tgt->tp_hw_port,
434 		    sizeof (srpt_hw_port_t) * tgt->tp_nports);
435 	}
436 
437 	if (tgt->tp_scsi_devid) {
438 		srpt_stp_free_scsi_devid_desc(tgt->tp_scsi_devid);
439 	}
440 
441 	stmf_free(tgt->tp_lport);
442 
443 	return (STMF_SUCCESS);
444 }
445 
446 /*
447  * srpt_stp_destroy_port()
448  */
449 stmf_status_t
450 srpt_stp_destroy_port(srpt_target_port_t *tgt)
451 {
452 	stmf_status_t		status;
453 	stmf_change_status_t	cstatus;
454 	uint64_t		guid;
455 
456 	ASSERT(tgt != NULL);
457 	ASSERT(tgt->tp_lport != NULL);
458 
459 	SRPT_DPRINTF_L3("stp_destroy_port, de-register STMF LPORT");
460 
461 	mutex_enter(&tgt->tp_lock);
462 	if (tgt->tp_drv_disabled != 0) {
463 		/* already being destroyed, get out now - should not happen */
464 		mutex_exit(&tgt->tp_lock);
465 		return (STMF_ALREADY);
466 	}
467 
468 	tgt->tp_drv_disabled = 1;
469 	guid = tgt->tp_ioc->ioc_guid;
470 	mutex_exit(&tgt->tp_lock);
471 
472 	SRPT_DPRINTF_L2("stp_destroy_port: unbind and de-register"
473 	    " services for GUID(%016llx)", (u_longlong_t)guid);
474 
475 	cstatus.st_completion_status = STMF_SUCCESS;
476 	cstatus.st_additional_info = NULL;
477 
478 	status = stmf_ctl(STMF_CMD_LPORT_OFFLINE, tgt->tp_lport, &cstatus);
479 
480 	/*
481 	 * Wait for asynchronous target off-line operation
482 	 * to complete and then deregister the target
483 	 * port.
484 	 */
485 	mutex_enter(&tgt->tp_lock);
486 	while (tgt->tp_state != SRPT_TGT_STATE_OFFLINE) {
487 		cv_wait(&tgt->tp_offline_complete, &tgt->tp_lock);
488 	}
489 	mutex_exit(&tgt->tp_lock);
490 
491 	SRPT_DPRINTF_L3("stp_destroy_port: IOC (0x%016llx) Target"
492 	    " SRP off-line complete", (u_longlong_t)guid);
493 
494 	/* loop waiting for all I/O to drain */
495 	for (;;) {
496 		status = stmf_deregister_local_port(tgt->tp_lport);
497 		if (status == STMF_BUSY) {
498 			delay(drv_usectohz(1000000));
499 		} else {
500 			break;
501 		}
502 	}
503 
504 	if (status == STMF_SUCCESS) {
505 		SRPT_DPRINTF_L3("stp_destroy_port, LPORT de-register"
506 		    " complete");
507 	} else {
508 		/*
509 		 * Something other than a BUSY error, this should not happen.
510 		 */
511 		SRPT_DPRINTF_L1(
512 		    "stp_destroy_port, de-register STMF error(0x%llx)",
513 		    (u_longlong_t)status);
514 	}
515 
516 	return (status);
517 }
518 
519 /*
520  * srpt_stp_xfer_data()
521  */
522 /* ARGSUSED */
523 static stmf_status_t
524 srpt_stp_xfer_data(struct scsi_task *task, struct stmf_data_buf *dbuf,
525 	uint32_t ioflags)
526 {
527 	srpt_iu_t		*iu;
528 	srpt_channel_t		*ch;
529 	srpt_ds_dbuf_t		*db;
530 	ibt_send_wr_t		wr;
531 	ibt_wr_ds_t		ds;
532 	ibt_status_t		status;
533 	uint32_t		xfer_len;
534 	uint32_t		xferred_len;
535 	uint32_t		rdma_len;
536 	uint32_t		base_offset;
537 	uint32_t		desc_offset;
538 	srp_direct_desc_t	*desc;
539 
540 	SRPT_DPRINTF_L3("stp_xfer_data, invoked task (%p), dbuf (%p)",
541 	    (void *)task, (void *)dbuf);
542 	iu = task->task_port_private;
543 	ASSERT(iu != NULL);
544 	ASSERT(iu->iu_ch != NULL);
545 	/*
546 	 * We should use iu->iu_ch->ch_swqe_posted to throttle
547 	 * send wqe posting. This is very unlikely because we limit
548 	 * the maximum number of initiator descriptors per IU (impact
549 	 * of fragmentation of intiator buffer space) but it could occur
550 	 * if the back-end (STMF) were to use too many small buffers. In
551 	 * that case we would want to return STMF_BUSY.
552 	 */
553 
554 	SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_flags (0x%x)",
555 	    dbuf->db_flags);
556 	SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_data_size (%d)",
557 	    dbuf->db_data_size);
558 	SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_relative_offset (%d)",
559 	    dbuf->db_relative_offset);
560 
561 	ASSERT((dbuf->db_flags & (DB_DIRECTION_TO_RPORT |
562 	    DB_DIRECTION_FROM_RPORT)) != (DB_DIRECTION_TO_RPORT |
563 	    DB_DIRECTION_FROM_RPORT));
564 
565 	db = dbuf->db_port_private;
566 
567 	/*
568 	 * Check to see if request will overflow the remote buffer; if so
569 	 * return a bad status and let STMF abort the task.
570 	 */
571 	if ((dbuf->db_relative_offset + dbuf->db_data_size) >
572 	    iu->iu_tot_xfer_len) {
573 		SRPT_DPRINTF_L2("stp_xfer_data, overflow of remote buffer");
574 		return (STMF_FAILURE);
575 	}
576 
577 	db->db_iu	= iu;
578 	wr.wr_trans  = IBT_RC_SRV;
579 	wr.wr_opcode = (dbuf->db_flags & DB_DIRECTION_TO_RPORT) ?
580 	    IBT_WRC_RDMAW : IBT_WRC_RDMAR;
581 	wr.wr_nds    = 1;
582 	wr.wr_sgl    = &ds;
583 
584 	/*
585 	 * We know that the data transfer is within the bounds described
586 	 * by our list of remote buffer descriptors.  Find the starting
587 	 * point based on the offset for the transfer, then perform the
588 	 * RDMA operations required of this transfer.
589 	 */
590 	base_offset = 0;
591 	desc = iu->iu_rdescs;
592 
593 	while ((base_offset + desc->dd_len) < dbuf->db_relative_offset) {
594 		base_offset += desc->dd_len;
595 		desc++;
596 	}
597 
598 	xfer_len    = dbuf->db_data_size;
599 	xferred_len = 0;
600 	desc_offset = dbuf->db_relative_offset - base_offset;
601 
602 	ch = iu->iu_ch;
603 
604 	/*
605 	 * If the channel is no longer connected then return an
606 	 * error and do not initiate I/O.  STMF should abort the
607 	 * task.
608 	 */
609 	rw_enter(&ch->ch_rwlock, RW_READER);
610 
611 	if (iu->iu_ch->ch_state == SRPT_CHANNEL_DISCONNECTING) {
612 		rw_exit(&iu->iu_ch->ch_rwlock);
613 		return (STMF_FAILURE);
614 	}
615 
616 	while (xfer_len > 0) {
617 		rdma_len = desc->dd_len - desc_offset;
618 
619 		/*
620 		 * We only generate completion entries on the last IB
621 		 * operation associated with any STMF buffer.
622 		 */
623 		if (rdma_len >= xfer_len) {
624 			rdma_len = xfer_len;
625 			wr.wr_flags  = IBT_WR_SEND_SIGNAL;
626 		} else {
627 			wr.wr_flags  = IBT_WR_NO_FLAGS;
628 		}
629 
630 		wr.wr.rc.rcwr.rdma.rdma_raddr = desc->dd_vaddr + desc_offset;
631 		wr.wr.rc.rcwr.rdma.rdma_rkey  = desc->dd_hdl;
632 		ds.ds_va  = db->db_sge.ds_va + xferred_len;
633 		ds.ds_key = db->db_sge.ds_key;
634 		ds.ds_len = rdma_len;
635 
636 		SRPT_DPRINTF_L4("stp_xfer_data, post RDMA operation");
637 
638 		/*
639 		 * If this task is being aborted or has been aborted,
640 		 * do not post additional I/O.
641 		 */
642 		DTRACE_SRP_8(xfer__start, srpt_channel_t, ch,
643 		    ibt_wr_ds_t, &(db->db_sge), srpt_iu_t, iu,
644 		    ibt_send_wr_t, &wr, uint32_t, rdma_len,
645 		    uint32_t, xferred_len, uint32_t, desc_offset,
646 		    uint32_t, wr.wr_opcode == IBT_WRC_RDMAR ? 0 : 1);
647 		mutex_enter(&iu->iu_lock);
648 		if ((iu->iu_flags & (SRPT_IU_SRP_ABORTING |
649 		    SRPT_IU_STMF_ABORTING | SRPT_IU_ABORTED)) != 0) {
650 			mutex_exit(&iu->iu_lock);
651 			rw_exit(&iu->iu_ch->ch_rwlock);
652 			return (STMF_SUCCESS);
653 		}
654 
655 		/*
656 		 * If a non-error CQE will be requested, add a reference to
657 		 * the IU and initialize the work request appropriately.
658 		 */
659 		if ((wr.wr_flags & IBT_WR_SEND_SIGNAL) != 0) {
660 			wr.wr_id = srpt_ch_alloc_swqe_wrid(ch,
661 			    SRPT_SWQE_TYPE_DATA, (void *)dbuf);
662 			if (wr.wr_id == 0) {
663 				rw_exit(&iu->iu_ch->ch_rwlock);
664 				mutex_exit(&iu->iu_lock);
665 				return (STMF_BUSY);
666 			}
667 			atomic_inc_32(&iu->iu_sq_posted_cnt);
668 		} else {
669 			wr.wr_id = 0;
670 		}
671 
672 		status = ibt_post_send(iu->iu_ch->ch_chan_hdl, &wr, 1, NULL);
673 		mutex_exit(&iu->iu_lock);
674 
675 		if (status != IBT_SUCCESS) {
676 			/*
677 			 * Could not post to IB transport, report to STMF and
678 			 * and let it initiate an abort of the task.
679 			 */
680 			SRPT_DPRINTF_L2("stp_xfer_data, post RDMA"
681 			    " error (%d)", status);
682 
683 			if ((wr.wr_flags & IBT_WR_SEND_SIGNAL) != 0) {
684 				srpt_ch_free_swqe_wrid(ch, wr.wr_id);
685 				atomic_dec_32(&iu->iu_sq_posted_cnt);
686 			}
687 			rw_exit(&iu->iu_ch->ch_rwlock);
688 			return (STMF_FAILURE);
689 		}
690 		xferred_len += rdma_len;
691 		xfer_len    -= rdma_len;
692 		desc_offset  = 0;
693 		desc++;
694 	}
695 
696 	rw_exit(&ch->ch_rwlock);
697 	return (STMF_SUCCESS);
698 }
699 
700 /*
701  * srpt_stp_send_mgmt_response() - Return SRP task managment response IU
702  */
703 ibt_status_t
704 srpt_stp_send_mgmt_response(srpt_iu_t *iu, uint8_t srp_rsp,
705 	uint_t fence)
706 {
707 	srp_rsp_t	*rsp;
708 	srp_rsp_data_t	*data;
709 	uint32_t	rsp_length;
710 	ibt_status_t	status;
711 	uint8_t		*bufp;
712 
713 	ASSERT(mutex_owned(&iu->iu_lock));
714 	rsp = iu->iu_buf;
715 	bufp = (uint8_t *)iu->iu_buf + SRP_RSP_SIZE;
716 	bzero(rsp, SRP_RSP_SIZE + sizeof (srp_rsp_data_t));
717 	rsp->rsp_type = SRP_IU_RSP;
718 
719 	/*
720 	 * Report ULP credits we have added since last response sent
721 	 * over this channel.
722 	 */
723 	rsp->rsp_req_limit_delta =
724 	    h2b32(atomic_swap_32(&iu->iu_ch->ch_req_lim_delta, 0));
725 	rsp->rsp_tag = iu->iu_tag;
726 
727 	/* srp_rsp_t is padded out, so use explicit size here */
728 	rsp_length = SRP_RSP_SIZE;
729 	if (srp_rsp != SRP_TM_SUCCESS) {
730 		rsp->rsp_flags |= SRP_RSP_VALID;
731 		data = (srp_rsp_data_t *)bufp;
732 		data->rd_rsp_status = srp_rsp;
733 		rsp->rsp_data_len = h2b32(sizeof (srp_rsp_data_t));
734 		rsp_length += sizeof (srp_rsp_data_t);
735 	}
736 
737 	SRPT_DPRINTF_L4("stp_send_mgmt_response, sending on ch(%p),"
738 	    " iu(%p), mgmt status(%d)", (void *)iu->iu_ch,
739 	    (void *)iu, srp_rsp);
740 
741 	DTRACE_SRP_4(task__response, srpt_channel_t, iu->iu_ch,
742 	    srp_rsp_t, iu->iu_buf, scsi_task_t, iu->iu_stmf_task,
743 	    int8_t, srp_rsp);
744 
745 	status = srpt_ch_post_send(iu->iu_ch, iu, rsp_length, fence);
746 	if (status != IBT_SUCCESS) {
747 		SRPT_DPRINTF_L2("stp_send_mgmt_response, post "
748 		    "response err(%d)", status);
749 	}
750 	return (status);
751 }
752 
753 /*
754  * srpt_stp_send_response() - Send SRP command response IU
755  */
756 ibt_status_t
757 srpt_stp_send_response(srpt_iu_t *iu, uint8_t scsi_status,
758 	uint8_t flags, uint32_t resid, uint16_t sense_length,
759 	uint8_t *sense_data, uint_t fence)
760 {
761 	srp_rsp_t	*rsp;
762 	uint32_t	rsp_length;
763 	uint8_t		*bufp;
764 	ibt_status_t	status;
765 
766 	ASSERT(mutex_owned(&iu->iu_lock));
767 	rsp = iu->iu_buf;
768 	bufp = (uint8_t *)iu->iu_buf + SRP_RSP_SIZE;
769 	bzero(rsp, SRP_RSP_SIZE);
770 	rsp->rsp_type = SRP_IU_RSP;
771 
772 	/*
773 	 * Report ULP credits we have added since last response sent
774 	 * over this channel.
775 	 */
776 	rsp->rsp_req_limit_delta =
777 	    h2b32(atomic_swap_32(&iu->iu_ch->ch_req_lim_delta, 0));
778 	rsp->rsp_tag = iu->iu_tag;
779 	rsp->rsp_status = scsi_status;
780 
781 	rsp_length = SRP_RSP_SIZE;
782 
783 	if (resid != 0) {
784 		rsp->rsp_flags |= flags;
785 
786 		if ((flags & SRP_RSP_DO_OVER) ||
787 		    (flags & SRP_RSP_DO_UNDER)) {
788 			rsp->rsp_do_resid_cnt = h2b32(resid);
789 		} else if ((flags & SRP_RSP_DI_OVER) ||
790 		    (flags & SRP_RSP_DI_UNDER)) {
791 			rsp->rsp_di_resid_cnt = h2b32(resid);
792 		}
793 	}
794 
795 	if (sense_length != 0) {
796 		rsp->rsp_flags |= SRP_RSP_SNS_VALID;
797 		if (SRP_RSP_SIZE + sense_length >
798 		    iu->iu_ch->ch_ti_iu_len) {
799 			sense_length = iu->iu_ch->ch_ti_iu_len -
800 			    SRP_RSP_SIZE;
801 		}
802 		bcopy(sense_data, bufp, sense_length);
803 		rsp->rsp_sense_data_len = h2b32(sense_length);
804 		rsp_length += sense_length;
805 	}
806 
807 	SRPT_DPRINTF_L4("stp_send_reponse, sending on ch(%p),"
808 	    " iu(%p), length(%d)", (void *)iu->iu_ch,
809 	    (void *)iu, rsp_length);
810 
811 	DTRACE_SRP_4(task__response, srpt_channel_t, iu->iu_ch,
812 	    srp_rsp_t, iu->iu_buf, scsi_task_t, iu->iu_stmf_task,
813 	    uint8_t, scsi_status);
814 
815 	status = srpt_ch_post_send(iu->iu_ch, iu, rsp_length, fence);
816 	if (status != IBT_SUCCESS) {
817 		SRPT_DPRINTF_L2("stp_send_response, post response err(%d)",
818 		    status);
819 	}
820 	return (status);
821 }
822 
823 /*
824  * srpt_stp_send_status()
825  */
826 /* ARGSUSED */
827 stmf_status_t
828 srpt_stp_send_status(struct scsi_task *task, uint32_t ioflags)
829 {
830 	srpt_iu_t	*iu;
831 	ibt_status_t	status;
832 
833 	ASSERT(task != NULL);
834 	iu = task->task_port_private;
835 
836 	ASSERT(iu != NULL);
837 
838 	mutex_enter(&iu->iu_lock);
839 
840 	ASSERT(iu->iu_ch != NULL);
841 
842 	SRPT_DPRINTF_L3("stp_send_status, invoked task (%p)"
843 	    ", task_completion_status (%d)"
844 	    ", task_resid (%d)"
845 	    ", task_status_ctrl (%d)"
846 	    ", task_scsi_status (%d)"
847 	    ", task_sense_length (%d)"
848 	    ", task_sense_data (%p)",
849 	    (void *)task,
850 	    (int)task->task_completion_status,
851 	    task->task_resid,
852 	    task->task_status_ctrl,
853 	    task->task_scsi_status,
854 	    task->task_sense_length,
855 	    (void *)task->task_sense_data);
856 
857 	DTRACE_SRP_4(scsi__response, srpt_channel_t, iu->iu_ch,
858 	    srp_rsp_t, iu->iu_buf, scsi_task_t, task,
859 	    int8_t, task->task_scsi_status);
860 
861 	if ((iu->iu_flags & (SRPT_IU_STMF_ABORTING |
862 	    SRPT_IU_SRP_ABORTING | SRPT_IU_ABORTED)) != 0) {
863 		mutex_exit(&iu->iu_lock);
864 		return (STMF_FAILURE);
865 	}
866 
867 	/*
868 	 * Indicate future aborts can not be initiated (although
869 	 * we will handle any that have been requested since the
870 	 * last I/O completed and before we are sending status).
871 	 */
872 	iu->iu_flags |= SRPT_IU_RESP_SENT;
873 
874 	/*
875 	 * Send SRP command response or SRP task mgmt response.
876 	 */
877 	if (task->task_mgmt_function == 0) {
878 		uint8_t		rsp_flags = 0;
879 		uint32_t	resbytes = 0;
880 
881 		if (task->task_status_ctrl == TASK_SCTRL_OVER) {
882 			resbytes = task->task_resid;
883 
884 			if (task->task_flags & TF_READ_DATA) {
885 				SRPT_DPRINTF_L3(
886 				    "stp_send_status, data out overrun");
887 				rsp_flags |= SRP_RSP_DO_OVER;
888 			} else if (task->task_flags & TF_WRITE_DATA) {
889 				SRPT_DPRINTF_L3(
890 				    "stp_send_status, data in overrun");
891 				rsp_flags |= SRP_RSP_DI_OVER;
892 			}
893 		} else if (task->task_status_ctrl == TASK_SCTRL_UNDER) {
894 			resbytes = task->task_resid;
895 
896 			if (task->task_flags & TF_READ_DATA) {
897 				SRPT_DPRINTF_L3(
898 				    "stp_send_status, data out underrun");
899 				rsp_flags |= SRP_RSP_DO_UNDER;
900 			} else if (task->task_flags & TF_WRITE_DATA) {
901 				SRPT_DPRINTF_L3(
902 				    "stp_send_status, data in underrun");
903 				rsp_flags |= SRP_RSP_DI_UNDER;
904 			}
905 		}
906 
907 		status = srpt_stp_send_response(iu,
908 		    task->task_scsi_status, rsp_flags, resbytes,
909 		    task->task_sense_length, task->task_sense_data, 0);
910 	} else {
911 		status = srpt_stp_send_mgmt_response(iu,
912 		    (task->task_scsi_status ?
913 		    SRP_TM_FAILED : SRP_TM_SUCCESS),
914 		    SRPT_FENCE_SEND);
915 	}
916 
917 	/*
918 	 * If we have an error posting the response return bad status
919 	 * to STMF and let it initiate an abort for the task.
920 	 */
921 	if (status != IBT_SUCCESS) {
922 		SRPT_DPRINTF_L2("stp_send_status, post response err(%d)",
923 		    status);
924 
925 		/* clear the response sent flag since it never went out */
926 		iu->iu_flags &= ~SRPT_IU_RESP_SENT;
927 
928 		mutex_exit(&iu->iu_lock);
929 		return (STMF_FAILURE);
930 	}
931 	mutex_exit(&iu->iu_lock);
932 	return (STMF_SUCCESS);
933 }
934 
935 /*
936  * srpt_stp_task_free() - STMF call-back.
937  */
938 static void
939 srpt_stp_task_free(struct scsi_task *task)
940 {
941 	srpt_iu_t	*iu;
942 	srpt_channel_t	*ch;
943 
944 	SRPT_DPRINTF_L3("stp_task_free, invoked task (%p)",
945 	    (void *)task);
946 
947 	iu = task->task_port_private;
948 	ASSERT(iu != NULL);
949 
950 	mutex_enter(&iu->iu_lock);
951 	ch = iu->iu_ch;
952 	mutex_exit(&iu->iu_lock);
953 
954 	ASSERT(ch != NULL);
955 	ASSERT(ch->ch_session != NULL);
956 
957 	/*
958 	 * Do not hold IU lock while task is being removed from
959 	 * the session list - possible deadlock if cleaning up
960 	 * channel when this is called.
961 	 */
962 	srpt_stp_remove_task(ch->ch_session, iu);
963 
964 	mutex_enter(&iu->iu_lock);
965 	iu->iu_stmf_task = NULL;
966 
967 	srpt_ioc_repost_recv_iu(iu->iu_ioc, iu);
968 
969 	mutex_exit(&iu->iu_lock);
970 
971 	srpt_ch_release_ref(ch, 0);
972 }
973 
974 /*
975  * srpt_stp_abort() - STMF call-back.
976  */
977 /* ARGSUSED */
978 static stmf_status_t
979 srpt_stp_abort(struct stmf_local_port *lport, int abort_cmd,
980 	void *arg, uint32_t flags)
981 {
982 	struct scsi_task	*task;
983 	srpt_iu_t		*iu;
984 	stmf_status_t		status;
985 
986 	SRPT_DPRINTF_L3("stp_abort, invoked lport (%p), arg (%p)",
987 	    (void *)lport, (void *)arg);
988 
989 	task = (struct scsi_task *)arg;
990 	ASSERT(task != NULL);
991 
992 	iu = (srpt_iu_t *)task->task_port_private;
993 	ASSERT(iu != NULL);
994 
995 	mutex_enter(&iu->iu_lock);
996 
997 	/*
998 	 * If no I/O is outstanding then immediately transition to
999 	 * aborted state.  If any I/O is in progress OR we've sent the
1000 	 * completion response, then indicate that an STMF abort has been
1001 	 * requested and ask STMF to call us back later to complete the abort.
1002 	 */
1003 	if ((iu->iu_flags & SRPT_IU_RESP_SENT) ||
1004 	    (iu->iu_sq_posted_cnt > 0)) {
1005 		SRPT_DPRINTF_L3("stp_abort, deferring abort request. "
1006 		    "%d outstanding I/O for IU %p",
1007 		    iu->iu_sq_posted_cnt, (void *)iu);
1008 		iu->iu_flags |= SRPT_IU_STMF_ABORTING;
1009 		status = STMF_BUSY;
1010 	} else {
1011 		SRPT_DPRINTF_L3("stp_abort, no outstanding I/O for %p",
1012 		    (void *)iu);
1013 		iu->iu_flags |= SRPT_IU_ABORTED;
1014 		/* Synchronous abort - STMF will call task_free */
1015 		status = STMF_ABORT_SUCCESS;
1016 	}
1017 
1018 	mutex_exit(&iu->iu_lock);
1019 	return (status);
1020 }
1021 
1022 /*
1023  * srpt_stp_task_poll() - STMF call-back
1024  */
1025 static void
1026 srpt_stp_task_poll(struct scsi_task *task)
1027 {
1028 	SRPT_DPRINTF_L3("stp_task_poll, invoked, task (%p)",
1029 	    (void *)task);
1030 }
1031 
1032 /*
1033  * srpt_stp_ctl() - STMF call-back
1034  */
1035 static void
1036 srpt_stp_ctl(struct stmf_local_port *lport, int cmd, void *arg)
1037 {
1038 	stmf_state_change_info_t	*sc_info = arg;
1039 	stmf_change_status_t		cstatus;
1040 	stmf_status_t			status;
1041 	srpt_target_port_t		*tgt;
1042 	char				*why;
1043 
1044 	ASSERT(sc_info != NULL);
1045 	ASSERT(lport != NULL);
1046 
1047 	tgt = lport->lport_port_private;
1048 	ASSERT(tgt->tp_ioc != NULL);
1049 
1050 	why = sc_info->st_additional_info;
1051 	if (why == NULL) {
1052 		why = "<null>";
1053 	}
1054 
1055 	SRPT_DPRINTF_L2("stp_ctl, invoked for LPORT (0x%016llx), cmd (%d), "
1056 	    "info (%s)", (u_longlong_t)tgt->tp_ibt_svc_id, cmd, why);
1057 
1058 	cstatus.st_completion_status = STMF_SUCCESS;
1059 	cstatus.st_additional_info = NULL;
1060 
1061 	switch (cmd) {
1062 	case STMF_CMD_LPORT_ONLINE:
1063 		SRPT_DPRINTF_L2("stp_ctl, LPORT_ONLINE command,"
1064 		    " st_rflags(0x%llx)", (u_longlong_t)sc_info->st_rflags);
1065 		/*
1066 		 * If the SCSI Target Port is not enabled by the driver,
1067 		 * don't start and instead return busy.  This is a
1068 		 * creation/destruction transitional state and the will
1069 		 * either go away or become enabled.
1070 		 */
1071 		mutex_enter(&tgt->tp_lock);
1072 
1073 		tgt->tp_requested_state = SRPT_TGT_STATE_ONLINE;
1074 
1075 		if (tgt->tp_drv_disabled != 0) {
1076 			SRPT_DPRINTF_L1("stp_ctl, set LPORT_ONLINE failed - "
1077 			    "LPORT (0x%016llx) BUSY",
1078 			    (u_longlong_t)tgt->tp_ibt_svc_id);
1079 			cstatus.st_completion_status = STMF_BUSY;
1080 		} else if ((tgt->tp_state == SRPT_TGT_STATE_ONLINE) ||
1081 		    (tgt->tp_state == SRPT_TGT_STATE_ONLINING)) {
1082 			cstatus.st_completion_status = STMF_ALREADY;
1083 		} else if (tgt->tp_state != SRPT_TGT_STATE_OFFLINE) {
1084 			cstatus.st_completion_status = STMF_INVALID_ARG;
1085 		} else {
1086 			tgt->tp_state = SRPT_TGT_STATE_ONLINING;
1087 			status = srpt_stp_start_srp(tgt);
1088 			if (status != IBT_SUCCESS) {
1089 				tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1090 				cstatus.st_completion_status = STMF_INVALID_ARG;
1091 				if (tgt->tp_num_active_ports == 0) {
1092 					SRPT_DPRINTF_L1(
1093 					    "stp_ctl, no ports active "
1094 					    "for HCA 0x%016llx. Target will "
1095 					    "not be placed online.",
1096 					    (u_longlong_t)tgt->tp_ibt_svc_id);
1097 				}
1098 			}
1099 		}
1100 		mutex_exit(&tgt->tp_lock);
1101 		SRPT_DPRINTF_L3("stp_ctl, (0x%016llx) LPORT_ONLINE command"
1102 		    " status (0x%llx)", (u_longlong_t)tgt->tp_ibt_svc_id,
1103 		    (u_longlong_t)cstatus.st_completion_status);
1104 		status = stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport,
1105 		    &cstatus);
1106 		if (status != STMF_SUCCESS) {
1107 			SRPT_DPRINTF_L1("stp_ctl, ONLINE_COMPLETE returned"
1108 			    " error(0x%llx)", (u_longlong_t)status);
1109 		}
1110 		break;
1111 
1112 	case STMF_CMD_LPORT_OFFLINE:
1113 		SRPT_DPRINTF_L2("stp_ctl, LPORT_OFFLINE command,"
1114 		    " st_rflags(0x%llx)", (u_longlong_t)sc_info->st_rflags);
1115 		mutex_enter(&tgt->tp_lock);
1116 
1117 		/*
1118 		 * Only keep persistent state if explicitly requested by user
1119 		 * action, such as stmfadm offline-target or
1120 		 * svcadm disable stmf.
1121 		 * If not requested by the user, this was likely triggered by
1122 		 * not having any HCA ports active.
1123 		 */
1124 		if (sc_info->st_rflags & STMF_RFLAG_USER_REQUEST) {
1125 			tgt->tp_requested_state = SRPT_TGT_STATE_OFFLINE;
1126 		}
1127 
1128 		if ((tgt->tp_state == SRPT_TGT_STATE_OFFLINE) ||
1129 		    (tgt->tp_state == SRPT_TGT_STATE_OFFLINING)) {
1130 			cstatus.st_completion_status = STMF_ALREADY;
1131 		} else if (tgt->tp_state != SRPT_TGT_STATE_ONLINE) {
1132 			cstatus.st_completion_status = STMF_INVALID_ARG;
1133 		} else {
1134 			tgt->tp_state = SRPT_TGT_STATE_OFFLINING;
1135 			srpt_stp_stop_srp(tgt);
1136 		}
1137 		mutex_exit(&tgt->tp_lock);
1138 		SRPT_DPRINTF_L3("stp_ctl, notify STMF OFFLINE complete"
1139 		    " (0x%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
1140 		status = stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE,
1141 		    lport, &cstatus);
1142 		if (status != STMF_SUCCESS) {
1143 			SRPT_DPRINTF_L1("stp_ctl, OFFLINE_COMPLETE returned"
1144 			    " error(0x%llx)", (u_longlong_t)status);
1145 		}
1146 		break;
1147 
1148 	case STMF_ACK_LPORT_ONLINE_COMPLETE:
1149 		SRPT_DPRINTF_L2("stp_ctl, LPORT_ONLINE_COMPLETE ACK from"
1150 		    " STMF");
1151 		mutex_enter(&tgt->tp_lock);
1152 		if (tgt->tp_state == SRPT_TGT_STATE_ONLINING) {
1153 			SRPT_DPRINTF_L2("stp_ctl, LPORT is ONLINE");
1154 			tgt->tp_state = SRPT_TGT_STATE_ONLINE;
1155 		} else {
1156 			SRPT_DPRINTF_L2("stp_ctl, LPORT not on-lining");
1157 		}
1158 		mutex_exit(&tgt->tp_lock);
1159 		break;
1160 
1161 	case STMF_ACK_LPORT_OFFLINE_COMPLETE:
1162 		SRPT_DPRINTF_L2("stp_ctl, LPORT_OFFLINE_COMPLETE ACK from"
1163 		    " STMF");
1164 		mutex_enter(&tgt->tp_lock);
1165 		if (tgt->tp_state == SRPT_TGT_STATE_OFFLINING) {
1166 			SRPT_DPRINTF_L2("stp_ctl, LPORT is OFFLINE");
1167 			tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1168 			cv_broadcast(&tgt->tp_offline_complete);
1169 		} else {
1170 			SRPT_DPRINTF_L2("stp_ctl, LPORT not off-lining");
1171 		}
1172 		mutex_exit(&tgt->tp_lock);
1173 		break;
1174 
1175 	default:
1176 		SRPT_DPRINTF_L2("stp_ctl, cmd (%d) not handled",
1177 		    cmd);
1178 		break;
1179 	}
1180 }
1181 
1182 /*
1183  * srpt_stp_info() - STMF call-back
1184  */
1185 /* ARGSUSED */
1186 static stmf_status_t
1187 srpt_stp_info(uint32_t cmd, struct stmf_local_port *lport,
1188 	void *arg, uint8_t *buf, uint32_t *bufsizep)
1189 {
1190 	SRPT_DPRINTF_L3("stp_info, invoked");
1191 	return (STMF_SUCCESS);
1192 }
1193 
1194 /*
1195  * srpt_stp_event_handler() - STMF call-back
1196  */
1197 /* ARGSUSED */
1198 static void
1199 srpt_stp_event_handler(struct stmf_local_port *lport, int eventid,
1200 	void *arg, uint32_t flags)
1201 {
1202 	SRPT_DPRINTF_L3("stp_event_handler, invoked");
1203 }
1204 
1205 /*
1206  * srpt_stp_alloc_scsi_devid_desc()
1207  *
1208  * Allocate and initialize a SCSI device ID descriptor for
1209  * the SRP protocol.  Names are eui.GUID format.
1210  *
1211  * Both extension and guid are passed in host order.
1212  */
1213 static scsi_devid_desc_t *
1214 srpt_stp_alloc_scsi_devid_desc(uint64_t guid)
1215 {
1216 	scsi_devid_desc_t	*sdd;
1217 
1218 	sdd = kmem_zalloc(sizeof (*sdd) + SRPT_EUI_ID_LEN + 1, KM_SLEEP);
1219 	sdd->protocol_id = PROTOCOL_SRP;
1220 	sdd->piv = 1;
1221 	sdd->code_set = CODE_SET_ASCII;
1222 	sdd->association = ID_IS_TARGET_PORT;
1223 	sdd->ident_length = SRPT_EUI_ID_LEN;
1224 	(void) sprintf((char *)sdd->ident, "eui.%016llX", (u_longlong_t)guid);
1225 	return (sdd);
1226 }
1227 
1228 /*
1229  * srpt_stp_free_scsi_devid_desc()
1230  *
1231  * Free a SRPT SCSI device ID descriptor previously allocated via
1232  * srpt_stp_alloc_scsi_devid_desc().
1233  */
1234 static void
1235 srpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd)
1236 {
1237 	kmem_free(sdd, sizeof (*sdd) + SRPT_EUI_ID_LEN + 1);
1238 }
1239 
1240 /*
1241  * srpt_stp_alloc_session()
1242  */
1243 srpt_session_t *
1244 srpt_stp_alloc_session(srpt_target_port_t *tgt,
1245 	uint8_t *i_id, uint8_t *t_id, uint8_t port,
1246 	char *local_gid, char *remote_gid)
1247 {
1248 	stmf_status_t		status;
1249 	srpt_session_t		*ss;
1250 	stmf_scsi_session_t	*stmf_ss;
1251 	uint64_t		i_guid;
1252 
1253 	ASSERT(tgt != NULL);
1254 	SRPT_DPRINTF_L3("stp_alloc_session, invoked");
1255 
1256 	mutex_enter(&tgt->tp_sess_list_lock);
1257 
1258 	i_guid = BE_IN64(&i_id[8]);
1259 
1260 	stmf_ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION,
1261 	    sizeof (srpt_session_t), 0);
1262 	if (stmf_ss == NULL) {
1263 		SRPT_DPRINTF_L2("stp_alloc_session, stmf_alloc"
1264 		    " returned NULL");
1265 		mutex_exit(&tgt->tp_sess_list_lock);
1266 		return (NULL);
1267 	}
1268 	ss = stmf_ss->ss_port_private;
1269 	ASSERT(ss != NULL);
1270 
1271 
1272 	rw_init(&ss->ss_rwlock, NULL, RW_DRIVER, NULL);
1273 	list_create(&ss->ss_task_list, sizeof (srpt_iu_t),
1274 	    offsetof(srpt_iu_t, iu_ss_task_node));
1275 
1276 	stmf_ss->ss_rport_id = srpt_stp_alloc_scsi_devid_desc(i_guid);
1277 	stmf_ss->ss_lport    = tgt->tp_lport;
1278 
1279 	ss->ss_ss	= stmf_ss;
1280 	ss->ss_hw_port	= port;
1281 	ss->ss_tgt	= tgt;
1282 	bcopy(i_id, ss->ss_i_id, SRP_PORT_ID_LEN);
1283 	bcopy(t_id, ss->ss_t_id, SRP_PORT_ID_LEN);
1284 
1285 	/*
1286 	 * Set the alias to include the initiator extension, this will enable
1287 	 * the administrator to identify multiple unique sessions originating
1288 	 * from the same initiator.
1289 	 */
1290 	(void) strlcpy(ss->ss_i_gid, remote_gid, SRPT_ALIAS_LEN);
1291 	(void) strlcpy(ss->ss_t_gid, local_gid, SRPT_ALIAS_LEN);
1292 	EUI_STR(ss->ss_i_name, BE_IN64(&ss->ss_i_id[8]));
1293 	EUI_STR(ss->ss_t_name, BE_IN64(&ss->ss_t_id[0]));
1294 	ALIAS_STR(ss->ss_i_alias, BE_IN64(&ss->ss_i_id[0]),
1295 	    BE_IN64(&ss->ss_i_id[8]));
1296 	ALIAS_STR(ss->ss_t_alias, BE_IN64(&ss->ss_t_id[0]),
1297 	    BE_IN64(&ss->ss_t_id[8]));
1298 
1299 	stmf_ss->ss_rport_alias = ss->ss_i_alias;
1300 
1301 	status = stmf_register_scsi_session(tgt->tp_lport, stmf_ss);
1302 	if (status != STMF_SUCCESS) {
1303 		SRPT_DPRINTF_L1("stp_alloc_session, STMF register session"
1304 		    " err(0x%llx)", (u_longlong_t)status);
1305 		list_destroy(&ss->ss_task_list);
1306 		rw_destroy(&ss->ss_rwlock);
1307 		stmf_free(stmf_ss);
1308 		mutex_exit(&tgt->tp_sess_list_lock);
1309 		return (NULL);
1310 	}
1311 
1312 	list_insert_tail(&tgt->tp_sess_list, ss);
1313 	mutex_exit(&tgt->tp_sess_list_lock);
1314 	return (ss);
1315 }
1316 
1317 /*
1318  * srpt_stp_free_session()
1319  */
1320 void
1321 srpt_stp_free_session(srpt_session_t *session)
1322 {
1323 	stmf_scsi_session_t	*stmf_ss;
1324 	srpt_target_port_t	*tgt;
1325 
1326 	ASSERT(session != NULL);
1327 
1328 	tgt = session->ss_tgt;
1329 
1330 	ASSERT(tgt != NULL);
1331 
1332 	SRPT_DPRINTF_L3("stp_free_session, invoked");
1333 
1334 	mutex_enter(&tgt->tp_sess_list_lock);
1335 
1336 	stmf_ss = session->ss_ss;
1337 
1338 	list_destroy(&session->ss_task_list);
1339 	rw_destroy(&session->ss_rwlock);
1340 
1341 	stmf_deregister_scsi_session(tgt->tp_lport, stmf_ss);
1342 	srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
1343 
1344 	list_remove(&tgt->tp_sess_list, session);
1345 	cv_signal(&tgt->tp_sess_complete);
1346 	mutex_exit(&tgt->tp_sess_list_lock);
1347 	stmf_free(stmf_ss);
1348 }
1349 
1350 /*
1351  * srpt_stp_login() - SRP SCSI Target port login
1352  */
1353 srpt_channel_t *
1354 srpt_stp_login(srpt_target_port_t *tgt, srp_login_req_t *login,
1355 	srp_login_rsp_t *login_rsp, srp_login_rej_t *login_rej,
1356 	uint8_t login_port, char *local_gid, char *remote_gid)
1357 {
1358 	uint32_t	reason;
1359 	uint32_t	req_it_ui_len;
1360 	uint8_t		rsp_flags;
1361 	srpt_ioc_t	*ioc;
1362 	srpt_channel_t	*ch = NULL;
1363 	srpt_channel_t	*next_ch = NULL;
1364 	srpt_session_t	*session = NULL;
1365 	srpt_session_t	sess;
1366 
1367 	ASSERT(tgt != NULL);
1368 	ASSERT(login != NULL);
1369 	ASSERT(login_rsp != NULL);
1370 	ASSERT(login_rej != NULL);
1371 
1372 	/* Store the string representation of connection info */
1373 	/* for Dtrace probes */
1374 	bzero(&sess, sizeof (srpt_session_t));
1375 	(void) strlcpy(sess.ss_i_gid, remote_gid, SRPT_ALIAS_LEN);
1376 	(void) strlcpy(sess.ss_t_gid, local_gid, SRPT_ALIAS_LEN);
1377 	EUI_STR(sess.ss_i_name,
1378 	    BE_IN64(&login->lreq_initiator_port_id[8]));
1379 	EUI_STR(sess.ss_t_name,
1380 	    BE_IN64(&login->lreq_target_port_id[0]));
1381 	ALIAS_STR(sess.ss_i_alias,
1382 	    BE_IN64(&login->lreq_initiator_port_id[0]),
1383 	    BE_IN64(&login->lreq_initiator_port_id[8]));
1384 	ALIAS_STR(sess.ss_t_alias,
1385 	    BE_IN64(&login->lreq_target_port_id[0]),
1386 	    BE_IN64(&login->lreq_target_port_id[8]));
1387 
1388 	DTRACE_SRP_2(login__command, srpt_session_t, &sess,
1389 	    srp_login_req_t, login);
1390 
1391 	/*
1392 	 * The target lock taken here serializes logins to this target
1393 	 * and prevents an STMF target port from starting a control
1394 	 * operation to transition the target state while a login is
1395 	 * being processed.
1396 	 */
1397 	bzero(login_rsp, sizeof (srp_login_rsp_t));
1398 	bzero(login_rej, sizeof (srp_login_rej_t));
1399 	mutex_enter(&tgt->tp_lock);
1400 	ioc = tgt->tp_ioc;
1401 	if (ioc == NULL) {
1402 		SRPT_DPRINTF_L1("stp_login, NULL I/O Controller");
1403 		reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1404 		goto reject_login;
1405 	}
1406 
1407 	/*
1408 	 * Validate that the SRP Target ID in the login request specifies
1409 	 * this I/O Controller SCSI Target Port.
1410 	 */
1411 	if (memcmp(login->lreq_target_port_id, tgt->tp_srp_port_id,
1412 	    SRP_PORT_ID_LEN) != 0) {
1413 		SRPT_DPRINTF_L2("stp_login, SRP CM SVC target ID mismatch."
1414 		    " Incoming TgtID 0x%016llx:0x%016llx",
1415 		    (u_longlong_t)BE_IN64(&login->lreq_target_port_id[0]),
1416 		    (u_longlong_t)BE_IN64(&login->lreq_target_port_id[8]));
1417 
1418 		reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1419 		goto reject_login;
1420 	}
1421 
1422 	if (tgt->tp_state != SRPT_TGT_STATE_ONLINE) {
1423 		SRPT_DPRINTF_L2("stp_login, SRP Login target not on-line");
1424 		reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1425 		goto reject_login;
1426 	}
1427 
1428 	/*
1429 	 * Initiator requested IU size must be as large as the specification
1430 	 * minimum and no greater than what we chose to support.
1431 	 */
1432 	req_it_ui_len = b2h32(login->lreq_req_it_iu_len);
1433 	SRPT_DPRINTF_L2("stp_login, requested iu size = %d", req_it_ui_len);
1434 	if (req_it_ui_len > srpt_iu_size) {
1435 		SRPT_DPRINTF_L2("stp_login, SRP Login IU size (%d) too large",
1436 		    req_it_ui_len);
1437 		reason = SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE;
1438 		goto reject_login;
1439 	}
1440 	if (req_it_ui_len < SRP_MIN_IU_SIZE) {
1441 		SRPT_DPRINTF_L2("stp_login, SRP Login IU size (%d) too small",
1442 		    req_it_ui_len);
1443 		reason = SRP_LOGIN_REJ_NO_REASON;
1444 		goto reject_login;
1445 	}
1446 
1447 	SRPT_DPRINTF_L2("stp_login, login req InitID 0x%016llx:0x%016llx",
1448 	    (u_longlong_t)BE_IN64(&login->lreq_initiator_port_id[0]),
1449 	    (u_longlong_t)BE_IN64(&login->lreq_initiator_port_id[8]));
1450 	SRPT_DPRINTF_L2("stp_login, login req TgtID 0x%016llx:0x%016llx",
1451 	    (u_longlong_t)BE_IN64(&login->lreq_target_port_id[0]),
1452 	    (u_longlong_t)BE_IN64(&login->lreq_target_port_id[8]));
1453 
1454 	/*
1455 	 * Processing is based on either single channel or multi-channel
1456 	 * operation.  In single channel, all current logins for this
1457 	 * same I_T_Nexus should be logged out.  In multi-channel
1458 	 * mode we would add an additional channel to an existing
1459 	 * I_T_Nexus if one currently exists (i.e. reference the
1460 	 * same SCSI session).
1461 	 */
1462 	rsp_flags = SRP_MULTI_CH_RESULT_NO_EXISTING;
1463 
1464 	switch (login->lreq_req_flags & SRP_LOGIN_MULTI_CH_MASK) {
1465 
1466 	case SRP_LOGIN_MULTI_CH_SINGLE:
1467 		/*
1468 		 * Only a single channel may be associated with a I_T_Nexus.
1469 		 * Disconnect any channel with the same SRP Initiator and
1470 		 * SRP target IDs.
1471 		 */
1472 		mutex_enter(&tgt->tp_ch_list_lock);
1473 		ch = list_head(&tgt->tp_ch_list);
1474 		while (ch != NULL) {
1475 			SRPT_DPRINTF_L3("stp_login, compare session,"
1476 			    " ch_state(%d)", ch->ch_state);
1477 			next_ch = list_next(&tgt->tp_ch_list, ch);
1478 
1479 			if (ch->ch_state != SRPT_CHANNEL_CONNECTING &&
1480 			    ch->ch_state != SRPT_CHANNEL_CONNECTED) {
1481 				SRPT_DPRINTF_L3("stp_login, compare session,"
1482 				    " channel not active");
1483 				ch = next_ch;
1484 				continue;
1485 			}
1486 
1487 			ASSERT(ch->ch_session != NULL);
1488 			SRPT_DPRINTF_L3("stp_login, compare session"
1489 			    " I_ID 0x%016llx:0x%016llx",
1490 			    (u_longlong_t)b2h64(*((uint64_t *)(void *)
1491 			    &ch->ch_session->ss_i_id[0])),
1492 			    (u_longlong_t)b2h64(*((uint64_t *)(void *)
1493 			    &ch->ch_session->ss_i_id[8])));
1494 			SRPT_DPRINTF_L3("stp_login, compare session"
1495 			    " T_ID 0x%016llx:0x%016llx",
1496 			    (u_longlong_t)b2h64(*((uint64_t *)(void *)
1497 			    &ch->ch_session->ss_t_id[0])),
1498 			    (u_longlong_t)b2h64(*((uint64_t *)(void *)
1499 			    &ch->ch_session->ss_t_id[8])));
1500 			if ((bcmp(login->lreq_initiator_port_id,
1501 			    ch->ch_session->ss_i_id,
1502 			    SRP_PORT_ID_LEN) == 0) &&
1503 			    (bcmp(login->lreq_target_port_id,
1504 			    ch->ch_session->ss_t_id,
1505 			    SRP_PORT_ID_LEN) == 0)) {
1506 				/*
1507 				 * if a session is in the process of connecting,
1508 				 * reject subsequent equivalent requests.
1509 				 */
1510 				if (ch->ch_state == SRPT_CHANNEL_CONNECTING) {
1511 					reason = SRP_LOGIN_REJ_INIT_CH_LIMIT;
1512 					mutex_exit(&tgt->tp_ch_list_lock);
1513 					goto reject_login;
1514 				}
1515 
1516 				SRPT_DPRINTF_L2("stp_login, terminate"
1517 				    " existing login");
1518 				rsp_flags =
1519 				    SRP_MULTI_CH_RESULT_TERM_EXISTING;
1520 				srpt_ch_disconnect(ch);
1521 			}
1522 
1523 			ch = next_ch;
1524 		}
1525 		mutex_exit(&tgt->tp_ch_list_lock);
1526 
1527 		/* Create the new session for this SRP login */
1528 		session = srpt_stp_alloc_session(tgt,
1529 		    login->lreq_initiator_port_id,
1530 		    login->lreq_target_port_id, login_port,
1531 		    local_gid, remote_gid);
1532 		if (session == NULL) {
1533 			SRPT_DPRINTF_L2("stp_login, session allocation"
1534 			    " failed");
1535 			reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1536 			goto reject_login;
1537 		}
1538 		break;
1539 
1540 	case SRP_LOGIN_MULTI_CH_MULTIPLE:
1541 		SRPT_DPRINTF_L2("stp_login, multichannel not supported yet");
1542 		reason = SRP_LOGIN_REJ_MULTI_CH_NOT_SUPPORTED;
1543 		goto reject_login;
1544 		/* break via goto */
1545 
1546 	default:
1547 		SRPT_DPRINTF_L2("stp_login, invalid multichannel field (%d)",
1548 		    login->lreq_req_flags & SRP_LOGIN_MULTI_CH_MASK);
1549 		reason = SRP_LOGIN_REJ_NO_REASON;
1550 		goto reject_login;
1551 		/* break via goto */
1552 	}
1553 
1554 	/*
1555 	 * Create new RDMA channel for this SRP login request.
1556 	 * The channel is returned with a single reference which
1557 	 * represents the reference held by the CM.
1558 	 */
1559 	ch = srpt_ch_alloc(tgt, login_port);
1560 	if (ch == NULL) {
1561 		SRPT_DPRINTF_L2("stp_login, unable to alloc RDMA channel");
1562 		reason = SRP_LOGIN_REJ_INSUFFICIENT_CH_RESOURCES;
1563 		srpt_stp_free_session(session);
1564 		goto reject_login;
1565 	}
1566 	ch->ch_session = session;
1567 	ch->ch_ti_iu_len = b2h32(login->lreq_req_it_iu_len);
1568 
1569 	/*
1570 	 * Add another reference to the channel which represents
1571 	 * a reference placed by the target port and add it to
1572 	 * the store of channels logged in for this target port.
1573 	 */
1574 	srpt_ch_add_ref(ch);
1575 	mutex_enter(&tgt->tp_ch_list_lock);
1576 	list_insert_tail(&tgt->tp_ch_list, ch);
1577 	mutex_exit(&tgt->tp_ch_list_lock);
1578 
1579 	srpt_format_login_rsp(login, login_rsp, rsp_flags);
1580 	mutex_exit(&tgt->tp_lock);
1581 	SRPT_DPRINTF_L2("stp_login, login successful");
1582 
1583 	DTRACE_SRP_3(login__response, srpt_session_t, &sess,
1584 	    srp_login_rsp_t, login_rsp, srp_login_rej_t, login_rej)
1585 
1586 	return (ch);
1587 
1588 reject_login:
1589 	srpt_format_login_rej(login, login_rej, reason);
1590 	mutex_exit(&tgt->tp_lock);
1591 
1592 	DTRACE_SRP_3(login__response, srpt_session_t, &sess,
1593 	    srp_login_rsp_t, login_rsp, srp_login_rej_t, login_rej);
1594 
1595 	return (NULL);
1596 }
1597 
1598 /*
1599  * srpt_stp_logout() - SRP logout
1600  *
1601  * Logout is not normally initiated in-band, but is so, just
1602  * initiate a disconnect.
1603  */
1604 void
1605 srpt_stp_logout(srpt_channel_t *ch)
1606 {
1607 	DTRACE_SRP_1(logout__command, srpt_channel_t, ch);
1608 	SRPT_DPRINTF_L2("stp_logout, invoked for ch (%p)", (void *)ch);
1609 	srpt_ch_disconnect(ch);
1610 }
1611 
1612 /*
1613  * srpt_format_login_rej() - Format login reject IU
1614  */
1615 static void
1616 srpt_format_login_rej(srp_login_req_t *req, srp_login_rej_t *rej,
1617 	uint32_t reason)
1618 {
1619 	rej->lrej_type   = SRP_IU_LOGIN_REJ;
1620 	rej->lrej_reason = h2b32(reason);
1621 	rej->lrej_tag    = req->lreq_tag;
1622 	rej->lrej_sup_buf_format =
1623 	    h2b16(SRP_DIRECT_BUFR_DESC | SRP_INDIRECT_BUFR_DESC);
1624 }
1625 
1626 /*
1627  * srpt_format_login_rsp() - Format login response IU
1628  */
1629 static void
1630 srpt_format_login_rsp(srp_login_req_t *req, srp_login_rsp_t *rsp,
1631 	uint8_t flags)
1632 {
1633 	rsp->lrsp_type   = SRP_IU_LOGIN_RSP;
1634 	rsp->lrsp_req_limit_delta = h2b32((uint32_t)srpt_send_msg_depth);
1635 	rsp->lrsp_tag    = req->lreq_tag;
1636 
1637 	rsp->lrsp_max_it_iu_len = req->lreq_req_it_iu_len;
1638 	/* by def. > min T_IU_LEN */
1639 	rsp->lrsp_max_ti_iu_len = req->lreq_req_it_iu_len;
1640 
1641 	rsp->lrsp_sup_buf_format =
1642 	    h2b16(SRP_DIRECT_BUFR_DESC | SRP_INDIRECT_BUFR_DESC);
1643 	rsp->lrsp_rsp_flags = flags;
1644 }
1645 
1646 /*
1647  * srpt_stp_add_task()
1648  */
1649 void
1650 srpt_stp_add_task(srpt_session_t *session, srpt_iu_t *iu)
1651 {
1652 	rw_enter(&session->ss_rwlock, RW_WRITER);
1653 	list_insert_tail(&session->ss_task_list, iu);
1654 	rw_exit(&session->ss_rwlock);
1655 }
1656 
1657 /*
1658  * srpt_stp_remove_task()
1659  */
1660 void
1661 srpt_stp_remove_task(srpt_session_t *session, srpt_iu_t *iu)
1662 {
1663 	rw_enter(&session->ss_rwlock, RW_WRITER);
1664 
1665 	ASSERT(!list_is_empty(&session->ss_task_list));
1666 
1667 	list_remove(&session->ss_task_list, iu);
1668 	rw_exit(&session->ss_rwlock);
1669 }
1670