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