Deleted Added
full compact
scsi_target.c (157009) scsi_target.c (162704)
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

--- 11 unchanged lines hidden (view full) ---

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 *
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

--- 11 unchanged lines hidden (view full) ---

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 157009 2006-03-22 17:00:14Z mjacob $
28 * $FreeBSD: head/share/examples/scsi_target/scsi_target.c 162704 2006-09-27 15:38:13Z mjacob $
29 */
30
31#include <sys/types.h>
32#include <ctype.h>
33#include <errno.h>
34#include <err.h>
35#include <fcntl.h>
36#include <signal.h>

--- 14 unchanged lines hidden (view full) ---

51#include <cam/scsi/scsi_all.h>
52#include <cam/scsi/scsi_targetio.h>
53#include <cam/scsi/scsi_message.h>
54#include "scsi_target.h"
55
56/* Maximum amount to transfer per CTIO */
57#define MAX_XFER MAXPHYS
58/* Maximum number of allocated CTIOs */
29 */
30
31#include <sys/types.h>
32#include <ctype.h>
33#include <errno.h>
34#include <err.h>
35#include <fcntl.h>
36#include <signal.h>

--- 14 unchanged lines hidden (view full) ---

51#include <cam/scsi/scsi_all.h>
52#include <cam/scsi/scsi_targetio.h>
53#include <cam/scsi/scsi_message.h>
54#include "scsi_target.h"
55
56/* Maximum amount to transfer per CTIO */
57#define MAX_XFER MAXPHYS
58/* Maximum number of allocated CTIOs */
59#define MAX_CTIOS 32
59#define MAX_CTIOS 64
60/* Maximum sector size for emulated volume */
61#define MAX_SECTOR 32768
62
63/* Global variables */
64int debug;
60/* Maximum sector size for emulated volume */
61#define MAX_SECTOR 32768
62
63/* Global variables */
64int debug;
65int notaio = 0;
65off_t volume_size;
66u_int sector_size;
67size_t buf_size;
68
69/* Local variables */
70static int targ_fd;
71static int kq_fd;
72static int file_fd;

--- 8 unchanged lines hidden (view full) ---

81
82/* Local functions */
83static void cleanup(void);
84static int init_ccbs(void);
85static void request_loop(void);
86static void handle_read(void);
87/* static int work_atio(struct ccb_accept_tio *); */
88static void queue_io(struct ccb_scsiio *);
66off_t volume_size;
67u_int sector_size;
68size_t buf_size;
69
70/* Local variables */
71static int targ_fd;
72static int kq_fd;
73static int file_fd;

--- 8 unchanged lines hidden (view full) ---

82
83/* Local functions */
84static void cleanup(void);
85static int init_ccbs(void);
86static void request_loop(void);
87static void handle_read(void);
88/* static int work_atio(struct ccb_accept_tio *); */
89static void queue_io(struct ccb_scsiio *);
89static void run_queue(struct ccb_accept_tio *);
90static int run_queue(struct ccb_accept_tio *);
90static int work_inot(struct ccb_immed_notify *);
91static struct ccb_scsiio *
92 get_ctio(void);
93/* static void free_ccb(union ccb *); */
94static cam_status get_sim_flags(u_int16_t *);
95static void rel_simq(void);
96static void abort_all_pending(void);
97static void usage(void);

--- 14 unchanged lines hidden (view full) ---

112 num_ctios = 0;
113 sector_size = SECTOR_SIZE;
114 buf_size = DFLTPHYS;
115
116 /* Prepare resource pools */
117 TAILQ_INIT(&pending_queue);
118 TAILQ_INIT(&work_queue);
119
91static int work_inot(struct ccb_immed_notify *);
92static struct ccb_scsiio *
93 get_ctio(void);
94/* static void free_ccb(union ccb *); */
95static cam_status get_sim_flags(u_int16_t *);
96static void rel_simq(void);
97static void abort_all_pending(void);
98static void usage(void);

--- 14 unchanged lines hidden (view full) ---

113 num_ctios = 0;
114 sector_size = SECTOR_SIZE;
115 buf_size = DFLTPHYS;
116
117 /* Prepare resource pools */
118 TAILQ_INIT(&pending_queue);
119 TAILQ_INIT(&work_queue);
120
120 while ((ch = getopt(argc, argv, "AdSTb:c:s:W:")) != -1) {
121 while ((ch = getopt(argc, argv, "AdSTYb:c:s:W:")) != -1) {
121 switch(ch) {
122 case 'A':
123 req_flags |= SID_Addr16;
124 break;
125 case 'd':
126 debug = 1;
127 break;
128 case 'S':

--- 59 unchanged lines hidden (view full) ---

188 req_flags |= SID_WBus32;
189 break;
190 default:
191 warnx("Width %s not supported", optarg);
192 usage();
193 /* NOTREACHED */
194 }
195 break;
122 switch(ch) {
123 case 'A':
124 req_flags |= SID_Addr16;
125 break;
126 case 'd':
127 debug = 1;
128 break;
129 case 'S':

--- 59 unchanged lines hidden (view full) ---

189 req_flags |= SID_WBus32;
190 break;
191 default:
192 warnx("Width %s not supported", optarg);
193 usage();
194 /* NOTREACHED */
195 }
196 break;
197 case 'Y':
198 notaio = 1;
199 break;
196 default:
197 usage();
198 /* NOTREACHED */
199 }
200 }
201 argc -= optind;
202 argv += optind;
203

--- 37 unchanged lines hidden (view full) ---

241 volume_size = mediasize / sector_size;
242 } else
243#endif
244 volume_size = st.st_size / sector_size;
245 } else {
246 volume_size = user_size / sector_size;
247 }
248 if (debug)
200 default:
201 usage();
202 /* NOTREACHED */
203 }
204 }
205 argc -= optind;
206 argv += optind;
207

--- 37 unchanged lines hidden (view full) ---

245 volume_size = mediasize / sector_size;
246 } else
247#endif
248 volume_size = st.st_size / sector_size;
249 } else {
250 volume_size = user_size / sector_size;
251 }
252 if (debug)
249#if __FreeBSD_version >= 500000
250 warnx("volume_size: %d bytes x %jd sectors",
251#else
252 warnx("volume_size: %d bytes x %lld sectors",
253#endif
253 warnx("volume_size: %d bytes x " OFF_FMT " sectors",
254 sector_size, volume_size);
255
256 if (volume_size <= 0)
257 errx(1, "volume must be larger than %d", sector_size);
258
254 sector_size, volume_size);
255
256 if (volume_size <= 0)
257 errx(1, "volume must be larger than %d", sector_size);
258
259 {
259 if (notaio == 0) {
260 struct aiocb aio, *aiop;
261
260 struct aiocb aio, *aiop;
261
262 /* Make sure we have working AIO support */
262 /* See if we have we have working AIO support */
263 memset(&aio, 0, sizeof(aio));
264 aio.aio_buf = malloc(sector_size);
265 if (aio.aio_buf == NULL)
266 err(1, "malloc");
267 aio.aio_fildes = file_fd;
268 aio.aio_offset = 0;
269 aio.aio_nbytes = sector_size;
270 signal(SIGSYS, SIG_IGN);
271 if (aio_read(&aio) != 0) {
263 memset(&aio, 0, sizeof(aio));
264 aio.aio_buf = malloc(sector_size);
265 if (aio.aio_buf == NULL)
266 err(1, "malloc");
267 aio.aio_fildes = file_fd;
268 aio.aio_offset = 0;
269 aio.aio_nbytes = sector_size;
270 signal(SIGSYS, SIG_IGN);
271 if (aio_read(&aio) != 0) {
272 printf("You must enable VFS_AIO in your kernel "
273 "or load the aio(4) module.\n");
274 err(1, "aio_read");
272 printf("AIO support is not available- switchin to"
273 " single-threaded mode.\n");
274 notaio = 1;
275 } else {
276 if (aio_waitcomplete(&aiop, NULL) != sector_size)
277 err(1, "aio_waitcomplete");
278 assert(aiop == &aio);
279 signal(SIGSYS, SIG_DFL);
275 }
280 }
276 if (aio_waitcomplete(&aiop, NULL) != sector_size)
277 err(1, "aio_waitcomplete");
278 assert(aiop == &aio);
279 signal(SIGSYS, SIG_DFL);
280 free((void *)aio.aio_buf);
281 free((void *)aio.aio_buf);
281 if (debug)
282 if (debug && notaio == 0)
282 warnx("aio support tested ok");
283 }
284
285 /* Go through all the control devices and find one that isn't busy. */
286 unit = 0;
287 do {
288 snprintf(targname, sizeof(targname), "/dev/targ%d", unit++);
289 targ_fd = open(targname, O_RDWR);

--- 16 unchanged lines hidden (view full) ---

306
307 /* Enable listening on the specified LUN */
308 if (ioctl(targ_fd, TARGIOCENABLE, &ioc_enlun) != 0)
309 err(1, "TARGIOCENABLE");
310
311 /* Enable debugging if requested */
312 if (debug) {
313 if (ioctl(targ_fd, TARGIOCDEBUG, &debug) != 0)
283 warnx("aio support tested ok");
284 }
285
286 /* Go through all the control devices and find one that isn't busy. */
287 unit = 0;
288 do {
289 snprintf(targname, sizeof(targname), "/dev/targ%d", unit++);
290 targ_fd = open(targname, O_RDWR);

--- 16 unchanged lines hidden (view full) ---

307
308 /* Enable listening on the specified LUN */
309 if (ioctl(targ_fd, TARGIOCENABLE, &ioc_enlun) != 0)
310 err(1, "TARGIOCENABLE");
311
312 /* Enable debugging if requested */
313 if (debug) {
314 if (ioctl(targ_fd, TARGIOCDEBUG, &debug) != 0)
314 err(1, "TARGIOCDEBUG");
315 warnx("TARGIOCDEBUG");
315 }
316
317 /* Set up inquiry data according to what SIM supports */
318 if (get_sim_flags(&sim_flags) != CAM_REQ_CMP)
319 errx(1, "get_sim_flags");
320 if (tcmd_init(req_flags, sim_flags) != 0)
321 errx(1, "Initializing tcmd subsystem failed");
322

--- 93 unchanged lines hidden (view full) ---

416
417 ts.tv_sec = 0;
418 ts.tv_nsec = 0;
419 tptr = NULL;
420 quit = 0;
421
422 /* Loop until user signal */
423 while (quit == 0) {
316 }
317
318 /* Set up inquiry data according to what SIM supports */
319 if (get_sim_flags(&sim_flags) != CAM_REQ_CMP)
320 errx(1, "get_sim_flags");
321 if (tcmd_init(req_flags, sim_flags) != 0)
322 errx(1, "Initializing tcmd subsystem failed");
323

--- 93 unchanged lines hidden (view full) ---

417
418 ts.tv_sec = 0;
419 ts.tv_nsec = 0;
420 tptr = NULL;
421 quit = 0;
422
423 /* Loop until user signal */
424 while (quit == 0) {
424 int retval, i;
425 int retval, i, oo;
425 struct ccb_hdr *ccb_h;
426
427 /* Check for the next signal, read ready, or AIO completion */
428 retval = kevent(kq_fd, NULL, 0, events, MAX_EVENTS, tptr);
429 if (retval < 0) {
430 if (errno == EINTR) {
431 if (debug)
432 warnx("EINTR, looping");
433 continue;
434 }
435 else {
436 err(1, "kevent failed");
437 }
438 } else if (retval > MAX_EVENTS) {
439 errx(1, "kevent returned more events than allocated?");
440 }
441
442 /* Process all received events. */
426 struct ccb_hdr *ccb_h;
427
428 /* Check for the next signal, read ready, or AIO completion */
429 retval = kevent(kq_fd, NULL, 0, events, MAX_EVENTS, tptr);
430 if (retval < 0) {
431 if (errno == EINTR) {
432 if (debug)
433 warnx("EINTR, looping");
434 continue;
435 }
436 else {
437 err(1, "kevent failed");
438 }
439 } else if (retval > MAX_EVENTS) {
440 errx(1, "kevent returned more events than allocated?");
441 }
442
443 /* Process all received events. */
443 for (i = 0; i < retval; i++) {
444 for (oo = i = 0; i < retval; i++) {
444 if ((events[i].flags & EV_ERROR) != 0)
445 errx(1, "kevent registration failed");
446
447 switch (events[i].filter) {
448 case EVFILT_READ:
449 if (debug)
450 warnx("read ready");
451 handle_read();

--- 7 unchanged lines hidden (view full) ---

459
460 ctio = (struct ccb_scsiio *)events[i].udata;
461 c_descr = (struct ctio_descr *)
462 ctio->ccb_h.targ_descr;
463 c_descr->event = AIO_DONE;
464 /* Queue on the appropriate ATIO */
465 queue_io(ctio);
466 /* Process any queued completions. */
445 if ((events[i].flags & EV_ERROR) != 0)
446 errx(1, "kevent registration failed");
447
448 switch (events[i].filter) {
449 case EVFILT_READ:
450 if (debug)
451 warnx("read ready");
452 handle_read();

--- 7 unchanged lines hidden (view full) ---

460
461 ctio = (struct ccb_scsiio *)events[i].udata;
462 c_descr = (struct ctio_descr *)
463 ctio->ccb_h.targ_descr;
464 c_descr->event = AIO_DONE;
465 /* Queue on the appropriate ATIO */
466 queue_io(ctio);
467 /* Process any queued completions. */
467 run_queue(c_descr->atio);
468 oo += run_queue(c_descr->atio);
468 break;
469 }
470 case EVFILT_SIGNAL:
471 if (debug)
472 warnx("signal ready, setting quit");
473 quit = 1;
474 break;
475 default:
469 break;
470 }
471 case EVFILT_SIGNAL:
472 if (debug)
473 warnx("signal ready, setting quit");
474 quit = 1;
475 break;
476 default:
476 warnx("unknown event %#x", events[i].filter);
477 warnx("unknown event %d", events[i].filter);
477 break;
478 }
479
480 if (debug)
478 break;
479 }
480
481 if (debug)
481 warnx("event done");
482 warnx("event %d done", events[i].filter);
482 }
483
483 }
484
485 if (oo) {
486 tptr = &ts;
487 continue;
488 }
489
484 /* Grab the first CCB and perform one work unit. */
485 if ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) {
486 union ccb *ccb;
487
488 ccb = (union ccb *)ccb_h;
489 switch (ccb_h->func_code) {
490 case XPT_ACCEPT_TARGET_IO:
491 /* Start one more transfer. */

--- 37 unchanged lines hidden (view full) ---

529 }
530}
531
532/* CCBs are ready from the kernel */
533static void
534handle_read()
535{
536 union ccb *ccb_array[MAX_INITIATORS], *ccb;
490 /* Grab the first CCB and perform one work unit. */
491 if ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) {
492 union ccb *ccb;
493
494 ccb = (union ccb *)ccb_h;
495 switch (ccb_h->func_code) {
496 case XPT_ACCEPT_TARGET_IO:
497 /* Start one more transfer. */

--- 37 unchanged lines hidden (view full) ---

535 }
536}
537
538/* CCBs are ready from the kernel */
539static void
540handle_read()
541{
542 union ccb *ccb_array[MAX_INITIATORS], *ccb;
537 int ccb_count, i;
543 int ccb_count, i, oo;
538
539 ccb_count = read(targ_fd, ccb_array, sizeof(ccb_array));
540 if (ccb_count <= 0) {
541 warn("read ccb ptrs");
542 return;
543 }
544 ccb_count /= sizeof(union ccb *);
545 if (ccb_count < 1) {

--- 35 unchanged lines hidden (view full) ---

581 struct ctio_descr *c_descr;
582
583 ctio = &ccb->ctio;
584 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
585 c_descr->event = CTIO_DONE;
586 /* Queue on the appropriate ATIO */
587 queue_io(ctio);
588 /* Process any queued completions. */
544
545 ccb_count = read(targ_fd, ccb_array, sizeof(ccb_array));
546 if (ccb_count <= 0) {
547 warn("read ccb ptrs");
548 return;
549 }
550 ccb_count /= sizeof(union ccb *);
551 if (ccb_count < 1) {

--- 35 unchanged lines hidden (view full) ---

587 struct ctio_descr *c_descr;
588
589 ctio = &ccb->ctio;
590 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
591 c_descr->event = CTIO_DONE;
592 /* Queue on the appropriate ATIO */
593 queue_io(ctio);
594 /* Process any queued completions. */
589 run_queue(c_descr->atio);
595 oo += run_queue(c_descr->atio);
590 break;
591 }
592 case XPT_IMMED_NOTIFY:
593 /* INOTs are handled with priority */
594 TAILQ_INSERT_HEAD(&work_queue, &ccb->ccb_h,
595 periph_links.tqe);
596 break;
597 default:

--- 16 unchanged lines hidden (view full) ---

614
615 if (debug)
616 warnx("Working on ATIO %p", atio);
617
618 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
619
620 /* Get a CTIO and initialize it according to our known parameters */
621 ctio = get_ctio();
596 break;
597 }
598 case XPT_IMMED_NOTIFY:
599 /* INOTs are handled with priority */
600 TAILQ_INSERT_HEAD(&work_queue, &ccb->ccb_h,
601 periph_links.tqe);
602 break;
603 default:

--- 16 unchanged lines hidden (view full) ---

620
621 if (debug)
622 warnx("Working on ATIO %p", atio);
623
624 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
625
626 /* Get a CTIO and initialize it according to our known parameters */
627 ctio = get_ctio();
622 if (ctio == NULL)
628 if (ctio == NULL) {
623 return (1);
629 return (1);
630 }
624 ret = 0;
625 ctio->ccb_h.flags = a_descr->flags;
626 ctio->tag_id = atio->tag_id;
627 ctio->init_id = atio->init_id;
628 /* XXX priority needs to be added to a_descr */
629 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
630 c_descr->atio = atio;
631 if ((a_descr->flags & CAM_DIR_IN) != 0)

--- 22 unchanged lines hidden (view full) ---

654 }
655
656 status = atio->ccb_h.status & CAM_STATUS_MASK;
657 switch (status) {
658 case CAM_CDB_RECVD:
659 ret = tcmd_handle(atio, ctio, ATIO_WORK);
660 break;
661 case CAM_REQ_ABORTED:
631 ret = 0;
632 ctio->ccb_h.flags = a_descr->flags;
633 ctio->tag_id = atio->tag_id;
634 ctio->init_id = atio->init_id;
635 /* XXX priority needs to be added to a_descr */
636 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
637 c_descr->atio = atio;
638 if ((a_descr->flags & CAM_DIR_IN) != 0)

--- 22 unchanged lines hidden (view full) ---

661 }
662
663 status = atio->ccb_h.status & CAM_STATUS_MASK;
664 switch (status) {
665 case CAM_CDB_RECVD:
666 ret = tcmd_handle(atio, ctio, ATIO_WORK);
667 break;
668 case CAM_REQ_ABORTED:
669 warn("ATIO %p aborted", a_descr);
662 /* Requeue on HBA */
663 TAILQ_REMOVE(&work_queue, &atio->ccb_h, periph_links.tqe);
664 send_ccb((union ccb *)atio, /*priority*/1);
665 ret = 1;
666 break;
667 default:
668 warnx("ATIO completed with unhandled status %#x", status);
669 abort();

--- 4 unchanged lines hidden (view full) ---

674 return (ret);
675}
676
677static void
678queue_io(struct ccb_scsiio *ctio)
679{
680 struct ccb_hdr *ccb_h;
681 struct io_queue *ioq;
670 /* Requeue on HBA */
671 TAILQ_REMOVE(&work_queue, &atio->ccb_h, periph_links.tqe);
672 send_ccb((union ccb *)atio, /*priority*/1);
673 ret = 1;
674 break;
675 default:
676 warnx("ATIO completed with unhandled status %#x", status);
677 abort();

--- 4 unchanged lines hidden (view full) ---

682 return (ret);
683}
684
685static void
686queue_io(struct ccb_scsiio *ctio)
687{
688 struct ccb_hdr *ccb_h;
689 struct io_queue *ioq;
682 struct ctio_descr *c_descr, *curr_descr;
690 struct ctio_descr *c_descr;
683
684 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
691
692 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
685 /* If the completion is for a specific ATIO, queue in order */
686 if (c_descr->atio != NULL) {
687 struct atio_descr *a_descr;
688
689 a_descr = (struct atio_descr *)c_descr->atio->ccb_h.targ_descr;
690 ioq = &a_descr->cmplt_io;
691 } else {
693 if (c_descr->atio == NULL) {
692 errx(1, "CTIO %p has NULL ATIO", ctio);
693 }
694 errx(1, "CTIO %p has NULL ATIO", ctio);
695 }
696 ioq = &((struct atio_descr *)c_descr->atio->ccb_h.targ_descr)->cmplt_io;
694
697
695 /* Insert in order, sorted by offset */
696 if (!TAILQ_EMPTY(ioq)) {
697 TAILQ_FOREACH_REVERSE(ccb_h, ioq, io_queue, periph_links.tqe) {
698 curr_descr = (struct ctio_descr *)ccb_h->targ_descr;
699 if (curr_descr->offset <= c_descr->offset) {
700 TAILQ_INSERT_AFTER(ioq, ccb_h, &ctio->ccb_h,
701 periph_links.tqe);
702 break;
703 }
704 if (TAILQ_PREV(ccb_h, io_queue, periph_links.tqe)
705 == NULL) {
706 TAILQ_INSERT_BEFORE(ccb_h, &ctio->ccb_h,
707 periph_links.tqe);
708 break;
709 }
698 if (TAILQ_EMPTY(ioq)) {
699 TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe);
700 return;
701 }
702
703 TAILQ_FOREACH_REVERSE(ccb_h, ioq, io_queue, periph_links.tqe) {
704 struct ctio_descr *curr_descr =
705 (struct ctio_descr *)ccb_h->targ_descr;
706 if (curr_descr->offset <= c_descr->offset) {
707 break;
710 }
708 }
709 }
710
711 if (ccb_h) {
712 TAILQ_INSERT_AFTER(ioq, ccb_h, &ctio->ccb_h, periph_links.tqe);
711 } else {
712 TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe);
713 }
714}
715
716/*
717 * Go through all completed AIO/CTIOs for a given ATIO and advance data
718 * counts, start continuation IO, etc.
719 */
713 } else {
714 TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe);
715 }
716}
717
718/*
719 * Go through all completed AIO/CTIOs for a given ATIO and advance data
720 * counts, start continuation IO, etc.
721 */
720static void
722static int
721run_queue(struct ccb_accept_tio *atio)
722{
723 struct atio_descr *a_descr;
724 struct ccb_hdr *ccb_h;
725 int sent_status, event;
726
727 if (atio == NULL)
723run_queue(struct ccb_accept_tio *atio)
724{
725 struct atio_descr *a_descr;
726 struct ccb_hdr *ccb_h;
727 int sent_status, event;
728
729 if (atio == NULL)
728 return;
730 return (0);
729
730 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
731
732 while ((ccb_h = TAILQ_FIRST(&a_descr->cmplt_io)) != NULL) {
733 struct ccb_scsiio *ctio;
734 struct ctio_descr *c_descr;
735
736 ctio = (struct ccb_scsiio *)ccb_h;

--- 19 unchanged lines hidden (view full) ---

756 periph_links.tqe);
757 tcmd_handle(atio, ctio, c_descr->event);
758
759 /* If entire transfer complete, send back ATIO */
760 if (sent_status != 0 && event == CTIO_DONE)
761 send_ccb((union ccb *)atio, /*priority*/1);
762 } else {
763 /* Gap in offsets so wait until later callback */
731
732 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
733
734 while ((ccb_h = TAILQ_FIRST(&a_descr->cmplt_io)) != NULL) {
735 struct ccb_scsiio *ctio;
736 struct ctio_descr *c_descr;
737
738 ctio = (struct ccb_scsiio *)ccb_h;

--- 19 unchanged lines hidden (view full) ---

758 periph_links.tqe);
759 tcmd_handle(atio, ctio, c_descr->event);
760
761 /* If entire transfer complete, send back ATIO */
762 if (sent_status != 0 && event == CTIO_DONE)
763 send_ccb((union ccb *)atio, /*priority*/1);
764 } else {
765 /* Gap in offsets so wait until later callback */
764 if (debug)
765 warnx("IO %p out of order", ccb_h);
766 break;
766 if (/* debug */ 1)
767 warnx("IO %p:%p out of order %s", ccb_h,
768 a_descr, c_descr->event == AIO_DONE?
769 "aio" : "ctio");
770 return (1);
767 }
768 }
771 }
772 }
773 return (0);
769}
770
771static int
772work_inot(struct ccb_immed_notify *inot)
773{
774 cam_status status;
775 int sense;
776

--- 74 unchanged lines hidden (view full) ---

851/* Return a CTIO/descr/buf combo from the freelist or malloc one */
852static struct ccb_scsiio *
853get_ctio()
854{
855 struct ccb_scsiio *ctio;
856 struct ctio_descr *c_descr;
857 struct sigevent *se;
858
774}
775
776static int
777work_inot(struct ccb_immed_notify *inot)
778{
779 cam_status status;
780 int sense;
781

--- 74 unchanged lines hidden (view full) ---

856/* Return a CTIO/descr/buf combo from the freelist or malloc one */
857static struct ccb_scsiio *
858get_ctio()
859{
860 struct ccb_scsiio *ctio;
861 struct ctio_descr *c_descr;
862 struct sigevent *se;
863
859 if (num_ctios == MAX_CTIOS)
864 if (num_ctios == MAX_CTIOS) {
865 warnx("at CTIO max");
860 return (NULL);
866 return (NULL);
867 }
861
862 ctio = (struct ccb_scsiio *)malloc(sizeof(*ctio));
863 if (ctio == NULL) {
864 warn("malloc CTIO");
865 return (NULL);
866 }
867 c_descr = (struct ctio_descr *)malloc(sizeof(*c_descr));
868 if (c_descr == NULL) {

--- 113 unchanged lines hidden (view full) ---

982 }
983 }
984}
985
986static void
987usage()
988{
989 fprintf(stderr,
868
869 ctio = (struct ccb_scsiio *)malloc(sizeof(*ctio));
870 if (ctio == NULL) {
871 warn("malloc CTIO");
872 return (NULL);
873 }
874 c_descr = (struct ctio_descr *)malloc(sizeof(*c_descr));
875 if (c_descr == NULL) {

--- 113 unchanged lines hidden (view full) ---

989 }
990 }
991}
992
993static void
994usage()
995{
996 fprintf(stderr,
990 "Usage: scsi_target [-AdST] [-b bufsize] [-c sectorsize]\n"
997 "Usage: scsi_target [-AdSTY] [-b bufsize] [-c sectorsize]\n"
991 "\t\t[-r numbufs] [-s volsize] [-W 8,16,32]\n"
992 "\t\tbus:target:lun filename\n");
993 exit(1);
994}
998 "\t\t[-r numbufs] [-s volsize] [-W 8,16,32]\n"
999 "\t\tbus:target:lun filename\n");
1000 exit(1);
1001}