Module Name:    src
Committed By:   reinoud
Date:           Tue Jun  5 20:02:43 UTC 2018

Modified Files:
        src/sys/arch/usermode/conf: GENERIC.common files.usermode
        src/sys/arch/usermode/dev: mainbus.c
        src/sys/arch/usermode/include: mainbus.h
        src/sys/arch/usermode/usermode: machdep.c
Added Files:
        src/sys/arch/usermode/dev: vatapi.c

Log Message:
Add ATAPI passtrough support giving the NetBSD/usermode kernel full control of
an ATAPI device. All ATAPI/SCSI commands are passed trough.

Note that ATAPI/SCSI calls are made in the foreground still. Lengthy calls
will still hug the CPU until completion. Making it asynchronous is in the
pipeline


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/usermode/conf/GENERIC.common
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/usermode/conf/files.usermode
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/usermode/dev/mainbus.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/dev/vatapi.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/usermode/include/mainbus.h
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/usermode/usermode/machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/usermode/conf/GENERIC.common
diff -u src/sys/arch/usermode/conf/GENERIC.common:1.27 src/sys/arch/usermode/conf/GENERIC.common:1.28
--- src/sys/arch/usermode/conf/GENERIC.common:1.27	Sat Jan 13 16:20:33 2018
+++ src/sys/arch/usermode/conf/GENERIC.common	Tue Jun  5 20:02:42 2018
@@ -1,9 +1,9 @@
-# $NetBSD: GENERIC.common,v 1.27 2018/01/13 16:20:33 reinoud Exp $
+# $NetBSD: GENERIC.common,v 1.28 2018/06/05 20:02:42 reinoud Exp $
 
 include "arch/usermode/conf/std.usermode"
 
 options 	INCLUDE_CONFIG_FILE
-#ident 		"GENERIC-$Revision: 1.27 $"
+#ident 		"GENERIC-$Revision: 1.28 $"
 maxusers 	32
 
 makeoptions	DEBUG="-O1 -g3"
@@ -64,7 +64,6 @@ ld*		at mainbus?
 veth0		at mainbus?
 vaudio0		at mainbus?
 audio0		at vaudio0
-
 spkr*		at audio?		# PC speaker (synthesized)
 
 vncfb0		at mainbus?
@@ -77,6 +76,17 @@ options 	WSKBD_DEFAULT_KEYREPEAT_DEL1=10
 options 	WSKBD_DEFAULT_KEYREPEAT_DELN=200
 options 	WSDISPLAY_COMPAT_USL		# wsconscfg VT handling
 
+# virtual devices */
+vatapi*		at mainbus?
+atapibus*	at vatapi?
+
+# cd, sd, and the like
+cd*		at atapibus?
+sd*		at atapibus?
+st*		at atapibus?
+uk*		at atapibus?
+
+# pseudo devices
 pseudo-device	loop
 pseudo-device	pty
 pseudo-device	bpfilter

Index: src/sys/arch/usermode/conf/files.usermode
diff -u src/sys/arch/usermode/conf/files.usermode:1.16 src/sys/arch/usermode/conf/files.usermode:1.17
--- src/sys/arch/usermode/conf/files.usermode:1.16	Fri Dec 30 20:08:36 2011
+++ src/sys/arch/usermode/conf/files.usermode	Tue Jun  5 20:02:42 2018
@@ -1,4 +1,4 @@
-# $NetBSD: files.usermode,v 1.16 2011/12/30 20:08:36 jmcneill Exp $
+# $NetBSD: files.usermode,v 1.17 2018/06/05 20:02:42 reinoud Exp $
 
 maxpartitions 8
 maxusers 8 16 64
@@ -42,6 +42,16 @@ attach	vncfb at thunkbus
 file	arch/usermode/dev/vncfb.c		vncfb
 file	arch/usermode/dev/vnckbdmap.c		vncfb
 
+include "dev/scsipi/files.scsipi"
+#device	vscsi: scsi
+#file	arch/usermode/dev/vscsi.c		vscsi needs-flag
+#attach	vscsi at thunkbus with vscsi_thunkbus
+#file	atch/usermode/dev/vscsi_thunkbus.c	vscsi_thunkbus
+
+device	vatapi { } : atapi, atapibus
+attach	vatapi at thunkbus with vatapi_thunkbus
+file	arch/usermode/dev/vatapi.c		vatapi_thunkbus
+
 file	arch/usermode/usermode/copy.c
 file	arch/usermode/usermode/intr.c
 file	arch/usermode/usermode/machdep.c

Index: src/sys/arch/usermode/dev/mainbus.c
diff -u src/sys/arch/usermode/dev/mainbus.c:1.9 src/sys/arch/usermode/dev/mainbus.c:1.10
--- src/sys/arch/usermode/dev/mainbus.c:1.9	Sat Jan  7 18:10:18 2012
+++ src/sys/arch/usermode/dev/mainbus.c	Tue Jun  5 20:02:43 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: mainbus.c,v 1.9 2012/01/07 18:10:18 jmcneill Exp $ */
+/* $NetBSD: mainbus.c,v 1.10 2018/06/05 20:02:43 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.9 2012/01/07 18:10:18 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.10 2018/06/05 20:02:43 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -52,6 +52,9 @@ CFATTACH_DECL_NEW(mainbus, sizeof(mainbu
 
 extern char *usermode_disk_image_path[];
 extern int usermode_disk_image_path_count;
+extern int   usermode_vdev_type[];
+extern char *usermode_vdev_path[];
+extern int usermode_vdev_count;
 extern char *usermode_tap_device;
 extern char *usermode_tap_eaddr;
 extern char *usermode_audio_device;
@@ -111,6 +114,12 @@ mainbus_attach(device_t parent, device_t
 		taa.u.diskimage.path = usermode_disk_image_path[i];
 		config_found_ia(self, "thunkbus", &taa, mainbus_print);
 	}
+
+	for (i = 0; i < usermode_vdev_count; i++) {
+		taa.taa_type = usermode_vdev_type[i];
+		taa.u.vdev.path = usermode_vdev_path[i];
+		config_found_ia(self, "thunkbus", &taa, mainbus_print);
+	}
 }
 
 static int

Index: src/sys/arch/usermode/include/mainbus.h
diff -u src/sys/arch/usermode/include/mainbus.h:1.7 src/sys/arch/usermode/include/mainbus.h:1.8
--- src/sys/arch/usermode/include/mainbus.h:1.7	Thu Dec 29 21:22:49 2011
+++ src/sys/arch/usermode/include/mainbus.h	Tue Jun  5 20:02:43 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: mainbus.h,v 1.7 2011/12/29 21:22:49 jmcneill Exp $ */
+/* $NetBSD: mainbus.h,v 1.8 2018/06/05 20:02:43 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca>
@@ -38,10 +38,15 @@ struct thunkbus_attach_args {
 #define THUNKBUS_TYPE_VNCFB	4
 #define THUNKBUS_TYPE_VETH	5
 #define THUNKBUS_TYPE_VAUDIO	6
+#define THUNKBUS_TYPE_VATAPI	7
+#define THUNKBUS_TYPE_VSCSI	8
 
 	union {
 		struct {
 			const char *path;
+		} vdev;
+		struct {
+			const char *path;
 		} diskimage;
 		struct {
 			const char *device;

Index: src/sys/arch/usermode/usermode/machdep.c
diff -u src/sys/arch/usermode/usermode/machdep.c:1.54 src/sys/arch/usermode/usermode/machdep.c:1.55
--- src/sys/arch/usermode/usermode/machdep.c:1.54	Thu Dec 22 14:47:59 2016
+++ src/sys/arch/usermode/usermode/machdep.c	Tue Jun  5 20:02:43 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.54 2016/12/22 14:47:59 cherry Exp $ */
+/* $NetBSD: machdep.c,v 1.55 2018/06/05 20:02:43 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org>
@@ -37,7 +37,7 @@
 #include "opt_memsize.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.54 2016/12/22 14:47:59 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.55 2018/06/05 20:02:43 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/systm.h>
@@ -57,12 +57,17 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 
 #include <dev/mm.h>
 #include <machine/vmparam.h>
 #include <machine/machdep.h>
+#include <machine/mainbus.h>
 #include <machine/thunk.h>
 
 #ifndef MAX_DISK_IMAGES
 #define MAX_DISK_IMAGES	4
 #endif
 
+#ifndef MAX_VDEVS
+#define MAX_VDEVS 4
+#endif
+
 char machine[_SYS_NMLN] = "";
 char machine_arch[_SYS_NMLN] = "";
 char module_machine_usermode[_SYS_NMLN] = "";
@@ -74,6 +79,10 @@ static char **saved_argv;
 char *usermode_disk_image_path[MAX_DISK_IMAGES];
 int usermode_disk_image_path_count = 0;
 
+int   usermode_vdev_type[MAX_VDEVS];
+char *usermode_vdev_path[MAX_VDEVS];
+int usermode_vdev_count = 0;
+
 static char usermode_tap_devicebuf[PATH_MAX] = "";
 char *usermode_tap_device = NULL;
 char *usermode_tap_eaddr = NULL;
@@ -95,23 +104,39 @@ usage(const char *pn)
 	    " [audio=<audiodev>]"
 	    " [disk=<diskimg> ...]"
 	    " [root=<device>]"
-	    " [vnc=<width>x<height>,<port>]\n",
+	    " [vnc=<width>x<height>,<port>]"
+	    " [vdev=atapi,device]\n",
 	    pn);
 	printf("       (ex. \"%s"
 	    " net=tap0,00:00:be:ef:ca:fe"
 	    " audio=audio0"
 	    " disk=root.fs"
 	    " root=ld0"
-	    " vnc=640x480,5900\")\n", pn);
+	    " vnc=640x480,5900"
+	    " vdev=atapi,/dev/rcd0d\")\n", pn);
+}
+
+
+static int
+vdev_type(const char *type)
+{
+	if (strcasecmp(type, "atapi")==0)
+		return THUNKBUS_TYPE_VATAPI;
+#if 0
+	if (strcasecmp(type, "scsi")==0)
+		return THUNKBUS_TYPE_VSCSI;
+#endif
+	return -1;
 }
 
+
 void
 main(int argc, char *argv[])
 {
 	extern void ttycons_consinit(void);
 	extern void pmap_bootstrap(void);
 	extern void kernmain(void);
-	int i, j, r, tmpopt = 0;
+	int type, i, j, r, tmpopt = 0;
 
 	saved_argv = argv;
 
@@ -189,6 +214,32 @@ main(int argc, char *argv[])
 				usermode_disk_image_path[
 				    usermode_disk_image_path_count++] =
 				    argv[i] + strlen("disk=");
+			} else if (strncmp(argv[i], "vdev=",
+			    strlen("vdev=")) == 0) {
+				char *vdev = argv[i] + strlen("vdev=");
+				char *t, *p;
+				if (usermode_disk_image_path_count ==
+				    MAX_VDEVS) {
+					printf("too many vdevs "
+					    "(increase MAX_VDEVS)\n");
+					usage(argv[0]);
+					return;
+				}
+				t = vdev;
+				p = strchr(t, ',');
+				if (p == NULL) {
+					printf("bad vdev= format\n");
+					return;
+				}
+				*p++ = '\0';
+				type = vdev_type(t);
+				if (type < 0) {
+					printf("unknown vdev device type\n");
+					return;
+				}
+				usermode_vdev_type[usermode_vdev_count] = type;
+				usermode_vdev_path[usermode_vdev_count] = p;
+				usermode_vdev_count++;
 			} else if (strncmp(argv[i], "root=",
 			    strlen("root=")) == 0) {
 				usermode_root_device = argv[i] +

Added files:

Index: src/sys/arch/usermode/dev/vatapi.c
diff -u /dev/null src/sys/arch/usermode/dev/vatapi.c:1.1
--- /dev/null	Tue Jun  5 20:02:43 2018
+++ src/sys/arch/usermode/dev/vatapi.c	Tue Jun  5 20:02:43 2018
@@ -0,0 +1,345 @@
+/* $NetBSD: vatapi.c,v 1.1 2018/06/05 20:02:43 reinoud Exp $ */
+
+/*-
+ * Copyright (c) 2018 Reinoud Zandijk <rein...@netbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: vatapi.c,v 1.1 2018/06/05 20:02:43 reinoud Exp $");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/disk.h>
+#include <sys/kmem.h>
+#include <sys/malloc.h>
+#include <sys/scsiio.h>
+
+#include <machine/mainbus.h>
+#include <machine/thunk.h>
+#include <machine/intr.h>
+
+#include <dev/scsipi/scsi_all.h>	/* for SCSI status */
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsipiconf.h>
+#include <dev/scsipi/atapiconf.h>
+
+/* parameter? */
+#define VDEV_ATAPI_DRIVE	0
+#define MAX_SIZE		((1<<16))
+
+/* forwards */
+struct vatapi_softc;
+
+static int	vatapi_match(device_t, cfdata_t, void *);
+static void	vatapi_attach(device_t, device_t, void *);
+static void	vatapi_callback(device_t self);
+
+static void	vatapi_minphys(struct buf *bp);
+static void	vatapi_kill_pending(struct scsipi_periph *periph);
+static void	vatapi_scsipi_request(struct scsipi_channel *chan,
+	scsipi_adapter_req_t req, void *arg);
+static void	vatapi_probe_device(struct atapibus_softc *, int);
+
+static void	vatapi_complete(void *arg);
+
+/* for debugging */
+void	scsipi_print_sense_data_real(struct scsi_sense_data *sense, int verbosity);
+
+
+/* Note its one vdev, one adapter, one channel for now */
+struct vatapi_softc {
+	device_t	sc_dev;
+	device_t	sc_pdev;
+
+	int		sc_flags;
+#define VATAPI_FLAG_POLLING	1
+#define VATAPI_FLAG_INTR	2
+	/* backing `device' with its active command */
+	int		sc_fd;
+	void		*sc_ih;
+	struct scsipi_xfer *sc_xs;
+
+	/* atapibus */
+	device_t	sc_vatapibus;
+	struct atapi_adapter    sc_atapi_adapter;
+#define sc_adapter sc_atapi_adapter._generic
+	struct scsipi_channel sc_channel;
+};
+
+CFATTACH_DECL_NEW(vatapi_thunkbus, sizeof(struct vatapi_softc),
+    vatapi_match, vatapi_attach, NULL, NULL);
+
+
+static const struct scsipi_bustype vatapi_bustype = {
+	SCSIPI_BUSTYPE_ATAPI,
+	atapi_scsipi_cmd,
+	atapi_interpret_sense,
+	atapi_print_addr,
+	vatapi_kill_pending,
+	NULL
+};
+
+int
+vatapi_match(device_t parent, cfdata_t match, void *opaque)
+{
+	struct thunkbus_attach_args *taa = opaque;
+
+	if (taa->taa_type != THUNKBUS_TYPE_VATAPI)
+		return 0;
+
+	return 1;
+}
+
+static void
+vatapi_attach(device_t parent, device_t self, void *opaque)
+{
+	struct vatapi_softc *sc = device_private(self);
+	struct thunkbus_attach_args *taa = opaque;
+
+	sc->sc_dev = self;
+	sc->sc_pdev = parent;
+
+	/* open device */
+	sc->sc_fd = thunk_open(taa->u.vdev.path, O_RDWR, 0);
+	if (sc->sc_fd < 0) {
+		aprint_error(": error %d opening path\n", thunk_geterrno());
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	sc->sc_ih = softint_establish(SOFTINT_BIO,
+		vatapi_complete, sc);
+
+	/* rest of the configuration is deferred */
+	config_interrupts(self, vatapi_callback);
+}
+
+static void
+vatapi_callback(device_t self)
+{
+	struct vatapi_softc *sc = device_private(self);
+	struct scsipi_adapter *adapt = &sc->sc_adapter;
+	struct scsipi_channel *chan  = &sc->sc_channel;
+
+	/* set up the scsipi adapter and channel */
+	memset(adapt, 0, sizeof(*adapt));
+	adapt->adapt_dev = sc->sc_dev;
+	adapt->adapt_nchannels = 1;
+	adapt->adapt_request   = vatapi_scsipi_request;
+	adapt->adapt_minphys   = vatapi_minphys;
+	adapt->adapt_flags     = 0; //SCSIPI_ADAPT_POLL_ONLY;
+	sc->sc_atapi_adapter.atapi_probe_device = vatapi_probe_device;
+
+	memset(chan,  0, sizeof(*chan));
+	chan->chan_adapter    = adapt;
+	chan->chan_bustype    = &vatapi_bustype;
+	chan->chan_channel    = 0;	/* location */
+	chan->chan_flags      = SCSIPI_CHAN_OPENINGS;
+	chan->chan_openings   = 1;
+	chan->chan_max_periph = 1;
+	chan->chan_ntargets   = 1;
+	chan->chan_nluns      = 1;
+
+	/* set polling */
+	//sc->sc_flags = VATAPI_FLAG_POLLING;
+
+	/* we `discovered' an atapi adapter */
+	sc->sc_vatapibus = config_found_ia(sc->sc_dev, "atapi", chan,
+		atapiprint);
+}
+
+
+/* XXX why is it be called minphys, when it enforces maxphys? */
+static void
+vatapi_minphys(struct buf *bp)
+{
+	if (bp->b_bcount > MAX_SIZE)
+		bp->b_bcount = MAX_SIZE;
+	minphys(bp);
+}
+
+/*
+ * ATAPI device probing
+ */
+static void
+vatapi_probe_device(struct atapibus_softc *atapi, int target)
+{
+	struct scsipi_channel *chan = atapi->sc_channel;
+	struct scsipi_periph *periph;
+	struct scsipibus_attach_args sa;
+	char vendor[33], product[65], revision[17];
+	struct scsipi_inquiry_data inqbuf;
+
+	if (target != VDEV_ATAPI_DRIVE)	/* only probe drive 0 */
+		return;
+
+	/* skip if already attached */
+	if (scsipi_lookup_periph(chan, target, 0) != NULL)
+		return;
+
+	/* allocate and set up periph structure */
+	periph = scsipi_alloc_periph(M_NOWAIT);
+	if (periph == NULL) {
+		aprint_error_dev(atapi->sc_dev,
+		    "can't allocate link for drive %d\n", target);
+		return;
+	}
+	periph->periph_channel = chan;
+	periph->periph_switch = &atapi_probe_periphsw;
+	periph->periph_target = target;
+	periph->periph_quirks = chan->chan_defquirks;
+
+	/* inquiry */
+	aprint_verbose("%s: inquiry devices\n", __func__);
+	memset(&inqbuf, 0, sizeof(inqbuf));
+	if (scsipi_inquire(periph, &inqbuf, XS_CTL_DISCOVERY) != 0) {
+		aprint_error_dev(atapi->sc_dev, ": scsipi_inquire failed\n");
+		free(periph, M_DEVBUF);
+		return;
+	}
+
+#define scsipi_strvis(a, al, b, bl) strlcpy(a, b, al)
+	scsipi_strvis(vendor, 33, inqbuf.vendor, 8);
+	scsipi_strvis(product, 65, inqbuf.product, 16);
+	scsipi_strvis(revision, 17, inqbuf.revision, 4);
+#undef scsipi_strvis
+
+	sa.sa_periph = periph;
+	sa.sa_inqbuf.type = inqbuf.device;
+	sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
+	    T_REMOV : T_FIXED;
+	if (sa.sa_inqbuf.removable)
+		periph->periph_flags |= PERIPH_REMOVABLE;
+	sa.sa_inqbuf.vendor = vendor;
+	sa.sa_inqbuf.product = product;
+	sa.sa_inqbuf.revision = revision;
+	sa.sa_inqptr = NULL;
+
+	/* ATAPI demands only READ10 and higher IIRC */
+	periph->periph_quirks |= PQUIRK_ONLYBIG;
+
+	aprint_verbose(": probedev on vendor '%s' product '%s' revision '%s'\n",
+		vendor, product, revision);
+
+	atapi_probe_device(atapi, target, periph, &sa);
+	/* atapi_probe_device() frees the periph when there is no device.*/
+}
+
+/*
+ * Issue a request for a periph.
+ */
+static void
+vatapi_scsipi_request(struct scsipi_channel *chan,
+	scsipi_adapter_req_t req, void *arg)
+{
+	device_t sc_dev = chan->chan_adapter->adapt_dev;
+	struct vatapi_softc *sc = device_private(sc_dev);
+ 	struct scsipi_xfer *xs = arg;
+
+	switch (req) {
+ 	case ADAPTER_REQ_GROW_RESOURCES:
+ 	case ADAPTER_REQ_SET_XFER_MODE:
+		return;
+	case ADAPTER_REQ_RUN_XFER :
+		KASSERT(sc->sc_xs == NULL);
+
+		/* queue the command */
+		KASSERT(sc->sc_xs == NULL);
+		sc->sc_xs = xs;
+		softint_schedule(sc->sc_ih);
+	}
+}
+
+
+static void
+vatapi_complete(void *arg)
+{
+	struct vatapi_softc *sc = arg;
+ 	struct scsipi_xfer *xs = sc->sc_xs;
+	scsireq_t kreq;
+
+	memset(&kreq, 0, sizeof(kreq));
+	memcpy(kreq.cmd, xs->cmd, xs->cmdlen);
+	kreq.cmdlen = xs->cmdlen;
+	kreq.databuf = xs->data;		/* in virt? */
+	kreq.datalen = xs->datalen;
+	kreq.timeout = xs->timeout;
+
+	kreq.flags = (xs->xs_control & XS_CTL_DATA_IN) ?
+		SCCMD_READ : SCCMD_WRITE;
+
+	kreq.senselen = sizeof(struct scsi_sense_data);
+
+	xs->error = XS_SHORTSENSE;
+	/* this is silly, but better make sure */
+	thunk_assert_presence((vaddr_t) kreq.databuf,
+		(size_t) kreq.datalen);
+
+	if (thunk_ioctl(sc->sc_fd, SCIOCCOMMAND, &kreq) != -1) {
+		switch (kreq.retsts) {
+		case SCCMD_OK :
+			xs->resid = 0;
+			xs->error = 0;
+			break;
+		case SCCMD_TIMEOUT :
+			break;
+		case SCCMD_BUSY :
+			break;
+		case SCCMD_SENSE :
+			xs->error = XS_SHORTSENSE;	/* ATAPI */
+			memcpy(&xs->sense.scsi_sense, kreq.sense,
+				sizeof(struct scsi_sense_data));
+//			scsipi_print_sense_data_real(
+//				(struct scsi_sense_data *) kreq.sense, 1);
+			break;
+		default:
+			thunk_printf("unhandled/unknown retstst %d\n", kreq.retsts);
+			break;
+		}
+	} else {
+		printf("thunk_ioctl == -1, errno %d\n", thunk_geterrno());
+	}
+	sc->sc_xs = NULL;
+	scsipi_done(xs);
+}
+
+
+/* 
+ * Kill off all pending xfers for a periph.
+ *
+ * Must be called at splbio().
+ */
+static void
+vatapi_kill_pending(struct scsipi_periph *periph)
+{
+	/* do we need to do anything ? (yet?) */
+	printf("%s: target %d\n", __func__, periph->periph_target);
+}
+

Reply via email to