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