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