xref: /freebsd/sys/dev/ocs_fc/ocs_cam.c (revision cddbc3b40812213ff00041f79174cac0be360a2a)
1 /*-
2  * Copyright (c) 2017 Broadcom. All rights reserved.
3  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33 
34 /**
35  * @defgroup scsi_api_target SCSI Target API
36  * @defgroup scsi_api_initiator SCSI Initiator API
37  * @defgroup cam_api Common Access Method (CAM) API
38  * @defgroup cam_io CAM IO
39  */
40 
41 /**
42  * @file
43  * Provides CAM functionality.
44  */
45 
46 #include "ocs.h"
47 #include "ocs_scsi.h"
48 #include "ocs_device.h"
49 
50 /* Default IO timeout value for initiators is 30 seconds */
51 #define OCS_CAM_IO_TIMEOUT	30
52 
53 typedef struct {
54 	ocs_scsi_sgl_t *sgl;
55 	uint32_t sgl_max;
56 	uint32_t sgl_count;
57 	int32_t rc;
58 } ocs_dmamap_load_arg_t;
59 
60 static void ocs_action(struct cam_sim *, union ccb *);
61 static void ocs_poll(struct cam_sim *);
62 
63 static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *,
64 					struct ccb_hdr *, uint32_t *);
65 static int32_t ocs_tgt_resource_abort(struct ocs_softc *, ocs_tgt_resource_t *);
66 static uint32_t ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb);
67 static void ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb);
68 static void ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb);
69 static int32_t ocs_target_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
70 static int32_t ocs_io_abort_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
71 static int32_t ocs_task_set_full_or_busy(ocs_io_t *io);
72 static int32_t ocs_initiator_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e,
73 		ocs_scsi_cmd_resp_t *, uint32_t, void *);
74 static uint32_t
75 ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role);
76 
77 static void ocs_ldt(void *arg);
78 static void ocs_ldt_task(void *arg, int pending);
79 static void ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt);
80 uint32_t ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp);
81 uint32_t ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id);
82 
83 int32_t ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node);
84 
85 static inline ocs_io_t *ocs_scsi_find_io(struct ocs_softc *ocs, uint32_t tag)
86 {
87 
88 	return ocs_io_get_instance(ocs, tag);
89 }
90 
91 static inline void ocs_target_io_free(ocs_io_t *io)
92 {
93 	io->tgt_io.state = OCS_CAM_IO_FREE;
94 	io->tgt_io.flags = 0;
95 	io->tgt_io.app = NULL;
96 	ocs_scsi_io_complete(io);
97 	if(io->ocs->io_in_use != 0)
98 		atomic_subtract_acq_32(&io->ocs->io_in_use, 1);
99 }
100 
101 static int32_t
102 ocs_attach_port(ocs_t *ocs, int chan)
103 {
104 
105 	struct cam_sim	*sim = NULL;
106 	struct cam_path	*path = NULL;
107 	uint32_t	max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS);
108 	ocs_fcport *fcp = FCPORT(ocs, chan);
109 
110 	if (NULL == (sim = cam_sim_alloc(ocs_action, ocs_poll,
111 				device_get_name(ocs->dev), ocs,
112 				device_get_unit(ocs->dev), &ocs->sim_lock,
113 				max_io, max_io, ocs->devq))) {
114 		device_printf(ocs->dev, "Can't allocate SIM\n");
115 		return 1;
116 	}
117 
118 	mtx_lock(&ocs->sim_lock);
119 	if (CAM_SUCCESS != xpt_bus_register(sim, ocs->dev, chan)) {
120 		device_printf(ocs->dev, "Can't register bus %d\n", 0);
121 		mtx_unlock(&ocs->sim_lock);
122 		cam_sim_free(sim, FALSE);
123 		return 1;
124 	}
125 	mtx_unlock(&ocs->sim_lock);
126 
127 	if (CAM_REQ_CMP != xpt_create_path(&path, NULL, cam_sim_path(sim),
128 				CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)) {
129 		device_printf(ocs->dev, "Can't create path\n");
130 		xpt_bus_deregister(cam_sim_path(sim));
131 		mtx_unlock(&ocs->sim_lock);
132 		cam_sim_free(sim, FALSE);
133 		return 1;
134 	}
135 
136 	fcp->ocs = ocs;
137 	fcp->sim  = sim;
138 	fcp->path = path;
139 
140 	callout_init_mtx(&fcp->ldt, &ocs->sim_lock, 0);
141 	TASK_INIT(&fcp->ltask, 1, ocs_ldt_task, fcp);
142 
143 	return 0;
144 }
145 
146 static int32_t
147 ocs_detach_port(ocs_t *ocs, int32_t chan)
148 {
149 	ocs_fcport *fcp = NULL;
150 	struct cam_sim	*sim = NULL;
151 	struct cam_path	*path = NULL;
152 	fcp = FCPORT(ocs, chan);
153 
154 	sim = fcp->sim;
155 	path = fcp->path;
156 
157 	callout_drain(&fcp->ldt);
158 	ocs_ldt_task(fcp, 0);
159 
160 	if (fcp->sim) {
161 		mtx_lock(&ocs->sim_lock);
162 			ocs_tgt_resource_abort(ocs, &fcp->targ_rsrc_wildcard);
163 			if (path) {
164 				xpt_async(AC_LOST_DEVICE, path, NULL);
165 				xpt_free_path(path);
166 				fcp->path = NULL;
167 			}
168 			xpt_bus_deregister(cam_sim_path(sim));
169 
170 			cam_sim_free(sim, FALSE);
171 			fcp->sim = NULL;
172 		mtx_unlock(&ocs->sim_lock);
173 	}
174 
175 	return 0;
176 }
177 
178 int32_t
179 ocs_cam_attach(ocs_t *ocs)
180 {
181 	struct cam_devq	*devq = NULL;
182 	int	i = 0;
183 	uint32_t	max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS);
184 
185 	if (NULL == (devq = cam_simq_alloc(max_io))) {
186 		device_printf(ocs->dev, "Can't allocate SIMQ\n");
187 		return -1;
188 	}
189 
190 	ocs->devq = devq;
191 
192 	if (mtx_initialized(&ocs->sim_lock) == 0) {
193 		mtx_init(&ocs->sim_lock, "ocs_sim_lock", NULL, MTX_DEF);
194 	}
195 
196 	for (i = 0; i < (ocs->num_vports + 1); i++) {
197 		if (ocs_attach_port(ocs, i)) {
198 			ocs_log_err(ocs, "Attach port failed for chan: %d\n", i);
199 			goto detach_port;
200 		}
201 	}
202 
203 	ocs->io_high_watermark = max_io;
204 	ocs->io_in_use = 0;
205 	return 0;
206 
207 detach_port:
208 	while (--i >= 0) {
209 		ocs_detach_port(ocs, i);
210 	}
211 
212 	cam_simq_free(ocs->devq);
213 
214 	if (mtx_initialized(&ocs->sim_lock))
215 		mtx_destroy(&ocs->sim_lock);
216 
217 	return 1;
218 }
219 
220 int32_t
221 ocs_cam_detach(ocs_t *ocs)
222 {
223 	int i = 0;
224 
225 	for (i = (ocs->num_vports); i >= 0; i--) {
226 		ocs_detach_port(ocs, i);
227 	}
228 
229 	cam_simq_free(ocs->devq);
230 
231 	if (mtx_initialized(&ocs->sim_lock))
232 		mtx_destroy(&ocs->sim_lock);
233 
234 	return 0;
235 }
236 
237 /***************************************************************************
238  * Functions required by SCSI base driver API
239  */
240 
241 /**
242  * @ingroup scsi_api_target
243  * @brief Attach driver to the BSD SCSI layer (a.k.a CAM)
244  *
245  * Allocates + initializes CAM related resources and attaches to the CAM
246  *
247  * @param ocs the driver instance's software context
248  *
249  * @return 0 on success, non-zero otherwise
250  */
251 int32_t
252 ocs_scsi_tgt_new_device(ocs_t *ocs)
253 {
254 	ocs->enable_task_set_full = ocs_scsi_get_property(ocs,
255 					OCS_SCSI_ENABLE_TASK_SET_FULL);
256 	ocs_log_debug(ocs, "task set full processing is %s\n",
257 		ocs->enable_task_set_full ? "enabled" : "disabled");
258 
259 	return 0;
260 }
261 
262 /**
263  * @ingroup scsi_api_target
264  * @brief Tears down target members of ocs structure.
265  *
266  * Called by OS code when device is removed.
267  *
268  * @param ocs pointer to ocs
269  *
270  * @return returns 0 for success, a negative error code value for failure.
271  */
272 int32_t
273 ocs_scsi_tgt_del_device(ocs_t *ocs)
274 {
275 
276 	return 0;
277 }
278 
279 /**
280  * @ingroup scsi_api_target
281  * @brief accept new domain notification
282  *
283  * Called by base drive when new domain is discovered.  A target-server
284  * will use this call to prepare for new remote node notifications
285  * arising from ocs_scsi_new_initiator().
286  *
287  * The domain context has an element <b>ocs_scsi_tgt_domain_t tgt_domain</b>
288  * which is declared by the target-server code and is used for target-server
289  * private data.
290  *
291  * This function will only be called if the base-driver has been enabled for
292  * target capability.
293  *
294  * Note that this call is made to target-server backends,
295  * the ocs_scsi_ini_new_domain() function is called to initiator-client backends.
296  *
297  * @param domain pointer to domain
298  *
299  * @return returns 0 for success, a negative error code value for failure.
300  */
301 int32_t
302 ocs_scsi_tgt_new_domain(ocs_domain_t *domain)
303 {
304 	return 0;
305 }
306 
307 /**
308  * @ingroup scsi_api_target
309  * @brief accept domain lost notification
310  *
311  * Called by base-driver when a domain goes away.  A target-server will
312  * use this call to clean up all domain scoped resources.
313  *
314  * Note that this call is made to target-server backends,
315  * the ocs_scsi_ini_del_domain() function is called to initiator-client backends.
316  *
317  * @param domain pointer to domain
318  *
319  * @return returns 0 for success, a negative error code value for failure.
320  */
321 void
322 ocs_scsi_tgt_del_domain(ocs_domain_t *domain)
323 {
324 }
325 
326 
327 /**
328  * @ingroup scsi_api_target
329  * @brief accept new sli port (sport) notification
330  *
331  * Called by base drive when new sport is discovered.  A target-server
332  * will use this call to prepare for new remote node notifications
333  * arising from ocs_scsi_new_initiator().
334  *
335  * The domain context has an element <b>ocs_scsi_tgt_sport_t tgt_sport</b>
336  * which is declared by the target-server code and is used for
337  * target-server private data.
338  *
339  * This function will only be called if the base-driver has been enabled for
340  * target capability.
341  *
342  * Note that this call is made to target-server backends,
343  * the ocs_scsi_tgt_new_domain() is called to initiator-client backends.
344  *
345  * @param sport pointer to SLI port
346  *
347  * @return returns 0 for success, a negative error code value for failure.
348  */
349 int32_t
350 ocs_scsi_tgt_new_sport(ocs_sport_t *sport)
351 {
352 	ocs_t *ocs = sport->ocs;
353 
354 	if(!sport->is_vport) {
355 		sport->tgt_data = FCPORT(ocs, 0);
356 	}
357 
358 	return 0;
359 }
360 
361 /**
362  * @ingroup scsi_api_target
363  * @brief accept SLI port gone notification
364  *
365  * Called by base-driver when a sport goes away.  A target-server will
366  * use this call to clean up all sport scoped resources.
367  *
368  * Note that this call is made to target-server backends,
369  * the ocs_scsi_ini_del_sport() is called to initiator-client backends.
370  *
371  * @param sport pointer to SLI port
372  *
373  * @return returns 0 for success, a negative error code value for failure.
374  */
375 void
376 ocs_scsi_tgt_del_sport(ocs_sport_t *sport)
377 {
378 	return;
379 }
380 
381 /**
382  * @ingroup scsi_api_target
383  * @brief receive notification of a new SCSI initiator node
384  *
385  * Sent by base driver to notify a target-server of the presense of a new
386  * remote initiator.   The target-server may use this call to prepare for
387  * inbound IO from this node.
388  *
389  * The ocs_node_t structure has and elment of type ocs_scsi_tgt_node_t named
390  * tgt_node that is declared and used by a target-server for private
391  * information.
392  *
393  * This function is only called if the target capability is enabled in driver.
394  *
395  * @param node pointer to new remote initiator node
396  *
397  * @return returns 0 for success, a negative error code value for failure.
398  *
399  * @note
400  */
401 int32_t
402 ocs_scsi_new_initiator(ocs_node_t *node)
403 {
404 	ocs_t	*ocs = node->ocs;
405 	struct ac_contract ac;
406 	struct ac_device_changed *adc;
407 
408 	ocs_fcport	*fcp = NULL;
409 
410 	fcp = node->sport->tgt_data;
411 	if (fcp == NULL) {
412 		ocs_log_err(ocs, "FCP is NULL \n");
413 		return 1;
414 	}
415 
416 	/*
417 	 * Update the IO watermark by decrementing it by the
418 	 * number of IOs reserved for each initiator.
419 	 */
420 	atomic_subtract_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
421 
422 	ac.contract_number = AC_CONTRACT_DEV_CHG;
423 	adc = (struct ac_device_changed *) ac.contract_data;
424 	adc->wwpn = ocs_node_get_wwpn(node);
425 	adc->port = node->rnode.fc_id;
426 	adc->target = node->instance_index;
427 	adc->arrived = 1;
428 	xpt_async(AC_CONTRACT, fcp->path, &ac);
429 
430 	return 0;
431 }
432 
433 /**
434  * @ingroup scsi_api_target
435  * @brief validate new initiator
436  *
437  * Sent by base driver to validate a remote initiatiator.   The target-server
438  * returns TRUE if this initiator should be accepted.
439  *
440  * This function is only called if the target capability is enabled in driver.
441  *
442  * @param node pointer to remote initiator node to validate
443  *
444  * @return TRUE if initiator should be accepted, FALSE if it should be rejected
445  *
446  * @note
447  */
448 
449 int32_t
450 ocs_scsi_validate_initiator(ocs_node_t *node)
451 {
452 	return 1;
453 }
454 
455 /**
456  * @ingroup scsi_api_target
457  * @brief Delete a SCSI initiator node
458  *
459  * Sent by base driver to notify a target-server that a remote initiator
460  * is now gone. The base driver will have terminated all outstanding IOs
461  * and the target-server will receive appropriate completions.
462  *
463  * This function is only called if the base driver is enabled for
464  * target capability.
465  *
466  * @param node pointer node being deleted
467  * @param reason Reason why initiator is gone.
468  *
469  * @return OCS_SCSI_CALL_COMPLETE to indicate that all work was completed
470  *
471  * @note
472  */
473 int32_t
474 ocs_scsi_del_initiator(ocs_node_t *node, ocs_scsi_del_initiator_reason_e reason)
475 {
476 	ocs_t	*ocs = node->ocs;
477 
478 	struct ac_contract ac;
479 	struct ac_device_changed *adc;
480 	ocs_fcport	*fcp = NULL;
481 
482 	fcp = node->sport->tgt_data;
483 	if (fcp == NULL) {
484 		ocs_log_err(ocs, "FCP is NULL \n");
485 		return 1;
486 	}
487 
488 	ac.contract_number = AC_CONTRACT_DEV_CHG;
489 	adc = (struct ac_device_changed *) ac.contract_data;
490 	adc->wwpn = ocs_node_get_wwpn(node);
491 	adc->port = node->rnode.fc_id;
492 	adc->target = node->instance_index;
493 	adc->arrived = 0;
494 	xpt_async(AC_CONTRACT, fcp->path, &ac);
495 
496 
497 	if (reason == OCS_SCSI_INITIATOR_MISSING) {
498 		return OCS_SCSI_CALL_COMPLETE;
499 	}
500 
501 	/*
502 	 * Update the IO watermark by incrementing it by the
503 	 * number of IOs reserved for each initiator.
504 	 */
505 	atomic_add_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
506 
507 	return OCS_SCSI_CALL_COMPLETE;
508 }
509 
510 /**
511  * @ingroup scsi_api_target
512  * @brief receive FCP SCSI Command
513  *
514  * Called by the base driver when a new SCSI command has been received.   The
515  * target-server will process the command, and issue data and/or response phase
516  * requests to the base driver.
517  *
518  * The IO context (ocs_io_t) structure has and element of type
519  * ocs_scsi_tgt_io_t named tgt_io that is declared and used by
520  * a target-server for private information.
521  *
522  * @param io pointer to IO context
523  * @param lun LUN for this IO
524  * @param cdb pointer to SCSI CDB
525  * @param cdb_len length of CDB in bytes
526  * @param flags command flags
527  *
528  * @return returns 0 for success, a negative error code value for failure.
529  */
530 int32_t ocs_scsi_recv_cmd(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
531 				uint32_t cdb_len, uint32_t flags)
532 {
533 	ocs_t *ocs = io->ocs;
534 	struct ccb_accept_tio *atio = NULL;
535 	ocs_node_t	*node = io->node;
536 	ocs_tgt_resource_t *trsrc = NULL;
537 	int32_t		rc = -1;
538 	ocs_fcport	*fcp = NULL;
539 
540 	fcp = node->sport->tgt_data;
541 	if (fcp == NULL) {
542 		ocs_log_err(ocs, "FCP is NULL \n");
543 		return 1;
544 	}
545 
546 	atomic_add_acq_32(&ocs->io_in_use, 1);
547 
548 	/* set target io timeout */
549 	io->timeout = ocs->target_io_timer_sec;
550 
551 	if (ocs->enable_task_set_full &&
552 		(ocs->io_in_use >= ocs->io_high_watermark)) {
553 		return ocs_task_set_full_or_busy(io);
554 	} else {
555 		atomic_store_rel_32(&io->node->tgt_node.busy_sent, FALSE);
556 	}
557 
558 	if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
559 		trsrc = &fcp->targ_rsrc[lun];
560 	} else if (fcp->targ_rsrc_wildcard.enabled) {
561 		trsrc = &fcp->targ_rsrc_wildcard;
562 	}
563 
564 	if (trsrc) {
565 		atio = (struct ccb_accept_tio *)STAILQ_FIRST(&trsrc->atio);
566 	}
567 
568 	if (atio) {
569 
570 		STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe);
571 
572 		atio->ccb_h.status = CAM_CDB_RECVD;
573 		atio->ccb_h.target_lun = lun;
574 		atio->sense_len = 0;
575 
576 		atio->init_id = node->instance_index;
577 		atio->tag_id = io->tag;
578 		atio->ccb_h.ccb_io_ptr = io;
579 
580 		if (flags & OCS_SCSI_CMD_SIMPLE)
581 			atio->tag_action = MSG_SIMPLE_Q_TAG;
582 		else if (flags &  FCP_TASK_ATTR_HEAD_OF_QUEUE)
583 			atio->tag_action = MSG_HEAD_OF_Q_TAG;
584 		else if (flags & FCP_TASK_ATTR_ORDERED)
585 			atio->tag_action = MSG_ORDERED_Q_TAG;
586 		else
587 			atio->tag_action = 0;
588 
589 		atio->cdb_len = cdb_len;
590 		ocs_memcpy(atio->cdb_io.cdb_bytes, cdb, cdb_len);
591 
592 		io->tgt_io.flags = 0;
593 		io->tgt_io.state = OCS_CAM_IO_COMMAND;
594 		io->tgt_io.lun = lun;
595 
596 		xpt_done((union ccb *)atio);
597 
598 		rc = 0;
599 	} else {
600 		device_printf(
601 			ocs->dev, "%s: no ATIO for LUN %lx (en=%s) OX_ID %#x\n",
602 			__func__, (unsigned long)lun,
603 			trsrc ? (trsrc->enabled ? "T" : "F") : "X",
604 			be16toh(io->init_task_tag));
605 
606 		io->tgt_io.state = OCS_CAM_IO_MAX;
607 		ocs_target_io_free(io);
608 	}
609 
610 	return rc;
611 }
612 
613 /**
614  * @ingroup scsi_api_target
615  * @brief receive FCP SCSI Command with first burst data.
616  *
617  * Receive a new FCP SCSI command from the base driver with first burst data.
618  *
619  * @param io pointer to IO context
620  * @param lun LUN for this IO
621  * @param cdb pointer to SCSI CDB
622  * @param cdb_len length of CDB in bytes
623  * @param flags command flags
624  * @param first_burst_buffers first burst buffers
625  * @param first_burst_buffer_count The number of bytes received in the first burst
626  *
627  * @return returns 0 for success, a negative error code value for failure.
628  */
629 int32_t ocs_scsi_recv_cmd_first_burst(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
630 		 			uint32_t cdb_len, uint32_t flags,
631 					ocs_dma_t first_burst_buffers[],
632 					uint32_t first_burst_buffer_count)
633 {
634 	return -1;
635 }
636 
637 /**
638  * @ingroup scsi_api_target
639  * @brief receive a TMF command IO
640  *
641  * Called by the base driver when a SCSI TMF command has been received.   The
642  * target-server will process the command, aborting commands as needed, and post
643  * a response using ocs_scsi_send_resp()
644  *
645  * The IO context (ocs_io_t) structure has and element of type ocs_scsi_tgt_io_t named
646  * tgt_io that is declared and used by a target-server for private information.
647  *
648  * If the target-server walks the nodes active_ios linked list, and starts IO
649  * abort processing, the code <b>must</b> be sure not to abort the IO passed into the
650  * ocs_scsi_recv_tmf() command.
651  *
652  * @param tmfio pointer to IO context
653  * @param lun logical unit value
654  * @param cmd command request
655  * @param abortio pointer to IO object to abort for TASK_ABORT (NULL for all other TMF)
656  * @param flags flags
657  *
658  * @return returns 0 for success, a negative error code value for failure.
659  */
660 int32_t ocs_scsi_recv_tmf(ocs_io_t *tmfio, uint64_t lun, ocs_scsi_tmf_cmd_e cmd,
661 				ocs_io_t *abortio, uint32_t flags)
662 {
663 	ocs_t *ocs = tmfio->ocs;
664 	ocs_node_t *node = tmfio->node;
665 	ocs_tgt_resource_t *trsrc = NULL;
666 	struct ccb_immediate_notify *inot = NULL;
667 	int32_t		rc = -1;
668 	ocs_fcport	*fcp = NULL;
669 
670 	fcp = node->sport->tgt_data;
671 	if (fcp == NULL) {
672 		ocs_log_err(ocs, "FCP is NULL \n");
673 		return 1;
674 	}
675 
676 	if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
677 		trsrc = &fcp->targ_rsrc[lun];
678 	} else if (fcp->targ_rsrc_wildcard.enabled) {
679 		trsrc = &fcp->targ_rsrc_wildcard;
680 	}
681 
682 	device_printf(tmfio->ocs->dev, "%s: io=%p cmd=%#x LU=%lx en=%s\n",
683 			__func__, tmfio, cmd, (unsigned long)lun,
684 			trsrc ? (trsrc->enabled ? "T" : "F") : "X");
685 	if (trsrc) {
686 		inot = (struct ccb_immediate_notify *)STAILQ_FIRST(&trsrc->inot);
687 	}
688 
689 	if (!inot) {
690 		device_printf(
691 			ocs->dev, "%s: no INOT for LUN %llx (en=%s) OX_ID %#x\n",
692 			__func__, (unsigned long long)lun, trsrc ? (trsrc->enabled ? "T" : "F") : "X",
693 			be16toh(tmfio->init_task_tag));
694 
695 		if (abortio) {
696 			ocs_scsi_io_complete(abortio);
697 		}
698 		ocs_scsi_io_complete(tmfio);
699 		goto ocs_scsi_recv_tmf_out;
700 	}
701 
702 
703 	tmfio->tgt_io.app = abortio;
704 
705 	STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe);
706 
707 	inot->tag_id = tmfio->tag;
708 	inot->seq_id = tmfio->tag;
709 
710 	if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
711 		inot->initiator_id = node->instance_index;
712 	} else {
713 		inot->initiator_id = CAM_TARGET_WILDCARD;
714 	}
715 
716 	inot->ccb_h.status = CAM_MESSAGE_RECV;
717 	inot->ccb_h.target_lun = lun;
718 
719 	switch (cmd) {
720 	case OCS_SCSI_TMF_ABORT_TASK:
721 		inot->arg = MSG_ABORT_TASK;
722 		inot->seq_id = abortio->tag;
723 		device_printf(ocs->dev, "%s: ABTS IO.%#x st=%#x\n",
724 			__func__, abortio->tag,	abortio->tgt_io.state);
725 		abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_RECV;
726 		abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_NOTIFY;
727 		break;
728 	case OCS_SCSI_TMF_QUERY_TASK_SET:
729 		device_printf(ocs->dev,
730 			"%s: OCS_SCSI_TMF_QUERY_TASK_SET not supported\n",
731 				__func__);
732 		STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe);
733 		ocs_scsi_io_complete(tmfio);
734 		goto ocs_scsi_recv_tmf_out;
735 		break;
736 	case OCS_SCSI_TMF_ABORT_TASK_SET:
737 		inot->arg = MSG_ABORT_TASK_SET;
738 		break;
739 	case OCS_SCSI_TMF_CLEAR_TASK_SET:
740 		inot->arg = MSG_CLEAR_TASK_SET;
741 		break;
742 	case OCS_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT:
743 		inot->arg = MSG_QUERY_ASYNC_EVENT;
744 		break;
745 	case OCS_SCSI_TMF_LOGICAL_UNIT_RESET:
746 		inot->arg = MSG_LOGICAL_UNIT_RESET;
747 		break;
748 	case OCS_SCSI_TMF_CLEAR_ACA:
749 		inot->arg = MSG_CLEAR_ACA;
750 		break;
751 	case OCS_SCSI_TMF_TARGET_RESET:
752 		inot->arg = MSG_TARGET_RESET;
753 		break;
754 	default:
755 		device_printf(ocs->dev, "%s: unsupported TMF %#x\n",
756 							 __func__, cmd);
757 		STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe);
758 		goto ocs_scsi_recv_tmf_out;
759 	}
760 
761 	rc = 0;
762 
763 	xpt_print(inot->ccb_h.path, "%s: func=%#x stat=%#x id=%#x lun=%#x"
764 			" flags=%#x tag=%#x seq=%#x ini=%#x arg=%#x\n",
765 			__func__, inot->ccb_h.func_code, inot->ccb_h.status,
766 			inot->ccb_h.target_id,
767 			(unsigned int)inot->ccb_h.target_lun, inot->ccb_h.flags,
768 			inot->tag_id, inot->seq_id, inot->initiator_id,
769 			inot->arg);
770 	xpt_done((union ccb *)inot);
771 
772 	if (abortio) {
773 		abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_DEV;
774 		rc = ocs_scsi_tgt_abort_io(abortio, ocs_io_abort_cb, tmfio);
775 	}
776 
777 ocs_scsi_recv_tmf_out:
778 	return rc;
779 }
780 
781 /**
782  * @ingroup scsi_api_initiator
783  * @brief Initializes any initiator fields on the ocs structure.
784  *
785  * Called by OS initialization code when a new device is discovered.
786  *
787  * @param ocs pointer to ocs
788  *
789  * @return returns 0 for success, a negative error code value for failure.
790  */
791 int32_t
792 ocs_scsi_ini_new_device(ocs_t *ocs)
793 {
794 
795 	return 0;
796 }
797 
798 /**
799  * @ingroup scsi_api_initiator
800  * @brief Tears down initiator members of ocs structure.
801  *
802  * Called by OS code when device is removed.
803  *
804  * @param ocs pointer to ocs
805  *
806  * @return returns 0 for success, a negative error code value for failure.
807  */
808 
809 int32_t
810 ocs_scsi_ini_del_device(ocs_t *ocs)
811 {
812 
813 	return 0;
814 }
815 
816 
817 /**
818  * @ingroup scsi_api_initiator
819  * @brief accept new domain notification
820  *
821  * Called by base drive when new domain is discovered.  An initiator-client
822  * will accept this call to prepare for new remote node notifications
823  * arising from ocs_scsi_new_target().
824  *
825  * The domain context has the element <b>ocs_scsi_ini_domain_t ini_domain</b>
826  * which is declared by the initiator-client code and is used for
827  * initiator-client private data.
828  *
829  * This function will only be called if the base-driver has been enabled for
830  * initiator capability.
831  *
832  * Note that this call is made to initiator-client backends,
833  * the ocs_scsi_tgt_new_domain() function is called to target-server backends.
834  *
835  * @param domain pointer to domain
836  *
837  * @return returns 0 for success, a negative error code value for failure.
838  */
839 int32_t
840 ocs_scsi_ini_new_domain(ocs_domain_t *domain)
841 {
842 	return 0;
843 }
844 
845 /**
846  * @ingroup scsi_api_initiator
847  * @brief accept domain lost notification
848  *
849  * Called by base-driver when a domain goes away.  An initiator-client will
850  * use this call to clean up all domain scoped resources.
851  *
852  * This function will only be called if the base-driver has been enabled for
853  * initiator capability.
854  *
855  * Note that this call is made to initiator-client backends,
856  * the ocs_scsi_tgt_del_domain() function is called to target-server backends.
857  *
858  * @param domain pointer to domain
859  *
860  * @return returns 0 for success, a negative error code value for failure.
861  */
862 void
863 ocs_scsi_ini_del_domain(ocs_domain_t *domain)
864 {
865 }
866 
867 /**
868  * @ingroup scsi_api_initiator
869  * @brief accept new sli port notification
870  *
871  * Called by base drive when new sli port (sport) is discovered.
872  * A target-server will use this call to prepare for new remote node
873  * notifications arising from ocs_scsi_new_initiator().
874  *
875  * This function will only be called if the base-driver has been enabled for
876  * target capability.
877  *
878  * Note that this call is made to target-server backends,
879  * the ocs_scsi_ini_new_sport() function is called to initiator-client backends.
880  *
881  * @param sport pointer to sport
882  *
883  * @return returns 0 for success, a negative error code value for failure.
884  */
885 int32_t
886 ocs_scsi_ini_new_sport(ocs_sport_t *sport)
887 {
888 	ocs_t *ocs = sport->ocs;
889 	ocs_fcport *fcp = FCPORT(ocs, 0);
890 
891 	if (!sport->is_vport) {
892 		sport->tgt_data = fcp;
893 		fcp->fc_id = sport->fc_id;
894 	}
895 
896 	return 0;
897 }
898 
899 /**
900  * @ingroup scsi_api_initiator
901  * @brief accept sli port gone notification
902  *
903  * Called by base-driver when a sport goes away.  A target-server will
904  * use this call to clean up all sport scoped resources.
905  *
906  * Note that this call is made to target-server backends,
907  * the ocs_scsi_ini_del_sport() function is called to initiator-client backends.
908  *
909  * @param sport pointer to SLI port
910  *
911  * @return returns 0 for success, a negative error code value for failure.
912  */
913 void
914 ocs_scsi_ini_del_sport(ocs_sport_t *sport)
915 {
916 	ocs_t *ocs = sport->ocs;
917 	ocs_fcport *fcp = FCPORT(ocs, 0);
918 
919 	if (!sport->is_vport) {
920 		fcp->fc_id = 0;
921 	}
922 }
923 
924 void
925 ocs_scsi_sport_deleted(ocs_sport_t *sport)
926 {
927 	ocs_t *ocs = sport->ocs;
928 	ocs_fcport *fcp = NULL;
929 
930 	ocs_xport_stats_t value;
931 
932 	if (!sport->is_vport) {
933 		return;
934 	}
935 
936 	fcp = sport->tgt_data;
937 
938 	ocs_xport_status(ocs->xport, OCS_XPORT_PORT_STATUS, &value);
939 
940 	if (value.value == 0) {
941 		ocs_log_debug(ocs, "PORT offline,.. skipping\n");
942 		return;
943 	}
944 
945 	if ((fcp->role != KNOB_ROLE_NONE)) {
946 		if(fcp->vport->sport != NULL) {
947 			ocs_log_debug(ocs,"sport is not NULL, skipping\n");
948 			return;
949 		}
950 
951 		ocs_sport_vport_alloc(ocs->domain, fcp->vport);
952 		return;
953 	}
954 
955 }
956 
957 int32_t
958 ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node)
959 {
960 	ocs_fc_target_t *tgt = NULL;
961 	uint32_t i;
962 
963 	for (i = 0; i < OCS_MAX_TARGETS; i++) {
964 		tgt = &fcp->tgt[i];
965 
966 		if (tgt->state == OCS_TGT_STATE_NONE)
967 			continue;
968 
969 		if (ocs_node_get_wwpn(node) == tgt->wwpn) {
970 			return i;
971 		}
972 	}
973 
974 	return -1;
975 }
976 
977 /**
978  * @ingroup scsi_api_initiator
979  * @brief receive notification of a new SCSI target node
980  *
981  * Sent by base driver to notify an initiator-client of the presense of a new
982  * remote target.   The initiator-server may use this call to prepare for
983  * inbound IO from this node.
984  *
985  * This function is only called if the base driver is enabled for
986  * initiator capability.
987  *
988  * @param node pointer to new remote initiator node
989  *
990  * @return none
991  *
992  * @note
993  */
994 
995 uint32_t
996 ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id)
997 {
998 	ocs_fc_target_t *tgt = NULL;
999 
1000 	tgt = &fcp->tgt[tgt_id];
1001 
1002 	tgt->node_id = node->instance_index;
1003 	tgt->state = OCS_TGT_STATE_VALID;
1004 
1005 	tgt->port_id = node->rnode.fc_id;
1006 	tgt->wwpn = ocs_node_get_wwpn(node);
1007 	tgt->wwnn = ocs_node_get_wwnn(node);
1008 	return 0;
1009 }
1010 
1011 uint32_t
1012 ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp)
1013 {
1014 	uint32_t i;
1015 
1016 	struct ocs_softc *ocs = node->ocs;
1017 	union ccb *ccb = NULL;
1018 	for (i = 0; i < OCS_MAX_TARGETS; i++) {
1019 		if (fcp->tgt[i].state == OCS_TGT_STATE_NONE)
1020 			break;
1021 	}
1022 
1023 	if (NULL == (ccb = xpt_alloc_ccb_nowait())) {
1024 		device_printf(ocs->dev, "%s: ccb allocation failed\n", __func__);
1025 		return -1;
1026 	}
1027 
1028 	if (CAM_REQ_CMP != xpt_create_path(&ccb->ccb_h.path, xpt_periph,
1029 				cam_sim_path(fcp->sim),
1030 				i, CAM_LUN_WILDCARD)) {
1031 		device_printf(
1032 			ocs->dev, "%s: target path creation failed\n", __func__);
1033 		xpt_free_ccb(ccb);
1034 		return -1;
1035 	}
1036 
1037 	ocs_update_tgt(node, fcp, i);
1038 	xpt_rescan(ccb);
1039 	return 0;
1040 }
1041 
1042 int32_t
1043 ocs_scsi_new_target(ocs_node_t *node)
1044 {
1045 	ocs_fcport	*fcp = NULL;
1046 	int32_t i;
1047 
1048 	fcp = node->sport->tgt_data;
1049 	if (fcp == NULL) {
1050 		printf("%s:FCP is NULL \n", __func__);
1051 		return 0;
1052 	}
1053 
1054 	i = ocs_tgt_find(fcp, node);
1055 
1056 	if (i < 0) {
1057 		ocs_add_new_tgt(node, fcp);
1058 		return 0;
1059 	}
1060 
1061 	ocs_update_tgt(node, fcp, i);
1062 	return 0;
1063 }
1064 
1065 static void
1066 ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt)
1067 {
1068 	struct cam_path *cpath = NULL;
1069 
1070 	if (!fcp->sim) {
1071 		device_printf(ocs->dev, "%s: calling with NULL sim\n", __func__);
1072 		return;
1073 	}
1074 
1075 	if (CAM_REQ_CMP == xpt_create_path(&cpath, NULL, cam_sim_path(fcp->sim),
1076 				tgt, CAM_LUN_WILDCARD)) {
1077 		xpt_async(AC_LOST_DEVICE, cpath, NULL);
1078 
1079 		xpt_free_path(cpath);
1080 	}
1081 }
1082 
1083 /*
1084  * Device Lost Timer Function- when we have decided that a device was lost,
1085  * we wait a specific period of time prior to telling the OS about lost device.
1086  *
1087  * This timer function gets activated when the device was lost.
1088  * This function fires once a second and then scans the port database
1089  * for devices that are marked dead but still have a virtual target assigned.
1090  * We decrement a counter for that port database entry, and when it hits zero,
1091  * we tell the OS the device was lost. Timer will be stopped when the device
1092  * comes back active or removed from the OS.
1093  */
1094 static void
1095 ocs_ldt(void *arg)
1096 {
1097 	ocs_fcport *fcp = arg;
1098 	taskqueue_enqueue(taskqueue_thread, &fcp->ltask);
1099 }
1100 
1101 static void
1102 ocs_ldt_task(void *arg, int pending)
1103 {
1104 	ocs_fcport *fcp = arg;
1105 	ocs_t	*ocs = fcp->ocs;
1106 	int i, more_to_do = 0;
1107 	ocs_fc_target_t *tgt = NULL;
1108 
1109 	for (i = 0; i < OCS_MAX_TARGETS; i++) {
1110 		tgt = &fcp->tgt[i];
1111 
1112 		if (tgt->state != OCS_TGT_STATE_LOST) {
1113 			continue;
1114 		}
1115 
1116 		if ((tgt->gone_timer != 0) && (ocs->attached)){
1117 			tgt->gone_timer -= 1;
1118 			more_to_do++;
1119 			continue;
1120 		}
1121 
1122 		if (tgt->is_target) {
1123 			tgt->is_target = 0;
1124 			ocs_delete_target(ocs, fcp, i);
1125 		}
1126 
1127 		tgt->state = OCS_TGT_STATE_NONE;
1128 	}
1129 
1130 	if (more_to_do) {
1131 		callout_reset(&fcp->ldt, hz, ocs_ldt, fcp);
1132 	} else {
1133 		callout_deactivate(&fcp->ldt);
1134 	}
1135 
1136 }
1137 
1138 /**
1139  * @ingroup scsi_api_initiator
1140  * @brief Delete a SCSI target node
1141  *
1142  * Sent by base driver to notify a initiator-client that a remote target
1143  * is now gone. The base driver will have terminated all  outstanding IOs
1144  * and the initiator-client will receive appropriate completions.
1145  *
1146  * The ocs_node_t structure has and elment of type ocs_scsi_ini_node_t named
1147  * ini_node that is declared and used by a target-server for private
1148  * information.
1149  *
1150  * This function is only called if the base driver is enabled for
1151  * initiator capability.
1152  *
1153  * @param node pointer node being deleted
1154  * @param reason reason for deleting the target
1155  *
1156  * @return Returns OCS_SCSI_CALL_ASYNC if target delete is queued for async
1157  * completion and OCS_SCSI_CALL_COMPLETE if call completed or error.
1158  *
1159  * @note
1160  */
1161 int32_t
1162 ocs_scsi_del_target(ocs_node_t *node, ocs_scsi_del_target_reason_e reason)
1163 {
1164 	struct ocs_softc *ocs = node->ocs;
1165 	ocs_fcport	*fcp = NULL;
1166 	ocs_fc_target_t *tgt = NULL;
1167 	int32_t	tgt_id;
1168 
1169 	if (ocs == NULL) {
1170 		ocs_log_err(ocs,"OCS is NULL \n");
1171 		return -1;
1172 	}
1173 
1174 	fcp = node->sport->tgt_data;
1175 	if (fcp == NULL) {
1176 		ocs_log_err(ocs,"FCP is NULL \n");
1177 		return -1;
1178 	}
1179 
1180 	tgt_id = ocs_tgt_find(fcp, node);
1181 	if (tgt_id == -1) {
1182 		ocs_log_err(ocs,"target is invalid\n");
1183 		return -1;
1184 	}
1185 
1186 	tgt = &fcp->tgt[tgt_id];
1187 
1188 	// IF in shutdown delete target.
1189 	if(!ocs->attached) {
1190 		ocs_delete_target(ocs, fcp, tgt_id);
1191 	} else {
1192 
1193 		tgt->state = OCS_TGT_STATE_LOST;
1194 		tgt->gone_timer = 30;
1195 		if (!callout_active(&fcp->ldt)) {
1196 			callout_reset(&fcp->ldt, hz, ocs_ldt, fcp);
1197 		}
1198 	}
1199 
1200 	return 0;
1201 }
1202 
1203 /**
1204  * @brief Initialize SCSI IO
1205  *
1206  * Initialize SCSI IO, this function is called once per IO during IO pool
1207  * allocation so that the target server may initialize any of its own private
1208  * data.
1209  *
1210  * @param io pointer to SCSI IO object
1211  *
1212  * @return returns 0 for success, a negative error code value for failure.
1213  */
1214 int32_t
1215 ocs_scsi_tgt_io_init(ocs_io_t *io)
1216 {
1217 	return 0;
1218 }
1219 
1220 /**
1221  * @brief Uninitialize SCSI IO
1222  *
1223  * Uninitialize target server private data in a SCSI io object
1224  *
1225  * @param io pointer to SCSI IO object
1226  *
1227  * @return returns 0 for success, a negative error code value for failure.
1228  */
1229 int32_t
1230 ocs_scsi_tgt_io_exit(ocs_io_t *io)
1231 {
1232 	return 0;
1233 }
1234 
1235 /**
1236  * @brief Initialize SCSI IO
1237  *
1238  * Initialize SCSI IO, this function is called once per IO during IO pool
1239  * allocation so that the initiator client may initialize any of its own private
1240  * data.
1241  *
1242  * @param io pointer to SCSI IO object
1243  *
1244  * @return returns 0 for success, a negative error code value for failure.
1245  */
1246 int32_t
1247 ocs_scsi_ini_io_init(ocs_io_t *io)
1248 {
1249 	return 0;
1250 }
1251 
1252 /**
1253  * @brief Uninitialize SCSI IO
1254  *
1255  * Uninitialize initiator client private data in a SCSI io object
1256  *
1257  * @param io pointer to SCSI IO object
1258  *
1259  * @return returns 0 for success, a negative error code value for failure.
1260  */
1261 int32_t
1262 ocs_scsi_ini_io_exit(ocs_io_t *io)
1263 {
1264 	return 0;
1265 }
1266 /*
1267  * End of functions required by SCSI base driver API
1268  ***************************************************************************/
1269 
1270 static __inline void
1271 ocs_set_ccb_status(union ccb *ccb, cam_status status)
1272 {
1273 	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1274 	ccb->ccb_h.status |= status;
1275 }
1276 
1277 static int32_t
1278 ocs_task_set_full_or_busy_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status,
1279 						uint32_t flags, void *arg)
1280 {
1281 
1282 	ocs_target_io_free(io);
1283 
1284 	return 0;
1285 }
1286 
1287 /**
1288  * @brief send SCSI task set full or busy status
1289  *
1290  * A SCSI task set full or busy response is sent depending on whether
1291  * another IO is already active on the LUN.
1292  *
1293  * @param io pointer to IO context
1294  *
1295  * @return returns 0 for success, a negative error code value for failure.
1296  */
1297 
1298 static int32_t
1299 ocs_task_set_full_or_busy(ocs_io_t *io)
1300 {
1301 	ocs_scsi_cmd_resp_t rsp = { 0 };
1302 	ocs_t *ocs = io->ocs;
1303 
1304 	/*
1305 	 * If there is another command for the LUN, then send task set full,
1306 	 * if this is the first one, then send the busy status.
1307 	 *
1308 	 * if 'busy sent' is FALSE, set it to TRUE and send BUSY
1309 	 * otherwise send FULL
1310 	 */
1311 	if (atomic_cmpset_acq_32(&io->node->tgt_node.busy_sent, FALSE, TRUE)) {
1312 		rsp.scsi_status = SCSI_STATUS_BUSY; /* Busy */
1313 		printf("%s: busy [%s] tag=%x iiu=%d ihw=%d\n", __func__,
1314 				io->node->display_name, io->tag,
1315 				io->ocs->io_in_use, io->ocs->io_high_watermark);
1316 	} else {
1317 		rsp.scsi_status = SCSI_STATUS_TASK_SET_FULL; /* Task set full */
1318 		printf("%s: full tag=%x iiu=%d\n", __func__, io->tag,
1319 			io->ocs->io_in_use);
1320 	}
1321 
1322 	/* Log a message here indicating a busy or task set full state */
1323 	if (OCS_LOG_ENABLE_Q_FULL_BUSY_MSG(ocs)) {
1324 		/* Log Task Set Full */
1325 		if (rsp.scsi_status == SCSI_STATUS_TASK_SET_FULL) {
1326 			/* Task Set Full Message */
1327 			ocs_log_info(ocs, "OCS CAM TASK SET FULL. Tasks >= %d\n",
1328 			 		ocs->io_high_watermark);
1329 		}
1330 		else if (rsp.scsi_status == SCSI_STATUS_BUSY) {
1331 			/* Log Busy Message */
1332 			ocs_log_info(ocs, "OCS CAM SCSI BUSY\n");
1333 		}
1334 	}
1335 
1336 	/* Send the response */
1337 	return
1338 	ocs_scsi_send_resp(io, 0, &rsp, ocs_task_set_full_or_busy_cb, NULL);
1339 }
1340 
1341 /**
1342  * @ingroup cam_io
1343  * @brief Process target IO completions
1344  *
1345  * @param io
1346  * @param scsi_status did the IO complete successfully
1347  * @param flags
1348  * @param arg application specific pointer provided in the call to ocs_target_io()
1349  *
1350  * @todo
1351  */
1352 static int32_t ocs_scsi_target_io_cb(ocs_io_t *io,
1353 				ocs_scsi_io_status_e scsi_status,
1354 				uint32_t flags, void *arg)
1355 {
1356 	union ccb *ccb = arg;
1357 	struct ccb_scsiio *csio = &ccb->csio;
1358 	struct ocs_softc *ocs = csio->ccb_h.ccb_ocs_ptr;
1359 	uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1360 	uint32_t io_is_done =
1361 		(ccb->ccb_h.flags & CAM_SEND_STATUS) == CAM_SEND_STATUS;
1362 
1363 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1364 
1365 	if (CAM_DIR_NONE != cam_dir) {
1366 		bus_dmasync_op_t op;
1367 
1368 		if (CAM_DIR_IN == cam_dir) {
1369 			op = BUS_DMASYNC_POSTREAD;
1370 		} else {
1371 			op = BUS_DMASYNC_POSTWRITE;
1372 		}
1373 		/* Synchronize the DMA memory with the CPU and free the mapping */
1374 		bus_dmamap_sync(ocs->buf_dmat, io->tgt_io.dmap, op);
1375 		if (io->tgt_io.flags & OCS_CAM_IO_F_DMAPPED) {
1376 			bus_dmamap_unload(ocs->buf_dmat, io->tgt_io.dmap);
1377 		}
1378 	}
1379 
1380 	if (io->tgt_io.sendresp) {
1381 		io->tgt_io.sendresp = 0;
1382 		ocs_scsi_cmd_resp_t  resp = { 0 };
1383 		io->tgt_io.state = OCS_CAM_IO_RESP;
1384 		resp.scsi_status = scsi_status;
1385 		if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1386 			resp.sense_data = (uint8_t *)&csio->sense_data;
1387 			resp.sense_data_length = csio->sense_len;
1388 		}
1389 		resp.residual = io->exp_xfer_len - io->transferred;
1390 
1391 		return ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb);
1392 	}
1393 
1394 	switch (scsi_status) {
1395 	case OCS_SCSI_STATUS_GOOD:
1396 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
1397 		break;
1398 	case OCS_SCSI_STATUS_ABORTED:
1399 		ocs_set_ccb_status(ccb, CAM_REQ_ABORTED);
1400 		break;
1401 	default:
1402 		ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1403 	}
1404 
1405 	if (io_is_done) {
1406 		if ((io->tgt_io.flags & OCS_CAM_IO_F_ABORT_NOTIFY) == 0) {
1407 			ocs_target_io_free(io);
1408 		}
1409 	} else {
1410 		io->tgt_io.state = OCS_CAM_IO_DATA_DONE;
1411 		/*device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n",
1412 				__func__, io->tgt_io.state, io->tag);*/
1413 	}
1414 
1415 	xpt_done(ccb);
1416 
1417 	return 0;
1418 }
1419 
1420 /**
1421  * @note	1. Since the CCB is assigned to the ocs_io_t on an XPT_CONT_TARGET_IO
1422  * 		   action, if an initiator aborts a command prior to the SIM receiving
1423  * 		   a CTIO, the IO's CCB will be NULL.
1424  */
1425 static int32_t
1426 ocs_io_abort_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
1427 {
1428 	struct ocs_softc *ocs = NULL;
1429 	ocs_io_t	*tmfio = arg;
1430 	ocs_scsi_tmf_resp_e tmf_resp = OCS_SCSI_TMF_FUNCTION_COMPLETE;
1431 	int32_t	rc = 0;
1432 
1433 	ocs = io->ocs;
1434 
1435 	io->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_DEV;
1436 
1437 	/* A good status indicates the IO was aborted and will be completed in
1438 	 * the IO's completion handler. Handle the other cases here. */
1439 	switch (scsi_status) {
1440 	case OCS_SCSI_STATUS_GOOD:
1441 		break;
1442 	case OCS_SCSI_STATUS_NO_IO:
1443 		break;
1444 	default:
1445 		device_printf(ocs->dev, "%s: unhandled status %d\n",
1446 				__func__, scsi_status);
1447 		tmf_resp = OCS_SCSI_TMF_FUNCTION_REJECTED;
1448 		rc = -1;
1449 	}
1450 
1451 	ocs_scsi_send_tmf_resp(tmfio, tmf_resp, NULL, ocs_target_tmf_cb, NULL);
1452 
1453 	return rc;
1454 }
1455 
1456 /**
1457  * @ingroup cam_io
1458  * @brief Process initiator IO completions
1459  *
1460  * @param io
1461  * @param scsi_status did the IO complete successfully
1462  * @param rsp pointer to response buffer
1463  * @param flags
1464  * @param arg application specific pointer provided in the call to ocs_target_io()
1465  *
1466  * @todo
1467  */
1468 static int32_t ocs_scsi_initiator_io_cb(ocs_io_t *io,
1469 					ocs_scsi_io_status_e scsi_status,
1470 					ocs_scsi_cmd_resp_t *rsp,
1471 					uint32_t flags, void *arg)
1472 {
1473 	union ccb *ccb = arg;
1474 	struct ccb_scsiio *csio = &ccb->csio;
1475 	struct ocs_softc *ocs = csio->ccb_h.ccb_ocs_ptr;
1476 	uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1477 	cam_status ccb_status= CAM_REQ_CMP_ERR;
1478 
1479 	if (CAM_DIR_NONE != cam_dir) {
1480 		bus_dmasync_op_t op;
1481 
1482 		if (CAM_DIR_IN == cam_dir) {
1483 			op = BUS_DMASYNC_POSTREAD;
1484 		} else {
1485 			op = BUS_DMASYNC_POSTWRITE;
1486 		}
1487 		/* Synchronize the DMA memory with the CPU and free the mapping */
1488 		bus_dmamap_sync(ocs->buf_dmat, io->tgt_io.dmap, op);
1489 		if (io->tgt_io.flags & OCS_CAM_IO_F_DMAPPED) {
1490 			bus_dmamap_unload(ocs->buf_dmat, io->tgt_io.dmap);
1491 		}
1492 	}
1493 
1494 	if (scsi_status == OCS_SCSI_STATUS_CHECK_RESPONSE) {
1495 		csio->scsi_status = rsp->scsi_status;
1496 		if (SCSI_STATUS_OK != rsp->scsi_status) {
1497 			ccb_status = CAM_SCSI_STATUS_ERROR;
1498 		}
1499 
1500 		csio->resid = rsp->residual;
1501 		if (rsp->residual > 0) {
1502 			uint32_t length = rsp->response_wire_length;
1503 			/* underflow */
1504 			if (csio->dxfer_len == (length + csio->resid)) {
1505 				ccb_status = CAM_REQ_CMP;
1506 			}
1507 		} else if (rsp->residual < 0) {
1508 			ccb_status = CAM_DATA_RUN_ERR;
1509 		}
1510 
1511 		if ((rsp->sense_data_length) &&
1512 			!(ccb->ccb_h.flags & (CAM_SENSE_PHYS | CAM_SENSE_PTR))) {
1513 			uint32_t	sense_len = 0;
1514 
1515 			ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1516 			if (rsp->sense_data_length < csio->sense_len) {
1517 				csio->sense_resid =
1518 					csio->sense_len - rsp->sense_data_length;
1519 				sense_len = rsp->sense_data_length;
1520 			} else {
1521 				csio->sense_resid = 0;
1522 				sense_len = csio->sense_len;
1523 			}
1524 			ocs_memcpy(&csio->sense_data, rsp->sense_data, sense_len);
1525 		}
1526 	} else if (scsi_status != OCS_SCSI_STATUS_GOOD) {
1527 		ccb_status = CAM_REQ_CMP_ERR;
1528 		ocs_set_ccb_status(ccb, ccb_status);
1529 		csio->ccb_h.status |= CAM_DEV_QFRZN;
1530 		xpt_freeze_devq(csio->ccb_h.path, 1);
1531 
1532 	} else {
1533 		ccb_status = CAM_REQ_CMP;
1534 	}
1535 
1536 	ocs_set_ccb_status(ccb, ccb_status);
1537 
1538 	ocs_scsi_io_free(io);
1539 
1540 	csio->ccb_h.ccb_io_ptr = NULL;
1541 	csio->ccb_h.ccb_ocs_ptr = NULL;
1542 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1543 
1544 	xpt_done(ccb);
1545 
1546 	return 0;
1547 }
1548 
1549 /**
1550  * @brief Load scatter-gather list entries into an IO
1551  *
1552  * This routine relies on the driver instance's software context pointer and
1553  * the IO object pointer having been already assigned to hooks in the CCB.
1554  * Although the routine does not return success/fail, callers can look at the
1555  * n_sge member to determine if the mapping failed (0 on failure).
1556  *
1557  * @param arg pointer to the CAM ccb for this IO
1558  * @param seg DMA address/length pairs
1559  * @param nseg number of DMA address/length pairs
1560  * @param error any errors while mapping the IO
1561  */
1562 static void
1563 ocs_scsi_dmamap_load(void *arg, bus_dma_segment_t *seg, int nseg, int error)
1564 {
1565 	ocs_dmamap_load_arg_t *sglarg = (ocs_dmamap_load_arg_t*) arg;
1566 
1567 	if (error) {
1568 		printf("%s: seg=%p nseg=%d error=%d\n",
1569 				__func__, seg, nseg, error);
1570 		sglarg->rc = -1;
1571 	} else {
1572 		uint32_t i = 0;
1573 		uint32_t c = 0;
1574 
1575 		if ((sglarg->sgl_count + nseg) > sglarg->sgl_max) {
1576 			printf("%s: sgl_count=%d nseg=%d max=%d\n", __func__,
1577 				sglarg->sgl_count, nseg, sglarg->sgl_max);
1578 			sglarg->rc = -2;
1579 			return;
1580 		}
1581 
1582 		for (i = 0, c = sglarg->sgl_count; i < nseg; i++, c++) {
1583 			sglarg->sgl[c].addr = seg[i].ds_addr;
1584 			sglarg->sgl[c].len  = seg[i].ds_len;
1585 		}
1586 
1587 		sglarg->sgl_count = c;
1588 
1589 		sglarg->rc = 0;
1590 	}
1591 }
1592 
1593 /**
1594  * @brief Build a scatter-gather list from a CAM CCB
1595  *
1596  * @param ocs the driver instance's software context
1597  * @param ccb pointer to the CCB
1598  * @param io pointer to the previously allocated IO object
1599  * @param sgl pointer to SGL
1600  * @param sgl_max number of entries in sgl
1601  *
1602  * @return 0 on success, non-zero otherwise
1603  */
1604 static int32_t
1605 ocs_build_scsi_sgl(struct ocs_softc *ocs, union ccb *ccb, ocs_io_t *io,
1606 		ocs_scsi_sgl_t *sgl, uint32_t sgl_max)
1607 {
1608 	ocs_dmamap_load_arg_t dmaarg;
1609 	int32_t	err = 0;
1610 
1611 	if (!ocs || !ccb || !io || !sgl) {
1612 		printf("%s: bad param o=%p c=%p i=%p s=%p\n", __func__,
1613 				ocs, ccb, io, sgl);
1614 		return -1;
1615 	}
1616 
1617 	io->tgt_io.flags &= ~OCS_CAM_IO_F_DMAPPED;
1618 
1619 	dmaarg.sgl = sgl;
1620 	dmaarg.sgl_count = 0;
1621 	dmaarg.sgl_max = sgl_max;
1622 	dmaarg.rc = 0;
1623 
1624 	err = bus_dmamap_load_ccb(ocs->buf_dmat, io->tgt_io.dmap, ccb,
1625 			ocs_scsi_dmamap_load, &dmaarg, 0);
1626 
1627 	if (err || dmaarg.rc) {
1628 		device_printf(
1629 			ocs->dev, "%s: bus_dmamap_load_ccb error (%d %d)\n",
1630 				__func__, err, dmaarg.rc);
1631 		return -1;
1632 	}
1633 
1634 	io->tgt_io.flags |= OCS_CAM_IO_F_DMAPPED;
1635 	return dmaarg.sgl_count;
1636 }
1637 
1638 /**
1639  * @ingroup cam_io
1640  * @brief Send a target IO
1641  *
1642  * @param ocs the driver instance's software context
1643  * @param ccb pointer to the CCB
1644  *
1645  * @return 0 on success, non-zero otherwise
1646  */
1647 static int32_t
1648 ocs_target_io(struct ocs_softc *ocs, union ccb *ccb)
1649 {
1650 	struct ccb_scsiio *csio = &ccb->csio;
1651 	ocs_io_t *io = NULL;
1652 	uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1653 	bool sendstatus = ccb->ccb_h.flags & CAM_SEND_STATUS;
1654 	uint32_t xferlen = csio->dxfer_len;
1655 	int32_t rc = 0;
1656 
1657 	io = ocs_scsi_find_io(ocs, csio->tag_id);
1658 	if (io == NULL) {
1659 		ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1660 		panic("bad tag value");
1661 		return 1;
1662 	}
1663 
1664 	/* Received an ABORT TASK for this IO */
1665 	if (io->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) {
1666 		/*device_printf(ocs->dev,
1667 			"%s: XPT_CONT_TARGET_IO state=%d tag=%#x xid=%#x flags=%#x\n",
1668 			__func__, io->tgt_io.state, io->tag, io->init_task_tag,
1669 			io->tgt_io.flags);*/
1670 		io->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM;
1671 
1672 		if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1673 			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
1674 			ocs_target_io_free(io);
1675 			return 1;
1676 		}
1677 
1678 		ocs_set_ccb_status(ccb, CAM_REQ_ABORTED);
1679 
1680 		return 1;
1681 	}
1682 
1683 	io->tgt_io.app = ccb;
1684 
1685 	ocs_set_ccb_status(ccb, CAM_REQ_INPROG);
1686 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
1687 
1688 	csio->ccb_h.ccb_ocs_ptr = ocs;
1689 	csio->ccb_h.ccb_io_ptr  = io;
1690 
1691 	if ((sendstatus && (xferlen == 0))) {
1692 		ocs_scsi_cmd_resp_t	resp = { 0 };
1693 
1694 		ocs_assert(ccb->ccb_h.flags & CAM_SEND_STATUS, -1);
1695 
1696 		io->tgt_io.state = OCS_CAM_IO_RESP;
1697 
1698 		resp.scsi_status = csio->scsi_status;
1699 
1700 		if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1701 			resp.sense_data = (uint8_t *)&csio->sense_data;
1702 			resp.sense_data_length = csio->sense_len;
1703 		}
1704 
1705 		resp.residual = io->exp_xfer_len - io->transferred;
1706 		rc = ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb);
1707 
1708 	} else if (xferlen != 0) {
1709 		ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL];
1710 		int32_t sgl_count = 0;
1711 
1712 		io->tgt_io.state = OCS_CAM_IO_DATA;
1713 
1714 		if (sendstatus)
1715 			io->tgt_io.sendresp = 1;
1716 
1717 		sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, ARRAY_SIZE(sgl));
1718 		if (sgl_count > 0) {
1719 			if (cam_dir == CAM_DIR_IN) {
1720 				rc = ocs_scsi_send_rd_data(io, 0, NULL, sgl,
1721 						sgl_count, csio->dxfer_len,
1722 						ocs_scsi_target_io_cb, ccb);
1723 			} else if (cam_dir == CAM_DIR_OUT) {
1724 				rc = ocs_scsi_recv_wr_data(io, 0, NULL, sgl,
1725 						sgl_count, csio->dxfer_len,
1726 						ocs_scsi_target_io_cb, ccb);
1727 			} else {
1728 				device_printf(ocs->dev, "%s:"
1729 						" unknown CAM direction %#x\n",
1730 						__func__, cam_dir);
1731 				ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
1732 				rc = 1;
1733 			}
1734 		} else {
1735 			device_printf(ocs->dev, "%s: building SGL failed\n",
1736 						__func__);
1737 			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1738 			rc = 1;
1739 		}
1740 	} else {
1741 		device_printf(ocs->dev, "%s: Wrong value xfer and sendstatus"
1742 					" are 0 \n", __func__);
1743 		ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
1744 		rc = 1;
1745 
1746 	}
1747 
1748 	if (rc) {
1749 		ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1750 		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1751 		io->tgt_io.state = OCS_CAM_IO_DATA_DONE;
1752 		device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n",
1753 				__func__, io->tgt_io.state, io->tag);
1754 	if ((sendstatus && (xferlen == 0))) {
1755 			ocs_target_io_free(io);
1756 		}
1757 	}
1758 
1759 	return rc;
1760 }
1761 
1762 static int32_t
1763 ocs_target_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags,
1764 		void *arg)
1765 {
1766 
1767 	/*device_printf(io->ocs->dev, "%s: tag=%x io=%p s=%#x\n",
1768 			 __func__, io->tag, io, scsi_status);*/
1769 	ocs_scsi_io_complete(io);
1770 
1771 	return 0;
1772 }
1773 
1774 /**
1775  * @ingroup cam_io
1776  * @brief Send an initiator IO
1777  *
1778  * @param ocs the driver instance's software context
1779  * @param ccb pointer to the CCB
1780  *
1781  * @return 0 on success, non-zero otherwise
1782  */
1783 static int32_t
1784 ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
1785 {
1786 	int32_t rc;
1787 	struct ccb_scsiio *csio = &ccb->csio;
1788 	struct ccb_hdr *ccb_h = &csio->ccb_h;
1789 	ocs_node_t *node = NULL;
1790 	ocs_io_t *io = NULL;
1791 	ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL];
1792 	int32_t sgl_count;
1793 	ocs_fcport	*fcp;
1794 
1795 	fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)));
1796 
1797 	if (fcp->tgt[ccb_h->target_id].state == OCS_TGT_STATE_LOST) {
1798 		device_printf(ocs->dev, "%s: device LOST %d\n", __func__,
1799 							ccb_h->target_id);
1800 		return CAM_REQUEUE_REQ;
1801 	}
1802 
1803 	if (fcp->tgt[ccb_h->target_id].state == OCS_TGT_STATE_NONE) {
1804 		device_printf(ocs->dev, "%s: device not ready %d\n", __func__,
1805 							ccb_h->target_id);
1806 		return CAM_SEL_TIMEOUT;
1807 	}
1808 
1809 	node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id);
1810 	if (node == NULL) {
1811 		device_printf(ocs->dev, "%s: no device %d\n", __func__,
1812 							ccb_h->target_id);
1813 		return CAM_SEL_TIMEOUT;
1814 	}
1815 
1816 	if (!node->targ) {
1817 		device_printf(ocs->dev, "%s: not target device %d\n", __func__,
1818 							ccb_h->target_id);
1819 		return CAM_SEL_TIMEOUT;
1820 	}
1821 
1822 	io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
1823 	if (io == NULL) {
1824 		device_printf(ocs->dev, "%s: unable to alloc IO\n", __func__);
1825 		return -1;
1826 	}
1827 
1828 	/* eventhough this is INI, use target structure as ocs_build_scsi_sgl
1829 	 * only references the tgt_io part of an ocs_io_t */
1830 	io->tgt_io.app = ccb;
1831 
1832 	csio->ccb_h.ccb_ocs_ptr = ocs;
1833 	csio->ccb_h.ccb_io_ptr  = io;
1834 
1835 	sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, ARRAY_SIZE(sgl));
1836 	if (sgl_count < 0) {
1837 		ocs_scsi_io_free(io);
1838 		device_printf(ocs->dev, "%s: building SGL failed\n", __func__);
1839 		return -1;
1840 	}
1841 
1842 	if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
1843 		io->timeout = 0;
1844 	} else if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) {
1845 		io->timeout = OCS_CAM_IO_TIMEOUT;
1846 	} else {
1847 		io->timeout = ccb->ccb_h.timeout;
1848 	}
1849 
1850 	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
1851 	case CAM_DIR_NONE:
1852 		rc = ocs_scsi_send_nodata_io(node, io, ccb_h->target_lun,
1853 				ccb->ccb_h.flags & CAM_CDB_POINTER ?
1854 				csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1855 				csio->cdb_len,
1856 				ocs_scsi_initiator_io_cb, ccb);
1857 		break;
1858 	case CAM_DIR_IN:
1859 		rc = ocs_scsi_send_rd_io(node, io, ccb_h->target_lun,
1860 				ccb->ccb_h.flags & CAM_CDB_POINTER ?
1861 				csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1862 				csio->cdb_len,
1863 				NULL,
1864 				sgl, sgl_count, csio->dxfer_len,
1865 				ocs_scsi_initiator_io_cb, ccb);
1866 		break;
1867 	case CAM_DIR_OUT:
1868 		rc = ocs_scsi_send_wr_io(node, io, ccb_h->target_lun,
1869 				ccb->ccb_h.flags & CAM_CDB_POINTER ?
1870 				csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1871 				csio->cdb_len,
1872 				NULL,
1873 				sgl, sgl_count, csio->dxfer_len,
1874 				ocs_scsi_initiator_io_cb, ccb);
1875 		break;
1876 	default:
1877 		panic("%s invalid data direction %08x\n", __func__,
1878 							ccb->ccb_h.flags);
1879 		break;
1880 	}
1881 
1882 	return rc;
1883 }
1884 
1885 static uint32_t
1886 ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role)
1887 {
1888 
1889 	uint32_t rc = 0, was = 0, i = 0;
1890 	ocs_vport_spec_t *vport = fcp->vport;
1891 
1892 	for (was = 0, i = 0; i < (ocs->num_vports + 1); i++) {
1893 		if (FCPORT(ocs, i)->role != KNOB_ROLE_NONE)
1894 		was++;
1895 	}
1896 
1897 	// Physical port
1898 	if ((was == 0) || (vport == NULL)) {
1899 		fcp->role = new_role;
1900 		if (vport == NULL) {
1901 			ocs->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1902 			ocs->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1903 		} else {
1904 			vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1905 			vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1906 		}
1907 
1908 		rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1909 		if (rc) {
1910 			ocs_log_debug(ocs, "port offline failed : %d\n", rc);
1911 		}
1912 
1913 		rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1914 		if (rc) {
1915 			ocs_log_debug(ocs, "port online failed : %d\n", rc);
1916 		}
1917 
1918 		return 0;
1919 	}
1920 
1921 	if ((fcp->role != KNOB_ROLE_NONE)){
1922 		fcp->role = new_role;
1923 		vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1924 		vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1925 		/* New Sport will be created in sport deleted cb */
1926 		return ocs_sport_vport_del(ocs, ocs->domain, vport->wwpn, vport->wwnn);
1927 	}
1928 
1929 	fcp->role = new_role;
1930 
1931 	vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1932 	vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1933 
1934 	if (fcp->role != KNOB_ROLE_NONE) {
1935 		return ocs_sport_vport_alloc(ocs->domain, vport);
1936 	}
1937 
1938 	return (0);
1939 }
1940 
1941 /**
1942  * @ingroup cam_api
1943  * @brief Process CAM actions
1944  *
1945  * The driver supplies this routine to the CAM during intialization and
1946  * is the main entry point for processing CAM Control Blocks (CCB)
1947  *
1948  * @param sim pointer to the SCSI Interface Module
1949  * @param ccb CAM control block
1950  *
1951  * @todo
1952  *  - populate path inquiry data via info retrieved from SLI port
1953  */
1954 static void
1955 ocs_action(struct cam_sim *sim, union ccb *ccb)
1956 {
1957 	struct ocs_softc *ocs = (struct ocs_softc *)cam_sim_softc(sim);
1958 	struct ccb_hdr	*ccb_h = &ccb->ccb_h;
1959 
1960 	int32_t	rc, bus;
1961 	bus = cam_sim_bus(sim);
1962 
1963 	switch (ccb_h->func_code) {
1964 	case XPT_SCSI_IO:
1965 
1966 		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
1967 			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
1968 				ccb->ccb_h.status = CAM_REQ_INVALID;
1969 				xpt_done(ccb);
1970 				break;
1971 			}
1972 		}
1973 
1974 		rc = ocs_initiator_io(ocs, ccb);
1975 		if (0 == rc) {
1976 			ocs_set_ccb_status(ccb, CAM_REQ_INPROG | CAM_SIM_QUEUED);
1977 			break;
1978 		} else {
1979 		  	if (rc == CAM_REQUEUE_REQ) {
1980 				cam_freeze_devq(ccb->ccb_h.path);
1981 				cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
1982 				ccb->ccb_h.status = CAM_REQUEUE_REQ;
1983 				xpt_done(ccb);
1984 				break;
1985 			}
1986 
1987 			ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1988 			if (rc > 0) {
1989 				ocs_set_ccb_status(ccb, rc);
1990 			} else {
1991 				ocs_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
1992 			}
1993 		}
1994 		xpt_done(ccb);
1995 		break;
1996 	case XPT_PATH_INQ:
1997 	{
1998 		struct ccb_pathinq *cpi = &ccb->cpi;
1999 		struct ccb_pathinq_settings_fc *fc = &cpi->xport_specific.fc;
2000 		ocs_fcport *fcp = FCPORT(ocs, bus);
2001 
2002 		uint64_t wwn = 0;
2003 		ocs_xport_stats_t value;
2004 
2005 		cpi->version_num = 1;
2006 
2007 		cpi->protocol = PROTO_SCSI;
2008 		cpi->protocol_version = SCSI_REV_SPC;
2009 
2010 		if (ocs->ocs_xport == OCS_XPORT_FC) {
2011 			cpi->transport = XPORT_FC;
2012 		} else {
2013 			cpi->transport = XPORT_UNKNOWN;
2014 		}
2015 
2016 		cpi->transport_version = 0;
2017 
2018 		/* Set the transport parameters of the SIM */
2019 		ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
2020 		fc->bitrate = value.value * 1000;	/* speed in Mbps */
2021 
2022 		wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWPN));
2023 		fc->wwpn = be64toh(wwn);
2024 
2025 		wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWNN));
2026 		fc->wwnn = be64toh(wwn);
2027 
2028 		fc->port = fcp->fc_id;
2029 
2030 		if (ocs->config_tgt) {
2031 			cpi->target_sprt =
2032 				PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2033 		}
2034 
2035 		cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
2036 		cpi->hba_misc |= PIM_EXTLUNS | PIM_NOSCAN;
2037 
2038 		cpi->hba_inquiry = PI_TAG_ABLE;
2039 		cpi->max_target = OCS_MAX_TARGETS;
2040 		cpi->initiator_id = ocs->max_remote_nodes + 1;
2041 
2042 		if (!ocs->enable_ini) {
2043 			cpi->hba_misc |= PIM_NOINITIATOR;
2044 		}
2045 
2046 		cpi->max_lun = OCS_MAX_LUN;
2047 		cpi->bus_id = cam_sim_bus(sim);
2048 
2049 		/* Need to supply a base transfer speed prior to linking up
2050 		 * Worst case, this would be FC 1Gbps */
2051 		cpi->base_transfer_speed = 1 * 1000 * 1000;
2052 
2053 		/* Calculate the max IO supported
2054 		 * Worst case would be an OS page per SGL entry */
2055 		cpi->maxio = PAGE_SIZE *
2056 			(ocs_scsi_get_property(ocs, OCS_SCSI_MAX_SGL) - 1);
2057 
2058 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2059 		strncpy(cpi->hba_vid, "Emulex", HBA_IDLEN);
2060 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2061 		cpi->unit_number = cam_sim_unit(sim);
2062 
2063 		cpi->ccb_h.status = CAM_REQ_CMP;
2064 		xpt_done(ccb);
2065 		break;
2066 	}
2067 	case XPT_GET_TRAN_SETTINGS:
2068 	{
2069 		struct ccb_trans_settings *cts = &ccb->cts;
2070 		struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
2071 		struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
2072 		ocs_xport_stats_t value;
2073 		ocs_fcport *fcp = FCPORT(ocs, bus);
2074 		ocs_fc_target_t *tgt = NULL;
2075 
2076 		if (ocs->ocs_xport != OCS_XPORT_FC) {
2077 			ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2078 			xpt_done(ccb);
2079 			break;
2080 		}
2081 
2082 		if (cts->ccb_h.target_id > OCS_MAX_TARGETS) {
2083 			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2084 			xpt_done(ccb);
2085 			break;
2086 		}
2087 
2088 		tgt = &fcp->tgt[cts->ccb_h.target_id];
2089 		if (tgt->state == OCS_TGT_STATE_NONE) {
2090 			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2091 			xpt_done(ccb);
2092 			break;
2093 		}
2094 
2095 		cts->protocol = PROTO_SCSI;
2096 		cts->protocol_version = SCSI_REV_SPC2;
2097 		cts->transport = XPORT_FC;
2098 		cts->transport_version = 2;
2099 
2100 		scsi->valid = CTS_SCSI_VALID_TQ;
2101 		scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2102 
2103 		/* speed in Mbps */
2104 		ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
2105 		fc->bitrate = value.value * 100;
2106 
2107 		fc->wwpn = tgt->wwpn;
2108 
2109 		fc->wwnn = tgt->wwnn;
2110 
2111 		fc->port = tgt->port_id;
2112 
2113 		fc->valid = CTS_FC_VALID_SPEED |
2114 			CTS_FC_VALID_WWPN |
2115 			CTS_FC_VALID_WWNN |
2116 			CTS_FC_VALID_PORT;
2117 
2118 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2119 		xpt_done(ccb);
2120 		break;
2121 	}
2122 	case XPT_SET_TRAN_SETTINGS:
2123 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2124 		xpt_done(ccb);
2125 		break;
2126 
2127 	case XPT_CALC_GEOMETRY:
2128 		cam_calc_geometry(&ccb->ccg, TRUE);
2129 		xpt_done(ccb);
2130 		break;
2131 
2132 	case XPT_GET_SIM_KNOB:
2133 	{
2134 		struct ccb_sim_knob *knob = &ccb->knob;
2135 		uint64_t wwn = 0;
2136 		ocs_fcport *fcp = FCPORT(ocs, bus);
2137 
2138 		if (ocs->ocs_xport != OCS_XPORT_FC) {
2139 			ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2140 			xpt_done(ccb);
2141 			break;
2142 		}
2143 
2144 		if (bus == 0) {
2145 			wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs,
2146 						OCS_SCSI_WWNN));
2147 			knob->xport_specific.fc.wwnn = be64toh(wwn);
2148 
2149 			wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs,
2150 						OCS_SCSI_WWPN));
2151 			knob->xport_specific.fc.wwpn = be64toh(wwn);
2152 		} else {
2153 			knob->xport_specific.fc.wwnn = fcp->vport->wwnn;
2154 			knob->xport_specific.fc.wwpn = fcp->vport->wwpn;
2155 		}
2156 
2157 		knob->xport_specific.fc.role = fcp->role;
2158 		knob->xport_specific.fc.valid = KNOB_VALID_ADDRESS |
2159 						KNOB_VALID_ROLE;
2160 
2161 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2162 		xpt_done(ccb);
2163 		break;
2164 	}
2165 	case XPT_SET_SIM_KNOB:
2166 	{
2167 		struct ccb_sim_knob *knob = &ccb->knob;
2168 		bool role_changed = FALSE;
2169 		ocs_fcport *fcp = FCPORT(ocs, bus);
2170 
2171 		if (ocs->ocs_xport != OCS_XPORT_FC) {
2172 			ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2173 			xpt_done(ccb);
2174 			break;
2175 		}
2176 
2177 		if (knob->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
2178 			device_printf(ocs->dev,
2179 				"%s: XPT_SET_SIM_KNOB wwnn=%llx wwpn=%llx\n",
2180 					__func__,
2181 					(unsigned long long)knob->xport_specific.fc.wwnn,
2182 					(unsigned long long)knob->xport_specific.fc.wwpn);
2183 		}
2184 
2185 		if (knob->xport_specific.fc.valid & KNOB_VALID_ROLE) {
2186 			switch (knob->xport_specific.fc.role) {
2187 			case KNOB_ROLE_NONE:
2188 				if (fcp->role != KNOB_ROLE_NONE) {
2189 					role_changed = TRUE;
2190 				}
2191 				break;
2192 			case KNOB_ROLE_TARGET:
2193 				if (fcp->role != KNOB_ROLE_TARGET) {
2194 					role_changed = TRUE;
2195 				}
2196 				break;
2197 			case KNOB_ROLE_INITIATOR:
2198 				if (fcp->role != KNOB_ROLE_INITIATOR) {
2199 					role_changed = TRUE;
2200 				}
2201 				break;
2202 			case KNOB_ROLE_BOTH:
2203 				if (fcp->role != KNOB_ROLE_BOTH) {
2204 					role_changed = TRUE;
2205 				}
2206 				break;
2207 			default:
2208 				device_printf(ocs->dev,
2209 					"%s: XPT_SET_SIM_KNOB unsupported role: %d\n",
2210 					__func__, knob->xport_specific.fc.role);
2211 			}
2212 
2213 			if (role_changed) {
2214 				device_printf(ocs->dev,
2215 						"BUS:%d XPT_SET_SIM_KNOB old_role: %d new_role: %d\n",
2216 						bus, fcp->role, knob->xport_specific.fc.role);
2217 
2218 				ocs_fcp_change_role(ocs, fcp, knob->xport_specific.fc.role);
2219 			}
2220 		}
2221 
2222 
2223 
2224 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2225 		xpt_done(ccb);
2226 		break;
2227 	}
2228 	case XPT_ABORT:
2229 	{
2230 		union ccb *accb = ccb->cab.abort_ccb;
2231 
2232 		switch (accb->ccb_h.func_code) {
2233 		case XPT_ACCEPT_TARGET_IO:
2234 			ocs_abort_atio(ocs, ccb);
2235 			break;
2236 		case XPT_IMMEDIATE_NOTIFY:
2237 			ocs_abort_inot(ocs, ccb);
2238 			break;
2239 		case XPT_SCSI_IO:
2240 			rc = ocs_abort_initiator_io(ocs, accb);
2241 			if (rc) {
2242 				ccb->ccb_h.status = CAM_UA_ABORT;
2243 			} else {
2244 				ccb->ccb_h.status = CAM_REQ_CMP;
2245 			}
2246 
2247 			break;
2248 		default:
2249 			printf("abort of unknown func %#x\n",
2250 					accb->ccb_h.func_code);
2251 			ccb->ccb_h.status = CAM_REQ_INVALID;
2252 			break;
2253 		}
2254 		break;
2255 	}
2256 	case XPT_RESET_BUS:
2257 		if (ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE) == 0) {
2258 			rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
2259 			if (rc) {
2260 				ocs_log_debug(ocs, "Failed to bring port online"
2261 								" : %d\n", rc);
2262 			}
2263 			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2264 		} else {
2265 			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2266 		}
2267 		xpt_done(ccb);
2268 		break;
2269 	case XPT_RESET_DEV:
2270 	{
2271 		ocs_node_t	*node = NULL;
2272 		ocs_io_t	*io = NULL;
2273 		int32_t		rc = 0;
2274 		ocs_fcport *fcp = FCPORT(ocs, bus);
2275 
2276 		node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id);
2277 		if (node == NULL) {
2278 			device_printf(ocs->dev, "%s: no device %d\n",
2279 						__func__, ccb_h->target_id);
2280 			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2281 			xpt_done(ccb);
2282 			break;
2283 		}
2284 
2285 		io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
2286 		if (io == NULL) {
2287 			device_printf(ocs->dev, "%s: unable to alloc IO\n",
2288 								 __func__);
2289 			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2290 			xpt_done(ccb);
2291 			break;
2292 		}
2293 
2294 		rc = ocs_scsi_send_tmf(node, io, NULL, ccb_h->target_lun,
2295 				OCS_SCSI_TMF_LOGICAL_UNIT_RESET,
2296 				NULL, 0, 0,	/* sgl, sgl_count, length */
2297 				ocs_initiator_tmf_cb, NULL/*arg*/);
2298 
2299 		if (rc) {
2300 			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2301 		} else {
2302 			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2303 		}
2304 
2305 		if (node->fcp2device) {
2306 			ocs_reset_crn(node, ccb_h->target_lun);
2307 		}
2308 
2309 		xpt_done(ccb);
2310 		break;
2311 	}
2312 	case XPT_EN_LUN:	/* target support */
2313 	{
2314 		ocs_tgt_resource_t *trsrc = NULL;
2315 		uint32_t	status = 0;
2316 		ocs_fcport *fcp = FCPORT(ocs, bus);
2317 
2318 		device_printf(ocs->dev, "XPT_EN_LUN %sable %d:%d\n",
2319 				ccb->cel.enable ? "en" : "dis",
2320 				ccb->ccb_h.target_id,
2321 				(unsigned int)ccb->ccb_h.target_lun);
2322 
2323 		trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status);
2324 		if (trsrc) {
2325 			trsrc->enabled = ccb->cel.enable;
2326 
2327 			/* Abort all ATIO/INOT on LUN disable */
2328 			if (trsrc->enabled == FALSE) {
2329 				ocs_tgt_resource_abort(ocs, trsrc);
2330 			} else {
2331 				STAILQ_INIT(&trsrc->atio);
2332 				STAILQ_INIT(&trsrc->inot);
2333 			}
2334 			status = CAM_REQ_CMP;
2335 		}
2336 
2337 		ocs_set_ccb_status(ccb, status);
2338 		xpt_done(ccb);
2339 		break;
2340 	}
2341 	/*
2342 	 * The flow of target IOs in CAM is:
2343 	 *  - CAM supplies a number of CCBs to the driver used for received
2344 	 *    commands.
2345 	 *  - when the driver receives a command, it copies the relevant
2346 	 *    information to the CCB and returns it to the CAM using xpt_done()
2347 	 *  - after the target server processes the request, it creates
2348 	 *    a new CCB containing information on how to continue the IO and
2349 	 *    passes that to the driver
2350 	 *  - the driver processes the "continue IO" (a.k.a CTIO) CCB
2351 	 *  - once the IO completes, the driver returns the CTIO to the CAM
2352 	 *    using xpt_done()
2353 	 */
2354 	case XPT_ACCEPT_TARGET_IO:	/* used to inform upper layer of
2355 						received CDB (a.k.a. ATIO) */
2356 	case XPT_IMMEDIATE_NOTIFY:	/* used to inform upper layer of other
2357 							 event (a.k.a. INOT) */
2358 	{
2359 		ocs_tgt_resource_t *trsrc = NULL;
2360 		uint32_t	status = 0;
2361 		ocs_fcport *fcp = FCPORT(ocs, bus);
2362 
2363 		/*printf("XPT_%s %p\n", ccb_h->func_code == XPT_ACCEPT_TARGET_IO ?
2364 				"ACCEPT_TARGET_IO" : "IMMEDIATE_NOTIFY", ccb);*/
2365 		trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status);
2366 		if (trsrc == NULL) {
2367 			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2368 			xpt_done(ccb);
2369 			break;
2370 		}
2371 
2372 		if (XPT_ACCEPT_TARGET_IO == ccb->ccb_h.func_code) {
2373 			struct ccb_accept_tio *atio = NULL;
2374 
2375 			atio = (struct ccb_accept_tio *)ccb;
2376 			atio->init_id = 0x0badbeef;
2377 			atio->tag_id  = 0xdeadc0de;
2378 
2379 			STAILQ_INSERT_TAIL(&trsrc->atio, &ccb->ccb_h,
2380 					sim_links.stqe);
2381 		} else {
2382 			STAILQ_INSERT_TAIL(&trsrc->inot, &ccb->ccb_h,
2383 					sim_links.stqe);
2384 		}
2385 		ccb->ccb_h.ccb_io_ptr  = NULL;
2386 		ccb->ccb_h.ccb_ocs_ptr = ocs;
2387 		ocs_set_ccb_status(ccb, CAM_REQ_INPROG);
2388 		/*
2389 		 * These actions give resources to the target driver.
2390 		 * If we didn't return here, this function would call
2391 		 * xpt_done(), signaling to the upper layers that an
2392 		 * IO or other event had arrived.
2393 		 */
2394 		break;
2395 	}
2396 	case XPT_NOTIFY_ACKNOWLEDGE:
2397 	{
2398 		ocs_io_t *io = NULL;
2399 		ocs_io_t *abortio = NULL;
2400 
2401 		/* Get the IO reference for this tag */
2402 		io = ocs_scsi_find_io(ocs, ccb->cna2.tag_id);
2403 		if (io == NULL) {
2404 			device_printf(ocs->dev,
2405 				"%s: XPT_NOTIFY_ACKNOWLEDGE no IO with tag %#x\n",
2406 					__func__, ccb->cna2.tag_id);
2407 			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2408 			xpt_done(ccb);
2409 			break;
2410 		}
2411 
2412 		abortio = io->tgt_io.app;
2413 		if (abortio) {
2414 			abortio->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_NOTIFY;
2415 			device_printf(ocs->dev,
2416 				"%s: XPT_NOTIFY_ACK state=%d tag=%#x xid=%#x"
2417 				" flags=%#x\n",	__func__, abortio->tgt_io.state,
2418 				abortio->tag, abortio->init_task_tag,
2419 					abortio->tgt_io.flags);
2420 			/* TMF response was sent in abort callback */
2421 		} else {
2422 			ocs_scsi_send_tmf_resp(io,
2423 					OCS_SCSI_TMF_FUNCTION_COMPLETE,
2424 					NULL, ocs_target_tmf_cb, NULL);
2425 		}
2426 
2427 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2428 		xpt_done(ccb);
2429 		break;
2430 	}
2431 	case XPT_CONT_TARGET_IO:	/* continue target IO, sending data/response (a.k.a. CTIO) */
2432 		if (ocs_target_io(ocs, ccb)) {
2433 			device_printf(ocs->dev,
2434 				"XPT_CONT_TARGET_IO failed flags=%x tag=%#x\n",
2435 				ccb->ccb_h.flags, ccb->csio.tag_id);
2436 			xpt_done(ccb);
2437 		}
2438 		break;
2439 	default:
2440 		device_printf(ocs->dev, "unhandled func_code = %#x\n",
2441 				ccb_h->func_code);
2442 		ccb_h->status = CAM_REQ_INVALID;
2443 		xpt_done(ccb);
2444 		break;
2445 	}
2446 }
2447 
2448 /**
2449  * @ingroup cam_api
2450  * @brief Process events
2451  *
2452  * @param sim pointer to the SCSI Interface Module
2453  *
2454  */
2455 static void
2456 ocs_poll(struct cam_sim *sim)
2457 {
2458 	printf("%s\n", __func__);
2459 }
2460 
2461 static int32_t
2462 ocs_initiator_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status,
2463 		ocs_scsi_cmd_resp_t *rsp, uint32_t flags, void *arg)
2464 {
2465 	int32_t	rc = 0;
2466 
2467 	switch (scsi_status) {
2468 	case OCS_SCSI_STATUS_GOOD:
2469 	case OCS_SCSI_STATUS_NO_IO:
2470 		break;
2471 	case OCS_SCSI_STATUS_CHECK_RESPONSE:
2472 		if (rsp->response_data_length == 0) {
2473 			ocs_log_test(io->ocs, "check response without data?!?\n");
2474 			rc = -1;
2475 			break;
2476 		}
2477 
2478 		if (rsp->response_data[3] != 0) {
2479 			ocs_log_test(io->ocs, "TMF status %08x\n",
2480 				be32toh(*((uint32_t *)rsp->response_data)));
2481 			rc = -1;
2482 			break;
2483 		}
2484 		break;
2485 	default:
2486 		ocs_log_test(io->ocs, "status=%#x\n", scsi_status);
2487 		rc = -1;
2488 	}
2489 
2490 	ocs_scsi_io_free(io);
2491 
2492 	return rc;
2493 }
2494 
2495 /**
2496  * @brief lookup target resource structure
2497  *
2498  * Arbitrarily support
2499  *  - wildcard target ID + LU
2500  *  - 0 target ID + non-wildcard LU
2501  *
2502  * @param ocs the driver instance's software context
2503  * @param ccb_h pointer to the CCB header
2504  * @param status returned status value
2505  *
2506  * @return pointer to the target resource, NULL if none available (e.g. if LU
2507  * 	   is not enabled)
2508  */
2509 static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *fcp,
2510 				struct ccb_hdr *ccb_h, uint32_t *status)
2511 {
2512 	target_id_t	tid = ccb_h->target_id;
2513 	lun_id_t	lun = ccb_h->target_lun;
2514 
2515 	if (CAM_TARGET_WILDCARD == tid) {
2516 		if (CAM_LUN_WILDCARD != lun) {
2517 			*status = CAM_LUN_INVALID;
2518 			return NULL;
2519 		}
2520 		return &fcp->targ_rsrc_wildcard;
2521 	} else {
2522 		if (lun < OCS_MAX_LUN) {
2523 			return &fcp->targ_rsrc[lun];
2524 		} else {
2525 			*status = CAM_LUN_INVALID;
2526 			return NULL;
2527 		}
2528 	}
2529 
2530 }
2531 
2532 static int32_t
2533 ocs_tgt_resource_abort(struct ocs_softc *ocs, ocs_tgt_resource_t *trsrc)
2534 {
2535 	union ccb *ccb = NULL;
2536 	uint32_t	count;
2537 
2538 	count = 0;
2539 	do {
2540 		ccb = (union ccb *)STAILQ_FIRST(&trsrc->atio);
2541 		if (ccb) {
2542 			STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe);
2543 			ccb->ccb_h.status = CAM_REQ_ABORTED;
2544 			xpt_done(ccb);
2545 			count++;
2546 		}
2547 	} while (ccb);
2548 
2549 	count = 0;
2550 	do {
2551 		ccb = (union ccb *)STAILQ_FIRST(&trsrc->inot);
2552 		if (ccb) {
2553 			STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe);
2554 			ccb->ccb_h.status = CAM_REQ_ABORTED;
2555 			xpt_done(ccb);
2556 			count++;
2557 		}
2558 	} while (ccb);
2559 
2560 	return 0;
2561 }
2562 
2563 static void
2564 ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb)
2565 {
2566 
2567 	ocs_io_t	*aio = NULL;
2568 	ocs_tgt_resource_t *trsrc = NULL;
2569 	uint32_t	status = CAM_REQ_INVALID;
2570 	struct ccb_hdr *cur = NULL;
2571 	union ccb *accb = ccb->cab.abort_ccb;
2572 
2573 	int bus = cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path));
2574 	ocs_fcport *fcp = FCPORT(ocs, bus);
2575 
2576 	trsrc = ocs_tgt_resource_get(fcp, &accb->ccb_h, &status);
2577 	if (trsrc != NULL) {
2578 		STAILQ_FOREACH(cur, &trsrc->atio, sim_links.stqe) {
2579 			if (cur != &accb->ccb_h)
2580 				continue;
2581 
2582 			STAILQ_REMOVE(&trsrc->atio, cur, ccb_hdr,
2583 							sim_links.stqe);
2584 			accb->ccb_h.status = CAM_REQ_ABORTED;
2585 			xpt_done(accb);
2586 			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2587 			return;
2588 		}
2589 	}
2590 
2591 	/* if the ATIO has a valid IO pointer, CAM is telling
2592 	 * the driver that the ATIO (which represents the entire
2593 	 * exchange) has been aborted. */
2594 
2595 	aio = accb->ccb_h.ccb_io_ptr;
2596 	if (aio == NULL) {
2597 		ccb->ccb_h.status = CAM_UA_ABORT;
2598 		return;
2599 	}
2600 
2601 	device_printf(ocs->dev,
2602 			"%s: XPT_ABORT ATIO state=%d tag=%#x"
2603 			" xid=%#x flags=%#x\n",	__func__,
2604 			aio->tgt_io.state, aio->tag,
2605 			aio->init_task_tag, aio->tgt_io.flags);
2606 	/* Expectations are:
2607 	 *  - abort task was received
2608 	 *  - already aborted IO in the DEVICE
2609 	 *  - already received NOTIFY ACKNOWLEDGE */
2610 
2611 	if ((aio->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) == 0) {
2612 		device_printf(ocs->dev,	"%s: abort not received or io completed \n", __func__);
2613 		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2614 		return;
2615 	}
2616 
2617 	aio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM;
2618 	ocs_target_io_free(aio);
2619 	ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2620 
2621 	return;
2622 }
2623 
2624 static void
2625 ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb)
2626 {
2627 	ocs_tgt_resource_t *trsrc = NULL;
2628 	uint32_t	status = CAM_REQ_INVALID;
2629 	struct ccb_hdr *cur = NULL;
2630 	union ccb *accb = ccb->cab.abort_ccb;
2631 
2632 	int bus = cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path));
2633 	ocs_fcport *fcp = FCPORT(ocs, bus);
2634 
2635 	trsrc = ocs_tgt_resource_get(fcp, &accb->ccb_h, &status);
2636 	if (trsrc) {
2637 		STAILQ_FOREACH(cur, &trsrc->inot, sim_links.stqe) {
2638 			if (cur != &accb->ccb_h)
2639 				continue;
2640 
2641 			STAILQ_REMOVE(&trsrc->inot, cur, ccb_hdr,
2642 							sim_links.stqe);
2643 			accb->ccb_h.status = CAM_REQ_ABORTED;
2644 			xpt_done(accb);
2645 			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2646 			return;
2647 		}
2648 	}
2649 
2650 	ocs_set_ccb_status(ccb, CAM_UA_ABORT);
2651 	return;
2652 }
2653 
2654 static uint32_t
2655 ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb)
2656 {
2657 
2658 	ocs_node_t	*node = NULL;
2659 	ocs_io_t	*io = NULL;
2660 	int32_t		rc = 0;
2661 	struct ccb_scsiio *csio = &accb->csio;
2662 
2663 	ocs_fcport *fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((accb)->ccb_h.path)));
2664 	node = ocs_node_get_instance(ocs, fcp->tgt[accb->ccb_h.target_id].node_id);
2665 	if (node == NULL) {
2666 		device_printf(ocs->dev, "%s: no device %d\n",
2667 				__func__, accb->ccb_h.target_id);
2668 		ocs_set_ccb_status(accb, CAM_DEV_NOT_THERE);
2669 		xpt_done(accb);
2670 		return (-1);
2671 	}
2672 
2673 	io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
2674 	if (io == NULL) {
2675 		device_printf(ocs->dev,
2676 				"%s: unable to alloc IO\n", __func__);
2677 		ocs_set_ccb_status(accb, CAM_REQ_CMP_ERR);
2678 		xpt_done(accb);
2679 		return (-1);
2680 	}
2681 
2682 	rc = ocs_scsi_send_tmf(node, io,
2683 			(ocs_io_t *)csio->ccb_h.ccb_io_ptr,
2684 			accb->ccb_h.target_lun,
2685 			OCS_SCSI_TMF_ABORT_TASK,
2686 			NULL, 0, 0,
2687 			ocs_initiator_tmf_cb, NULL/*arg*/);
2688 
2689 	return rc;
2690 }
2691 
2692 void
2693 ocs_scsi_ini_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
2694 {
2695 	switch(type) {
2696 	case OCS_SCSI_DDUMP_DEVICE: {
2697 		//ocs_t *ocs = obj;
2698 		break;
2699 	}
2700 	case OCS_SCSI_DDUMP_DOMAIN: {
2701 		//ocs_domain_t *domain = obj;
2702 		break;
2703 	}
2704 	case OCS_SCSI_DDUMP_SPORT: {
2705 		//ocs_sport_t *sport = obj;
2706 		break;
2707 	}
2708 	case OCS_SCSI_DDUMP_NODE: {
2709 		//ocs_node_t *node = obj;
2710 		break;
2711 	}
2712 	case OCS_SCSI_DDUMP_IO: {
2713 		//ocs_io_t *io = obj;
2714 		break;
2715 	}
2716 	default: {
2717 		break;
2718 	}
2719 	}
2720 }
2721 
2722 void
2723 ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
2724 {
2725 	switch(type) {
2726 	case OCS_SCSI_DDUMP_DEVICE: {
2727 		//ocs_t *ocs = obj;
2728 		break;
2729 	}
2730 	case OCS_SCSI_DDUMP_DOMAIN: {
2731 		//ocs_domain_t *domain = obj;
2732 		break;
2733 	}
2734 	case OCS_SCSI_DDUMP_SPORT: {
2735 		//ocs_sport_t *sport = obj;
2736 		break;
2737 	}
2738 	case OCS_SCSI_DDUMP_NODE: {
2739 		//ocs_node_t *node = obj;
2740 		break;
2741 	}
2742 	case OCS_SCSI_DDUMP_IO: {
2743 		ocs_io_t *io = obj;
2744 		char *state_str = NULL;
2745 
2746 		switch (io->tgt_io.state) {
2747 		case OCS_CAM_IO_FREE:
2748 			state_str = "FREE";
2749 			break;
2750 		case OCS_CAM_IO_COMMAND:
2751 			state_str = "COMMAND";
2752 			break;
2753 		case OCS_CAM_IO_DATA:
2754 			state_str = "DATA";
2755 			break;
2756 		case OCS_CAM_IO_DATA_DONE:
2757 			state_str = "DATA_DONE";
2758 			break;
2759 		case OCS_CAM_IO_RESP:
2760 			state_str = "RESP";
2761 			break;
2762 		default:
2763 			state_str = "xxx BAD xxx";
2764 		}
2765 		ocs_ddump_value(textbuf, "cam_st", "%s", state_str);
2766 		if (io->tgt_io.app) {
2767 			ocs_ddump_value(textbuf, "cam_flags", "%#x",
2768 				((union ccb *)(io->tgt_io.app))->ccb_h.flags);
2769 			ocs_ddump_value(textbuf, "cam_status", "%#x",
2770 				((union ccb *)(io->tgt_io.app))->ccb_h.status);
2771 		}
2772 
2773 		break;
2774 	}
2775 	default: {
2776 		break;
2777 	}
2778 	}
2779 }
2780 
2781 int32_t ocs_scsi_get_block_vaddr(ocs_io_t *io, uint64_t blocknumber,
2782 				ocs_scsi_vaddr_len_t addrlen[],
2783 				uint32_t max_addrlen, void **dif_vaddr)
2784 {
2785 	return -1;
2786 }
2787 
2788 uint32_t
2789 ocs_get_crn(ocs_node_t *node, uint8_t *crn, uint64_t lun)
2790 {
2791 	uint32_t idx;
2792 	struct ocs_lun_crn *lcrn = NULL;
2793 	idx = lun % OCS_MAX_LUN;
2794 
2795 	lcrn = node->ini_node.lun_crn[idx];
2796 
2797 	if (lcrn == NULL) {
2798 		lcrn = ocs_malloc(node->ocs, sizeof(struct ocs_lun_crn),
2799 					M_ZERO|M_NOWAIT);
2800 		if (lcrn == NULL) {
2801 			return (1);
2802 		}
2803 
2804 		lcrn->lun = lun;
2805 		node->ini_node.lun_crn[idx] = lcrn;
2806 	}
2807 
2808 	if (lcrn->lun != lun) {
2809 		return (1);
2810 	}
2811 
2812 	if (lcrn->crnseed == 0)
2813 		lcrn->crnseed = 1;
2814 
2815 	*crn = lcrn->crnseed++;
2816 	return (0);
2817 }
2818 
2819 void
2820 ocs_del_crn(ocs_node_t *node)
2821 {
2822 	uint32_t i;
2823 	struct ocs_lun_crn *lcrn = NULL;
2824 
2825 	for(i = 0; i < OCS_MAX_LUN; i++) {
2826 		lcrn = node->ini_node.lun_crn[i];
2827 		if (lcrn) {
2828 			ocs_free(node->ocs, lcrn, sizeof(*lcrn));
2829 		}
2830 	}
2831 
2832 	return;
2833 }
2834 
2835 void
2836 ocs_reset_crn(ocs_node_t *node, uint64_t lun)
2837 {
2838 	uint32_t idx;
2839 	struct ocs_lun_crn *lcrn = NULL;
2840 	idx = lun % OCS_MAX_LUN;
2841 
2842 	lcrn = node->ini_node.lun_crn[idx];
2843 	if (lcrn)
2844 		lcrn->crnseed = 0;
2845 
2846 	return;
2847 }
2848