scsi_target.c revision 107178
1/*
2 * SCSI Disk Emulator
3 *
4 * Copyright (c) 2002 Nate Lawson.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions, and the following disclaimer,
12 *    without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: head/share/examples/scsi_target/scsi_target.c 107178 2002-11-22 22:55:51Z njl $
29 */
30
31#include <sys/types.h>
32#include <errno.h>
33#include <err.h>
34#include <fcntl.h>
35#include <signal.h>
36#include <stddef.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <sysexits.h>
41#include <unistd.h>
42#include <aio.h>
43#include <sys/stat.h>
44#include <sys/queue.h>
45#include <sys/event.h>
46#include <sys/param.h>
47#include <cam/cam_queue.h>
48#include <cam/scsi/scsi_all.h>
49#include <cam/scsi/scsi_targetio.h>
50#include <cam/scsi/scsi_message.h>
51#include "scsi_target.h"
52
53/* Maximum amount to transfer per CTIO */
54#define MAX_XFER	MAXPHYS
55/* Maximum number of allocated CTIOs */
56#define MAX_CTIOS	32
57/* Maximum sector size for emulated volume */
58#define MAX_SECTOR	32768
59
60/* Global variables */
61int		debug;
62u_int32_t	volume_size;
63size_t		sector_size;
64size_t		buf_size;
65
66/* Local variables */
67static int    targ_fd;
68static int    kq_fd;
69static int    file_fd;
70static int    num_ctios;
71static struct ccb_queue		pending_queue;
72static struct ccb_queue		work_queue;
73static struct ioc_enable_lun	ioc_enlun = {
74	CAM_BUS_WILDCARD,
75	CAM_TARGET_WILDCARD,
76	CAM_LUN_WILDCARD
77};
78
79/* Local functions */
80static void		cleanup(void);
81static int		init_ccbs(void);
82static void		request_loop(void);
83static void		handle_read(void);
84/* static int		work_atio(struct ccb_accept_tio *); */
85static void		queue_io(struct ccb_scsiio *);
86static void		run_queue(struct ccb_accept_tio *);
87static int		work_inot(struct ccb_immed_notify *);
88static struct ccb_scsiio *
89			get_ctio(void);
90/* static void		free_ccb(union ccb *); */
91static cam_status	get_sim_flags(u_int16_t *);
92static void		rel_simq(void);
93static void		abort_all_pending(void);
94static void		usage(void);
95
96int
97main(int argc, char *argv[])
98{
99	int ch, unit;
100	char *file_name, targname[16];
101	u_int16_t req_flags, sim_flags;
102	off_t user_size;
103
104	/* Initialize */
105	debug = 0;
106	req_flags = sim_flags = 0;
107	user_size = 0;
108	targ_fd = file_fd = kq_fd = -1;
109	num_ctios = 0;
110	sector_size = SECTOR_SIZE;
111	buf_size = DFLTPHYS;
112
113	/* Prepare resource pools */
114	TAILQ_INIT(&pending_queue);
115	TAILQ_INIT(&work_queue);
116
117	while ((ch = getopt(argc, argv, "AdSTb:c:s:W:")) != -1) {
118		switch(ch) {
119		case 'A':
120			req_flags |= SID_Addr16;
121			break;
122		case 'd':
123			debug = 1;
124			break;
125		case 'S':
126			req_flags |= SID_Sync;
127			break;
128		case 'T':
129			req_flags |= SID_CmdQue;
130			break;
131		case 'b':
132			buf_size = atoi(optarg);
133			if (buf_size < 256 || buf_size > MAX_XFER)
134				errx(1, "Unreasonable buf size: %s", optarg);
135			break;
136		case 'c':
137			sector_size = atoi(optarg);
138			if (sector_size < 512 || sector_size > MAX_SECTOR)
139				errx(1, "Unreasonable sector size: %s", optarg);
140			break;
141		case 's':
142			user_size = strtoll(optarg, (char **)NULL, /*base*/10);
143			if (user_size < 0)
144				errx(1, "Unreasonable volume size: %s", optarg);
145			break;
146		case 'W':
147			req_flags &= ~(SID_WBus16 | SID_WBus32);
148			switch (atoi(optarg)) {
149			case 8:
150				/* Leave req_flags zeroed */
151				break;
152			case 16:
153				req_flags |= SID_WBus16;
154				break;
155			case 32:
156				req_flags |= SID_WBus32;
157				break;
158			default:
159				warnx("Width %s not supported", optarg);
160				usage();
161				/* NOTREACHED */
162			}
163			break;
164		default:
165			usage();
166			/* NOTREACHED */
167		}
168	}
169	argc -= optind;
170	argv += optind;
171
172	if (argc != 2)
173		usage();
174
175	sscanf(argv[0], "%u:%u:%u", &ioc_enlun.path_id, &ioc_enlun.target_id,
176	       &ioc_enlun.lun_id);
177	file_name = argv[1];
178
179	if (ioc_enlun.path_id == CAM_BUS_WILDCARD ||
180	    ioc_enlun.target_id == CAM_TARGET_WILDCARD ||
181	    ioc_enlun.lun_id == CAM_LUN_WILDCARD) {
182		warnx("Incomplete target path specified");
183		usage();
184		/* NOTREACHED */
185	}
186	/* We don't support any vendor-specific commands */
187	ioc_enlun.grp6_len = 0;
188	ioc_enlun.grp7_len = 0;
189
190	/* Open backing store for IO */
191	file_fd = open(file_name, O_RDWR);
192	if (file_fd < 0)
193		err(1, "open backing store file");
194
195	/* Check backing store size or use the size user gave us */
196	if (user_size == 0) {
197		struct stat st;
198
199		if (fstat(file_fd, &st) < 0)
200			err(1, "fstat file");
201		volume_size = st.st_size / sector_size;
202	} else {
203		volume_size = user_size / sector_size;
204	}
205	if (volume_size <= 0)
206		errx(1, "volume must be larger than %d", sector_size);
207
208	/* Go through all the control devices and find one that isn't busy. */
209	unit = 0;
210	do {
211		snprintf(targname, sizeof(targname), "/dev/targ%d", unit++);
212    		targ_fd = open(targname, O_RDWR);
213	} while (targ_fd < 0 && errno == EBUSY);
214
215	if (targ_fd < 0)
216    	    err(1, "Tried to open %d devices, none available", unit);
217
218	/* The first three are handled by kevent() later */
219	signal(SIGHUP, SIG_IGN);
220	signal(SIGINT, SIG_IGN);
221	signal(SIGTERM, SIG_IGN);
222	signal(SIGPROF, SIG_IGN);
223	signal(SIGALRM, SIG_IGN);
224	signal(SIGSTOP, SIG_IGN);
225	signal(SIGTSTP, SIG_IGN);
226
227	/* Register a cleanup handler to run when exiting */
228	atexit(cleanup);
229
230	/* Enable listening on the specified LUN */
231	if (ioctl(targ_fd, TARGIOCENABLE, &ioc_enlun) != 0)
232		err(1, "TARGIOCENABLE");
233
234	/* Enable debugging if requested */
235	if (debug) {
236		if (ioctl(targ_fd, TARGIOCDEBUG, &debug) != 0)
237			err(1, "TARGIOCDEBUG");
238	}
239
240	/* Set up inquiry data according to what SIM supports */
241	if (get_sim_flags(&sim_flags) != CAM_REQ_CMP)
242		errx(1, "get_sim_flags");
243	if (tcmd_init(req_flags, sim_flags) != 0)
244		errx(1, "Initializing tcmd subsystem failed");
245
246	/* Queue ATIOs and INOTs on descriptor */
247	if (init_ccbs() != 0)
248		errx(1, "init_ccbs failed");
249
250	if (debug)
251		warnx("main loop beginning");
252	request_loop();
253
254	exit(0);
255}
256
257static void
258cleanup()
259{
260	struct ccb_hdr *ccb_h;
261
262	if (debug) {
263		warnx("cleanup called");
264		debug = 0;
265		ioctl(targ_fd, TARGIOCDEBUG, &debug);
266	}
267	ioctl(targ_fd, TARGIOCDISABLE, NULL);
268	close(targ_fd);
269
270	while ((ccb_h = TAILQ_FIRST(&pending_queue)) != NULL) {
271		TAILQ_REMOVE(&pending_queue, ccb_h, periph_links.tqe);
272		free_ccb((union ccb *)ccb_h);
273	}
274	while ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) {
275		TAILQ_REMOVE(&work_queue, ccb_h, periph_links.tqe);
276		free_ccb((union ccb *)ccb_h);
277	}
278
279	if (kq_fd != -1)
280		close(kq_fd);
281}
282
283/* Allocate ATIOs/INOTs and queue on HBA */
284static int
285init_ccbs()
286{
287	int i;
288
289	for (i = 0; i < MAX_INITIATORS; i++) {
290		struct ccb_accept_tio *atio;
291		struct atio_descr *a_descr;
292		struct ccb_immed_notify *inot;
293
294		atio = (struct ccb_accept_tio *)malloc(sizeof(*atio));
295		if (atio == NULL) {
296			warn("malloc ATIO");
297			return (-1);
298		}
299		a_descr = (struct atio_descr *)malloc(sizeof(*a_descr));
300		if (a_descr == NULL) {
301			free(atio);
302			warn("malloc atio_descr");
303			return (-1);
304		}
305		atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
306		atio->ccb_h.targ_descr = a_descr;
307		send_ccb((union ccb *)atio, /*priority*/1);
308
309		inot = (struct ccb_immed_notify *)malloc(sizeof(*inot));
310		if (inot == NULL) {
311			warn("malloc INOT");
312			return (-1);
313		}
314		inot->ccb_h.func_code = XPT_IMMED_NOTIFY;
315		send_ccb((union ccb *)inot, /*priority*/1);
316	}
317
318	return (0);
319}
320
321static void
322request_loop()
323{
324	struct kevent events[MAX_EVENTS];
325	struct timespec ts, *tptr;
326	int quit;
327
328	/* Register kqueue for event notification */
329	if ((kq_fd = kqueue()) < 0)
330		err(1, "init kqueue");
331
332	/* Set up some default events */
333	EV_SET(&events[0], SIGHUP, EVFILT_SIGNAL, EV_ADD|EV_ENABLE, 0, 0, 0);
334	EV_SET(&events[1], SIGINT, EVFILT_SIGNAL, EV_ADD|EV_ENABLE, 0, 0, 0);
335	EV_SET(&events[2], SIGTERM, EVFILT_SIGNAL, EV_ADD|EV_ENABLE, 0, 0, 0);
336	EV_SET(&events[3], targ_fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
337	if (kevent(kq_fd, events, 4, NULL, 0, NULL) < 0)
338		err(1, "kevent signal registration");
339
340	ts.tv_sec = 0;
341	ts.tv_nsec = 0;
342	tptr = NULL;
343	quit = 0;
344
345	/* Loop until user signal */
346	while (quit == 0) {
347		int retval, i;
348		struct ccb_hdr *ccb_h;
349
350		/* Check for the next signal, read ready, or AIO completion */
351		retval = kevent(kq_fd, NULL, 0, events, MAX_EVENTS, tptr);
352		if (retval < 0) {
353			if (errno == EINTR) {
354				if (debug)
355					warnx("EINTR, looping");
356				continue;
357            		}
358			else {
359				err(1, "kevent failed");
360			}
361		} else if (retval > MAX_EVENTS) {
362			errx(1, "kevent returned more events than allocated?");
363		}
364
365		/* Process all received events. */
366		for (i = 0; i < retval; i++) {
367			if ((events[i].flags & EV_ERROR) != 0)
368				errx(1, "kevent registration failed");
369
370			switch (events[i].filter) {
371			case EVFILT_READ:
372				if (debug)
373					warnx("read ready");
374				handle_read();
375				break;
376			case EVFILT_AIO:
377			{
378				struct ccb_scsiio *ctio;
379				struct ctio_descr *c_descr;
380				if (debug)
381					warnx("aio ready");
382
383				ctio = (struct ccb_scsiio *)events[i].udata;
384				c_descr = (struct ctio_descr *)
385					  ctio->ccb_h.targ_descr;
386				c_descr->event = AIO_DONE;
387				/* Queue on the appropriate ATIO */
388				queue_io(ctio);
389				/* Process any queued completions. */
390				run_queue(c_descr->atio);
391				break;
392			}
393			case EVFILT_SIGNAL:
394				if (debug)
395					warnx("signal ready, setting quit");
396				quit = 1;
397				break;
398			default:
399				warnx("unknown event %#x", events[i].filter);
400				break;
401			}
402
403			if (debug)
404				warnx("event done");
405		}
406
407		/* Grab the first CCB and perform one work unit. */
408		if ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) {
409			union ccb *ccb;
410
411			ccb = (union ccb *)ccb_h;
412			switch (ccb_h->func_code) {
413			case XPT_ACCEPT_TARGET_IO:
414				/* Start one more transfer. */
415				retval = work_atio(&ccb->atio);
416				break;
417			case XPT_IMMED_NOTIFY:
418				retval = work_inot(&ccb->cin);
419				break;
420			default:
421				warnx("Unhandled ccb type %#x on workq",
422				      ccb_h->func_code);
423				abort();
424				/* NOTREACHED */
425			}
426
427			/* Assume work function handled the exception */
428			if ((ccb_h->status & CAM_DEV_QFRZN) != 0) {
429				warnx("Queue frozen receiving CCB, releasing");
430				rel_simq();
431			}
432
433			/* No more work needed for this command. */
434			if (retval == 0) {
435				TAILQ_REMOVE(&work_queue, ccb_h,
436					     periph_links.tqe);
437			}
438		}
439
440		/*
441		 * Poll for new events (i.e. completions) while we
442		 * are processing CCBs on the work_queue. Once it's
443		 * empty, use an infinite wait.
444		 */
445		if (!TAILQ_EMPTY(&work_queue))
446			tptr = &ts;
447		else
448			tptr = NULL;
449	}
450}
451
452/* CCBs are ready from the kernel */
453static void
454handle_read()
455{
456	union ccb *ccb_array[MAX_INITIATORS], *ccb;
457	int ccb_count, i;
458
459	ccb_count = read(targ_fd, ccb_array, sizeof(ccb_array));
460	if (ccb_count <= 0) {
461		warn("read ccb ptrs");
462		return;
463	}
464	ccb_count /= sizeof(union ccb *);
465	if (ccb_count < 1) {
466		warnx("truncated read ccb ptr?");
467		return;
468	}
469
470	for (i = 0; i < ccb_count; i++) {
471		ccb = ccb_array[i];
472		TAILQ_REMOVE(&pending_queue, &ccb->ccb_h, periph_links.tqe);
473
474		switch (ccb->ccb_h.func_code) {
475		case XPT_ACCEPT_TARGET_IO:
476		{
477			struct ccb_accept_tio *atio;
478			struct atio_descr *a_descr;
479
480			/* Initialize ATIO descr for this transaction */
481			atio = &ccb->atio;
482			a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
483			bzero(a_descr, sizeof(*a_descr));
484			TAILQ_INIT(&a_descr->cmplt_io);
485			a_descr->flags = atio->ccb_h.flags &
486				(CAM_DIS_DISCONNECT | CAM_TAG_ACTION_VALID);
487			/* XXX add a_descr->priority */
488			if ((atio->ccb_h.flags & CAM_CDB_POINTER) == 0)
489				a_descr->cdb = atio->cdb_io.cdb_bytes;
490			else
491				a_descr->cdb = atio->cdb_io.cdb_ptr;
492
493			/* ATIOs are processed in FIFO order */
494			TAILQ_INSERT_TAIL(&work_queue, &ccb->ccb_h,
495					  periph_links.tqe);
496			break;
497		}
498		case XPT_CONT_TARGET_IO:
499		{
500			struct ccb_scsiio *ctio;
501			struct ctio_descr *c_descr;
502
503			ctio = &ccb->ctio;
504			c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
505			c_descr->event = CTIO_DONE;
506			/* Queue on the appropriate ATIO */
507			queue_io(ctio);
508			/* Process any queued completions. */
509			run_queue(c_descr->atio);
510			break;
511		}
512		case XPT_IMMED_NOTIFY:
513			/* INOTs are handled with priority */
514			TAILQ_INSERT_HEAD(&work_queue, &ccb->ccb_h,
515					  periph_links.tqe);
516			break;
517		default:
518			warnx("Unhandled ccb type %#x in handle_read",
519			      ccb->ccb_h.func_code);
520			break;
521		}
522	}
523}
524
525/* Process an ATIO CCB from the kernel */
526int
527work_atio(struct ccb_accept_tio *atio)
528{
529	struct ccb_scsiio *ctio;
530	struct atio_descr *a_descr;
531	struct ctio_descr *c_descr;
532	cam_status status;
533	int ret;
534
535	if (debug)
536		warnx("Working on ATIO %p", atio);
537
538	a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
539
540	/* Get a CTIO and initialize it according to our known parameters */
541	ctio = get_ctio();
542	if (ctio == NULL)
543		return (1);
544	ret = 0;
545	ctio->ccb_h.flags = a_descr->flags;
546	ctio->tag_id = atio->tag_id;
547	ctio->init_id = atio->init_id;
548	/* XXX priority needs to be added to a_descr */
549	c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
550	c_descr->atio = atio;
551	if ((a_descr->flags & CAM_DIR_IN) != 0)
552		c_descr->offset = a_descr->base_off + a_descr->targ_req;
553	else if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT)
554		c_descr->offset = a_descr->base_off + a_descr->init_req;
555
556	/*
557	 * Return a check condition if there was an error while
558	 * receiving this ATIO.
559	 */
560	if (atio->sense_len != 0) {
561		struct scsi_sense_data *sense;
562
563		if (debug) {
564			warnx("ATIO with %u bytes sense received",
565			      atio->sense_len);
566		}
567		sense = &atio->sense_data;
568		tcmd_sense(ctio->init_id, ctio, sense->flags,
569			   sense->add_sense_code, sense->add_sense_code_qual);
570		send_ccb((union ccb *)ctio, /*priority*/1);
571		return (0);
572	}
573
574	status = atio->ccb_h.status & CAM_STATUS_MASK;
575	switch (status) {
576	case CAM_CDB_RECVD:
577		ret = tcmd_handle(atio, ctio, ATIO_WORK);
578		break;
579	case CAM_REQ_ABORTED:
580		/* Requeue on HBA */
581		TAILQ_REMOVE(&work_queue, &atio->ccb_h, periph_links.tqe);
582		send_ccb((union ccb *)atio, /*priority*/1);
583		ret = 1;
584		break;
585	default:
586		warnx("ATIO completed with unhandled status %#x", status);
587		abort();
588		/* NOTREACHED */
589		break;
590	}
591
592	return (ret);
593}
594
595static void
596queue_io(struct ccb_scsiio *ctio)
597{
598	struct ccb_hdr *ccb_h;
599	struct io_queue *ioq;
600	struct ctio_descr *c_descr, *curr_descr;
601
602	c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
603	/* If the completion is for a specific ATIO, queue in order */
604	if (c_descr->atio != NULL) {
605		struct atio_descr *a_descr;
606
607		a_descr = (struct atio_descr *)c_descr->atio->ccb_h.targ_descr;
608		ioq = &a_descr->cmplt_io;
609	} else {
610		errx(1, "CTIO %p has NULL ATIO", ctio);
611	}
612
613	/* Insert in order, sorted by offset */
614	if (!TAILQ_EMPTY(ioq)) {
615		TAILQ_FOREACH_REVERSE(ccb_h, ioq, io_queue, periph_links.tqe) {
616			curr_descr = (struct ctio_descr *)ccb_h->targ_descr;
617			if (curr_descr->offset <= c_descr->offset) {
618				TAILQ_INSERT_AFTER(ioq, ccb_h, &ctio->ccb_h,
619						   periph_links.tqe);
620				break;
621			}
622			if (TAILQ_PREV(ccb_h, io_queue, periph_links.tqe)
623			    == NULL) {
624				TAILQ_INSERT_BEFORE(ccb_h, &ctio->ccb_h,
625						    periph_links.tqe);
626				break;
627			}
628		}
629	} else {
630		TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe);
631	}
632}
633
634/*
635 * Go through all completed AIO/CTIOs for a given ATIO and advance data
636 * counts, start continuation IO, etc.
637 */
638static void
639run_queue(struct ccb_accept_tio *atio)
640{
641	struct atio_descr *a_descr;
642	struct ccb_hdr *ccb_h;
643	int sent_status, event;
644
645	if (atio == NULL)
646		return;
647
648	a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
649
650	while ((ccb_h = TAILQ_FIRST(&a_descr->cmplt_io)) != NULL) {
651		struct ccb_scsiio *ctio;
652		struct ctio_descr *c_descr;
653
654		ctio = (struct ccb_scsiio *)ccb_h;
655		c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
656
657		/* If completed item is in range, call handler */
658		if ((c_descr->event == AIO_DONE &&
659		    c_descr->offset == a_descr->base_off + a_descr->targ_ack)
660		 || (c_descr->event == CTIO_DONE &&
661		    c_descr->offset == a_descr->base_off + a_descr->init_ack)) {
662			sent_status = (ccb_h->flags & CAM_SEND_STATUS) != 0;
663			event = c_descr->event;
664
665			TAILQ_REMOVE(&a_descr->cmplt_io, ccb_h,
666				     periph_links.tqe);
667			tcmd_handle(atio, ctio, c_descr->event);
668
669			/* If entire transfer complete, send back ATIO */
670			if (sent_status != 0 && event == CTIO_DONE)
671				send_ccb((union ccb *)atio, /*priority*/1);
672		} else {
673			/* Gap in offsets so wait until later callback */
674			if (debug)
675				warnx("IO %p out of order", ccb_h);
676			break;
677		}
678	}
679}
680
681static int
682work_inot(struct ccb_immed_notify *inot)
683{
684	cam_status status;
685	int sense;
686
687	if (debug)
688		warnx("Working on INOT %p", inot);
689
690	status = inot->ccb_h.status;
691	sense = (status & CAM_AUTOSNS_VALID) != 0;
692	status &= CAM_STATUS_MASK;
693
694	switch (status) {
695	case CAM_SCSI_BUS_RESET:
696		tcmd_ua(CAM_TARGET_WILDCARD, UA_BUS_RESET);
697		abort_all_pending();
698		break;
699	case CAM_BDR_SENT:
700		tcmd_ua(CAM_TARGET_WILDCARD, UA_BDR);
701		abort_all_pending();
702		break;
703	case CAM_MESSAGE_RECV:
704		switch (inot->message_args[0]) {
705		case MSG_TASK_COMPLETE:
706		case MSG_INITIATOR_DET_ERR:
707		case MSG_ABORT_TASK_SET:
708		case MSG_MESSAGE_REJECT:
709		case MSG_NOOP:
710		case MSG_PARITY_ERROR:
711		case MSG_TARGET_RESET:
712		case MSG_ABORT_TASK:
713		case MSG_CLEAR_TASK_SET:
714		default:
715			warnx("INOT message %#x", inot->message_args[0]);
716			break;
717		}
718		break;
719	case CAM_REQ_ABORTED:
720		warnx("INOT %p aborted", inot);
721		break;
722	default:
723		warnx("Unhandled INOT status %#x", status);
724		break;
725	}
726
727	/* If there is sense data, use it */
728	if (sense != 0) {
729		struct scsi_sense_data *sense;
730
731		sense = &inot->sense_data;
732		tcmd_sense(inot->initiator_id, NULL, sense->flags,
733			   sense->add_sense_code, sense->add_sense_code_qual);
734		if (debug)
735			warnx("INOT has sense: %#x", sense->flags);
736	}
737
738	/* Requeue on SIM */
739	TAILQ_REMOVE(&work_queue, &inot->ccb_h, periph_links.tqe);
740	send_ccb((union ccb *)inot, /*priority*/1);
741
742	return (1);
743}
744
745void
746send_ccb(union ccb *ccb, int priority)
747{
748	if (debug)
749		warnx("sending ccb (%#x)", ccb->ccb_h.func_code);
750	ccb->ccb_h.pinfo.priority = priority;
751	if (XPT_FC_IS_QUEUED(ccb)) {
752		TAILQ_INSERT_TAIL(&pending_queue, &ccb->ccb_h,
753				  periph_links.tqe);
754	}
755	if (write(targ_fd, &ccb, sizeof(ccb)) != sizeof(ccb)) {
756		warn("write ccb");
757		ccb->ccb_h.status = CAM_PROVIDE_FAIL;
758	}
759}
760
761/* Return a CTIO/descr/buf combo from the freelist or malloc one */
762static struct ccb_scsiio *
763get_ctio()
764{
765	struct ccb_scsiio *ctio;
766	struct ctio_descr *c_descr;
767	struct sigevent *se;
768
769	if (num_ctios == MAX_CTIOS)
770		return (NULL);
771
772	ctio = (struct ccb_scsiio *)malloc(sizeof(*ctio));
773	if (ctio == NULL) {
774		warn("malloc CTIO");
775		return (NULL);
776	}
777	c_descr = (struct ctio_descr *)malloc(sizeof(*c_descr));
778	if (c_descr == NULL) {
779		free(ctio);
780		warn("malloc ctio_descr");
781		return (NULL);
782	}
783	c_descr->buf = malloc(buf_size);
784	if (c_descr->buf == NULL) {
785		free(c_descr);
786		free(ctio);
787		warn("malloc backing store");
788		return (NULL);
789	}
790	num_ctios++;
791
792	/* Initialize CTIO, CTIO descr, and AIO */
793	ctio->ccb_h.func_code = XPT_CONT_TARGET_IO;
794	ctio->ccb_h.retry_count = 2;
795	ctio->ccb_h.timeout = 5;
796	ctio->data_ptr = c_descr->buf;
797	ctio->ccb_h.targ_descr = c_descr;
798	c_descr->aiocb.aio_buf = c_descr->buf;
799	c_descr->aiocb.aio_fildes = file_fd;
800	se = &c_descr->aiocb.aio_sigevent;
801	se->sigev_notify = SIGEV_KEVENT;
802	se->sigev_notify_kqueue = kq_fd;
803	se->sigev_value.sigval_ptr = ctio;
804
805	return (ctio);
806}
807
808void
809free_ccb(union ccb *ccb)
810{
811	switch (ccb->ccb_h.func_code) {
812	case XPT_CONT_TARGET_IO:
813	{
814		struct ctio_descr *c_descr;
815
816		c_descr = (struct ctio_descr *)ccb->ccb_h.targ_descr;
817		free(c_descr->buf);
818		num_ctios--;
819		/* FALLTHROUGH */
820	}
821	case XPT_ACCEPT_TARGET_IO:
822		free(ccb->ccb_h.targ_descr);
823		/* FALLTHROUGH */
824	case XPT_IMMED_NOTIFY:
825	default:
826		free(ccb);
827		break;
828	}
829}
830
831static cam_status
832get_sim_flags(u_int16_t *flags)
833{
834	struct ccb_pathinq cpi;
835	cam_status status;
836
837	/* Find SIM capabilities */
838	bzero(&cpi, sizeof(cpi));
839	cpi.ccb_h.func_code = XPT_PATH_INQ;
840	send_ccb((union ccb *)&cpi, /*priority*/1);
841	status = cpi.ccb_h.status & CAM_STATUS_MASK;
842	if (status != CAM_REQ_CMP) {
843		fprintf(stderr, "CPI failed, status %#x\n", status);
844		return (status);
845	}
846
847	/* Can only enable on controllers that support target mode */
848	if ((cpi.target_sprt & PIT_PROCESSOR) == 0) {
849		fprintf(stderr, "HBA does not support target mode\n");
850		status = CAM_PATH_INVALID;
851		return (status);
852	}
853
854	*flags = cpi.hba_inquiry;
855	return (status);
856}
857
858static void
859rel_simq()
860{
861	struct ccb_relsim crs;
862
863	bzero(&crs, sizeof(crs));
864	crs.ccb_h.func_code = XPT_REL_SIMQ;
865	crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
866	crs.openings = 0;
867	crs.release_timeout = 0;
868	crs.qfrozen_cnt = 0;
869	send_ccb((union ccb *)&crs, /*priority*/0);
870}
871
872/* Cancel all pending CCBs. */
873static void
874abort_all_pending()
875{
876	struct ccb_abort	 cab;
877	struct ccb_hdr		*ccb_h;
878
879	if (debug)
880		  warnx("abort_all_pending");
881
882	bzero(&cab, sizeof(cab));
883	cab.ccb_h.func_code = XPT_ABORT;
884	TAILQ_FOREACH(ccb_h, &pending_queue, periph_links.tqe) {
885		if (debug)
886			  warnx("Aborting pending CCB %p\n", ccb_h);
887		cab.abort_ccb = (union ccb *)ccb_h;
888		send_ccb((union ccb *)&cab, /*priority*/1);
889		if (cab.ccb_h.status != CAM_REQ_CMP) {
890			warnx("Unable to abort CCB, status %#x\n",
891			       cab.ccb_h.status);
892		}
893	}
894}
895
896static void
897usage()
898{
899	fprintf(stderr,
900		"Usage: scsi_target [-AdST] [-b bufsize] [-c sectorsize]\n"
901		"\t\t[-r numbufs] [-s volsize] [-W 8,16,32]\n"
902		"\t\tbus:target:lun filename\n");
903	exit(1);
904}
905