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