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