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