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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
+ * 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);
+}
+