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
53typedef 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
60static void ocs_action(struct cam_sim *, union ccb *);
61static void ocs_poll(struct cam_sim *);
62
63static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *,
64					struct ccb_hdr *, uint32_t *);
65static int32_t ocs_tgt_resource_abort(struct ocs_softc *, ocs_tgt_resource_t *);
66static uint32_t ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb);
67static void ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb);
68static void ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb);
69static int32_t ocs_target_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
70static int32_t ocs_io_abort_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
71static int32_t ocs_task_set_full_or_busy(ocs_io_t *io);
72static int32_t ocs_initiator_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e,
73		ocs_scsi_cmd_resp_t *, uint32_t, void *);
74static uint32_t
75ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role);
76
77static void ocs_ldt(void *arg);
78static void ocs_ldt_task(void *arg, int pending);
79static void ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt);
80uint32_t ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp);
81uint32_t ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id);
82
83int32_t ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node);
84
85static 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
91static 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
101static int32_t
102ocs_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
146static int32_t
147ocs_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
178int32_t
179ocs_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
207detach_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
220int32_t
221ocs_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 */
251int32_t
252ocs_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 */
272int32_t
273ocs_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 */
301int32_t
302ocs_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 */
321void
322ocs_scsi_tgt_del_domain(ocs_domain_t *domain)
323{
324}
325
326
327/**
328 * @ingroup scsi_api_target
329 * @brief accept new sli port (sport) notification
330 *
331 * Called by base drive when new sport is discovered.  A target-server
332 * will use this call to prepare for new remote node notifications
333 * arising from ocs_scsi_new_initiator().
334 *
335 * The domain context has an element <b>ocs_scsi_tgt_sport_t tgt_sport</b>
336 * which is declared by the target-server code and is used for
337 * target-server private data.
338 *
339 * This function will only be called if the base-driver has been enabled for
340 * target capability.
341 *
342 * Note that this call is made to target-server backends,
343 * the ocs_scsi_tgt_new_domain() is called to initiator-client backends.
344 *
345 * @param sport pointer to SLI port
346 *
347 * @return returns 0 for success, a negative error code value for failure.
348 */
349int32_t
350ocs_scsi_tgt_new_sport(ocs_sport_t *sport)
351{
352	ocs_t *ocs = sport->ocs;
353
354	if(!sport->is_vport) {
355		sport->tgt_data = FCPORT(ocs, 0);
356	}
357
358	return 0;
359}
360
361/**
362 * @ingroup scsi_api_target
363 * @brief accept SLI port gone notification
364 *
365 * Called by base-driver when a sport goes away.  A target-server will
366 * use this call to clean up all sport scoped resources.
367 *
368 * Note that this call is made to target-server backends,
369 * the ocs_scsi_ini_del_sport() is called to initiator-client backends.
370 *
371 * @param sport pointer to SLI port
372 *
373 * @return returns 0 for success, a negative error code value for failure.
374 */
375void
376ocs_scsi_tgt_del_sport(ocs_sport_t *sport)
377{
378	return;
379}
380
381/**
382 * @ingroup scsi_api_target
383 * @brief receive notification of a new SCSI initiator node
384 *
385 * Sent by base driver to notify a target-server of the presense of a new
386 * remote initiator.   The target-server may use this call to prepare for
387 * inbound IO from this node.
388 *
389 * The ocs_node_t structure has and elment of type ocs_scsi_tgt_node_t named
390 * tgt_node that is declared and used by a target-server for private
391 * information.
392 *
393 * This function is only called if the target capability is enabled in driver.
394 *
395 * @param node pointer to new remote initiator node
396 *
397 * @return returns 0 for success, a negative error code value for failure.
398 *
399 * @note
400 */
401int32_t
402ocs_scsi_new_initiator(ocs_node_t *node)
403{
404	ocs_t	*ocs = node->ocs;
405	struct ac_contract ac;
406	struct ac_device_changed *adc;
407
408	ocs_fcport	*fcp = NULL;
409
410	fcp = node->sport->tgt_data;
411	if (fcp == NULL) {
412		ocs_log_err(ocs, "FCP is NULL \n");
413		return 1;
414	}
415
416	/*
417	 * Update the IO watermark by decrementing it by the
418	 * number of IOs reserved for each initiator.
419	 */
420	atomic_subtract_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
421
422	ac.contract_number = AC_CONTRACT_DEV_CHG;
423	adc = (struct ac_device_changed *) ac.contract_data;
424	adc->wwpn = ocs_node_get_wwpn(node);
425	adc->port = node->rnode.fc_id;
426	adc->target = node->instance_index;
427	adc->arrived = 1;
428	xpt_async(AC_CONTRACT, fcp->path, &ac);
429
430	return 0;
431}
432
433/**
434 * @ingroup scsi_api_target
435 * @brief validate new initiator
436 *
437 * Sent by base driver to validate a remote initiatiator.   The target-server
438 * returns TRUE if this initiator should be accepted.
439 *
440 * This function is only called if the target capability is enabled in driver.
441 *
442 * @param node pointer to remote initiator node to validate
443 *
444 * @return TRUE if initiator should be accepted, FALSE if it should be rejected
445 *
446 * @note
447 */
448
449int32_t
450ocs_scsi_validate_initiator(ocs_node_t *node)
451{
452	return 1;
453}
454
455/**
456 * @ingroup scsi_api_target
457 * @brief Delete a SCSI initiator node
458 *
459 * Sent by base driver to notify a target-server that a remote initiator
460 * is now gone. The base driver will have terminated all outstanding IOs
461 * and the target-server will receive appropriate completions.
462 *
463 * This function is only called if the base driver is enabled for
464 * target capability.
465 *
466 * @param node pointer node being deleted
467 * @param reason Reason why initiator is gone.
468 *
469 * @return OCS_SCSI_CALL_COMPLETE to indicate that all work was completed
470 *
471 * @note
472 */
473int32_t
474ocs_scsi_del_initiator(ocs_node_t *node, ocs_scsi_del_initiator_reason_e reason)
475{
476	ocs_t	*ocs = node->ocs;
477
478	struct ac_contract ac;
479	struct ac_device_changed *adc;
480	ocs_fcport	*fcp = NULL;
481
482	fcp = node->sport->tgt_data;
483	if (fcp == NULL) {
484		ocs_log_err(ocs, "FCP is NULL \n");
485		return 1;
486	}
487
488	ac.contract_number = AC_CONTRACT_DEV_CHG;
489	adc = (struct ac_device_changed *) ac.contract_data;
490	adc->wwpn = ocs_node_get_wwpn(node);
491	adc->port = node->rnode.fc_id;
492	adc->target = node->instance_index;
493	adc->arrived = 0;
494	xpt_async(AC_CONTRACT, fcp->path, &ac);
495
496
497	if (reason == OCS_SCSI_INITIATOR_MISSING) {
498		return OCS_SCSI_CALL_COMPLETE;
499	}
500
501	/*
502	 * Update the IO watermark by incrementing it by the
503	 * number of IOs reserved for each initiator.
504	 */
505	atomic_add_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
506
507	return OCS_SCSI_CALL_COMPLETE;
508}
509
510/**
511 * @ingroup scsi_api_target
512 * @brief receive FCP SCSI Command
513 *
514 * Called by the base driver when a new SCSI command has been received.   The
515 * target-server will process the command, and issue data and/or response phase
516 * requests to the base driver.
517 *
518 * The IO context (ocs_io_t) structure has and element of type
519 * ocs_scsi_tgt_io_t named tgt_io that is declared and used by
520 * a target-server for private information.
521 *
522 * @param io pointer to IO context
523 * @param lun LUN for this IO
524 * @param cdb pointer to SCSI CDB
525 * @param cdb_len length of CDB in bytes
526 * @param flags command flags
527 *
528 * @return returns 0 for success, a negative error code value for failure.
529 */
530int32_t ocs_scsi_recv_cmd(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
531				uint32_t cdb_len, uint32_t flags)
532{
533	ocs_t *ocs = io->ocs;
534	struct ccb_accept_tio *atio = NULL;
535	ocs_node_t	*node = io->node;
536	ocs_tgt_resource_t *trsrc = NULL;
537	int32_t		rc = -1;
538	ocs_fcport	*fcp = NULL;
539
540	fcp = node->sport->tgt_data;
541	if (fcp == NULL) {
542		ocs_log_err(ocs, "FCP is NULL \n");
543		return 1;
544	}
545
546	atomic_add_acq_32(&ocs->io_in_use, 1);
547
548	/* set target io timeout */
549	io->timeout = ocs->target_io_timer_sec;
550
551	if (ocs->enable_task_set_full &&
552		(ocs->io_in_use >= ocs->io_high_watermark)) {
553		return ocs_task_set_full_or_busy(io);
554	} else {
555		atomic_store_rel_32(&io->node->tgt_node.busy_sent, FALSE);
556	}
557
558	if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
559		trsrc = &fcp->targ_rsrc[lun];
560	} else if (fcp->targ_rsrc_wildcard.enabled) {
561		trsrc = &fcp->targ_rsrc_wildcard;
562	}
563
564	if (trsrc) {
565		atio = (struct ccb_accept_tio *)STAILQ_FIRST(&trsrc->atio);
566	}
567
568	if (atio) {
569
570		STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe);
571
572		atio->ccb_h.status = CAM_CDB_RECVD;
573		atio->ccb_h.target_lun = lun;
574		atio->sense_len = 0;
575
576		atio->init_id = node->instance_index;
577		atio->tag_id = io->tag;
578		atio->ccb_h.ccb_io_ptr = io;
579
580		if (flags & OCS_SCSI_CMD_SIMPLE)
581			atio->tag_action = MSG_SIMPLE_Q_TAG;
582		else if (flags & OCS_SCSI_CMD_HEAD_OF_QUEUE)
583			atio->tag_action = MSG_HEAD_OF_Q_TAG;
584		else if (flags & OCS_SCSI_CMD_ORDERED)
585			atio->tag_action = MSG_ORDERED_Q_TAG;
586		else if (flags & OCS_SCSI_CMD_ACA)
587			atio->tag_action = MSG_ACA_TASK;
588		else
589			atio->tag_action = CAM_TAG_ACTION_NONE;
590		atio->priority = (flags & OCS_SCSI_PRIORITY_MASK) >>
591		    OCS_SCSI_PRIORITY_SHIFT;
592
593		atio->cdb_len = cdb_len;
594		ocs_memcpy(atio->cdb_io.cdb_bytes, cdb, cdb_len);
595
596		io->tgt_io.flags = 0;
597		io->tgt_io.state = OCS_CAM_IO_COMMAND;
598		io->tgt_io.lun = lun;
599
600		xpt_done((union ccb *)atio);
601
602		rc = 0;
603	} else {
604		device_printf(
605			ocs->dev, "%s: no ATIO for LUN %lx (en=%s) OX_ID %#x\n",
606			__func__, (unsigned long)lun,
607			trsrc ? (trsrc->enabled ? "T" : "F") : "X",
608			be16toh(io->init_task_tag));
609
610		io->tgt_io.state = OCS_CAM_IO_MAX;
611		ocs_target_io_free(io);
612	}
613
614	return rc;
615}
616
617/**
618 * @ingroup scsi_api_target
619 * @brief receive FCP SCSI Command with first burst data.
620 *
621 * Receive a new FCP SCSI command from the base driver with first burst data.
622 *
623 * @param io pointer to IO context
624 * @param lun LUN for this IO
625 * @param cdb pointer to SCSI CDB
626 * @param cdb_len length of CDB in bytes
627 * @param flags command flags
628 * @param first_burst_buffers first burst buffers
629 * @param first_burst_buffer_count The number of bytes received in the first burst
630 *
631 * @return returns 0 for success, a negative error code value for failure.
632 */
633int32_t ocs_scsi_recv_cmd_first_burst(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
634		 			uint32_t cdb_len, uint32_t flags,
635					ocs_dma_t first_burst_buffers[],
636					uint32_t first_burst_buffer_count)
637{
638	return -1;
639}
640
641/**
642 * @ingroup scsi_api_target
643 * @brief receive a TMF command IO
644 *
645 * Called by the base driver when a SCSI TMF command has been received.   The
646 * target-server will process the command, aborting commands as needed, and post
647 * a response using ocs_scsi_send_resp()
648 *
649 * The IO context (ocs_io_t) structure has and element of type ocs_scsi_tgt_io_t named
650 * tgt_io that is declared and used by a target-server for private information.
651 *
652 * If the target-server walks the nodes active_ios linked list, and starts IO
653 * abort processing, the code <b>must</b> be sure not to abort the IO passed into the
654 * ocs_scsi_recv_tmf() command.
655 *
656 * @param tmfio pointer to IO context
657 * @param lun logical unit value
658 * @param cmd command request
659 * @param abortio pointer to IO object to abort for TASK_ABORT (NULL for all other TMF)
660 * @param flags flags
661 *
662 * @return returns 0 for success, a negative error code value for failure.
663 */
664int32_t ocs_scsi_recv_tmf(ocs_io_t *tmfio, uint64_t lun, ocs_scsi_tmf_cmd_e cmd,
665				ocs_io_t *abortio, uint32_t flags)
666{
667	ocs_t *ocs = tmfio->ocs;
668	ocs_node_t *node = tmfio->node;
669	ocs_tgt_resource_t *trsrc = NULL;
670	struct ccb_immediate_notify *inot = NULL;
671	int32_t		rc = -1;
672	ocs_fcport	*fcp = NULL;
673
674	fcp = node->sport->tgt_data;
675	if (fcp == NULL) {
676		ocs_log_err(ocs, "FCP is NULL \n");
677		return 1;
678	}
679
680	if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
681		trsrc = &fcp->targ_rsrc[lun];
682	} else if (fcp->targ_rsrc_wildcard.enabled) {
683		trsrc = &fcp->targ_rsrc_wildcard;
684	}
685
686	device_printf(tmfio->ocs->dev, "%s: io=%p cmd=%#x LU=%lx en=%s\n",
687			__func__, tmfio, cmd, (unsigned long)lun,
688			trsrc ? (trsrc->enabled ? "T" : "F") : "X");
689	if (trsrc) {
690		inot = (struct ccb_immediate_notify *)STAILQ_FIRST(&trsrc->inot);
691	}
692
693	if (!inot) {
694		device_printf(
695			ocs->dev, "%s: no INOT for LUN %llx (en=%s) OX_ID %#x\n",
696			__func__, (unsigned long long)lun, trsrc ? (trsrc->enabled ? "T" : "F") : "X",
697			be16toh(tmfio->init_task_tag));
698
699		if (abortio) {
700			ocs_scsi_io_complete(abortio);
701		}
702		ocs_scsi_io_complete(tmfio);
703		goto ocs_scsi_recv_tmf_out;
704	}
705
706
707	tmfio->tgt_io.app = abortio;
708
709	STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe);
710
711	inot->tag_id = tmfio->tag;
712	inot->seq_id = tmfio->tag;
713
714	if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
715		inot->initiator_id = node->instance_index;
716	} else {
717		inot->initiator_id = CAM_TARGET_WILDCARD;
718	}
719
720	inot->ccb_h.status = CAM_MESSAGE_RECV;
721	inot->ccb_h.target_lun = lun;
722
723	switch (cmd) {
724	case OCS_SCSI_TMF_ABORT_TASK:
725		inot->arg = MSG_ABORT_TASK;
726		inot->seq_id = abortio->tag;
727		device_printf(ocs->dev, "%s: ABTS IO.%#x st=%#x\n",
728			__func__, abortio->tag,	abortio->tgt_io.state);
729		abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_RECV;
730		abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_NOTIFY;
731		break;
732	case OCS_SCSI_TMF_QUERY_TASK_SET:
733		device_printf(ocs->dev,
734			"%s: OCS_SCSI_TMF_QUERY_TASK_SET not supported\n",
735				__func__);
736		STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe);
737		ocs_scsi_io_complete(tmfio);
738		goto ocs_scsi_recv_tmf_out;
739		break;
740	case OCS_SCSI_TMF_ABORT_TASK_SET:
741		inot->arg = MSG_ABORT_TASK_SET;
742		break;
743	case OCS_SCSI_TMF_CLEAR_TASK_SET:
744		inot->arg = MSG_CLEAR_TASK_SET;
745		break;
746	case OCS_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT:
747		inot->arg = MSG_QUERY_ASYNC_EVENT;
748		break;
749	case OCS_SCSI_TMF_LOGICAL_UNIT_RESET:
750		inot->arg = MSG_LOGICAL_UNIT_RESET;
751		break;
752	case OCS_SCSI_TMF_CLEAR_ACA:
753		inot->arg = MSG_CLEAR_ACA;
754		break;
755	case OCS_SCSI_TMF_TARGET_RESET:
756		inot->arg = MSG_TARGET_RESET;
757		break;
758	default:
759		device_printf(ocs->dev, "%s: unsupported TMF %#x\n",
760							 __func__, cmd);
761		STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe);
762		goto ocs_scsi_recv_tmf_out;
763	}
764
765	rc = 0;
766
767	xpt_print(inot->ccb_h.path, "%s: func=%#x stat=%#x id=%#x lun=%#x"
768			" flags=%#x tag=%#x seq=%#x ini=%#x arg=%#x\n",
769			__func__, inot->ccb_h.func_code, inot->ccb_h.status,
770			inot->ccb_h.target_id,
771			(unsigned int)inot->ccb_h.target_lun, inot->ccb_h.flags,
772			inot->tag_id, inot->seq_id, inot->initiator_id,
773			inot->arg);
774	xpt_done((union ccb *)inot);
775
776	if (abortio) {
777		abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_DEV;
778		rc = ocs_scsi_tgt_abort_io(abortio, ocs_io_abort_cb, tmfio);
779	}
780
781ocs_scsi_recv_tmf_out:
782	return rc;
783}
784
785/**
786 * @ingroup scsi_api_initiator
787 * @brief Initializes any initiator fields on the ocs structure.
788 *
789 * Called by OS initialization code when a new device is discovered.
790 *
791 * @param ocs pointer to ocs
792 *
793 * @return returns 0 for success, a negative error code value for failure.
794 */
795int32_t
796ocs_scsi_ini_new_device(ocs_t *ocs)
797{
798
799	return 0;
800}
801
802/**
803 * @ingroup scsi_api_initiator
804 * @brief Tears down initiator members of ocs structure.
805 *
806 * Called by OS code when device is removed.
807 *
808 * @param ocs pointer to ocs
809 *
810 * @return returns 0 for success, a negative error code value for failure.
811 */
812
813int32_t
814ocs_scsi_ini_del_device(ocs_t *ocs)
815{
816
817	return 0;
818}
819
820
821/**
822 * @ingroup scsi_api_initiator
823 * @brief accept new domain notification
824 *
825 * Called by base drive when new domain is discovered.  An initiator-client
826 * will accept this call to prepare for new remote node notifications
827 * arising from ocs_scsi_new_target().
828 *
829 * The domain context has the element <b>ocs_scsi_ini_domain_t ini_domain</b>
830 * which is declared by the initiator-client code and is used for
831 * initiator-client private data.
832 *
833 * This function will only be called if the base-driver has been enabled for
834 * initiator capability.
835 *
836 * Note that this call is made to initiator-client backends,
837 * the ocs_scsi_tgt_new_domain() function is called to target-server backends.
838 *
839 * @param domain pointer to domain
840 *
841 * @return returns 0 for success, a negative error code value for failure.
842 */
843int32_t
844ocs_scsi_ini_new_domain(ocs_domain_t *domain)
845{
846	return 0;
847}
848
849/**
850 * @ingroup scsi_api_initiator
851 * @brief accept domain lost notification
852 *
853 * Called by base-driver when a domain goes away.  An initiator-client will
854 * use this call to clean up all domain scoped resources.
855 *
856 * This function will only be called if the base-driver has been enabled for
857 * initiator capability.
858 *
859 * Note that this call is made to initiator-client backends,
860 * the ocs_scsi_tgt_del_domain() function is called to target-server backends.
861 *
862 * @param domain pointer to domain
863 *
864 * @return returns 0 for success, a negative error code value for failure.
865 */
866void
867ocs_scsi_ini_del_domain(ocs_domain_t *domain)
868{
869}
870
871/**
872 * @ingroup scsi_api_initiator
873 * @brief accept new sli port notification
874 *
875 * Called by base drive when new sli port (sport) is discovered.
876 * A target-server will use this call to prepare for new remote node
877 * notifications arising from ocs_scsi_new_initiator().
878 *
879 * This function will only be called if the base-driver has been enabled for
880 * target capability.
881 *
882 * Note that this call is made to target-server backends,
883 * the ocs_scsi_ini_new_sport() function is called to initiator-client backends.
884 *
885 * @param sport pointer to sport
886 *
887 * @return returns 0 for success, a negative error code value for failure.
888 */
889int32_t
890ocs_scsi_ini_new_sport(ocs_sport_t *sport)
891{
892	ocs_t *ocs = sport->ocs;
893	ocs_fcport *fcp = FCPORT(ocs, 0);
894
895	if (!sport->is_vport) {
896		sport->tgt_data = fcp;
897		fcp->fc_id = sport->fc_id;
898	}
899
900	return 0;
901}
902
903/**
904 * @ingroup scsi_api_initiator
905 * @brief accept sli port gone notification
906 *
907 * Called by base-driver when a sport goes away.  A target-server will
908 * use this call to clean up all sport scoped resources.
909 *
910 * Note that this call is made to target-server backends,
911 * the ocs_scsi_ini_del_sport() function is called to initiator-client backends.
912 *
913 * @param sport pointer to SLI port
914 *
915 * @return returns 0 for success, a negative error code value for failure.
916 */
917void
918ocs_scsi_ini_del_sport(ocs_sport_t *sport)
919{
920	ocs_t *ocs = sport->ocs;
921	ocs_fcport *fcp = FCPORT(ocs, 0);
922
923	if (!sport->is_vport) {
924		fcp->fc_id = 0;
925	}
926}
927
928void
929ocs_scsi_sport_deleted(ocs_sport_t *sport)
930{
931	ocs_t *ocs = sport->ocs;
932	ocs_fcport *fcp = NULL;
933
934	ocs_xport_stats_t value;
935
936	if (!sport->is_vport) {
937		return;
938	}
939
940	fcp = sport->tgt_data;
941
942	ocs_xport_status(ocs->xport, OCS_XPORT_PORT_STATUS, &value);
943
944	if (value.value == 0) {
945		ocs_log_debug(ocs, "PORT offline,.. skipping\n");
946		return;
947	}
948
949	if ((fcp->role != KNOB_ROLE_NONE)) {
950		if(fcp->vport->sport != NULL) {
951			ocs_log_debug(ocs,"sport is not NULL, skipping\n");
952			return;
953		}
954
955		ocs_sport_vport_alloc(ocs->domain, fcp->vport);
956		return;
957	}
958
959}
960
961int32_t
962ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node)
963{
964	ocs_fc_target_t *tgt = NULL;
965	uint32_t i;
966
967	for (i = 0; i < OCS_MAX_TARGETS; i++) {
968		tgt = &fcp->tgt[i];
969
970		if (tgt->state == OCS_TGT_STATE_NONE)
971			continue;
972
973		if (ocs_node_get_wwpn(node) == tgt->wwpn) {
974			return i;
975		}
976	}
977
978	return -1;
979}
980
981/**
982 * @ingroup scsi_api_initiator
983 * @brief receive notification of a new SCSI target node
984 *
985 * Sent by base driver to notify an initiator-client of the presense of a new
986 * remote target.   The initiator-server may use this call to prepare for
987 * inbound IO from this node.
988 *
989 * This function is only called if the base driver is enabled for
990 * initiator capability.
991 *
992 * @param node pointer to new remote initiator node
993 *
994 * @return none
995 *
996 * @note
997 */
998
999uint32_t
1000ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id)
1001{
1002	ocs_fc_target_t *tgt = NULL;
1003
1004	tgt = &fcp->tgt[tgt_id];
1005
1006	tgt->node_id = node->instance_index;
1007	tgt->state = OCS_TGT_STATE_VALID;
1008
1009	tgt->port_id = node->rnode.fc_id;
1010	tgt->wwpn = ocs_node_get_wwpn(node);
1011	tgt->wwnn = ocs_node_get_wwnn(node);
1012	return 0;
1013}
1014
1015uint32_t
1016ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp)
1017{
1018	uint32_t i;
1019
1020	struct ocs_softc *ocs = node->ocs;
1021	union ccb *ccb = NULL;
1022	for (i = 0; i < OCS_MAX_TARGETS; i++) {
1023		if (fcp->tgt[i].state == OCS_TGT_STATE_NONE)
1024			break;
1025	}
1026
1027	if (NULL == (ccb = xpt_alloc_ccb_nowait())) {
1028		device_printf(ocs->dev, "%s: ccb allocation failed\n", __func__);
1029		return -1;
1030	}
1031
1032	if (CAM_REQ_CMP != xpt_create_path(&ccb->ccb_h.path, xpt_periph,
1033				cam_sim_path(fcp->sim),
1034				i, CAM_LUN_WILDCARD)) {
1035		device_printf(
1036			ocs->dev, "%s: target path creation failed\n", __func__);
1037		xpt_free_ccb(ccb);
1038		return -1;
1039	}
1040
1041	ocs_update_tgt(node, fcp, i);
1042	xpt_rescan(ccb);
1043	return 0;
1044}
1045
1046int32_t
1047ocs_scsi_new_target(ocs_node_t *node)
1048{
1049	ocs_fcport	*fcp = NULL;
1050	int32_t i;
1051
1052	fcp = node->sport->tgt_data;
1053	if (fcp == NULL) {
1054		printf("%s:FCP is NULL \n", __func__);
1055		return 0;
1056	}
1057
1058	i = ocs_tgt_find(fcp, node);
1059
1060	if (i < 0) {
1061		ocs_add_new_tgt(node, fcp);
1062		return 0;
1063	}
1064
1065	ocs_update_tgt(node, fcp, i);
1066	return 0;
1067}
1068
1069static void
1070ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt)
1071{
1072	struct cam_path *cpath = NULL;
1073
1074	if (!fcp->sim) {
1075		device_printf(ocs->dev, "%s: calling with NULL sim\n", __func__);
1076		return;
1077	}
1078
1079	if (CAM_REQ_CMP == xpt_create_path(&cpath, NULL, cam_sim_path(fcp->sim),
1080				tgt, CAM_LUN_WILDCARD)) {
1081		xpt_async(AC_LOST_DEVICE, cpath, NULL);
1082
1083		xpt_free_path(cpath);
1084	}
1085}
1086
1087/*
1088 * Device Lost Timer Function- when we have decided that a device was lost,
1089 * we wait a specific period of time prior to telling the OS about lost device.
1090 *
1091 * This timer function gets activated when the device was lost.
1092 * This function fires once a second and then scans the port database
1093 * for devices that are marked dead but still have a virtual target assigned.
1094 * We decrement a counter for that port database entry, and when it hits zero,
1095 * we tell the OS the device was lost. Timer will be stopped when the device
1096 * comes back active or removed from the OS.
1097 */
1098static void
1099ocs_ldt(void *arg)
1100{
1101	ocs_fcport *fcp = arg;
1102	taskqueue_enqueue(taskqueue_thread, &fcp->ltask);
1103}
1104
1105static void
1106ocs_ldt_task(void *arg, int pending)
1107{
1108	ocs_fcport *fcp = arg;
1109	ocs_t	*ocs = fcp->ocs;
1110	int i, more_to_do = 0;
1111	ocs_fc_target_t *tgt = NULL;
1112
1113	for (i = 0; i < OCS_MAX_TARGETS; i++) {
1114		tgt = &fcp->tgt[i];
1115
1116		if (tgt->state != OCS_TGT_STATE_LOST) {
1117			continue;
1118		}
1119
1120		if ((tgt->gone_timer != 0) && (ocs->attached)){
1121			tgt->gone_timer -= 1;
1122			more_to_do++;
1123			continue;
1124		}
1125
1126		if (tgt->is_target) {
1127			tgt->is_target = 0;
1128			ocs_delete_target(ocs, fcp, i);
1129		}
1130
1131		tgt->state = OCS_TGT_STATE_NONE;
1132	}
1133
1134	if (more_to_do) {
1135		callout_reset(&fcp->ldt, hz, ocs_ldt, fcp);
1136	} else {
1137		callout_deactivate(&fcp->ldt);
1138	}
1139
1140}
1141
1142/**
1143 * @ingroup scsi_api_initiator
1144 * @brief Delete a SCSI target node
1145 *
1146 * Sent by base driver to notify a initiator-client that a remote target
1147 * is now gone. The base driver will have terminated all  outstanding IOs
1148 * and the initiator-client will receive appropriate completions.
1149 *
1150 * The ocs_node_t structure has and elment of type ocs_scsi_ini_node_t named
1151 * ini_node that is declared and used by a target-server for private
1152 * information.
1153 *
1154 * This function is only called if the base driver is enabled for
1155 * initiator capability.
1156 *
1157 * @param node pointer node being deleted
1158 * @param reason reason for deleting the target
1159 *
1160 * @return Returns OCS_SCSI_CALL_ASYNC if target delete is queued for async
1161 * completion and OCS_SCSI_CALL_COMPLETE if call completed or error.
1162 *
1163 * @note
1164 */
1165int32_t
1166ocs_scsi_del_target(ocs_node_t *node, ocs_scsi_del_target_reason_e reason)
1167{
1168	struct ocs_softc *ocs = node->ocs;
1169	ocs_fcport	*fcp = NULL;
1170	ocs_fc_target_t *tgt = NULL;
1171	uint32_t	tgt_id;
1172
1173	fcp = node->sport->tgt_data;
1174	if (fcp == NULL) {
1175		ocs_log_err(ocs,"FCP is NULL \n");
1176		return 0;
1177	}
1178
1179	tgt_id = ocs_tgt_find(fcp, node);
1180
1181	tgt = &fcp->tgt[tgt_id];
1182
1183	// IF in shutdown delete target.
1184	if(!ocs->attached) {
1185		ocs_delete_target(ocs, fcp, tgt_id);
1186	} else {
1187
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 */
1209int32_t
1210ocs_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 */
1224int32_t
1225ocs_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 */
1241int32_t
1242ocs_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 */
1256int32_t
1257ocs_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
1265static __inline void
1266ocs_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
1272static int32_t
1273ocs_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
1293static int32_t
1294ocs_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 */
1347static 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 */
1420static int32_t
1421ocs_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 */
1463static 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		}
1494
1495		csio->resid = rsp->residual;
1496		if (rsp->residual > 0) {
1497			uint32_t length = rsp->response_wire_length;
1498			/* underflow */
1499			if (csio->dxfer_len == (length + csio->resid)) {
1500				ccb_status = CAM_REQ_CMP;
1501			}
1502		} else if (rsp->residual < 0) {
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		ocs_set_ccb_status(ccb, ccb_status);
1524		csio->ccb_h.status |= CAM_DEV_QFRZN;
1525		xpt_freeze_devq(csio->ccb_h.path, 1);
1526
1527	} else {
1528		ccb_status = CAM_REQ_CMP;
1529	}
1530
1531	ocs_set_ccb_status(ccb, ccb_status);
1532
1533	ocs_scsi_io_free(io);
1534
1535	csio->ccb_h.ccb_io_ptr = NULL;
1536	csio->ccb_h.ccb_ocs_ptr = NULL;
1537	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1538
1539	xpt_done(ccb);
1540
1541	return 0;
1542}
1543
1544/**
1545 * @brief Load scatter-gather list entries into an IO
1546 *
1547 * This routine relies on the driver instance's software context pointer and
1548 * the IO object pointer having been already assigned to hooks in the CCB.
1549 * Although the routine does not return success/fail, callers can look at the
1550 * n_sge member to determine if the mapping failed (0 on failure).
1551 *
1552 * @param arg pointer to the CAM ccb for this IO
1553 * @param seg DMA address/length pairs
1554 * @param nseg number of DMA address/length pairs
1555 * @param error any errors while mapping the IO
1556 */
1557static void
1558ocs_scsi_dmamap_load(void *arg, bus_dma_segment_t *seg, int nseg, int error)
1559{
1560	ocs_dmamap_load_arg_t *sglarg = (ocs_dmamap_load_arg_t*) arg;
1561
1562	if (error) {
1563		printf("%s: seg=%p nseg=%d error=%d\n",
1564				__func__, seg, nseg, error);
1565		sglarg->rc = -1;
1566	} else {
1567		uint32_t i = 0;
1568		uint32_t c = 0;
1569
1570		if ((sglarg->sgl_count + nseg) > sglarg->sgl_max) {
1571			printf("%s: sgl_count=%d nseg=%d max=%d\n", __func__,
1572				sglarg->sgl_count, nseg, sglarg->sgl_max);
1573			sglarg->rc = -2;
1574			return;
1575		}
1576
1577		for (i = 0, c = sglarg->sgl_count; i < nseg; i++, c++) {
1578			sglarg->sgl[c].addr = seg[i].ds_addr;
1579			sglarg->sgl[c].len  = seg[i].ds_len;
1580		}
1581
1582		sglarg->sgl_count = c;
1583
1584		sglarg->rc = 0;
1585	}
1586}
1587
1588/**
1589 * @brief Build a scatter-gather list from a CAM CCB
1590 *
1591 * @param ocs the driver instance's software context
1592 * @param ccb pointer to the CCB
1593 * @param io pointer to the previously allocated IO object
1594 * @param sgl pointer to SGL
1595 * @param sgl_max number of entries in sgl
1596 *
1597 * @return 0 on success, non-zero otherwise
1598 */
1599static int32_t
1600ocs_build_scsi_sgl(struct ocs_softc *ocs, union ccb *ccb, ocs_io_t *io,
1601		ocs_scsi_sgl_t *sgl, uint32_t sgl_max)
1602{
1603	ocs_dmamap_load_arg_t dmaarg;
1604	int32_t	err = 0;
1605
1606	if (!ocs || !ccb || !io || !sgl) {
1607		printf("%s: bad param o=%p c=%p i=%p s=%p\n", __func__,
1608				ocs, ccb, io, sgl);
1609		return -1;
1610	}
1611
1612	io->tgt_io.flags &= ~OCS_CAM_IO_F_DMAPPED;
1613
1614	dmaarg.sgl = sgl;
1615	dmaarg.sgl_count = 0;
1616	dmaarg.sgl_max = sgl_max;
1617	dmaarg.rc = 0;
1618
1619	err = bus_dmamap_load_ccb(ocs->buf_dmat, io->tgt_io.dmap, ccb,
1620			ocs_scsi_dmamap_load, &dmaarg, 0);
1621
1622	if (err || dmaarg.rc) {
1623		device_printf(
1624			ocs->dev, "%s: bus_dmamap_load_ccb error (%d %d)\n",
1625				__func__, err, dmaarg.rc);
1626		return -1;
1627	}
1628
1629	io->tgt_io.flags |= OCS_CAM_IO_F_DMAPPED;
1630	return dmaarg.sgl_count;
1631}
1632
1633/**
1634 * @ingroup cam_io
1635 * @brief Send a target IO
1636 *
1637 * @param ocs the driver instance's software context
1638 * @param ccb pointer to the CCB
1639 *
1640 * @return 0 on success, non-zero otherwise
1641 */
1642static int32_t
1643ocs_target_io(struct ocs_softc *ocs, union ccb *ccb)
1644{
1645	struct ccb_scsiio *csio = &ccb->csio;
1646	ocs_io_t *io = NULL;
1647	uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1648	bool sendstatus = ccb->ccb_h.flags & CAM_SEND_STATUS;
1649	uint32_t xferlen = csio->dxfer_len;
1650	int32_t rc = 0;
1651
1652	io = ocs_scsi_find_io(ocs, csio->tag_id);
1653	if (io == NULL) {
1654		ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1655		panic("bad tag value");
1656		return 1;
1657	}
1658
1659	/* Received an ABORT TASK for this IO */
1660	if (io->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) {
1661		/*device_printf(ocs->dev,
1662			"%s: XPT_CONT_TARGET_IO state=%d tag=%#x xid=%#x flags=%#x\n",
1663			__func__, io->tgt_io.state, io->tag, io->init_task_tag,
1664			io->tgt_io.flags);*/
1665		io->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM;
1666
1667		if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1668			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
1669			ocs_target_io_free(io);
1670			return 1;
1671		}
1672
1673		ocs_set_ccb_status(ccb, CAM_REQ_ABORTED);
1674
1675		return 1;
1676	}
1677
1678	io->tgt_io.app = ccb;
1679
1680	ocs_set_ccb_status(ccb, CAM_REQ_INPROG);
1681	ccb->ccb_h.status |= CAM_SIM_QUEUED;
1682
1683	csio->ccb_h.ccb_ocs_ptr = ocs;
1684	csio->ccb_h.ccb_io_ptr  = io;
1685
1686	if ((sendstatus && (xferlen == 0))) {
1687		ocs_scsi_cmd_resp_t	resp = { 0 };
1688
1689		ocs_assert(ccb->ccb_h.flags & CAM_SEND_STATUS, -1);
1690
1691		io->tgt_io.state = OCS_CAM_IO_RESP;
1692
1693		resp.scsi_status = csio->scsi_status;
1694
1695		if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1696			resp.sense_data = (uint8_t *)&csio->sense_data;
1697			resp.sense_data_length = csio->sense_len;
1698		}
1699
1700		resp.residual = io->exp_xfer_len - io->transferred;
1701		rc = ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb);
1702
1703	} else if (xferlen != 0) {
1704		ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL];
1705		int32_t sgl_count = 0;
1706
1707		io->tgt_io.state = OCS_CAM_IO_DATA;
1708
1709		if (sendstatus)
1710			io->tgt_io.sendresp = 1;
1711
1712		sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, ARRAY_SIZE(sgl));
1713		if (sgl_count > 0) {
1714			if (cam_dir == CAM_DIR_IN) {
1715				rc = ocs_scsi_send_rd_data(io, 0, NULL, sgl,
1716						sgl_count, csio->dxfer_len,
1717						ocs_scsi_target_io_cb, ccb);
1718			} else if (cam_dir == CAM_DIR_OUT) {
1719				rc = ocs_scsi_recv_wr_data(io, 0, NULL, sgl,
1720						sgl_count, csio->dxfer_len,
1721						ocs_scsi_target_io_cb, ccb);
1722			} else {
1723				device_printf(ocs->dev, "%s:"
1724						" unknown CAM direction %#x\n",
1725						__func__, cam_dir);
1726				ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
1727				rc = 1;
1728			}
1729		} else {
1730			device_printf(ocs->dev, "%s: building SGL failed\n",
1731						__func__);
1732			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1733			rc = 1;
1734		}
1735	} else {
1736		device_printf(ocs->dev, "%s: Wrong value xfer and sendstatus"
1737					" are 0 \n", __func__);
1738		ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
1739		rc = 1;
1740
1741	}
1742
1743	if (rc) {
1744		ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1745		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1746		io->tgt_io.state = OCS_CAM_IO_DATA_DONE;
1747		device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n",
1748				__func__, io->tgt_io.state, io->tag);
1749	if ((sendstatus && (xferlen == 0))) {
1750			ocs_target_io_free(io);
1751		}
1752	}
1753
1754	return rc;
1755}
1756
1757static int32_t
1758ocs_target_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags,
1759		void *arg)
1760{
1761
1762	/*device_printf(io->ocs->dev, "%s: tag=%x io=%p s=%#x\n",
1763			 __func__, io->tag, io, scsi_status);*/
1764	ocs_scsi_io_complete(io);
1765
1766	return 0;
1767}
1768
1769/**
1770 * @ingroup cam_io
1771 * @brief Send an initiator IO
1772 *
1773 * @param ocs the driver instance's software context
1774 * @param ccb pointer to the CCB
1775 *
1776 * @return 0 on success, non-zero otherwise
1777 */
1778static int32_t
1779ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
1780{
1781	int32_t rc;
1782	struct ccb_scsiio *csio = &ccb->csio;
1783	struct ccb_hdr *ccb_h = &csio->ccb_h;
1784	ocs_node_t *node = NULL;
1785	ocs_io_t *io = NULL;
1786	ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL];
1787	int32_t flags, sgl_count;
1788
1789	ocs_fcport	*fcp = NULL;
1790	fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)));
1791	if (fcp == NULL) {
1792		device_printf(ocs->dev, "%s: fcp is NULL\n", __func__);
1793		return -1;
1794	}
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
1834	sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, ARRAY_SIZE(sgl));
1835	if (sgl_count < 0) {
1836		ocs_scsi_io_free(io);
1837		device_printf(ocs->dev, "%s: building SGL failed\n", __func__);
1838		return -1;
1839	}
1840
1841	if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
1842		io->timeout = 0;
1843	} else if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) {
1844		io->timeout = OCS_CAM_IO_TIMEOUT;
1845	} else {
1846		io->timeout = ccb->ccb_h.timeout;
1847	}
1848
1849	switch (csio->tag_action) {
1850	case MSG_HEAD_OF_Q_TAG:
1851		flags = OCS_SCSI_CMD_HEAD_OF_QUEUE;
1852		break;
1853	case MSG_ORDERED_Q_TAG:
1854		flags = OCS_SCSI_CMD_ORDERED;
1855		break;
1856	case MSG_ACA_TASK:
1857		flags = OCS_SCSI_CMD_ACA;
1858		break;
1859	case CAM_TAG_ACTION_NONE:
1860	case MSG_SIMPLE_Q_TAG:
1861	default:
1862		flags = OCS_SCSI_CMD_SIMPLE;
1863		break;
1864	}
1865	flags |= (csio->priority << OCS_SCSI_PRIORITY_SHIFT) &
1866	    OCS_SCSI_PRIORITY_MASK;
1867
1868	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
1869	case CAM_DIR_NONE:
1870		rc = ocs_scsi_send_nodata_io(node, io, ccb_h->target_lun,
1871				ccb->ccb_h.flags & CAM_CDB_POINTER ?
1872				csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1873				csio->cdb_len,
1874				ocs_scsi_initiator_io_cb, ccb, flags);
1875		break;
1876	case CAM_DIR_IN:
1877		rc = ocs_scsi_send_rd_io(node, io, ccb_h->target_lun,
1878				ccb->ccb_h.flags & CAM_CDB_POINTER ?
1879				csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1880				csio->cdb_len,
1881				NULL,
1882				sgl, sgl_count, csio->dxfer_len,
1883				ocs_scsi_initiator_io_cb, ccb, flags);
1884		break;
1885	case CAM_DIR_OUT:
1886		rc = ocs_scsi_send_wr_io(node, io, ccb_h->target_lun,
1887				ccb->ccb_h.flags & CAM_CDB_POINTER ?
1888				csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1889				csio->cdb_len,
1890				NULL,
1891				sgl, sgl_count, csio->dxfer_len,
1892				ocs_scsi_initiator_io_cb, ccb, flags);
1893		break;
1894	default:
1895		panic("%s invalid data direction %08x\n", __func__,
1896							ccb->ccb_h.flags);
1897		break;
1898	}
1899
1900	return rc;
1901}
1902
1903static uint32_t
1904ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role)
1905{
1906
1907	uint32_t rc = 0, was = 0, i = 0;
1908	ocs_vport_spec_t *vport = fcp->vport;
1909
1910	for (was = 0, i = 0; i < (ocs->num_vports + 1); i++) {
1911		if (FCPORT(ocs, i)->role != KNOB_ROLE_NONE)
1912		was++;
1913	}
1914
1915	// Physical port
1916	if ((was == 0) || (vport == NULL)) {
1917		fcp->role = new_role;
1918		if (vport == NULL) {
1919			ocs->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1920			ocs->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1921		} else {
1922			vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1923			vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1924		}
1925
1926		rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1927		if (rc) {
1928			ocs_log_debug(ocs, "port offline failed : %d\n", rc);
1929		}
1930
1931		rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1932		if (rc) {
1933			ocs_log_debug(ocs, "port online failed : %d\n", rc);
1934		}
1935
1936		return 0;
1937	}
1938
1939	if ((fcp->role != KNOB_ROLE_NONE)){
1940		fcp->role = new_role;
1941		vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1942		vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1943		/* New Sport will be created in sport deleted cb */
1944		return ocs_sport_vport_del(ocs, ocs->domain, vport->wwpn, vport->wwnn);
1945	}
1946
1947	fcp->role = new_role;
1948
1949	vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1950	vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1951
1952	if (fcp->role != KNOB_ROLE_NONE) {
1953		return ocs_sport_vport_alloc(ocs->domain, vport);
1954	}
1955
1956	return (0);
1957}
1958
1959/**
1960 * @ingroup cam_api
1961 * @brief Process CAM actions
1962 *
1963 * The driver supplies this routine to the CAM during intialization and
1964 * is the main entry point for processing CAM Control Blocks (CCB)
1965 *
1966 * @param sim pointer to the SCSI Interface Module
1967 * @param ccb CAM control block
1968 *
1969 * @todo
1970 *  - populate path inquiry data via info retrieved from SLI port
1971 */
1972static void
1973ocs_action(struct cam_sim *sim, union ccb *ccb)
1974{
1975	struct ocs_softc *ocs = (struct ocs_softc *)cam_sim_softc(sim);
1976	struct ccb_hdr	*ccb_h = &ccb->ccb_h;
1977
1978	int32_t	rc, bus;
1979	bus = cam_sim_bus(sim);
1980
1981	switch (ccb_h->func_code) {
1982	case XPT_SCSI_IO:
1983
1984		if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
1985			if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
1986				ccb->ccb_h.status = CAM_REQ_INVALID;
1987				xpt_done(ccb);
1988				break;
1989			}
1990		}
1991
1992		rc = ocs_initiator_io(ocs, ccb);
1993		if (0 == rc) {
1994			ocs_set_ccb_status(ccb, CAM_REQ_INPROG | CAM_SIM_QUEUED);
1995			break;
1996		} else {
1997		  	if (rc == CAM_REQUEUE_REQ) {
1998				cam_freeze_devq(ccb->ccb_h.path);
1999				cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
2000				ccb->ccb_h.status = CAM_REQUEUE_REQ;
2001				xpt_done(ccb);
2002				break;
2003			}
2004
2005			ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2006			if (rc > 0) {
2007				ocs_set_ccb_status(ccb, rc);
2008			} else {
2009				ocs_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
2010			}
2011		}
2012		xpt_done(ccb);
2013		break;
2014	case XPT_PATH_INQ:
2015	{
2016		struct ccb_pathinq *cpi = &ccb->cpi;
2017		struct ccb_pathinq_settings_fc *fc = &cpi->xport_specific.fc;
2018		ocs_fcport *fcp = FCPORT(ocs, bus);
2019
2020		uint64_t wwn = 0;
2021		ocs_xport_stats_t value;
2022
2023		cpi->version_num = 1;
2024
2025		cpi->protocol = PROTO_SCSI;
2026		cpi->protocol_version = SCSI_REV_SPC;
2027
2028		if (ocs->ocs_xport == OCS_XPORT_FC) {
2029			cpi->transport = XPORT_FC;
2030		} else {
2031			cpi->transport = XPORT_UNKNOWN;
2032		}
2033
2034		cpi->transport_version = 0;
2035
2036		/* Set the transport parameters of the SIM */
2037		ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
2038		fc->bitrate = value.value * 1000;	/* speed in Mbps */
2039
2040		wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWPN));
2041		fc->wwpn = be64toh(wwn);
2042
2043		wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWNN));
2044		fc->wwnn = be64toh(wwn);
2045
2046		fc->port = fcp->fc_id;
2047
2048		if (ocs->config_tgt) {
2049			cpi->target_sprt =
2050				PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2051		}
2052
2053		cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
2054		cpi->hba_misc |= PIM_EXTLUNS | PIM_NOSCAN;
2055
2056		cpi->hba_inquiry = PI_TAG_ABLE;
2057		cpi->max_target = OCS_MAX_TARGETS;
2058		cpi->initiator_id = ocs->max_remote_nodes + 1;
2059
2060		if (!ocs->enable_ini) {
2061			cpi->hba_misc |= PIM_NOINITIATOR;
2062		}
2063
2064		cpi->max_lun = OCS_MAX_LUN;
2065		cpi->bus_id = cam_sim_bus(sim);
2066
2067		/* Need to supply a base transfer speed prior to linking up
2068		 * Worst case, this would be FC 1Gbps */
2069		cpi->base_transfer_speed = 1 * 1000 * 1000;
2070
2071		/* Calculate the max IO supported
2072		 * Worst case would be an OS page per SGL entry */
2073		cpi->maxio = PAGE_SIZE *
2074			(ocs_scsi_get_property(ocs, OCS_SCSI_MAX_SGL) - 1);
2075
2076		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2077		strncpy(cpi->hba_vid, "Emulex", HBA_IDLEN);
2078		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2079		cpi->unit_number = cam_sim_unit(sim);
2080
2081		cpi->ccb_h.status = CAM_REQ_CMP;
2082		xpt_done(ccb);
2083		break;
2084	}
2085	case XPT_GET_TRAN_SETTINGS:
2086	{
2087		struct ccb_trans_settings *cts = &ccb->cts;
2088		struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
2089		struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
2090		ocs_xport_stats_t value;
2091		ocs_fcport *fcp = FCPORT(ocs, bus);
2092		ocs_fc_target_t *tgt = NULL;
2093
2094		if (ocs->ocs_xport != OCS_XPORT_FC) {
2095			ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2096			xpt_done(ccb);
2097			break;
2098		}
2099
2100		if (cts->ccb_h.target_id > OCS_MAX_TARGETS) {
2101			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2102			xpt_done(ccb);
2103			break;
2104		}
2105
2106		tgt = &fcp->tgt[cts->ccb_h.target_id];
2107		if (tgt->state == OCS_TGT_STATE_NONE) {
2108			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2109			xpt_done(ccb);
2110			break;
2111		}
2112
2113		cts->protocol = PROTO_SCSI;
2114		cts->protocol_version = SCSI_REV_SPC2;
2115		cts->transport = XPORT_FC;
2116		cts->transport_version = 2;
2117
2118		scsi->valid = CTS_SCSI_VALID_TQ;
2119		scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2120
2121		/* speed in Mbps */
2122		ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
2123		fc->bitrate = value.value * 100;
2124
2125		fc->wwpn = tgt->wwpn;
2126
2127		fc->wwnn = tgt->wwnn;
2128
2129		fc->port = tgt->port_id;
2130
2131		fc->valid = CTS_FC_VALID_SPEED |
2132			CTS_FC_VALID_WWPN |
2133			CTS_FC_VALID_WWNN |
2134			CTS_FC_VALID_PORT;
2135
2136		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2137		xpt_done(ccb);
2138		break;
2139	}
2140	case XPT_SET_TRAN_SETTINGS:
2141		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2142		xpt_done(ccb);
2143		break;
2144
2145	case XPT_CALC_GEOMETRY:
2146		cam_calc_geometry(&ccb->ccg, TRUE);
2147		xpt_done(ccb);
2148		break;
2149
2150	case XPT_GET_SIM_KNOB:
2151	{
2152		struct ccb_sim_knob *knob = &ccb->knob;
2153		uint64_t wwn = 0;
2154		ocs_fcport *fcp = FCPORT(ocs, bus);
2155
2156		if (ocs->ocs_xport != OCS_XPORT_FC) {
2157			ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2158			xpt_done(ccb);
2159			break;
2160		}
2161
2162		if (bus == 0) {
2163			wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs,
2164						OCS_SCSI_WWNN));
2165			knob->xport_specific.fc.wwnn = be64toh(wwn);
2166
2167			wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs,
2168						OCS_SCSI_WWPN));
2169			knob->xport_specific.fc.wwpn = be64toh(wwn);
2170		} else {
2171			knob->xport_specific.fc.wwnn = fcp->vport->wwnn;
2172			knob->xport_specific.fc.wwpn = fcp->vport->wwpn;
2173		}
2174
2175		knob->xport_specific.fc.role = fcp->role;
2176		knob->xport_specific.fc.valid = KNOB_VALID_ADDRESS |
2177						KNOB_VALID_ROLE;
2178
2179		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2180		xpt_done(ccb);
2181		break;
2182	}
2183	case XPT_SET_SIM_KNOB:
2184	{
2185		struct ccb_sim_knob *knob = &ccb->knob;
2186		bool role_changed = FALSE;
2187		ocs_fcport *fcp = FCPORT(ocs, bus);
2188
2189		if (ocs->ocs_xport != OCS_XPORT_FC) {
2190			ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2191			xpt_done(ccb);
2192			break;
2193		}
2194
2195		if (knob->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
2196			device_printf(ocs->dev,
2197				"%s: XPT_SET_SIM_KNOB wwnn=%llx wwpn=%llx\n",
2198					__func__,
2199					(unsigned long long)knob->xport_specific.fc.wwnn,
2200					(unsigned long long)knob->xport_specific.fc.wwpn);
2201		}
2202
2203		if (knob->xport_specific.fc.valid & KNOB_VALID_ROLE) {
2204			switch (knob->xport_specific.fc.role) {
2205			case KNOB_ROLE_NONE:
2206				if (fcp->role != KNOB_ROLE_NONE) {
2207					role_changed = TRUE;
2208				}
2209				break;
2210			case KNOB_ROLE_TARGET:
2211				if (fcp->role != KNOB_ROLE_TARGET) {
2212					role_changed = TRUE;
2213				}
2214				break;
2215			case KNOB_ROLE_INITIATOR:
2216				if (fcp->role != KNOB_ROLE_INITIATOR) {
2217					role_changed = TRUE;
2218				}
2219				break;
2220			case KNOB_ROLE_BOTH:
2221				if (fcp->role != KNOB_ROLE_BOTH) {
2222					role_changed = TRUE;
2223				}
2224				break;
2225			default:
2226				device_printf(ocs->dev,
2227					"%s: XPT_SET_SIM_KNOB unsupported role: %d\n",
2228					__func__, knob->xport_specific.fc.role);
2229			}
2230
2231			if (role_changed) {
2232				device_printf(ocs->dev,
2233						"BUS:%d XPT_SET_SIM_KNOB old_role: %d new_role: %d\n",
2234						bus, fcp->role, knob->xport_specific.fc.role);
2235
2236				ocs_fcp_change_role(ocs, fcp, knob->xport_specific.fc.role);
2237			}
2238		}
2239
2240
2241
2242		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2243		xpt_done(ccb);
2244		break;
2245	}
2246	case XPT_ABORT:
2247	{
2248		union ccb *accb = ccb->cab.abort_ccb;
2249
2250		switch (accb->ccb_h.func_code) {
2251		case XPT_ACCEPT_TARGET_IO:
2252			ocs_abort_atio(ocs, ccb);
2253			break;
2254		case XPT_IMMEDIATE_NOTIFY:
2255			ocs_abort_inot(ocs, ccb);
2256			break;
2257		case XPT_SCSI_IO:
2258			rc = ocs_abort_initiator_io(ocs, accb);
2259			if (rc) {
2260				ccb->ccb_h.status = CAM_UA_ABORT;
2261			} else {
2262				ccb->ccb_h.status = CAM_REQ_CMP;
2263			}
2264
2265			break;
2266		default:
2267			printf("abort of unknown func %#x\n",
2268					accb->ccb_h.func_code);
2269			ccb->ccb_h.status = CAM_REQ_INVALID;
2270			break;
2271		}
2272		break;
2273	}
2274	case XPT_RESET_BUS:
2275		if (ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE) == 0) {
2276			ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
2277
2278			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2279		} else {
2280			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2281		}
2282		xpt_done(ccb);
2283		break;
2284	case XPT_RESET_DEV:
2285	{
2286		ocs_node_t	*node = NULL;
2287		ocs_io_t	*io = NULL;
2288		int32_t		rc = 0;
2289		ocs_fcport *fcp = FCPORT(ocs, bus);
2290
2291		node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id);
2292		if (node == NULL) {
2293			device_printf(ocs->dev, "%s: no device %d\n",
2294						__func__, ccb_h->target_id);
2295			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2296			xpt_done(ccb);
2297			break;
2298		}
2299
2300		io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
2301		if (io == NULL) {
2302			device_printf(ocs->dev, "%s: unable to alloc IO\n",
2303								 __func__);
2304			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2305			xpt_done(ccb);
2306			break;
2307		}
2308
2309		rc = ocs_scsi_send_tmf(node, io, NULL, ccb_h->target_lun,
2310				OCS_SCSI_TMF_LOGICAL_UNIT_RESET,
2311				NULL, 0, 0,	/* sgl, sgl_count, length */
2312				ocs_initiator_tmf_cb, NULL/*arg*/);
2313
2314		if (rc) {
2315			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2316		} else {
2317			ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2318		}
2319
2320		if (node->fcp2device) {
2321			ocs_reset_crn(node, ccb_h->target_lun);
2322		}
2323
2324		xpt_done(ccb);
2325		break;
2326	}
2327	case XPT_EN_LUN:	/* target support */
2328	{
2329		ocs_tgt_resource_t *trsrc = NULL;
2330		uint32_t	status = 0;
2331		ocs_fcport *fcp = FCPORT(ocs, bus);
2332
2333		device_printf(ocs->dev, "XPT_EN_LUN %sable %d:%d\n",
2334				ccb->cel.enable ? "en" : "dis",
2335				ccb->ccb_h.target_id,
2336				(unsigned int)ccb->ccb_h.target_lun);
2337
2338		trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status);
2339		if (trsrc) {
2340			trsrc->enabled = ccb->cel.enable;
2341
2342			/* Abort all ATIO/INOT on LUN disable */
2343			if (trsrc->enabled == FALSE) {
2344				ocs_tgt_resource_abort(ocs, trsrc);
2345			} else {
2346				STAILQ_INIT(&trsrc->atio);
2347				STAILQ_INIT(&trsrc->inot);
2348			}
2349			status = CAM_REQ_CMP;
2350		}
2351
2352		ocs_set_ccb_status(ccb, status);
2353		xpt_done(ccb);
2354		break;
2355	}
2356	/*
2357	 * The flow of target IOs in CAM is:
2358	 *  - CAM supplies a number of CCBs to the driver used for received
2359	 *    commands.
2360	 *  - when the driver receives a command, it copies the relevant
2361	 *    information to the CCB and returns it to the CAM using xpt_done()
2362	 *  - after the target server processes the request, it creates
2363	 *    a new CCB containing information on how to continue the IO and
2364	 *    passes that to the driver
2365	 *  - the driver processes the "continue IO" (a.k.a CTIO) CCB
2366	 *  - once the IO completes, the driver returns the CTIO to the CAM
2367	 *    using xpt_done()
2368	 */
2369	case XPT_ACCEPT_TARGET_IO:	/* used to inform upper layer of
2370						received CDB (a.k.a. ATIO) */
2371	case XPT_IMMEDIATE_NOTIFY:	/* used to inform upper layer of other
2372							 event (a.k.a. INOT) */
2373	{
2374		ocs_tgt_resource_t *trsrc = NULL;
2375		uint32_t	status = 0;
2376		ocs_fcport *fcp = FCPORT(ocs, bus);
2377
2378		/*printf("XPT_%s %p\n", ccb_h->func_code == XPT_ACCEPT_TARGET_IO ?
2379				"ACCEPT_TARGET_IO" : "IMMEDIATE_NOTIFY", ccb);*/
2380		trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status);
2381		if (trsrc == NULL) {
2382			ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2383			xpt_done(ccb);
2384			break;
2385		}
2386
2387		if (XPT_ACCEPT_TARGET_IO == ccb->ccb_h.func_code) {
2388			struct ccb_accept_tio *atio = NULL;
2389
2390			atio = (struct ccb_accept_tio *)ccb;
2391			atio->init_id = 0x0badbeef;
2392			atio->tag_id  = 0xdeadc0de;
2393
2394			STAILQ_INSERT_TAIL(&trsrc->atio, &ccb->ccb_h,
2395					sim_links.stqe);
2396		} else {
2397			STAILQ_INSERT_TAIL(&trsrc->inot, &ccb->ccb_h,
2398					sim_links.stqe);
2399		}
2400		ccb->ccb_h.ccb_io_ptr  = NULL;
2401		ccb->ccb_h.ccb_ocs_ptr = ocs;
2402		ocs_set_ccb_status(ccb, CAM_REQ_INPROG);
2403		/*
2404		 * These actions give resources to the target driver.
2405		 * If we didn't return here, this function would call
2406		 * xpt_done(), signaling to the upper layers that an
2407		 * IO or other event had arrived.
2408		 */
2409		break;
2410	}
2411	case XPT_NOTIFY_ACKNOWLEDGE:
2412	{
2413		ocs_io_t *io = NULL;
2414		ocs_io_t *abortio = NULL;
2415
2416		/* Get the IO reference for this tag */
2417		io = ocs_scsi_find_io(ocs, ccb->cna2.tag_id);
2418		if (io == NULL) {
2419			device_printf(ocs->dev,
2420				"%s: XPT_NOTIFY_ACKNOWLEDGE no IO with tag %#x\n",
2421					__func__, ccb->cna2.tag_id);
2422			ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2423			xpt_done(ccb);
2424			break;
2425		}
2426
2427		abortio = io->tgt_io.app;
2428		if (abortio) {
2429			abortio->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_NOTIFY;
2430			device_printf(ocs->dev,
2431				"%s: XPT_NOTIFY_ACK state=%d tag=%#x xid=%#x"
2432				" flags=%#x\n",	__func__, abortio->tgt_io.state,
2433				abortio->tag, abortio->init_task_tag,
2434					abortio->tgt_io.flags);
2435			/* TMF response was sent in abort callback */
2436		} else {
2437			ocs_scsi_send_tmf_resp(io,
2438					OCS_SCSI_TMF_FUNCTION_COMPLETE,
2439					NULL, ocs_target_tmf_cb, NULL);
2440		}
2441
2442		ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2443		xpt_done(ccb);
2444		break;
2445	}
2446	case XPT_CONT_TARGET_IO:	/* continue target IO, sending data/response (a.k.a. CTIO) */
2447		if (ocs_target_io(ocs, ccb)) {
2448			device_printf(ocs->dev,
2449				"XPT_CONT_TARGET_IO failed flags=%x tag=%#x\n",
2450				ccb->ccb_h.flags, ccb->csio.tag_id);
2451			xpt_done(ccb);
2452		}
2453		break;
2454	default:
2455		device_printf(ocs->dev, "unhandled func_code = %#x\n",
2456				ccb_h->func_code);
2457		ccb_h->status = CAM_REQ_INVALID;
2458		xpt_done(ccb);
2459		break;
2460	}
2461}
2462
2463/**
2464 * @ingroup cam_api
2465 * @brief Process events
2466 *
2467 * @param sim pointer to the SCSI Interface Module
2468 *
2469 */
2470static void
2471ocs_poll(struct cam_sim *sim)
2472{
2473	printf("%s\n", __func__);
2474}
2475
2476static int32_t
2477ocs_initiator_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status,
2478		ocs_scsi_cmd_resp_t *rsp, uint32_t flags, void *arg)
2479{
2480	int32_t	rc = 0;
2481
2482	switch (scsi_status) {
2483	case OCS_SCSI_STATUS_GOOD:
2484	case OCS_SCSI_STATUS_NO_IO:
2485		break;
2486	case OCS_SCSI_STATUS_CHECK_RESPONSE:
2487		if (rsp->response_data_length == 0) {
2488			ocs_log_test(io->ocs, "check response without data?!?\n");
2489			rc = -1;
2490			break;
2491		}
2492
2493		if (rsp->response_data[3] != 0) {
2494			ocs_log_test(io->ocs, "TMF status %08x\n",
2495				be32toh(*((uint32_t *)rsp->response_data)));
2496			rc = -1;
2497			break;
2498		}
2499		break;
2500	default:
2501		ocs_log_test(io->ocs, "status=%#x\n", scsi_status);
2502		rc = -1;
2503	}
2504
2505	ocs_scsi_io_free(io);
2506
2507	return rc;
2508}
2509
2510/**
2511 * @brief lookup target resource structure
2512 *
2513 * Arbitrarily support
2514 *  - wildcard target ID + LU
2515 *  - 0 target ID + non-wildcard LU
2516 *
2517 * @param ocs the driver instance's software context
2518 * @param ccb_h pointer to the CCB header
2519 * @param status returned status value
2520 *
2521 * @return pointer to the target resource, NULL if none available (e.g. if LU
2522 * 	   is not enabled)
2523 */
2524static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *fcp,
2525				struct ccb_hdr *ccb_h, uint32_t *status)
2526{
2527	target_id_t	tid = ccb_h->target_id;
2528	lun_id_t	lun = ccb_h->target_lun;
2529
2530	if (CAM_TARGET_WILDCARD == tid) {
2531		if (CAM_LUN_WILDCARD != lun) {
2532			*status = CAM_LUN_INVALID;
2533			return NULL;
2534		}
2535		return &fcp->targ_rsrc_wildcard;
2536	} else {
2537		if (lun < OCS_MAX_LUN) {
2538			return &fcp->targ_rsrc[lun];
2539		} else {
2540			*status = CAM_LUN_INVALID;
2541			return NULL;
2542		}
2543	}
2544
2545}
2546
2547static int32_t
2548ocs_tgt_resource_abort(struct ocs_softc *ocs, ocs_tgt_resource_t *trsrc)
2549{
2550	union ccb *ccb = NULL;
2551	uint32_t	count;
2552
2553	count = 0;
2554	do {
2555		ccb = (union ccb *)STAILQ_FIRST(&trsrc->atio);
2556		if (ccb) {
2557			STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe);
2558			ccb->ccb_h.status = CAM_REQ_ABORTED;
2559			xpt_done(ccb);
2560			count++;
2561		}
2562	} while (ccb);
2563
2564	count = 0;
2565	do {
2566		ccb = (union ccb *)STAILQ_FIRST(&trsrc->inot);
2567		if (ccb) {
2568			STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe);
2569			ccb->ccb_h.status = CAM_REQ_ABORTED;
2570			xpt_done(ccb);
2571			count++;
2572		}
2573	} while (ccb);
2574
2575	return 0;
2576}
2577
2578static void
2579ocs_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
2639static void
2640ocs_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
2669static uint32_t
2670ocs_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
2707void
2708ocs_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
2737void
2738ocs_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
2796int32_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
2803uint32_t
2804ocs_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
2834void
2835ocs_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
2850void
2851ocs_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