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