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