scsi_ctl.c revision 237726
1/*-
2 * Copyright (c) 2008, 2009 Silicon Graphics International Corp.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions, and the following disclaimer,
10 *    without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 *    substantially similar to the "NO WARRANTY" disclaimer below
13 *    ("Disclaimer") and any redistribution must be conditioned upon
14 *    including a substantially similar Disclaimer requirement for further
15 *    binary redistribution.
16 *
17 * NO WARRANTY
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGES.
29 *
30 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/scsi_ctl.c#4 $
31 */
32/*
33 * Peripheral driver interface between CAM and CTL (CAM Target Layer).
34 *
35 * Author: Ken Merry <ken@FreeBSD.org>
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: head/sys/cam/ctl/scsi_ctl.c 237726 2012-06-28 19:39:30Z ken $");
40
41#include <sys/param.h>
42#include <sys/queue.h>
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/lock.h>
46#include <sys/mutex.h>
47#include <sys/condvar.h>
48#include <sys/malloc.h>
49#include <sys/bus.h>
50#include <sys/endian.h>
51#include <sys/sbuf.h>
52#include <sys/sysctl.h>
53#include <sys/types.h>
54#include <sys/systm.h>
55#include <machine/bus.h>
56
57#include <cam/cam.h>
58#include <cam/cam_ccb.h>
59#include <cam/cam_periph.h>
60#include <cam/cam_queue.h>
61#include <cam/cam_xpt_periph.h>
62#include <cam/cam_debug.h>
63#include <cam/cam_sim.h>
64#include <cam/cam_xpt.h>
65
66#include <cam/scsi/scsi_all.h>
67#include <cam/scsi/scsi_message.h>
68
69#include <cam/ctl/ctl_io.h>
70#include <cam/ctl/ctl.h>
71#include <cam/ctl/ctl_frontend.h>
72#include <cam/ctl/ctl_util.h>
73#include <cam/ctl/ctl_error.h>
74
75typedef enum {
76	CTLFE_CCB_WAITING 	= 0x01
77} ctlfe_ccb_types;
78
79struct ctlfe_softc {
80	struct ctl_frontend fe;
81	path_id_t path_id;
82	struct cam_sim *sim;
83	char port_name[DEV_IDLEN];
84	STAILQ_HEAD(, ctlfe_lun_softc) lun_softc_list;
85	STAILQ_ENTRY(ctlfe_softc) links;
86};
87
88STAILQ_HEAD(, ctlfe_softc) ctlfe_softc_list;
89struct mtx ctlfe_list_mtx;
90static char ctlfe_mtx_desc[] = "ctlfelist";
91static int ctlfe_dma_enabled = 1;
92#ifdef CTLFE_INIT_ENABLE
93static int ctlfe_max_targets = 1;
94static int ctlfe_num_targets = 0;
95#endif
96
97typedef enum {
98	CTLFE_LUN_NONE		= 0x00,
99	CTLFE_LUN_WILDCARD	= 0x01
100} ctlfe_lun_flags;
101
102struct ctlfe_lun_softc {
103	struct ctlfe_softc *parent_softc;
104	struct cam_periph *periph;
105	ctlfe_lun_flags flags;
106	struct callout dma_callout;
107	uint64_t ccbs_alloced;
108	uint64_t ccbs_freed;
109	uint64_t ctios_sent;
110	uint64_t ctios_returned;
111	uint64_t atios_sent;
112	uint64_t atios_returned;
113	uint64_t inots_sent;
114	uint64_t inots_returned;
115	/* bus_dma_tag_t dma_tag; */
116	TAILQ_HEAD(, ccb_hdr) work_queue;
117	STAILQ_ENTRY(ctlfe_lun_softc) links;
118};
119
120typedef enum {
121	CTLFE_CMD_NONE		= 0x00,
122	CTLFE_CMD_PIECEWISE	= 0x01
123} ctlfe_cmd_flags;
124
125/*
126 * The size limit of this structure is CTL_PORT_PRIV_SIZE, from ctl_io.h.
127 * Currently that is 600 bytes.
128 */
129struct ctlfe_lun_cmd_info {
130	int cur_transfer_index;
131	ctlfe_cmd_flags flags;
132	/*
133	 * XXX KDM struct bus_dma_segment is 8 bytes on i386, and 16
134	 * bytes on amd64.  So with 32 elements, this is 256 bytes on
135	 * i386 and 512 bytes on amd64.
136	 */
137	bus_dma_segment_t cam_sglist[32];
138};
139
140/*
141 * When we register the adapter/bus, request that this many ctl_ios be
142 * allocated.  This should be the maximum supported by the adapter, but we
143 * currently don't have a way to get that back from the path inquiry.
144 * XXX KDM add that to the path inquiry.
145 */
146#define	CTLFE_REQ_CTL_IO	4096
147/*
148 * Number of Accept Target I/O CCBs to allocate and queue down to the
149 * adapter per LUN.
150 * XXX KDM should this be controlled by CTL?
151 */
152#define	CTLFE_ATIO_PER_LUN	1024
153/*
154 * Number of Immediate Notify CCBs (used for aborts, resets, etc.) to
155 * allocate and queue down to the adapter per LUN.
156 * XXX KDM should this be controlled by CTL?
157 */
158#define	CTLFE_IN_PER_LUN	1024
159
160/*
161 * Timeout (in seconds) on CTIO CCB allocation for doing a DMA or sending
162 * status to the initiator.  The SIM is expected to have its own timeouts,
163 * so we're not putting this timeout around the CCB execution time.  The
164 * SIM should timeout and let us know if it has an issue.
165 */
166#define	CTLFE_DMA_TIMEOUT	60
167
168/*
169 * Turn this on to enable extra debugging prints.
170 */
171#if 0
172#define	CTLFE_DEBUG
173#endif
174
175/*
176 * Use randomly assigned WWNN/WWPN values.  This is to work around an issue
177 * in the FreeBSD initiator that makes it unable to rescan the target if
178 * the target gets rebooted and the WWNN/WWPN stay the same.
179 */
180#if 0
181#define	RANDOM_WWNN
182#endif
183
184SYSCTL_INT(_kern_cam_ctl, OID_AUTO, dma_enabled, CTLFLAG_RW,
185	   &ctlfe_dma_enabled, 0, "DMA enabled");
186MALLOC_DEFINE(M_CTLFE, "CAM CTL FE", "CAM CTL FE interface");
187
188#define	ccb_type	ppriv_field0
189/* This is only used in the ATIO */
190#define	io_ptr		ppriv_ptr1
191
192/* This is only used in the CTIO */
193#define	ccb_atio	ppriv_ptr1
194
195int			ctlfeinitialize(void);
196void			ctlfeshutdown(void);
197static periph_init_t	ctlfeinit;
198static void		ctlfeasync(void *callback_arg, uint32_t code,
199				   struct cam_path *path, void *arg);
200static periph_ctor_t	ctlferegister;
201static periph_oninv_t	ctlfeoninvalidate;
202static periph_dtor_t	ctlfecleanup;
203static periph_start_t	ctlfestart;
204static void		ctlfedone(struct cam_periph *periph,
205				  union ccb *done_ccb);
206
207static void 		ctlfe_onoffline(void *arg, int online);
208static void 		ctlfe_online(void *arg);
209static void 		ctlfe_offline(void *arg);
210static int 		ctlfe_targ_enable(void *arg, struct ctl_id targ_id);
211static int 		ctlfe_targ_disable(void *arg, struct ctl_id targ_id);
212static int 		ctlfe_lun_enable(void *arg, struct ctl_id targ_id,
213					 int lun_id);
214static int 		ctlfe_lun_disable(void *arg, struct ctl_id targ_id,
215					  int lun_id);
216static void		ctlfe_dump_sim(struct cam_sim *sim);
217static void		ctlfe_dump_queue(struct ctlfe_lun_softc *softc);
218static void		ctlfe_dma_timeout(void *arg);
219static void 		ctlfe_datamove_done(union ctl_io *io);
220static void 		ctlfe_dump(void);
221
222static struct periph_driver ctlfe_driver =
223{
224	ctlfeinit, "ctl",
225	TAILQ_HEAD_INITIALIZER(ctlfe_driver.units), /*generation*/ 0
226};
227PERIPHDRIVER_DECLARE(ctl, ctlfe_driver);
228
229extern struct ctl_softc *control_softc;
230extern int ctl_disable;
231
232int
233ctlfeinitialize(void)
234{
235	cam_status status;
236
237	/* Don't initialize if we're disabled */
238	if (ctl_disable != 0)
239		return (0);
240
241	STAILQ_INIT(&ctlfe_softc_list);
242
243	mtx_init(&ctlfe_list_mtx, ctlfe_mtx_desc, NULL, MTX_DEF);
244
245	xpt_lock_buses();
246	periphdriver_register(&ctlfe_driver);
247	xpt_unlock_buses();
248
249	status = xpt_register_async(AC_PATH_REGISTERED | AC_PATH_DEREGISTERED |
250				    AC_CONTRACT, ctlfeasync, NULL, NULL);
251
252	if (status != CAM_REQ_CMP) {
253		printf("ctl: Failed to attach async callback due to CAM "
254		       "status 0x%x!\n", status);
255	}
256
257	return (0);
258}
259
260void
261ctlfeshutdown(void)
262{
263	return;
264}
265
266void
267ctlfeinit(void)
268{
269	cam_status status;
270
271	/* Don't initialize if we're disabled */
272	if (ctl_disable != 0)
273		return;
274
275	STAILQ_INIT(&ctlfe_softc_list);
276
277	mtx_init(&ctlfe_list_mtx, ctlfe_mtx_desc, NULL, MTX_DEF);
278
279	KASSERT(control_softc != NULL, ("CTL is not initialized!"));
280
281	status = xpt_register_async(AC_PATH_REGISTERED | AC_PATH_DEREGISTERED |
282				    AC_CONTRACT, ctlfeasync, NULL, NULL);
283
284	if (status != CAM_REQ_CMP) {
285		printf("ctl: Failed to attach async callback due to CAM "
286		       "status 0x%x!\n", status);
287	}
288}
289
290static void
291ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
292{
293
294#ifdef CTLFEDEBUG
295	printf("%s: entered\n", __func__);
296#endif
297
298	/*
299	 * When a new path gets registered, and it is capable of target
300	 * mode, go ahead and attach.  Later on, we may need to be more
301	 * selective, but for now this will be sufficient.
302 	 */
303	switch (code) {
304	case AC_PATH_REGISTERED: {
305		struct ctl_frontend *fe;
306		struct ctlfe_softc *bus_softc;
307		struct ctlfe_lun_softc *lun_softc;
308		struct cam_path *path;
309		struct ccb_pathinq *cpi;
310		cam_status status;
311		int retval;
312
313		cpi = (struct ccb_pathinq *)arg;
314
315		/* Don't attach if it doesn't support target mode */
316		if ((cpi->target_sprt & PIT_PROCESSOR) == 0) {
317#ifdef CTLFEDEBUG
318			printf("%s: SIM %s%d doesn't support target mode\n",
319			       __func__, cpi->dev_name, cpi->unit_number);
320#endif
321			break;
322		}
323
324#ifdef CTLFE_INIT_ENABLE
325		if (ctlfe_num_targets >= ctlfe_max_targets) {
326			union ccb *ccb;
327			struct cam_sim *sim;
328
329			ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP,
330						  M_NOWAIT | M_ZERO);
331			if (ccb == NULL) {
332				printf("%s: unable to malloc CCB!\n", __func__);
333				xpt_free_path(path);
334				return;
335			}
336			xpt_setup_ccb(&ccb->ccb_h, cpi->ccb_h.path,
337				      /*priority*/ 1);
338
339			sim = xpt_path_sim(cpi->ccb_h.path);
340
341			ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
342			ccb->knob.xport_specific.valid = KNOB_VALID_ROLE;
343			ccb->knob.xport_specific.fc.role = KNOB_ROLE_INITIATOR;
344
345			/* We should hold the SIM lock here */
346			mtx_assert(sim->mtx, MA_OWNED);
347
348			xpt_action(ccb);
349
350			if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
351			     CAM_REQ_CMP) {
352				printf("%s: SIM %s%d (path id %d) initiator "
353				       "enable failed with status %#x\n",
354				       __func__, cpi->dev_name,
355				       cpi->unit_number, cpi->ccb_h.path_id,
356				       ccb->ccb_h.status);
357			} else {
358				printf("%s: SIM %s%d (path id %d) initiator "
359				       "enable succeeded\n",
360				       __func__, cpi->dev_name,
361				       cpi->unit_number, cpi->ccb_h.path_id);
362			}
363
364			free(ccb, M_TEMP);
365
366			break;
367		} else {
368			ctlfe_num_targets++;
369		}
370
371		printf("%s: ctlfe_num_targets = %d\n", __func__,
372		       ctlfe_num_targets);
373#endif /* CTLFE_INIT_ENABLE */
374
375		/*
376		 * We're in an interrupt context here, so we have to
377		 * use M_NOWAIT.  Of course this means trouble if we
378		 * can't allocate memory.
379		 */
380		bus_softc = malloc(sizeof(*bus_softc), M_CTLFE,
381				   M_NOWAIT | M_ZERO);
382		if (bus_softc == NULL) {
383			printf("%s: unable to malloc %zd bytes for softc\n",
384			       __func__, sizeof(*bus_softc));
385			return;
386		}
387
388		bus_softc->path_id = cpi->ccb_h.path_id;
389		bus_softc->sim = xpt_path_sim(cpi->ccb_h.path);
390		STAILQ_INIT(&bus_softc->lun_softc_list);
391
392		fe = &bus_softc->fe;
393
394		/*
395		 * XXX KDM should we be more accurate here ?
396		 */
397		if (cpi->transport == XPORT_FC)
398			fe->port_type = CTL_PORT_FC;
399		else
400			fe->port_type = CTL_PORT_SCSI;
401
402		/* XXX KDM what should the real number be here? */
403		fe->num_requested_ctl_io = 4096;
404		snprintf(bus_softc->port_name, sizeof(bus_softc->port_name),
405			 "%s%d", cpi->dev_name, cpi->unit_number);
406		/*
407		 * XXX KDM it would be nice to allocate storage in the
408		 * frontend structure itself.
409	 	 */
410		fe->port_name = bus_softc->port_name;
411		fe->physical_port = cpi->unit_number;
412		fe->virtual_port = cpi->bus_id;
413		fe->port_online = ctlfe_online;
414		fe->port_offline = ctlfe_offline;
415		fe->onoff_arg = bus_softc;
416		fe->targ_enable = ctlfe_targ_enable;
417		fe->targ_disable = ctlfe_targ_disable;
418		fe->lun_enable = ctlfe_lun_enable;
419		fe->lun_disable = ctlfe_lun_disable;
420		fe->targ_lun_arg = bus_softc;
421		fe->fe_datamove = ctlfe_datamove_done;
422		fe->fe_done = ctlfe_datamove_done;
423		fe->fe_dump = ctlfe_dump;
424		/*
425		 * XXX KDM the path inquiry doesn't give us the maximum
426		 * number of targets supported.
427		 */
428		fe->max_targets = cpi->max_target;
429		fe->max_target_id = cpi->max_target;
430
431		/*
432		 * XXX KDM need to figure out whether we're the master or
433		 * slave.
434		 */
435#ifdef CTLFEDEBUG
436		printf("%s: calling ctl_frontend_register() for %s%d\n",
437		       __func__, cpi->dev_name, cpi->unit_number);
438#endif
439		retval = ctl_frontend_register(fe, /*master_SC*/ 1);
440		if (retval != 0) {
441			printf("%s: ctl_frontend_register() failed with "
442			       "error %d!\n", __func__, retval);
443			free(bus_softc, M_CTLFE);
444			break;
445		} else {
446			mtx_lock(&ctlfe_list_mtx);
447			STAILQ_INSERT_TAIL(&ctlfe_softc_list, bus_softc, links);
448			mtx_unlock(&ctlfe_list_mtx);
449		}
450
451		status = xpt_create_path(&path, /*periph*/ NULL,
452					 bus_softc->path_id,CAM_TARGET_WILDCARD,
453					 CAM_LUN_WILDCARD);
454		if (status != CAM_REQ_CMP) {
455			printf("%s: unable to create path for wildcard "
456			       "periph\n", __func__);
457			break;
458		}
459		lun_softc = malloc(sizeof(*lun_softc), M_CTLFE,
460				   M_NOWAIT | M_ZERO);
461		if (lun_softc == NULL) {
462			xpt_print(path, "%s: unable to allocate softc for "
463				  "wildcard periph\n", __func__);
464			xpt_free_path(path);
465			break;
466		}
467
468		lun_softc->parent_softc = bus_softc;
469		lun_softc->flags |= CTLFE_LUN_WILDCARD;
470
471		status = cam_periph_alloc(ctlferegister,
472					  ctlfeoninvalidate,
473					  ctlfecleanup,
474					  ctlfestart,
475					  "ctl",
476					  CAM_PERIPH_BIO,
477					  path,
478					  ctlfeasync,
479					  0,
480					  lun_softc);
481
482		xpt_free_path(path);
483
484		break;
485	}
486	case AC_PATH_DEREGISTERED:
487		/* ctl_frontend_deregister() */
488		break;
489	case AC_CONTRACT: {
490		struct ac_contract *ac;
491
492		ac = (struct ac_contract *)arg;
493
494		switch (ac->contract_number) {
495		case AC_CONTRACT_DEV_CHG: {
496			struct ac_device_changed *dev_chg;
497			struct ctlfe_softc *softc;
498			int retval, found;
499
500			dev_chg = (struct ac_device_changed *)ac->contract_data;
501
502			printf("%s: WWPN %#jx port 0x%06x path %u target %u %s\n",
503			       __func__, dev_chg->wwpn, dev_chg->port,
504			       xpt_path_path_id(path), dev_chg->target,
505			       (dev_chg->arrived == 0) ?  "left" : "arrived");
506
507			found = 0;
508
509			mtx_lock(&ctlfe_list_mtx);
510			STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
511				if (softc->path_id == xpt_path_path_id(path)) {
512					found = 1;
513					break;
514				}
515			}
516			mtx_unlock(&ctlfe_list_mtx);
517
518			if (found == 0) {
519				printf("%s: CTL port for CAM path %u not "
520				       "found!\n", __func__,
521				       xpt_path_path_id(path));
522				break;
523			}
524			if (dev_chg->arrived != 0) {
525				retval = ctl_add_initiator(dev_chg->wwpn,
526					softc->fe.targ_port, dev_chg->target);
527			} else {
528				retval = ctl_remove_initiator(
529					softc->fe.targ_port, dev_chg->target);
530			}
531
532			if (retval != 0) {
533				printf("%s: could not %s port %d iid %u "
534				       "WWPN %#jx!\n", __func__,
535				       (dev_chg->arrived != 0) ? "add" :
536				       "remove", softc->fe.targ_port,
537				       dev_chg->target,
538				       (uintmax_t)dev_chg->wwpn);
539			}
540			break;
541		}
542		default:
543			printf("%s: unsupported contract number %ju\n",
544			       __func__, (uintmax_t)ac->contract_number);
545			break;
546		}
547		break;
548	}
549	default:
550		break;
551	}
552}
553
554static cam_status
555ctlferegister(struct cam_periph *periph, void *arg)
556{
557	struct ctlfe_softc *bus_softc;
558	struct ctlfe_lun_softc *softc;
559	struct cam_sim *sim;
560	union ccb en_lun_ccb;
561	cam_status status;
562	int i;
563
564	softc = (struct ctlfe_lun_softc *)arg;
565	bus_softc = softc->parent_softc;
566	sim = xpt_path_sim(periph->path);
567
568	TAILQ_INIT(&softc->work_queue);
569	softc->periph = periph;
570
571	callout_init_mtx(&softc->dma_callout, sim->mtx, /*flags*/ 0);
572	periph->softc = softc;
573
574	xpt_setup_ccb(&en_lun_ccb.ccb_h, periph->path, /*priority*/ 1);
575	en_lun_ccb.ccb_h.func_code = XPT_EN_LUN;
576	en_lun_ccb.cel.grp6_len = 0;
577	en_lun_ccb.cel.grp7_len = 0;
578	en_lun_ccb.cel.enable = 1;
579	xpt_action(&en_lun_ccb);
580	status = (en_lun_ccb.ccb_h.status & CAM_STATUS_MASK);
581	if (status != CAM_REQ_CMP) {
582		xpt_print(periph->path, "%s: Enable LUN failed, status 0x%x\n",
583			  __func__, en_lun_ccb.ccb_h.status);
584		return (status);
585	}
586
587	status = CAM_REQ_CMP;
588
589	for (i = 0; i < CTLFE_ATIO_PER_LUN; i++) {
590		union ccb *new_ccb;
591
592		new_ccb = (union ccb *)malloc(sizeof(*new_ccb), M_CTLFE,
593					      M_ZERO|M_NOWAIT);
594		if (new_ccb == NULL) {
595			status = CAM_RESRC_UNAVAIL;
596			break;
597		}
598		xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1);
599		new_ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
600		new_ccb->ccb_h.cbfcnp = ctlfedone;
601		xpt_action(new_ccb);
602		softc->atios_sent++;
603		status = new_ccb->ccb_h.status;
604		if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
605			free(new_ccb, M_CTLFE);
606			break;
607		}
608	}
609
610	status = cam_periph_acquire(periph);
611	if ((status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
612		xpt_print(periph->path, "%s: could not acquire reference "
613			  "count, status = %#x\n", __func__, status);
614		return (status);
615	}
616
617	if (i == 0) {
618		xpt_print(periph->path, "%s: could not allocate ATIO CCBs, "
619			  "status 0x%x\n", __func__, status);
620		return (CAM_REQ_CMP_ERR);
621	}
622
623	for (i = 0; i < CTLFE_IN_PER_LUN; i++) {
624		union ccb *new_ccb;
625
626		new_ccb = (union ccb *)malloc(sizeof(*new_ccb), M_CTLFE,
627					      M_ZERO|M_NOWAIT);
628		if (new_ccb == NULL) {
629			status = CAM_RESRC_UNAVAIL;
630			break;
631		}
632
633		xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1);
634		new_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
635		new_ccb->ccb_h.cbfcnp = ctlfedone;
636		xpt_action(new_ccb);
637		softc->inots_sent++;
638		status = new_ccb->ccb_h.status;
639		if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
640			/*
641			 * Note that we don't free the CCB here.  If the
642			 * status is not CAM_REQ_INPROG, then we're
643			 * probably talking to a SIM that says it is
644			 * target-capable but doesn't support the
645			 * XPT_IMMEDIATE_NOTIFY CCB.  i.e. it supports the
646			 * older API.  In that case, it'll call xpt_done()
647			 * on the CCB, and we need to free it in our done
648			 * routine as a result.
649			 */
650			break;
651		}
652	}
653	if ((i == 0)
654	 || (status != CAM_REQ_INPROG)) {
655		xpt_print(periph->path, "%s: could not allocate immediate "
656			  "notify CCBs, status 0x%x\n", __func__, status);
657		return (CAM_REQ_CMP_ERR);
658	}
659	return (CAM_REQ_CMP);
660}
661
662static void
663ctlfeoninvalidate(struct cam_periph *periph)
664{
665	union ccb en_lun_ccb;
666	cam_status status;
667	struct ctlfe_lun_softc *softc;
668
669	softc = (struct ctlfe_lun_softc *)periph->softc;
670
671	xpt_setup_ccb(&en_lun_ccb.ccb_h, periph->path, /*priority*/ 1);
672	en_lun_ccb.ccb_h.func_code = XPT_EN_LUN;
673	en_lun_ccb.cel.grp6_len = 0;
674	en_lun_ccb.cel.grp7_len = 0;
675	en_lun_ccb.cel.enable = 0;
676	xpt_action(&en_lun_ccb);
677	status = (en_lun_ccb.ccb_h.status & CAM_STATUS_MASK);
678	if (status != CAM_REQ_CMP) {
679		xpt_print(periph->path, "%s: Disable LUN failed, status 0x%x\n",
680			  __func__, en_lun_ccb.ccb_h.status);
681		/*
682		 * XXX KDM what do we do now?
683		 */
684	}
685	xpt_print(periph->path, "LUN removed, %ju ATIOs outstanding, %ju "
686		  "INOTs outstanding, %d refs\n", softc->atios_sent -
687		  softc->atios_returned, softc->inots_sent -
688		  softc->inots_returned, periph->refcount);
689}
690
691static void
692ctlfecleanup(struct cam_periph *periph)
693{
694	struct ctlfe_lun_softc *softc;
695	struct ctlfe_softc *bus_softc;
696
697	xpt_print(periph->path, "%s: Called\n", __func__);
698
699	softc = (struct ctlfe_lun_softc *)periph->softc;
700	bus_softc = softc->parent_softc;
701
702	STAILQ_REMOVE(&bus_softc->lun_softc_list, softc, ctlfe_lun_softc,links);
703
704	/*
705	 * XXX KDM is there anything else that needs to be done here?
706	 */
707	free(softc, M_CTLFE);
708}
709
710static void
711ctlfestart(struct cam_periph *periph, union ccb *start_ccb)
712{
713	struct ctlfe_lun_softc *softc;
714	struct ccb_hdr *ccb_h;
715
716	softc = (struct ctlfe_lun_softc *)periph->softc;
717
718	softc->ccbs_alloced++;
719
720	ccb_h = TAILQ_FIRST(&softc->work_queue);
721	if (periph->immediate_priority <= periph->pinfo.priority) {
722		panic("shouldn't get to the CCB waiting case!");
723		start_ccb->ccb_h.ccb_type = CTLFE_CCB_WAITING;
724		SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
725				  periph_links.sle);
726		periph->immediate_priority = CAM_PRIORITY_NONE;
727		wakeup(&periph->ccb_list);
728	} else if (ccb_h == NULL) {
729		softc->ccbs_freed++;
730		xpt_release_ccb(start_ccb);
731	} else {
732		struct ccb_accept_tio *atio;
733		struct ccb_scsiio *csio;
734		uint8_t *data_ptr;
735		uint32_t dxfer_len;
736		ccb_flags flags;
737		union ctl_io *io;
738		uint8_t scsi_status;
739
740		/* Take the ATIO off the work queue */
741		TAILQ_REMOVE(&softc->work_queue, ccb_h, periph_links.tqe);
742		atio = (struct ccb_accept_tio *)ccb_h;
743		io = (union ctl_io *)ccb_h->io_ptr;
744		csio = &start_ccb->csio;
745
746		flags = atio->ccb_h.flags &
747			(CAM_DIS_DISCONNECT|CAM_TAG_ACTION_VALID|CAM_DIR_MASK);
748
749		if ((io == NULL)
750		 || (io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE) {
751			/*
752			 * We're done, send status back.
753			 */
754			flags |= CAM_SEND_STATUS;
755			if (io == NULL) {
756				scsi_status = SCSI_STATUS_BUSY;
757				csio->sense_len = 0;
758			} else if ((io->io_hdr.status & CTL_STATUS_MASK) ==
759				   CTL_CMD_ABORTED) {
760				io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED;
761
762				/*
763				 * If this command was aborted, we don't
764				 * need to send status back to the SIM.
765				 * Just free the CTIO and ctl_io, and
766				 * recycle the ATIO back to the SIM.
767				 */
768				xpt_print(periph->path, "%s: aborted "
769					  "command 0x%04x discarded\n",
770					  __func__, io->scsiio.tag_num);
771				ctl_free_io(io);
772				/*
773				 * For a wildcard attachment, commands can
774				 * come in with a specific target/lun.  Reset
775				 * the target and LUN fields back to the
776				 * wildcard values before we send them back
777				 * down to the SIM.  The SIM has a wildcard
778				 * LUN enabled, not whatever target/lun
779				 * these happened to be.
780				 */
781				if (softc->flags & CTLFE_LUN_WILDCARD) {
782					atio->ccb_h.target_id =
783						CAM_TARGET_WILDCARD;
784					atio->ccb_h.target_lun =
785						CAM_LUN_WILDCARD;
786				}
787
788				if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
789					cam_release_devq(periph->path,
790							 /*relsim_flags*/0,
791							 /*reduction*/0,
792 							 /*timeout*/0,
793							 /*getcount_only*/0);
794					atio->ccb_h.status &= ~CAM_DEV_QFRZN;
795				}
796
797				ccb_h = TAILQ_FIRST(&softc->work_queue);
798
799				if (atio->ccb_h.func_code !=
800				    XPT_ACCEPT_TARGET_IO) {
801					xpt_print(periph->path, "%s: func_code "
802						  "is %#x\n", __func__,
803						  atio->ccb_h.func_code);
804				}
805				start_ccb->ccb_h.func_code = XPT_ABORT;
806				start_ccb->cab.abort_ccb = (union ccb *)atio;
807				start_ccb->ccb_h.cbfcnp = ctlfedone;
808
809				/* Tell the SIM that we've aborted this ATIO */
810				xpt_action(start_ccb);
811				softc->ccbs_freed++;
812				xpt_release_ccb(start_ccb);
813
814				/*
815				 * Send the ATIO back down to the SIM.
816				 */
817				xpt_action((union ccb *)atio);
818				softc->atios_sent++;
819
820				/*
821				 * If we still have work to do, ask for
822				 * another CCB.  Otherwise, deactivate our
823				 * callout.
824				 */
825				if (ccb_h != NULL)
826					xpt_schedule(periph, /*priority*/ 1);
827				else
828					callout_stop(&softc->dma_callout);
829
830				return;
831			} else {
832				io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED;
833				scsi_status = io->scsiio.scsi_status;
834				csio->sense_len = io->scsiio.sense_len;
835			}
836			data_ptr = NULL;
837			dxfer_len = 0;
838			if (io == NULL) {
839				printf("%s: tag %04x io is NULL\n", __func__,
840				       atio->tag_id);
841			} else {
842#ifdef CTLFEDEBUG
843				printf("%s: tag %04x status %x\n", __func__,
844				       atio->tag_id, io->io_hdr.status);
845#endif
846			}
847			csio->sglist_cnt = 0;
848			if (csio->sense_len != 0) {
849				csio->sense_data = io->scsiio.sense_data;
850				flags |= CAM_SEND_SENSE;
851			} else if (scsi_status == SCSI_STATUS_CHECK_COND) {
852				xpt_print(periph->path, "%s: check condition "
853					  "with no sense\n", __func__);
854			}
855		} else {
856			struct ctlfe_lun_cmd_info *cmd_info;
857
858			/*
859			 * Datamove call, we need to setup the S/G list.
860			 * If we pass in a S/G list, the isp(4) driver at
861			 * least expects physical/bus addresses.
862			 */
863
864			cmd_info = (struct ctlfe_lun_cmd_info *)
865				io->io_hdr.port_priv;
866
867			KASSERT(sizeof(*cmd_info) < CTL_PORT_PRIV_SIZE,
868				("%s: sizeof(struct ctlfe_lun_cmd_info) %zd < "
869				"CTL_PORT_PRIV_SIZE %d", __func__,
870				sizeof(*cmd_info), CTL_PORT_PRIV_SIZE));
871			io->io_hdr.flags &= ~CTL_FLAG_DMA_QUEUED;
872
873			/*
874			 * Need to zero this, in case it has been used for
875			 * a previous datamove for this particular I/O.
876			 */
877			bzero(cmd_info, sizeof(*cmd_info));
878			scsi_status = 0;
879
880			/*
881			 * Set the direction, relative to the initiator.
882			 */
883			flags &= ~CAM_DIR_MASK;
884			if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) ==
885			     CTL_FLAG_DATA_IN)
886				flags |= CAM_DIR_IN;
887			else
888				flags |= CAM_DIR_OUT;
889
890			csio->cdb_len = atio->cdb_len;
891
892			if (io->scsiio.kern_sg_entries == 0) {
893				/* No S/G list */
894				data_ptr = io->scsiio.kern_data_ptr;
895				dxfer_len = io->scsiio.kern_data_len;
896				csio->sglist_cnt = 0;
897
898				if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
899					flags |= CAM_DATA_PHYS;
900			} else if (io->scsiio.kern_sg_entries <=
901				   (sizeof(cmd_info->cam_sglist)/
902				   sizeof(cmd_info->cam_sglist[0]))) {
903				/*
904				 * S/G list with physical or virtual pointers.
905				 * Just populate the CAM S/G list with the
906				 * pointers.
907				 */
908				int i;
909				struct ctl_sg_entry *ctl_sglist;
910				bus_dma_segment_t *cam_sglist;
911
912				ctl_sglist = (struct ctl_sg_entry *)
913					io->scsiio.kern_data_ptr;
914				cam_sglist = cmd_info->cam_sglist;
915
916				for (i = 0; i < io->scsiio.kern_sg_entries;i++){
917					cam_sglist[i].ds_addr =
918						(bus_addr_t)ctl_sglist[i].addr;
919					cam_sglist[i].ds_len =
920						ctl_sglist[i].len;
921				}
922				csio->sglist_cnt = io->scsiio.kern_sg_entries;
923				flags |= CAM_SCATTER_VALID;
924				if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
925					flags |= CAM_SG_LIST_PHYS;
926				else
927					flags &= ~CAM_SG_LIST_PHYS;
928				data_ptr = (uint8_t *)cam_sglist;
929				dxfer_len = io->scsiio.kern_data_len;
930			} else {
931				/* S/G list with virtual pointers */
932				struct ctl_sg_entry *sglist;
933				int *ti;
934
935				/*
936				 * XXX KDM this is a temporary hack.  The
937				 * isp(4) driver can't deal with S/G lists
938				 * with virtual pointers, so we need to
939				 * go through and send down one virtual
940				 * pointer at a time.
941				 */
942				sglist = (struct ctl_sg_entry *)
943					io->scsiio.kern_data_ptr;
944				ti = &cmd_info->cur_transfer_index;
945				data_ptr = sglist[*ti].addr;
946				dxfer_len = sglist[*ti].len;
947				csio->sglist_cnt = 0;
948				cmd_info->flags |= CTLFE_CMD_PIECEWISE;
949				(*ti)++;
950			}
951
952			io->scsiio.ext_data_filled += dxfer_len;
953
954			if (io->scsiio.ext_data_filled >
955			    io->scsiio.kern_total_len) {
956				xpt_print(periph->path, "%s: tag 0x%04x "
957					  "fill len %u > total %u\n",
958					  __func__, io->scsiio.tag_num,
959					  io->scsiio.ext_data_filled,
960					  io->scsiio.kern_total_len);
961			}
962		}
963
964#ifdef CTLFEDEBUG
965		printf("%s: %s: tag %04x flags %x ptr %p len %u\n", __func__,
966		       (flags & CAM_SEND_STATUS) ? "done" : "datamove",
967		       atio->tag_id, flags, data_ptr, dxfer_len);
968#endif
969
970		/*
971		 * Valid combinations:
972		 *  - CAM_SEND_STATUS, SCATTER_VALID = 0, dxfer_len = 0,
973		 *    sglist_cnt = 0
974		 *  - CAM_SEND_STATUS = 0, SCATTER_VALID = 0, dxfer_len != 0,
975		 *    sglist_cnt = 0
976		 *  - CAM_SEND_STATUS = 0, SCATTER_VALID, dxfer_len != 0,
977		 *    sglist_cnt != 0
978		 */
979#ifdef CTLFEDEBUG
980		if (((flags & CAM_SEND_STATUS)
981		  && (((flags & CAM_SCATTER_VALID) != 0)
982		   || (dxfer_len != 0)
983		   || (csio->sglist_cnt != 0)))
984		 || (((flags & CAM_SEND_STATUS) == 0)
985		  && (dxfer_len == 0))
986		 || ((flags & CAM_SCATTER_VALID)
987		  && (csio->sglist_cnt == 0))
988		 || (((flags & CAM_SCATTER_VALID) == 0)
989		  && (csio->sglist_cnt != 0))) {
990			printf("%s: tag %04x cdb %02x flags %#x dxfer_len "
991			       "%d sg %u\n", __func__, atio->tag_id,
992			       atio->cdb_io.cdb_bytes[0], flags, dxfer_len,
993			       csio->sglist_cnt);
994			if (io != NULL) {
995				printf("%s: tag %04x io status %#x\n", __func__,
996				       atio->tag_id, io->io_hdr.status);
997			} else {
998				printf("%s: tag %04x no associated io\n",
999				       __func__, atio->tag_id);
1000			}
1001		}
1002#endif
1003		cam_fill_ctio(csio,
1004			      /*retries*/ 2,
1005			      ctlfedone,
1006			      flags,
1007			      (flags & CAM_TAG_ACTION_VALID) ?
1008			       MSG_SIMPLE_Q_TAG : 0,
1009			      atio->tag_id,
1010			      atio->init_id,
1011			      scsi_status,
1012			      /*data_ptr*/ data_ptr,
1013			      /*dxfer_len*/ dxfer_len,
1014			      /*timeout*/ 5 * 1000);
1015		start_ccb->ccb_h.ccb_atio = atio;
1016		if (((flags & CAM_SEND_STATUS) == 0)
1017		 && (io != NULL))
1018			io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;
1019
1020		softc->ctios_sent++;
1021
1022		xpt_action(start_ccb);
1023
1024		if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1025			cam_release_devq(periph->path,
1026					 /*relsim_flags*/0,
1027					 /*reduction*/0,
1028 					 /*timeout*/0,
1029					 /*getcount_only*/0);
1030			atio->ccb_h.status &= ~CAM_DEV_QFRZN;
1031		}
1032
1033		ccb_h = TAILQ_FIRST(&softc->work_queue);
1034	}
1035	/*
1036	 * If we still have work to do, ask for another CCB.  Otherwise,
1037	 * deactivate our callout.
1038	 */
1039	if (ccb_h != NULL)
1040		xpt_schedule(periph, /*priority*/ 1);
1041	else
1042		callout_stop(&softc->dma_callout);
1043}
1044
1045static void
1046ctlfe_free_ccb(struct cam_periph *periph, union ccb *ccb)
1047{
1048	struct ctlfe_lun_softc *softc;
1049
1050	softc = (struct ctlfe_lun_softc *)periph->softc;
1051
1052	switch (ccb->ccb_h.func_code) {
1053	case XPT_ACCEPT_TARGET_IO:
1054		softc->atios_returned++;
1055		break;
1056	case XPT_IMMEDIATE_NOTIFY:
1057	case XPT_NOTIFY_ACKNOWLEDGE:
1058		softc->inots_returned++;
1059		break;
1060	default:
1061		break;
1062	}
1063
1064	free(ccb, M_CTLFE);
1065
1066	KASSERT(softc->atios_returned <= softc->atios_sent, ("%s: "
1067		"atios_returned %ju > atios_sent %ju", __func__,
1068		softc->atios_returned, softc->atios_sent));
1069	KASSERT(softc->inots_returned <= softc->inots_sent, ("%s: "
1070		"inots_returned %ju > inots_sent %ju", __func__,
1071		softc->inots_returned, softc->inots_sent));
1072
1073	/*
1074	 * If we have received all of our CCBs, we can release our
1075	 * reference on the peripheral driver.  It will probably go away
1076	 * now.
1077	 */
1078	if ((softc->atios_returned == softc->atios_sent)
1079	 && (softc->inots_returned == softc->inots_sent)) {
1080		cam_periph_release_locked(periph);
1081	}
1082}
1083
1084static void
1085ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
1086{
1087	struct ctlfe_lun_softc *softc;
1088	struct ctlfe_softc *bus_softc;
1089
1090#ifdef CTLFE_DEBUG
1091	printf("%s: entered, func_code = %#x, type = %#lx\n", __func__,
1092	       done_ccb->ccb_h.func_code, done_ccb->ccb_h.ccb_type);
1093#endif
1094
1095	softc = (struct ctlfe_lun_softc *)periph->softc;
1096	bus_softc = softc->parent_softc;
1097
1098	if (done_ccb->ccb_h.ccb_type == CTLFE_CCB_WAITING) {
1099		panic("shouldn't get to the CCB waiting case!");
1100		wakeup(&done_ccb->ccb_h.cbfcnp);
1101		return;
1102	}
1103
1104	/*
1105	 * If the peripheral is invalid, ATIOs and immediate notify CCBs
1106	 * need to be freed.  Most of the ATIOs and INOTs that come back
1107	 * will be CCBs that are being returned from the SIM as a result of
1108	 * our disabling the LUN.
1109	 *
1110	 * Other CCB types are handled in their respective cases below.
1111	 */
1112	if (periph->flags & CAM_PERIPH_INVALID) {
1113		switch (done_ccb->ccb_h.func_code) {
1114		case XPT_ACCEPT_TARGET_IO:
1115		case XPT_IMMEDIATE_NOTIFY:
1116		case XPT_NOTIFY_ACKNOWLEDGE:
1117			ctlfe_free_ccb(periph, done_ccb);
1118			return;
1119		default:
1120			break;
1121		}
1122
1123	}
1124	switch (done_ccb->ccb_h.func_code) {
1125	case XPT_ACCEPT_TARGET_IO: {
1126		union ctl_io *io;
1127		struct ccb_accept_tio *atio;
1128
1129		atio = &done_ccb->atio;
1130
1131		softc->atios_returned++;
1132
1133		/*
1134		 * Allocate a ctl_io, pass it to CTL, and wait for the
1135		 * datamove or done.
1136		 */
1137		io = ctl_alloc_io(bus_softc->fe.ctl_pool_ref);
1138		if (io == NULL) {
1139			atio->ccb_h.flags &= ~CAM_DIR_MASK;
1140			atio->ccb_h.flags |= CAM_DIR_NONE;
1141
1142			printf("%s: ctl_alloc_io failed!\n", __func__);
1143
1144			/*
1145			 * XXX KDM need to set SCSI_STATUS_BUSY, but there
1146			 * is no field in the ATIO structure to do that,
1147			 * and we aren't able to allocate a ctl_io here.
1148			 * What to do?
1149			 */
1150			atio->sense_len = 0;
1151			done_ccb->ccb_h.io_ptr = NULL;
1152			TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h,
1153					  periph_links.tqe);
1154			xpt_schedule(periph, /*priority*/ 1);
1155			break;
1156		}
1157		ctl_zero_io(io);
1158
1159		/* Save pointers on both sides */
1160		io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = done_ccb;
1161		done_ccb->ccb_h.io_ptr = io;
1162
1163		/*
1164		 * Only SCSI I/O comes down this path, resets, etc. come
1165		 * down the immediate notify path below.
1166		 */
1167		io->io_hdr.io_type = CTL_IO_SCSI;
1168		io->io_hdr.nexus.initid.id = atio->init_id;
1169		io->io_hdr.nexus.targ_port = bus_softc->fe.targ_port;
1170		io->io_hdr.nexus.targ_target.id = atio->ccb_h.target_id;
1171		io->io_hdr.nexus.targ_lun = atio->ccb_h.target_lun;
1172		io->scsiio.tag_num = atio->tag_id;
1173		switch (atio->tag_action) {
1174		case CAM_TAG_ACTION_NONE:
1175			io->scsiio.tag_type = CTL_TAG_UNTAGGED;
1176			break;
1177		case MSG_SIMPLE_TASK:
1178			io->scsiio.tag_type = CTL_TAG_SIMPLE;
1179			break;
1180		case MSG_HEAD_OF_QUEUE_TASK:
1181        		io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE;
1182			break;
1183		case MSG_ORDERED_TASK:
1184        		io->scsiio.tag_type = CTL_TAG_ORDERED;
1185			break;
1186		case MSG_ACA_TASK:
1187			io->scsiio.tag_type = CTL_TAG_ACA;
1188			break;
1189		default:
1190			io->scsiio.tag_type = CTL_TAG_UNTAGGED;
1191			printf("%s: unhandled tag type %#x!!\n", __func__,
1192			       atio->tag_action);
1193			break;
1194		}
1195		if (atio->cdb_len > sizeof(io->scsiio.cdb)) {
1196			printf("%s: WARNING: CDB len %d > ctl_io space %zd\n",
1197			       __func__, atio->cdb_len, sizeof(io->scsiio.cdb));
1198		}
1199		io->scsiio.cdb_len = min(atio->cdb_len, sizeof(io->scsiio.cdb));
1200		bcopy(atio->cdb_io.cdb_bytes, io->scsiio.cdb,
1201		      io->scsiio.cdb_len);
1202
1203#ifdef CTLFEDEBUG
1204		printf("%s: %ju:%d:%ju:%d: tag %04x CDB %02x\n", __func__,
1205		        (uintmax_t)io->io_hdr.nexus.initid.id,
1206		        io->io_hdr.nexus.targ_port,
1207		        (uintmax_t)io->io_hdr.nexus.targ_target.id,
1208		        io->io_hdr.nexus.targ_lun,
1209			io->scsiio.tag_num, io->scsiio.cdb[0]);
1210#endif
1211
1212		ctl_queue(io);
1213		break;
1214	}
1215	case XPT_CONT_TARGET_IO: {
1216		struct ccb_accept_tio *atio;
1217		union ctl_io *io;
1218
1219		atio = (struct ccb_accept_tio *)done_ccb->ccb_h.ccb_atio;
1220		io = (union ctl_io *)atio->ccb_h.io_ptr;
1221
1222		softc->ctios_returned++;
1223#ifdef CTLFEDEBUG
1224		printf("%s: got XPT_CONT_TARGET_IO tag %#x flags %#x\n",
1225		       __func__, atio->tag_id, done_ccb->ccb_h.flags);
1226#endif
1227		/*
1228		 * If we were sending status back to the initiator, free up
1229		 * resources.  If we were doing a datamove, call the
1230		 * datamove done routine.
1231		 */
1232		if (done_ccb->ccb_h.flags & CAM_SEND_STATUS) {
1233			softc->ccbs_freed++;
1234			xpt_release_ccb(done_ccb);
1235			ctl_free_io(io);
1236			/*
1237			 * For a wildcard attachment, commands can come in
1238			 * with a specific target/lun.  Reset the target
1239			 * and LUN fields back to the wildcard values before
1240			 * we send them back down to the SIM.  The SIM has
1241			 * a wildcard LUN enabled, not whatever target/lun
1242			 * these happened to be.
1243			 */
1244			if (softc->flags & CTLFE_LUN_WILDCARD) {
1245				atio->ccb_h.target_id = CAM_TARGET_WILDCARD;
1246				atio->ccb_h.target_lun = CAM_LUN_WILDCARD;
1247			}
1248			if (periph->flags & CAM_PERIPH_INVALID) {
1249				ctlfe_free_ccb(periph, (union ccb *)atio);
1250				return;
1251			} else {
1252				xpt_action((union ccb *)atio);
1253				softc->atios_sent++;
1254			}
1255		} else {
1256			struct ctlfe_lun_cmd_info *cmd_info;
1257			struct ccb_scsiio *csio;
1258
1259			csio = &done_ccb->csio;
1260			cmd_info = (struct ctlfe_lun_cmd_info *)
1261				io->io_hdr.port_priv;
1262
1263			io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG;
1264
1265			io->scsiio.ext_data_len += csio->dxfer_len;
1266			if (io->scsiio.ext_data_len >
1267			    io->scsiio.kern_total_len) {
1268				xpt_print(periph->path, "%s: tag 0x%04x "
1269					  "done len %u > total %u sent %u\n",
1270					  __func__, io->scsiio.tag_num,
1271					  io->scsiio.ext_data_len,
1272					  io->scsiio.kern_total_len,
1273					  io->scsiio.ext_data_filled);
1274			}
1275			/*
1276			 * Translate CAM status to CTL status.  Success
1277			 * does not change the overall, ctl_io status.  In
1278			 * that case we just set port_status to 0.  If we
1279			 * have a failure, though, set a data phase error
1280			 * for the overall ctl_io.
1281			 */
1282			switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) {
1283			case CAM_REQ_CMP:
1284				io->io_hdr.port_status = 0;
1285				break;
1286			default:
1287				/*
1288				 * XXX KDM the isp(4) driver doesn't really
1289				 * seem to send errors back for data
1290				 * transfers that I can tell.  There is one
1291				 * case where it'll send CAM_REQ_CMP_ERR,
1292				 * but probably not that many more cases.
1293				 * So set a generic data phase error here,
1294				 * like the SXP driver sets.
1295				 */
1296				io->io_hdr.port_status = 0xbad1;
1297				ctl_set_data_phase_error(&io->scsiio);
1298				/*
1299				 * XXX KDM figure out residual.
1300				 */
1301				break;
1302			}
1303			/*
1304			 * If we had to break this S/G list into multiple
1305			 * pieces, figure out where we are in the list, and
1306			 * continue sending pieces if necessary.
1307			 */
1308			if ((cmd_info->flags & CTLFE_CMD_PIECEWISE)
1309			 && (io->io_hdr.port_status == 0)
1310			 && (cmd_info->cur_transfer_index <
1311			     io->scsiio.kern_sg_entries)) {
1312				struct ctl_sg_entry *sglist;
1313				ccb_flags flags;
1314				uint8_t scsi_status;
1315				uint8_t *data_ptr;
1316				uint32_t dxfer_len;
1317				int *ti;
1318
1319				sglist = (struct ctl_sg_entry *)
1320					io->scsiio.kern_data_ptr;
1321				ti = &cmd_info->cur_transfer_index;
1322				flags = atio->ccb_h.flags &
1323					(CAM_DIS_DISCONNECT|
1324					 CAM_TAG_ACTION_VALID|
1325					 CAM_DIR_MASK);
1326
1327				/*
1328				 * Set the direction, relative to the initiator.
1329				 */
1330				flags &= ~CAM_DIR_MASK;
1331				if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) ==
1332				     CTL_FLAG_DATA_IN)
1333					flags |= CAM_DIR_IN;
1334				else
1335					flags |= CAM_DIR_OUT;
1336
1337				data_ptr = sglist[*ti].addr;
1338				dxfer_len = sglist[*ti].len;
1339				(*ti)++;
1340
1341				scsi_status = 0;
1342
1343				if (((flags & CAM_SEND_STATUS) == 0)
1344				 && (dxfer_len == 0)) {
1345					printf("%s: tag %04x no status or "
1346					       "len cdb = %02x\n", __func__,
1347					       atio->tag_id,
1348					atio->cdb_io.cdb_bytes[0]);
1349					printf("%s: tag %04x io status %#x\n",
1350					       __func__, atio->tag_id,
1351					       io->io_hdr.status);
1352				}
1353
1354				cam_fill_ctio(csio,
1355					      /*retries*/ 2,
1356					      ctlfedone,
1357					      flags,
1358					      (flags & CAM_TAG_ACTION_VALID) ?
1359					       MSG_SIMPLE_Q_TAG : 0,
1360					      atio->tag_id,
1361					      atio->init_id,
1362					      scsi_status,
1363					      /*data_ptr*/ data_ptr,
1364					      /*dxfer_len*/ dxfer_len,
1365					      /*timeout*/ 5 * 1000);
1366
1367				csio->resid = 0;
1368				csio->ccb_h.ccb_atio = atio;
1369				io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;
1370				softc->ctios_sent++;
1371				xpt_action((union ccb *)csio);
1372			} else {
1373				/*
1374				 * Release the CTIO.  The ATIO will be sent back
1375				 * down to the SIM once we send status.
1376				 */
1377				softc->ccbs_freed++;
1378				xpt_release_ccb(done_ccb);
1379
1380				/* Call the backend move done callback */
1381				io->scsiio.be_move_done(io);
1382			}
1383		}
1384		break;
1385	}
1386	case XPT_IMMEDIATE_NOTIFY: {
1387		union ctl_io *io;
1388		struct ccb_immediate_notify *inot;
1389		cam_status status;
1390		int frozen;
1391
1392		inot = &done_ccb->cin1;
1393
1394		softc->inots_returned++;
1395
1396		frozen = (done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
1397
1398		printf("%s: got XPT_IMMEDIATE_NOTIFY status %#x tag %#x "
1399		       "seq %#x\n", __func__, inot->ccb_h.status,
1400		       inot->tag_id, inot->seq_id);
1401
1402		io = ctl_alloc_io(bus_softc->fe.ctl_pool_ref);
1403		if (io != NULL) {
1404			int send_ctl_io;
1405
1406			send_ctl_io = 1;
1407
1408			ctl_zero_io(io);
1409			io->io_hdr.io_type = CTL_IO_TASK;
1410			io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr =done_ccb;
1411			inot->ccb_h.io_ptr = io;
1412			io->io_hdr.nexus.initid.id = inot->initiator_id;
1413			io->io_hdr.nexus.targ_port = bus_softc->fe.targ_port;
1414			io->io_hdr.nexus.targ_target.id = inot->ccb_h.target_id;
1415			io->io_hdr.nexus.targ_lun = inot->ccb_h.target_lun;
1416			/* XXX KDM should this be the tag_id? */
1417			io->taskio.tag_num = inot->seq_id;
1418
1419			status = inot->ccb_h.status & CAM_STATUS_MASK;
1420			switch (status) {
1421			case CAM_SCSI_BUS_RESET:
1422				io->taskio.task_action = CTL_TASK_BUS_RESET;
1423				break;
1424			case CAM_BDR_SENT:
1425				io->taskio.task_action = CTL_TASK_TARGET_RESET;
1426				break;
1427			case CAM_MESSAGE_RECV:
1428				switch (inot->arg) {
1429				case MSG_ABORT_TASK_SET:
1430					/*
1431					 * XXX KDM this isn't currently
1432					 * supported by CTL.  It ends up
1433					 * being a no-op.
1434					 */
1435					io->taskio.task_action =
1436						CTL_TASK_ABORT_TASK_SET;
1437					break;
1438				case MSG_TARGET_RESET:
1439					io->taskio.task_action =
1440						CTL_TASK_TARGET_RESET;
1441					break;
1442				case MSG_ABORT_TASK:
1443					io->taskio.task_action =
1444						CTL_TASK_ABORT_TASK;
1445					break;
1446				case MSG_LOGICAL_UNIT_RESET:
1447					io->taskio.task_action =
1448						CTL_TASK_LUN_RESET;
1449					break;
1450				case MSG_CLEAR_TASK_SET:
1451					/*
1452					 * XXX KDM this isn't currently
1453					 * supported by CTL.  It ends up
1454					 * being a no-op.
1455					 */
1456					io->taskio.task_action =
1457						CTL_TASK_CLEAR_TASK_SET;
1458					break;
1459				case MSG_CLEAR_ACA:
1460					io->taskio.task_action =
1461						CTL_TASK_CLEAR_ACA;
1462					break;
1463				case MSG_NOOP:
1464					send_ctl_io = 0;
1465					break;
1466				default:
1467					xpt_print(periph->path, "%s: "
1468						  "unsupported message 0x%x\n",
1469						  __func__, inot->arg);
1470					send_ctl_io = 0;
1471					break;
1472				}
1473				break;
1474			case CAM_REQ_ABORTED:
1475				/*
1476				 * This request was sent back by the driver.
1477				 * XXX KDM what do we do here?
1478				 */
1479				send_ctl_io = 0;
1480				break;
1481			case CAM_REQ_INVALID:
1482			case CAM_PROVIDE_FAIL:
1483			default:
1484				/*
1485				 * We should only get here if we're talking
1486				 * to a talking to a SIM that is target
1487				 * capable but supports the old API.  In
1488				 * that case, we need to just free the CCB.
1489				 * If we actually send a notify acknowledge,
1490				 * it will send that back with an error as
1491				 * well.
1492				 */
1493
1494				if ((status != CAM_REQ_INVALID)
1495				 && (status != CAM_PROVIDE_FAIL))
1496					xpt_print(periph->path, "%s: "
1497						  "unsupported CAM status "
1498						  "0x%x\n", __func__, status);
1499
1500				ctl_free_io(io);
1501				ctlfe_free_ccb(periph, done_ccb);
1502
1503				return;
1504			}
1505			if (send_ctl_io != 0) {
1506				ctl_queue(io);
1507			} else {
1508				ctl_free_io(io);
1509				done_ccb->ccb_h.status = CAM_REQ_INPROG;
1510				done_ccb->ccb_h.func_code =
1511					XPT_NOTIFY_ACKNOWLEDGE;
1512				xpt_action(done_ccb);
1513			}
1514		} else {
1515			xpt_print(periph->path, "%s: could not allocate "
1516				  "ctl_io for immediate notify!\n", __func__);
1517			/* requeue this to the adapter */
1518			done_ccb->ccb_h.status = CAM_REQ_INPROG;
1519			done_ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
1520			xpt_action(done_ccb);
1521		}
1522
1523		if (frozen != 0) {
1524			cam_release_devq(periph->path,
1525					 /*relsim_flags*/ 0,
1526					 /*opening reduction*/ 0,
1527					 /*timeout*/ 0,
1528					 /*getcount_only*/ 0);
1529		}
1530		break;
1531	}
1532	case XPT_NOTIFY_ACKNOWLEDGE:
1533		/*
1534		 * Queue this back down to the SIM as an immediate notify.
1535		 */
1536		done_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
1537		xpt_action(done_ccb);
1538		softc->inots_sent++;
1539		break;
1540	case XPT_ABORT:
1541		/*
1542		 * XPT_ABORT is an immediate CCB, we shouldn't get here.
1543		 */
1544		panic("%s: XPT_ABORT CCB returned!", __func__);
1545		break;
1546	case XPT_SET_SIM_KNOB:
1547	case XPT_GET_SIM_KNOB:
1548		break;
1549	default:
1550		panic("%s: unexpected CCB type %#x", __func__,
1551		      done_ccb->ccb_h.func_code);
1552		break;
1553	}
1554}
1555
1556static void
1557ctlfe_onoffline(void *arg, int online)
1558{
1559	struct ctlfe_softc *bus_softc;
1560	union ccb *ccb;
1561	cam_status status;
1562	struct cam_path *path;
1563	struct cam_sim *sim;
1564	int set_wwnn;
1565
1566	bus_softc = (struct ctlfe_softc *)arg;
1567
1568	set_wwnn = 0;
1569
1570	status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id,
1571		CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
1572	if (status != CAM_REQ_CMP) {
1573		printf("%s: unable to create path!\n", __func__);
1574		return;
1575	}
1576	ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP, M_WAITOK | M_ZERO);
1577	if (ccb == NULL) {
1578		printf("%s: unable to malloc CCB!\n", __func__);
1579		xpt_free_path(path);
1580		return;
1581	}
1582	xpt_setup_ccb(&ccb->ccb_h, path, /*priority*/ 1);
1583
1584	sim = xpt_path_sim(path);
1585
1586	/*
1587	 * Copan WWN format:
1588	 *
1589	 * Bits 63-60:	0x5		NAA, IEEE registered name
1590	 * Bits 59-36:	0x000ED5	IEEE Company name assigned to Copan
1591	 * Bits 35-12:			Copan SSN (Sequential Serial Number)
1592	 * Bits 11-8:			Type of port:
1593	 *					1 == N-Port
1594	 *					2 == F-Port
1595	 *					3 == NL-Port
1596	 * Bits 7-0:			0 == Node Name, >0 == Port Number
1597	 */
1598
1599	if (online != 0) {
1600
1601		ccb->ccb_h.func_code = XPT_GET_SIM_KNOB;
1602
1603		CAM_SIM_LOCK(sim);
1604
1605		xpt_action(ccb);
1606
1607		CAM_SIM_UNLOCK(sim);
1608
1609		if ((ccb->knob.xport_specific.valid & KNOB_VALID_ADDRESS) != 0){
1610#ifdef RANDOM_WWNN
1611			uint64_t random_bits;
1612#endif
1613
1614			printf("%s: %s current WWNN %#jx\n", __func__,
1615			       bus_softc->port_name,
1616			       ccb->knob.xport_specific.fc.wwnn);
1617			printf("%s: %s current WWPN %#jx\n", __func__,
1618			       bus_softc->port_name,
1619			       ccb->knob.xport_specific.fc.wwpn);
1620
1621#ifdef RANDOM_WWNN
1622			arc4rand(&random_bits, sizeof(random_bits), 0);
1623#endif
1624
1625			/*
1626			 * XXX KDM this is a bit of a kludge for now.  We
1627			 * take the current WWNN/WWPN from the card, and
1628			 * replace the company identifier and the NL-Port
1629			 * indicator and the port number (for the WWPN).
1630			 * This should be replaced later with ddb_GetWWNN,
1631			 * or possibly a more centralized scheme.  (It
1632			 * would be nice to have the WWNN/WWPN for each
1633			 * port stored in the ctl_frontend structure.)
1634			 */
1635#ifdef RANDOM_WWNN
1636			ccb->knob.xport_specific.fc.wwnn =
1637				(random_bits &
1638				0x0000000fffffff00ULL) |
1639				/* Company ID */ 0x5000ED5000000000ULL |
1640				/* NL-Port */    0x0300;
1641			ccb->knob.xport_specific.fc.wwpn =
1642				(random_bits &
1643				0x0000000fffffff00ULL) |
1644				/* Company ID */ 0x5000ED5000000000ULL |
1645				/* NL-Port */    0x3000 |
1646				/* Port Num */ (bus_softc->fe.targ_port & 0xff);
1647
1648			/*
1649			 * This is a bit of an API break/reversal, but if
1650			 * we're doing the random WWNN that's a little
1651			 * different anyway.  So record what we're actually
1652			 * using with the frontend code so it's reported
1653			 * accurately.
1654			 */
1655			bus_softc->fe.wwnn =
1656				ccb->knob.xport_specific.fc.wwnn;
1657			bus_softc->fe.wwpn =
1658				ccb->knob.xport_specific.fc.wwpn;
1659			set_wwnn = 1;
1660#else /* RANDOM_WWNN */
1661			/*
1662			 * If the user has specified a WWNN/WWPN, send them
1663			 * down to the SIM.  Otherwise, record what the SIM
1664			 * has reported.
1665			 */
1666			if ((bus_softc->fe.wwnn != 0)
1667			 && (bus_softc->fe.wwpn != 0)) {
1668				ccb->knob.xport_specific.fc.wwnn =
1669					bus_softc->fe.wwnn;
1670				ccb->knob.xport_specific.fc.wwpn =
1671					bus_softc->fe.wwpn;
1672				set_wwnn = 1;
1673			} else {
1674				bus_softc->fe.wwnn =
1675					ccb->knob.xport_specific.fc.wwnn;
1676				bus_softc->fe.wwpn =
1677					ccb->knob.xport_specific.fc.wwpn;
1678			}
1679#endif /* RANDOM_WWNN */
1680
1681
1682			if (set_wwnn != 0) {
1683				printf("%s: %s new WWNN %#jx\n", __func__,
1684				       bus_softc->port_name,
1685				ccb->knob.xport_specific.fc.wwnn);
1686				printf("%s: %s new WWPN %#jx\n", __func__,
1687				       bus_softc->port_name,
1688				       ccb->knob.xport_specific.fc.wwpn);
1689			}
1690		} else {
1691			printf("%s: %s has no valid WWNN/WWPN\n", __func__,
1692			       bus_softc->port_name);
1693		}
1694	}
1695	ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
1696	ccb->knob.xport_specific.valid = KNOB_VALID_ROLE;
1697	if (set_wwnn != 0)
1698		ccb->knob.xport_specific.valid |= KNOB_VALID_ADDRESS;
1699
1700	if (online != 0)
1701		ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET;
1702	else
1703		ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE;
1704
1705
1706	CAM_SIM_LOCK(sim);
1707
1708	xpt_action(ccb);
1709
1710	CAM_SIM_UNLOCK(sim);
1711
1712	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1713		printf("%s: SIM %s (path id %d) target %s failed with "
1714		       "status %#x\n",
1715		       __func__, bus_softc->port_name, bus_softc->path_id,
1716		       (online != 0) ? "enable" : "disable",
1717		       ccb->ccb_h.status);
1718	} else {
1719		printf("%s: SIM %s (path id %d) target %s succeeded\n",
1720		       __func__, bus_softc->port_name, bus_softc->path_id,
1721		       (online != 0) ? "enable" : "disable");
1722	}
1723
1724	free(ccb, M_TEMP);
1725	xpt_free_path(path);
1726
1727	return;
1728}
1729
1730static void
1731ctlfe_online(void *arg)
1732{
1733	ctlfe_onoffline(arg, /*online*/ 1);
1734}
1735
1736static void
1737ctlfe_offline(void *arg)
1738{
1739	ctlfe_onoffline(arg, /*online*/ 0);
1740}
1741
1742static int
1743ctlfe_targ_enable(void *arg, struct ctl_id targ_id)
1744{
1745	return (0);
1746}
1747
1748static int
1749ctlfe_targ_disable(void *arg, struct ctl_id targ_id)
1750{
1751	return (0);
1752}
1753
1754/*
1755 * This will get called to enable a LUN on every bus that is attached to
1756 * CTL.  So we only need to create a path/periph for this particular bus.
1757 */
1758static int
1759ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id)
1760{
1761	struct ctlfe_softc *bus_softc;
1762	struct ctlfe_lun_softc *softc;
1763	struct cam_path *path;
1764	struct cam_periph *periph;
1765	struct cam_sim *sim;
1766	cam_status status;
1767
1768
1769	bus_softc = (struct ctlfe_softc *)arg;
1770
1771	status = xpt_create_path_unlocked(&path, /*periph*/ NULL,
1772					  bus_softc->path_id,
1773					  targ_id.id,
1774					  lun_id);
1775	/* XXX KDM need some way to return status to CTL here? */
1776	if (status != CAM_REQ_CMP) {
1777		printf("%s: could not create path, status %#x\n", __func__,
1778		       status);
1779		return (1);
1780	}
1781
1782	softc = malloc(sizeof(*softc), M_CTLFE, M_WAITOK | M_ZERO);
1783	if (softc == NULL) {
1784		printf("%s: could not allocate %zd bytes for softc\n",
1785		       __func__, sizeof(*softc));
1786		xpt_free_path(path);
1787		return (1);
1788	}
1789	sim = xpt_path_sim(path);
1790	mtx_lock(sim->mtx);
1791	periph = cam_periph_find(path, "ctl");
1792	if (periph != NULL) {
1793		/* We've already got a periph, no need to alloc a new one. */
1794		xpt_free_path(path);
1795		free(softc, M_CTLFE);
1796		mtx_unlock(sim->mtx);
1797		return (0);
1798	}
1799
1800	softc->parent_softc = bus_softc;
1801	STAILQ_INSERT_TAIL(&bus_softc->lun_softc_list, softc, links);
1802
1803	status = cam_periph_alloc(ctlferegister,
1804				  ctlfeoninvalidate,
1805				  ctlfecleanup,
1806				  ctlfestart,
1807				  "ctl",
1808				  CAM_PERIPH_BIO,
1809				  path,
1810				  ctlfeasync,
1811				  0,
1812				  softc);
1813
1814	mtx_unlock(sim->mtx);
1815
1816	xpt_free_path(path);
1817
1818	return (0);
1819}
1820
1821/*
1822 * XXX KDM we disable LUN removal here.  The problem is that the isp(4)
1823 * driver doesn't currently handle LUN removal properly.  We need to keep
1824 * enough state here at the peripheral level even after LUNs have been
1825 * removed inside CTL.
1826 *
1827 * Once the isp(4) driver is fixed, this can be re-enabled.
1828 */
1829static int
1830ctlfe_lun_disable(void *arg, struct ctl_id targ_id, int lun_id)
1831{
1832#ifdef NOTYET
1833	struct ctlfe_softc *softc;
1834	struct ctlfe_lun_softc *lun_softc;
1835
1836	softc = (struct ctlfe_softc *)arg;
1837
1838	mtx_lock(softc->sim->mtx);
1839	STAILQ_FOREACH(lun_softc, &softc->lun_softc_list, links) {
1840		struct cam_path *path;
1841
1842		path = lun_softc->periph->path;
1843
1844		if ((xpt_path_target_id(path) == targ_id.id)
1845		 && (xpt_path_lun_id(path) == lun_id)) {
1846			break;
1847		}
1848	}
1849	if (lun_softc == NULL) {
1850		mtx_unlock(softc->sim->mtx);
1851		printf("%s: can't find target %d lun %d\n", __func__,
1852		       targ_id.id, lun_id);
1853		return (1);
1854	}
1855
1856	cam_periph_invalidate(lun_softc->periph);
1857
1858	mtx_unlock(softc->sim->mtx);
1859#endif
1860
1861	return (0);
1862}
1863
1864static void
1865ctlfe_dump_sim(struct cam_sim *sim)
1866{
1867	int i;
1868
1869	printf("%s%d: max tagged openings: %d, max dev openings: %d\n",
1870	       sim->sim_name, sim->unit_number,
1871	       sim->max_tagged_dev_openings, sim->max_dev_openings);
1872	printf("%s%d: max_ccbs: %u, ccb_count: %u\n",
1873	       sim->sim_name, sim->unit_number,
1874	       sim->max_ccbs, sim->ccb_count);
1875	printf("%s%d: ccb_freeq is %sempty\n",
1876	       sim->sim_name, sim->unit_number,
1877	       (SLIST_FIRST(&sim->ccb_freeq) == NULL) ? "" : "NOT ");
1878	printf("%s%d: alloc_queue.entries %d, alloc_openings %d\n",
1879	       sim->sim_name, sim->unit_number,
1880	       sim->devq->alloc_queue.entries, sim->devq->alloc_openings);
1881	printf("%s%d: qfrozen_cnt:", sim->sim_name, sim->unit_number);
1882	for (i = 0; i < CAM_RL_VALUES; i++) {
1883		printf("%s%u", (i != 0) ? ":" : "",
1884		sim->devq->alloc_queue.qfrozen_cnt[i]);
1885	}
1886	printf("\n");
1887}
1888
1889/*
1890 * Assumes that the SIM lock is held.
1891 */
1892static void
1893ctlfe_dump_queue(struct ctlfe_lun_softc *softc)
1894{
1895	struct ccb_hdr *hdr;
1896	struct cam_periph *periph;
1897	int num_items;
1898
1899	periph = softc->periph;
1900	num_items = 0;
1901
1902	TAILQ_FOREACH(hdr, &softc->work_queue, periph_links.tqe) {
1903		union ctl_io *io;
1904
1905		io = hdr->io_ptr;
1906
1907		num_items++;
1908
1909		/*
1910		 * This can happen when we get an ATIO but can't allocate
1911		 * a ctl_io.  See the XPT_ACCEPT_TARGET_IO case in ctlfedone().
1912		 */
1913		if (io == NULL) {
1914			struct ccb_scsiio *csio;
1915
1916			csio = (struct ccb_scsiio *)hdr;
1917
1918			xpt_print(periph->path, "CCB %#x ctl_io allocation "
1919				  "failed\n", csio->tag_id);
1920			continue;
1921		}
1922
1923		/*
1924		 * Only regular SCSI I/O is put on the work
1925		 * queue, so we can print sense here.  There may be no
1926		 * sense if it's no the queue for a DMA, but this serves to
1927		 * print out the CCB as well.
1928		 *
1929		 * XXX KDM switch this over to scsi_sense_print() when
1930		 * CTL is merged in with CAM.
1931		 */
1932		ctl_io_error_print(io, NULL);
1933
1934		/*
1935		 * We're sending status back to the
1936		 * initiator, so we're on the queue waiting
1937		 * for a CTIO to do that.
1938		 */
1939		if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
1940			continue;
1941
1942		/*
1943		 * Otherwise, we're on the queue waiting to
1944		 * do a data transfer.
1945		 */
1946		xpt_print(periph->path, "Total %u, Current %u, Resid %u\n",
1947			  io->scsiio.kern_total_len, io->scsiio.kern_data_len,
1948			  io->scsiio.kern_data_resid);
1949	}
1950
1951	xpt_print(periph->path, "%d requests total waiting for CCBs\n",
1952		  num_items);
1953	xpt_print(periph->path, "%ju CCBs oustanding (%ju allocated, %ju "
1954		  "freed)\n", (uintmax_t)(softc->ccbs_alloced -
1955		  softc->ccbs_freed), (uintmax_t)softc->ccbs_alloced,
1956		  (uintmax_t)softc->ccbs_freed);
1957	xpt_print(periph->path, "%ju CTIOs outstanding (%ju sent, %ju "
1958		  "returned\n", (uintmax_t)(softc->ctios_sent -
1959		  softc->ctios_returned), softc->ctios_sent,
1960		  softc->ctios_returned);
1961}
1962
1963/*
1964 * This function is called when we fail to get a CCB for a DMA or status return
1965 * to the initiator within the specified time period.
1966 *
1967 * The callout code should insure that we hold the sim mutex here.
1968 */
1969static void
1970ctlfe_dma_timeout(void *arg)
1971{
1972	struct ctlfe_lun_softc *softc;
1973	struct cam_periph *periph;
1974	struct cam_sim *sim;
1975	int num_queued;
1976
1977	softc = (struct ctlfe_lun_softc *)arg;
1978	periph = softc->periph;
1979	sim = xpt_path_sim(periph->path);
1980	num_queued = 0;
1981
1982	/*
1983	 * Nothing to do...
1984	 */
1985	if (TAILQ_FIRST(&softc->work_queue) == NULL) {
1986		xpt_print(periph->path, "TIMEOUT triggered after %d "
1987			  "seconds, but nothing on work queue??\n",
1988			  CTLFE_DMA_TIMEOUT);
1989		return;
1990	}
1991
1992	xpt_print(periph->path, "TIMEOUT (%d seconds) waiting for DMA to "
1993		  "start\n", CTLFE_DMA_TIMEOUT);
1994
1995	ctlfe_dump_queue(softc);
1996
1997	ctlfe_dump_sim(sim);
1998
1999	xpt_print(periph->path, "calling xpt_schedule() to attempt to "
2000		  "unstick our queue\n");
2001
2002	xpt_schedule(periph, /*priority*/ 1);
2003
2004	xpt_print(periph->path, "xpt_schedule() call complete\n");
2005}
2006
2007/*
2008 * Datamove/done routine called by CTL.  Put ourselves on the queue to
2009 * receive a CCB from CAM so we can queue the continue I/O request down
2010 * to the adapter.
2011 */
2012static void
2013ctlfe_datamove_done(union ctl_io *io)
2014{
2015	union ccb *ccb;
2016	struct cam_sim *sim;
2017	struct cam_periph *periph;
2018	struct ctlfe_lun_softc *softc;
2019
2020	ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
2021
2022	sim = xpt_path_sim(ccb->ccb_h.path);
2023
2024	mtx_lock(sim->mtx);
2025
2026	periph = xpt_path_periph(ccb->ccb_h.path);
2027
2028	softc = (struct ctlfe_lun_softc *)periph->softc;
2029
2030	if (io->io_hdr.io_type == CTL_IO_TASK) {
2031		/*
2032		 * Task management commands don't require any further
2033		 * communication back to the adapter.  Requeue the CCB
2034		 * to the adapter, and free the CTL I/O.
2035		 */
2036		xpt_print(ccb->ccb_h.path, "%s: returning task I/O "
2037			  "tag %#x seq %#x\n", __func__,
2038			  ccb->cin1.tag_id, ccb->cin1.seq_id);
2039		/*
2040		 * Send the notify acknowledge down to the SIM, to let it
2041		 * know we processed the task management command.
2042		 */
2043		ccb->ccb_h.status = CAM_REQ_INPROG;
2044		ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
2045		xpt_action(ccb);
2046		ctl_free_io(io);
2047	} else {
2048		if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
2049			io->io_hdr.flags |= CTL_FLAG_STATUS_QUEUED;
2050		else
2051			io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED;
2052
2053		TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h,
2054				  periph_links.tqe);
2055
2056		/*
2057		 * Reset the timeout for our latest active DMA.
2058		 */
2059		callout_reset(&softc->dma_callout,
2060			      CTLFE_DMA_TIMEOUT * hz,
2061			      ctlfe_dma_timeout, softc);
2062		/*
2063		 * Ask for the CAM transport layer to send us a CCB to do
2064		 * the DMA or send status, unless ctlfe_dma_enabled is set
2065		 * to 0.
2066		 */
2067		if (ctlfe_dma_enabled != 0)
2068			xpt_schedule(periph, /*priority*/ 1);
2069	}
2070
2071	mtx_unlock(sim->mtx);
2072}
2073
2074static void
2075ctlfe_dump(void)
2076{
2077	struct ctlfe_softc *bus_softc;
2078
2079	STAILQ_FOREACH(bus_softc, &ctlfe_softc_list, links) {
2080		struct ctlfe_lun_softc *lun_softc;
2081
2082		ctlfe_dump_sim(bus_softc->sim);
2083
2084		STAILQ_FOREACH(lun_softc, &bus_softc->lun_softc_list, links) {
2085			ctlfe_dump_queue(lun_softc);
2086		}
2087	}
2088}
2089