[Midnightbsd-cvs] src [11816] trunk/share/examples/scsi_target: update example

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Thu Jul 12 19:17:05 EDT 2018


Revision: 11816
          http://svnweb.midnightbsd.org/src/?rev=11816
Author:   laffer1
Date:     2018-07-12 19:17:04 -0400 (Thu, 12 Jul 2018)
Log Message:
-----------
update example

Modified Paths:
--------------
    trunk/share/examples/scsi_target/Makefile
    trunk/share/examples/scsi_target/scsi_cmds.c
    trunk/share/examples/scsi_target/scsi_target.8
    trunk/share/examples/scsi_target/scsi_target.c
    trunk/share/examples/scsi_target/scsi_target.h

Property Changed:
----------------
    trunk/share/examples/scsi_target/scsi_target.8

Modified: trunk/share/examples/scsi_target/Makefile
===================================================================
--- trunk/share/examples/scsi_target/Makefile	2018-07-12 23:16:47 UTC (rev 11815)
+++ trunk/share/examples/scsi_target/Makefile	2018-07-12 23:17:04 UTC (rev 11816)
@@ -1,4 +1,5 @@
-# $FreeBSD: src/share/examples/scsi_target/Makefile,v 1.5 2004/02/04 10:15:26 ru Exp $
+# $MidnightBSD$
+# $FreeBSD: stable/10/share/examples/scsi_target/Makefile 125429 2004-02-04 10:15:26Z ru $
 
 PROG=	scsi_target
 SRCS=	scsi_target.h scsi_target.c scsi_cmds.c

Modified: trunk/share/examples/scsi_target/scsi_cmds.c
===================================================================
--- trunk/share/examples/scsi_target/scsi_cmds.c	2018-07-12 23:16:47 UTC (rev 11815)
+++ trunk/share/examples/scsi_target/scsi_cmds.c	2018-07-12 23:17:04 UTC (rev 11816)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * SCSI Disk Emulator
  *
@@ -25,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/share/examples/scsi_target/scsi_cmds.c,v 1.6 2004/01/09 19:33:21 njl Exp $
+ * $FreeBSD: stable/10/share/examples/scsi_target/scsi_cmds.c 229997 2012-01-12 00:34:33Z ken $
  */
 
 #include <stdio.h>
@@ -35,6 +36,7 @@
 #include <string.h>
 #include <err.h>
 #include <aio.h>
+#include <unistd.h>
 #include <assert.h>
 #include <sys/param.h>
 #include <sys/types.h>
@@ -48,6 +50,9 @@
 typedef int targ_start_func(struct ccb_accept_tio *, struct ccb_scsiio *);
 typedef void targ_done_func(struct ccb_accept_tio *, struct ccb_scsiio *,
 			      io_ops);
+#ifndef	REPORT_LUNS
+#define	REPORT_LUNS	0xa0
+#endif
 
 struct targ_cdb_handlers {
 	u_int8_t	  cmd;
@@ -87,7 +92,7 @@
 	{ SYNCHRONIZE_CACHE,	tcmd_null_ok,		NULL },
 	{ MODE_SENSE_6,		tcmd_illegal_req,	NULL },
 	{ MODE_SELECT_6,	tcmd_illegal_req,	NULL },
-	/* XXX REPORT_LUNS should be handled here. */
+	{ REPORT_LUNS,		tcmd_illegal_req,	NULL },
 #ifdef READ_16
 	{ READ_16,		tcmd_rdwr,		tcmd_rdwr_done },
 	{ WRITE_16,		tcmd_rdwr,		tcmd_rdwr_done },
@@ -99,8 +104,8 @@
 static struct scsi_inquiry_data inq_data;
 static struct initiator_state istates[MAX_INITIATORS];
 extern int		debug;
-extern uint64_t		volume_size;
-extern size_t		sector_size;
+extern off_t		volume_size;
+extern u_int		sector_size;
 extern size_t		buf_size;
 
 cam_status
@@ -152,6 +157,16 @@
 		}
 		last_cmd = h;
 	}
+
+	/* call completion and exit */
+	if (event != ATIO_WORK) {
+		if (last_cmd->done != NULL)
+			last_cmd->done(atio, ctio, event);
+		else
+			free_ccb((union ccb *)ctio);
+		return (1);
+	}
+
 	if (last_cmd->cmd == ILLEGAL_CDB) {
 		if (event != ATIO_WORK) {
 			warnx("no done func for %#x???", a_descr->cdb[0]);
@@ -164,15 +179,6 @@
 		return (0);
 	}
 
-	/* call completion and exit */
-	if (event != ATIO_WORK) {
-		if (last_cmd->done != NULL)
-			last_cmd->done(atio, ctio, event);
-		else
-			free_ccb((union ccb *)ctio);
-		return (1);
-	}
-
 	istate = tcmd_get_istate(ctio->init_id);
 	if (istate == NULL) {
 		tcmd_illegal_req(atio, ctio);
@@ -237,7 +243,7 @@
 	       u_int8_t asc, u_int8_t ascq)
 {
 	struct initiator_state *istate;
-	struct scsi_sense_data *sense;
+	struct scsi_sense_data_fixed *sense;
 
 	/* Set our initiator's istate */
 	istate = tcmd_get_istate(init_id);
@@ -244,7 +250,7 @@
 	if (istate == NULL)
 		return;
 	istate->pending_ca |= CA_CMD_SENSE; /* XXX set instead of or? */
-	sense = &istate->sense_data;
+	sense = (struct scsi_sense_data_fixed *)&istate->sense_data;
 	bzero(sense, sizeof(*sense));
 	sense->error_code = SSD_CURRENT_ERROR;
 	sense->flags = flags;
@@ -251,8 +257,8 @@
 	sense->add_sense_code = asc;
 	sense->add_sense_code_qual = ascq;
 	sense->extra_len =
-		offsetof(struct scsi_sense_data, sense_key_spec[2]) -
-		offsetof(struct scsi_sense_data, extra_len);
+		offsetof(struct scsi_sense_data_fixed, sense_key_spec[2]) -
+		offsetof(struct scsi_sense_data_fixed, extra_len);
 
 	/* Fill out the supplied CTIO */
 	if (ctio != NULL) {
@@ -293,7 +299,7 @@
 	struct scsi_inquiry *inq;
 	struct atio_descr *a_descr;
 	struct initiator_state *istate;
-	struct scsi_sense_data *sense;
+	struct scsi_sense_data_fixed *sense;
 
 	a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
 	inq = (struct scsi_inquiry *)a_descr->cdb;
@@ -305,7 +311,7 @@
 	 * complain if EVPD or CMDDT is set.
 	 */
 	istate = tcmd_get_istate(ctio->init_id);
-	sense = &istate->sense_data;
+	sense = (struct scsi_sense_data_fixed *)&istate->sense_data;
 	if ((inq->byte2 & SI_EVPD) != 0) {
 		tcmd_illegal_req(atio, ctio);
 		sense->sense_key_spec[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD |
@@ -323,7 +329,7 @@
 		bcopy(&inq_data, ctio->data_ptr, sizeof(inq_data));
 		ctio->dxfer_len = inq_data.additional_length + 4;
 		ctio->dxfer_len = min(ctio->dxfer_len,
-				      SCSI_CDB6_LEN(inq->length));
+				      scsi_2btoul(inq->length));
 		ctio->ccb_h.flags |= CAM_DIR_IN | CAM_SEND_STATUS;
 		ctio->scsi_status = SCSI_STATUS_OK;
 	}
@@ -356,7 +362,7 @@
 
 	/* Advertise only what the SIM can actually support */
 	req_flags &= sim_flags;
-	scsi_ulto2b(req_flags, &inq->reserved[1]);
+	scsi_ulto2b(req_flags, &inq->spc2_flags);
 
 	inq->response_format = 2; /* SCSI2 Inquiry Format */
 	inq->additional_length = SHORT_INQUIRY_LENGTH -
@@ -371,7 +377,7 @@
 tcmd_req_sense(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio)
 {
 	struct scsi_request_sense *rsense;
-	struct scsi_sense_data *sense;
+	struct scsi_sense_data_fixed *sense;
 	struct initiator_state *istate;
 	size_t dlen;
 	struct atio_descr *a_descr;
@@ -380,7 +386,7 @@
 	rsense = (struct scsi_request_sense *)a_descr->cdb;
 	
 	istate = tcmd_get_istate(ctio->init_id);
-	sense = &istate->sense_data;
+	sense = (struct scsi_sense_data_fixed *)&istate->sense_data;
 
 	if (debug) {
 		cdb_debug(a_descr->cdb, "REQ SENSE from %u: ", atio->init_id);
@@ -395,7 +401,7 @@
 	}
 
 	bcopy(sense, ctio->data_ptr, sizeof(struct scsi_sense_data));
-	dlen = offsetof(struct scsi_sense_data, extra_len) +
+	dlen = offsetof(struct scsi_sense_data_fixed, extra_len) +
 			sense->extra_len + 1;
 	ctio->dxfer_len = min(dlen, SCSI_CDB6_LEN(rsense->length));
 	ctio->ccb_h.flags |= CAM_DIR_IN | CAM_SEND_STATUS;
@@ -477,7 +483,7 @@
 	c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
 
 	/* Command needs to be decoded */
-	if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_RESV) {
+	if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_BOTH) {
 		if (debug)
 			warnx("Calling rdwr_decode");
 		ret = tcmd_rdwr_decode(atio, ctio);
@@ -492,21 +498,13 @@
 	if ((a_descr->flags & CAM_DIR_IN) != 0) {
 		ret = start_io(atio, ctio, CAM_DIR_IN);
 		if (debug)
-#if __FreeBSD_version >= 500000
-			warnx("Starting DIR_IN @%jd:%u",
-#else
-			warnx("Starting DIR_IN @%lld:%u",
-#endif
-			    c_descr->offset, a_descr->targ_req);
+			warnx("Starting %p DIR_IN @" OFF_FMT ":%u",
+			    a_descr, c_descr->offset, a_descr->targ_req);
 	} else {
 		ret = start_io(atio, ctio, CAM_DIR_OUT);
 		if (debug)
-#if __FreeBSD_version >= 500000
-			warnx("Starting DIR_OUT @%jd:%u",
-#else
-			warnx("Starting DIR_OUT @%lld:%u",
-#endif
-			    c_descr->offset, a_descr->init_req);
+			warnx("Starting %p DIR_OUT @" OFF_FMT ":%u",
+			    a_descr, c_descr->offset, a_descr->init_req);
 	}
 
 	return (ret);
@@ -568,29 +566,17 @@
 	a_descr->total_len = count * sector_size;
 	if (a_descr->total_len == 0) {
 		if (debug)
-#if __FreeBSD_version >= 500000
-			warnx("r/w 0 blocks @ blkno %ju", blkno);
-#else
-			warnx("r/w 0 blocks @ blkno %llu", blkno);
-#endif
+			warnx("r/w 0 blocks @ blkno " OFF_FMT, blkno);
 		tcmd_null_ok(atio, ctio);
 		return (0);
 	} else if (cdb[0] == WRITE_6 || cdb[0] == WRITE_10) {
 		a_descr->flags |= CAM_DIR_OUT;
 		if (debug)
-#if __FreeBSD_version >= 500000
-			warnx("write %u blocks @ blkno %ju", count, blkno);
-#else
-			warnx("write %u blocks @ blkno %llu", count, blkno);
-#endif
+			warnx("write %u blocks @ blkno " OFF_FMT, count, blkno);
 	} else {
 		a_descr->flags |= CAM_DIR_IN;
 		if (debug)
-#if __FreeBSD_version >= 500000
-			warnx("read %u blocks @ blkno %ju", count, blkno);
-#else
-			warnx("read %u blocks @ blkno %llu", count, blkno);
-#endif
+			warnx("read %u blocks @ blkno " OFF_FMT,  count, blkno);
 	}
 	return (1);
 }
@@ -622,14 +608,41 @@
 	/* If DIR_IN, start read from target, otherwise begin CTIO xfer. */
 	ret = 1;
 	if (dir == CAM_DIR_IN) {
-		if (aio_read(&c_descr->aiocb) < 0)
-			err(1, "aio_read"); /* XXX */
+		if (notaio) {
+			if (debug)
+				warnx("read sync %lu @ block " OFF_FMT,
+				    (unsigned long)
+				    (ctio->dxfer_len / sector_size),
+				    c_descr->offset / sector_size);
+			if (lseek(c_descr->aiocb.aio_fildes,
+			    c_descr->aiocb.aio_offset, SEEK_SET) < 0) {
+				perror("lseek");
+				err(1, "lseek");
+			}
+			if (read(c_descr->aiocb.aio_fildes,
+			    (void *)c_descr->aiocb.aio_buf,
+			    ctio->dxfer_len) != ctio->dxfer_len) {
+				err(1, "read");
+			}
+		} else {
+			if (debug)
+				warnx("read async %lu @ block " OFF_FMT,
+				    (unsigned long)
+				    (ctio->dxfer_len / sector_size),
+				    c_descr->offset / sector_size);
+			if (aio_read(&c_descr->aiocb) < 0) {
+				err(1, "aio_read"); /* XXX */
+			}
+		}
 		a_descr->targ_req += ctio->dxfer_len;
+		/* if we're done, we can mark the CCB as to send status */
 		if (a_descr->targ_req == a_descr->total_len) {
 			ctio->ccb_h.flags |= CAM_SEND_STATUS;
 			ctio->scsi_status = SCSI_STATUS_OK;
 			ret = 0;
 		}
+		if (notaio)
+			tcmd_rdwr_done(atio, ctio, AIO_DONE);
 	} else {
 		if (a_descr->targ_ack == a_descr->total_len)
 			tcmd_null_ok(atio, ctio);
@@ -661,7 +674,7 @@
 
 	switch (event) {
 	case AIO_DONE:
-		if (aio_return(&c_descr->aiocb) < 0) {
+		if (!notaio && aio_return(&c_descr->aiocb) < 0) {
 			warn("aio_return error");
 			/* XXX */
 			tcmd_sense(ctio->init_id, ctio,
@@ -671,8 +684,12 @@
 		}
 		a_descr->targ_ack += ctio->dxfer_len;
 		if ((a_descr->flags & CAM_DIR_IN) != 0) {
-			if (debug)
-				warnx("sending CTIO for AIO read");
+			if (debug) {
+				if (notaio)
+					warnx("sending CTIO for AIO read");
+				else
+					warnx("sending CTIO for sync read");
+			}
 			a_descr->init_req += ctio->dxfer_len;
 			send_ccb((union ccb *)ctio, /*priority*/1);
 		} else {
@@ -685,18 +702,55 @@
 		}
 		break;
 	case CTIO_DONE:
-		if (ctio->ccb_h.status != CAM_REQ_CMP) {
-			/* XXX */
+		switch (ctio->ccb_h.status & CAM_STATUS_MASK) {
+		case CAM_REQ_CMP:
+			break;
+		case CAM_REQUEUE_REQ:
+			warnx("requeueing request");
+			if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+				if (aio_write(&c_descr->aiocb) < 0) {
+					err(1, "aio_write"); /* XXX */
+				}
+			} else {
+				if (aio_read(&c_descr->aiocb) < 0) {
+					err(1, "aio_read"); /* XXX */
+				}
+			}
+			return;
+		default:
 			errx(1, "CTIO failed, status %#x", ctio->ccb_h.status);
 		}
 		a_descr->init_ack += ctio->dxfer_len;
 		if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT &&
 		    ctio->dxfer_len > 0) {
-			if (debug)
-				warnx("sending AIO for CTIO write");
 			a_descr->targ_req += ctio->dxfer_len;
-			if (aio_write(&c_descr->aiocb) < 0)
-				err(1, "aio_write"); /* XXX */
+			if (notaio) {
+				if (debug)
+					warnx("write sync %lu @ block "
+					    OFF_FMT, (unsigned long)
+					    (ctio->dxfer_len / sector_size),
+					    c_descr->offset / sector_size);
+				if (lseek(c_descr->aiocb.aio_fildes,
+				    c_descr->aiocb.aio_offset, SEEK_SET) < 0) {
+					perror("lseek");
+					err(1, "lseek");
+				}
+				if (write(c_descr->aiocb.aio_fildes,
+				    (void *) c_descr->aiocb.aio_buf,
+				    ctio->dxfer_len) != ctio->dxfer_len) {
+					err(1, "write");
+				}
+				tcmd_rdwr_done(atio, ctio, AIO_DONE);
+			} else {
+				if (debug)
+					warnx("write async %lu @ block "
+					    OFF_FMT, (unsigned long)
+					    (ctio->dxfer_len / sector_size),
+					    c_descr->offset / sector_size);
+				if (aio_write(&c_descr->aiocb) < 0) {
+					err(1, "aio_write"); /* XXX */
+				}
+			}
 		} else {
 			if (debug)
 				warnx("CTIO done freeing CTIO");

Modified: trunk/share/examples/scsi_target/scsi_target.8
===================================================================
--- trunk/share/examples/scsi_target/scsi_target.8	2018-07-12 23:16:47 UTC (rev 11815)
+++ trunk/share/examples/scsi_target/scsi_target.8	2018-07-12 23:17:04 UTC (rev 11816)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
 .\" Copyright (c) 2002
 .\"	Nate Lawson.  All rights reserved.
 .\"
@@ -25,7 +26,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/examples/scsi_target/scsi_target.8,v 1.5 2005/01/21 08:36:36 ru Exp $
+.\" $FreeBSD: stable/10/share/examples/scsi_target/scsi_target.8 307403 2016-10-16 22:02:50Z sevan $
 .\"
 .Dd November 15, 2002
 .Dt SCSI_TARGET 8
@@ -155,4 +156,4 @@
 It was rewritten for
 .Fx 5.0
 by
-.An Nate Lawson Aq nate at root.org .
+.An Nate Lawson Aq Mt nate at root.org .


Property changes on: trunk/share/examples/scsi_target/scsi_target.8
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/share/examples/scsi_target/scsi_target.c
===================================================================
--- trunk/share/examples/scsi_target/scsi_target.c	2018-07-12 23:16:47 UTC (rev 11815)
+++ trunk/share/examples/scsi_target/scsi_target.c	2018-07-12 23:17:04 UTC (rev 11816)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * SCSI Disk Emulator
  *
@@ -25,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/share/examples/scsi_target/scsi_target.c,v 1.16 2003/10/18 04:54:08 simokawa Exp $
+ * $FreeBSD: stable/10/share/examples/scsi_target/scsi_target.c 255120 2013-09-01 13:01:59Z mav $
  */
 
 #include <sys/types.h>
@@ -56,12 +57,13 @@
 /* Maximum amount to transfer per CTIO */
 #define MAX_XFER	MAXPHYS
 /* Maximum number of allocated CTIOs */
-#define MAX_CTIOS	32
+#define MAX_CTIOS	64
 /* Maximum sector size for emulated volume */
 #define MAX_SECTOR	32768
 
 /* Global variables */
 int		debug;
+int		notaio = 0;
 off_t		volume_size;
 u_int		sector_size;
 size_t		buf_size;
@@ -86,8 +88,8 @@
 static void		handle_read(void);
 /* static int		work_atio(struct ccb_accept_tio *); */
 static void		queue_io(struct ccb_scsiio *);
-static void		run_queue(struct ccb_accept_tio *);
-static int		work_inot(struct ccb_immed_notify *);
+static int		run_queue(struct ccb_accept_tio *);
+static int		work_inot(struct ccb_immediate_notify *);
 static struct ccb_scsiio *
 			get_ctio(void);
 /* static void		free_ccb(union ccb *); */
@@ -99,8 +101,8 @@
 int
 main(int argc, char *argv[])
 {
-	int ch, unit;
-	char *file_name, targname[16];
+	int ch;
+	char *file_name;
 	u_int16_t req_flags, sim_flags;
 	off_t user_size;
 
@@ -117,7 +119,7 @@
 	TAILQ_INIT(&pending_queue);
 	TAILQ_INIT(&work_queue);
 
-	while ((ch = getopt(argc, argv, "AdSTb:c:s:W:")) != -1) {
+	while ((ch = getopt(argc, argv, "AdSTYb:c:s:W:")) != -1) {
 		switch(ch) {
 		case 'A':
 			req_flags |= SID_Addr16;
@@ -193,6 +195,9 @@
 				/* NOTREACHED */
 			}
 			break;
+		case 'Y':
+			notaio = 1;
+			break;
 		default:
 			usage();
 			/* NOTREACHED */
@@ -222,7 +227,7 @@
 	/* Open backing store for IO */
 	file_fd = open(file_name, O_RDWR);
 	if (file_fd < 0)
-		err(1, "open backing store file");
+		errx(EX_NOINPUT, "open backing store file");
 
 	/* Check backing store size or use the size user gave us */
 	if (user_size == 0) {
@@ -246,20 +251,16 @@
 		volume_size = user_size / sector_size;
 	}
 	if (debug)
-#if __FreeBSD_version >= 500000
-		warnx("volume_size: %d bytes x %jd sectors",
-#else
-		warnx("volume_size: %d bytes x %lld sectors",
-#endif
+		warnx("volume_size: %d bytes x " OFF_FMT " sectors",
 		    sector_size, volume_size);
 
 	if (volume_size <= 0)
 		errx(1, "volume must be larger than %d", sector_size);
 
-	{
+	if (notaio == 0) {
 		struct aiocb aio, *aiop;
 		
-		/* Make sure we have working AIO support */
+		/* See if we have we have working AIO support */
 		memset(&aio, 0, sizeof(aio));
 		aio.aio_buf = malloc(sector_size);
 		if (aio.aio_buf == NULL)
@@ -269,28 +270,25 @@
 		aio.aio_nbytes = sector_size;
 		signal(SIGSYS, SIG_IGN);
 		if (aio_read(&aio) != 0) {
-			printf("You must enable VFS_AIO in your kernel "
-			       "or load the aio(4) module.\n");
-			err(1, "aio_read");
+			printf("AIO support is not available- switchin to"
+			       " single-threaded mode.\n");
+			notaio = 1;
+		} else {
+			if (aio_waitcomplete(&aiop, NULL) != sector_size)
+				err(1, "aio_waitcomplete");
+			assert(aiop == &aio);
+			signal(SIGSYS, SIG_DFL);
 		}
-		if (aio_waitcomplete(&aiop, NULL) != sector_size)
-			err(1, "aio_waitcomplete");
-		assert(aiop == &aio);
-		signal(SIGSYS, SIG_DFL);
 		free((void *)aio.aio_buf);
-		if (debug)
+		if (debug && notaio == 0)
 			warnx("aio support tested ok");
 	}
 
-	/* Go through all the control devices and find one that isn't busy. */
-	unit = 0;
-	do {
-		snprintf(targname, sizeof(targname), "/dev/targ%d", unit++);
-    		targ_fd = open(targname, O_RDWR);
-	} while (targ_fd < 0 && errno == EBUSY);
-
+	targ_fd = open("/dev/targ", O_RDWR);
 	if (targ_fd < 0)
-    	    err(1, "Tried to open %d devices, none available", unit);
+    	    err(1, "/dev/targ");
+	else
+	    warnx("opened /dev/targ");
 
 	/* The first three are handled by kevent() later */
 	signal(SIGHUP, SIG_IGN);
@@ -311,12 +309,13 @@
 	/* Enable debugging if requested */
 	if (debug) {
 		if (ioctl(targ_fd, TARGIOCDEBUG, &debug) != 0)
-			err(1, "TARGIOCDEBUG");
+			warnx("TARGIOCDEBUG");
 	}
 
 	/* Set up inquiry data according to what SIM supports */
 	if (get_sim_flags(&sim_flags) != CAM_REQ_CMP)
 		errx(1, "get_sim_flags");
+
 	if (tcmd_init(req_flags, sim_flags) != 0)
 		errx(1, "Initializing tcmd subsystem failed");
 
@@ -326,6 +325,7 @@
 
 	if (debug)
 		warnx("main loop beginning");
+
 	request_loop();
 
 	exit(0);
@@ -366,7 +366,7 @@
 	for (i = 0; i < MAX_INITIATORS; i++) {
 		struct ccb_accept_tio *atio;
 		struct atio_descr *a_descr;
-		struct ccb_immed_notify *inot;
+		struct ccb_immediate_notify *inot;
 
 		atio = (struct ccb_accept_tio *)malloc(sizeof(*atio));
 		if (atio == NULL) {
@@ -383,12 +383,12 @@
 		atio->ccb_h.targ_descr = a_descr;
 		send_ccb((union ccb *)atio, /*priority*/1);
 
-		inot = (struct ccb_immed_notify *)malloc(sizeof(*inot));
+		inot = (struct ccb_immediate_notify *)malloc(sizeof(*inot));
 		if (inot == NULL) {
 			warn("malloc INOT");
 			return (-1);
 		}
-		inot->ccb_h.func_code = XPT_IMMED_NOTIFY;
+		inot->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
 		send_ccb((union ccb *)inot, /*priority*/1);
 	}
 
@@ -421,7 +421,7 @@
 
 	/* Loop until user signal */
 	while (quit == 0) {
-		int retval, i;
+		int retval, i, oo;
 		struct ccb_hdr *ccb_h;
 
 		/* Check for the next signal, read ready, or AIO completion */
@@ -440,7 +440,7 @@
 		}
 
 		/* Process all received events. */
-		for (i = 0; i < retval; i++) {
+		for (oo = i = 0; i < retval; i++) {
 			if ((events[i].flags & EV_ERROR) != 0)
 				errx(1, "kevent registration failed");
 
@@ -464,7 +464,7 @@
 				/* Queue on the appropriate ATIO */
 				queue_io(ctio);
 				/* Process any queued completions. */
-				run_queue(c_descr->atio);
+				oo += run_queue(c_descr->atio);
 				break;
 			}
 			case EVFILT_SIGNAL:
@@ -473,14 +473,19 @@
 				quit = 1;
 				break;
 			default:
-				warnx("unknown event %#x", events[i].filter);
+				warnx("unknown event %d", events[i].filter);
 				break;
 			}
 
 			if (debug)
-				warnx("event done");
+				warnx("event %d done", events[i].filter);
 		}
 
+		if (oo) {
+			tptr = &ts;
+			continue;
+		}
+
 		/* Grab the first CCB and perform one work unit. */
 		if ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) {
 			union ccb *ccb;
@@ -491,8 +496,8 @@
 				/* Start one more transfer. */
 				retval = work_atio(&ccb->atio);
 				break;
-			case XPT_IMMED_NOTIFY:
-				retval = work_inot(&ccb->cin);
+			case XPT_IMMEDIATE_NOTIFY:
+				retval = work_inot(&ccb->cin1);
 				break;
 			default:
 				warnx("Unhandled ccb type %#x on workq",
@@ -534,7 +539,7 @@
 handle_read()
 {
 	union ccb *ccb_array[MAX_INITIATORS], *ccb;
-	int ccb_count, i;
+	int ccb_count, i, oo;
 
 	ccb_count = read(targ_fd, ccb_array, sizeof(ccb_array));
 	if (ccb_count <= 0) {
@@ -586,10 +591,10 @@
 			/* Queue on the appropriate ATIO */
 			queue_io(ctio);
 			/* Process any queued completions. */
-			run_queue(c_descr->atio);
+			oo += run_queue(c_descr->atio);
 			break;
 		}
-		case XPT_IMMED_NOTIFY:
+		case XPT_IMMEDIATE_NOTIFY:
 			/* INOTs are handled with priority */
 			TAILQ_INSERT_HEAD(&work_queue, &ccb->ccb_h,
 					  periph_links.tqe);
@@ -619,8 +624,9 @@
 
 	/* Get a CTIO and initialize it according to our known parameters */
 	ctio = get_ctio();
-	if (ctio == NULL)
+	if (ctio == NULL) {
 		return (1);
+	}
 	ret = 0;
 	ctio->ccb_h.flags = a_descr->flags;
 	ctio->tag_id = atio->tag_id;
@@ -640,13 +646,13 @@
 	 * receiving this ATIO.
 	 */
 	if (atio->sense_len != 0) {
-		struct scsi_sense_data *sense;
+		struct scsi_sense_data_fixed *sense;
 
 		if (debug) {
 			warnx("ATIO with %u bytes sense received",
 			      atio->sense_len);
 		}
-		sense = &atio->sense_data;
+		sense = (struct scsi_sense_data_fixed *)&atio->sense_data;
 		tcmd_sense(ctio->init_id, ctio, sense->flags,
 			   sense->add_sense_code, sense->add_sense_code_qual);
 		send_ccb((union ccb *)ctio, /*priority*/1);
@@ -659,6 +665,7 @@
 		ret = tcmd_handle(atio, ctio, ATIO_WORK);
 		break;
 	case CAM_REQ_ABORTED:
+		warn("ATIO %p aborted", a_descr);
 		/* Requeue on HBA */
 		TAILQ_REMOVE(&work_queue, &atio->ccb_h, periph_links.tqe);
 		send_ccb((union ccb *)atio, /*priority*/1);
@@ -679,35 +686,29 @@
 {
 	struct ccb_hdr *ccb_h;
 	struct io_queue *ioq;
-	struct ctio_descr *c_descr, *curr_descr;
+	struct ctio_descr *c_descr;
 	
 	c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
-	/* If the completion is for a specific ATIO, queue in order */
-	if (c_descr->atio != NULL) {
-		struct atio_descr *a_descr;
-
-		a_descr = (struct atio_descr *)c_descr->atio->ccb_h.targ_descr;
-		ioq = &a_descr->cmplt_io;
-	} else {
+	if (c_descr->atio == NULL) {
 		errx(1, "CTIO %p has NULL ATIO", ctio);
 	}
+	ioq = &((struct atio_descr *)c_descr->atio->ccb_h.targ_descr)->cmplt_io;
 
-	/* Insert in order, sorted by offset */
-	if (!TAILQ_EMPTY(ioq)) {
-		TAILQ_FOREACH_REVERSE(ccb_h, ioq, io_queue, periph_links.tqe) {
-			curr_descr = (struct ctio_descr *)ccb_h->targ_descr;
-			if (curr_descr->offset <= c_descr->offset) {
-				TAILQ_INSERT_AFTER(ioq, ccb_h, &ctio->ccb_h,
-						   periph_links.tqe);
-				break;
-			}
-			if (TAILQ_PREV(ccb_h, io_queue, periph_links.tqe)
-			    == NULL) {
-				TAILQ_INSERT_BEFORE(ccb_h, &ctio->ccb_h, 
-						    periph_links.tqe);
-				break;
-			}
+	if (TAILQ_EMPTY(ioq)) {
+		TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe);
+		return;
+	}
+
+	TAILQ_FOREACH_REVERSE(ccb_h, ioq, io_queue, periph_links.tqe) {
+		struct ctio_descr *curr_descr = 
+		    (struct ctio_descr *)ccb_h->targ_descr;
+		if (curr_descr->offset <= c_descr->offset) {
+			break;
 		}
+	}
+
+	if (ccb_h) {
+		TAILQ_INSERT_AFTER(ioq, ccb_h, &ctio->ccb_h, periph_links.tqe);
 	} else {
 		TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe);
 	}
@@ -717,7 +718,7 @@
  * Go through all completed AIO/CTIOs for a given ATIO and advance data
  * counts, start continuation IO, etc.
  */
-static void
+static int
 run_queue(struct ccb_accept_tio *atio)
 {
 	struct atio_descr *a_descr;
@@ -725,7 +726,7 @@
 	int sent_status, event;
 
 	if (atio == NULL)
-		return;
+		return (0);
 
 	a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
 
@@ -761,24 +762,25 @@
 				send_ccb((union ccb *)atio, /*priority*/1);
 		} else {
 			/* Gap in offsets so wait until later callback */
-			if (debug)
-				warnx("IO %p out of order", ccb_h);
-			break;
+			if (/* debug */ 1)
+				warnx("IO %p:%p out of order %s",  ccb_h,
+				    a_descr, c_descr->event == AIO_DONE?
+				    "aio" : "ctio");
+			return (1);
 		}
 	}
+	return (0);
 }
 
 static int
-work_inot(struct ccb_immed_notify *inot)
+work_inot(struct ccb_immediate_notify *inot)
 {
 	cam_status status;
-	int sense;
 
 	if (debug)
 		warnx("Working on INOT %p", inot);
 
 	status = inot->ccb_h.status;
-	sense = (status & CAM_AUTOSNS_VALID) != 0;
 	status &= CAM_STATUS_MASK;
 
 	switch (status) {
@@ -791,7 +793,7 @@
 		abort_all_pending();
 		break;
 	case CAM_MESSAGE_RECV:
-		switch (inot->message_args[0]) {
+		switch (inot->arg) {
 		case MSG_TASK_COMPLETE:
 		case MSG_INITIATOR_DET_ERR:
 		case MSG_ABORT_TASK_SET:
@@ -802,7 +804,7 @@
 		case MSG_ABORT_TASK:
 		case MSG_CLEAR_TASK_SET:
 		default:
-			warnx("INOT message %#x", inot->message_args[0]);
+			warnx("INOT message %#x", inot->arg);
 			break;
 		}
 		break;
@@ -814,17 +816,6 @@
 		break;
 	}
 
-	/* If there is sense data, use it */
-	if (sense != 0) {
-		struct scsi_sense_data *sense;
-
-		sense = &inot->sense_data;
-		tcmd_sense(inot->initiator_id, NULL, sense->flags,
-			   sense->add_sense_code, sense->add_sense_code_qual);
-		if (debug)
-			warnx("INOT has sense: %#x", sense->flags);
-	}
-
 	/* Requeue on SIM */
 	TAILQ_REMOVE(&work_queue, &inot->ccb_h, periph_links.tqe);
 	send_ccb((union ccb *)inot, /*priority*/1);
@@ -856,8 +847,10 @@
 	struct ctio_descr *c_descr;
 	struct sigevent *se;
 
-	if (num_ctios == MAX_CTIOS)
+	if (num_ctios == MAX_CTIOS) {
+		warnx("at CTIO max");
 		return (NULL);
+	}
 
 	ctio = (struct ccb_scsiio *)malloc(sizeof(*ctio));
 	if (ctio == NULL) {
@@ -890,7 +883,7 @@
 	se = &c_descr->aiocb.aio_sigevent;
 	se->sigev_notify = SIGEV_KEVENT;
 	se->sigev_notify_kqueue = kq_fd;
-	se->sigev_value.sigval_ptr = ctio;
+	se->sigev_value.sival_ptr = ctio;
 
 	return (ctio);
 }
@@ -911,7 +904,7 @@
 	case XPT_ACCEPT_TARGET_IO:
 		free(ccb->ccb_h.targ_descr);
 		/* FALLTHROUGH */
-	case XPT_IMMED_NOTIFY:
+	case XPT_IMMEDIATE_NOTIFY:
 	default:
 		free(ccb);
 		break;
@@ -987,7 +980,7 @@
 usage()
 {
 	fprintf(stderr,
-		"Usage: scsi_target [-AdST] [-b bufsize] [-c sectorsize]\n"
+		"Usage: scsi_target [-AdSTY] [-b bufsize] [-c sectorsize]\n"
 		"\t\t[-r numbufs] [-s volsize] [-W 8,16,32]\n"
 		"\t\tbus:target:lun filename\n");
 	exit(1);

Modified: trunk/share/examples/scsi_target/scsi_target.h
===================================================================
--- trunk/share/examples/scsi_target/scsi_target.h	2018-07-12 23:16:47 UTC (rev 11815)
+++ trunk/share/examples/scsi_target/scsi_target.h	2018-07-12 23:17:04 UTC (rev 11816)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * SCSI Target Emulator
  *
@@ -25,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/share/examples/scsi_target/scsi_target.h,v 1.3 2004/01/09 19:26:30 njl Exp $
+ * $FreeBSD: stable/10/share/examples/scsi_target/scsi_target.h 196955 2009-09-07 23:16:27Z sbruno $
  */
 
 #ifndef _SCSI_TARGET_H
@@ -33,9 +34,9 @@
 
 /*
  * Maximum number of parallel commands to accept,
- * 256 for Fibre Channel (SPI is 16).
+ * 1024 for Fibre Channel (SPI is 16).
  */
-#define MAX_INITIATORS		256
+#define MAX_INITIATORS		8
 #define	SECTOR_SIZE		512
 #define MAX_EVENTS		(MAX_INITIATORS + 5)
 				/* kqueue for AIO, signals */
@@ -114,4 +115,16 @@
 extern void		free_ccb(union ccb *ccb);
 static __inline u_int	min(u_int a, u_int b) { return (a < b ? a : b); }
 
+/* Global Data */
+extern int notaio;
+
+/*
+ * Compat Defines
+ */
+#if __FreeBSD_version >= 500000
+#define	OFF_FMT	"%ju"
+#else
+#define	OFF_FMT "%llu"
+#endif
+
 #endif /* _SCSI_TARGET_H */



More information about the Midnightbsd-cvs mailing list