summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2008-12-03 23:39:33 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2008-12-03 23:39:33 +0000
commit6cd9762e49e7e88ad61f8e32d52133aa0a642639 (patch)
tree3ce7a0c6946e6f49c7794a7c3e128b282741d26d
parentb2b1b8bb0d677b8a82c30123fef6213fe5e7e5c6 (diff)
add vscsi(4), a virtual scsi controller that passes all scsi requests up to
userland for handling. this is to scsi what tun(4) is for networks. this is going into the tree so i can work on some crazy scsi stuff, but its not being enabled since it is useless unless you're working on some crazy scsi stuff.
-rw-r--r--sys/conf/files7
-rw-r--r--sys/dev/vscsi.c568
-rw-r--r--sys/dev/vscsivar.h63
-rw-r--r--sys/kern/init_main.c6
-rw-r--r--sys/sys/conf.h11
5 files changed, 652 insertions, 3 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 14ae228f121..37871a15781 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.449 2008/11/24 04:46:59 tedu Exp $
+# $OpenBSD: files,v 1.450 2008/12/03 23:39:32 dlg Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -444,6 +444,11 @@ file dev/ipmi.c ipmi needs-flag
device vmt
file dev/vmt.c vmt needs-flag
+# Virtual SCSI
+device vscsi: scsi
+attach vscsi at root
+file dev/vscsi.c vscsi needs-flag
+
# Software RAID
device softraid: scsi
attach softraid at root
diff --git a/sys/dev/vscsi.c b/sys/dev/vscsi.c
new file mode 100644
index 00000000000..baac8d343f4
--- /dev/null
+++ b/sys/dev/vscsi.c
@@ -0,0 +1,568 @@
+/* $OpenBSD: vscsi.c,v 1.1 2008/12/03 23:39:32 dlg Exp $ */
+
+/*
+ * Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/queue.h>
+#include <sys/rwlock.h>
+#include <sys/pool.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/selinfo.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <dev/vscsivar.h>
+
+#ifdef VSCSI_DEBUG
+#define VSCSI_D_INIT (1<<0)
+
+int vscsidebug = 0;
+
+#define DPRINTF(_m, _p...) do { \
+ if (ISSET(vscsidebug, (_m))) \
+ printf(p); \
+ } while (0)
+#else
+#define DPRINTF(_m, _p...) /* _m, _p */
+#endif
+
+int vscsi_match(struct device *, void *, void *);
+void vscsi_attach(struct device *, struct device *, void *);
+void vscsi_shutdown(void *);
+
+struct vscsi_ccb {
+ TAILQ_ENTRY(vscsi_ccb) ccb_entry;
+ int ccb_tag;
+ struct scsi_xfer *ccb_xs;
+ size_t ccb_datalen;
+};
+
+TAILQ_HEAD(vscsi_ccb_list, vscsi_ccb);
+
+struct vscsi_softc {
+ struct device sc_dev;
+ struct scsi_link sc_link;
+ struct scsibus_softc *sc_scsibus;
+
+ struct pool sc_ccb_pool;
+ struct vscsi_ccb_list sc_ccb_i2t;
+ struct vscsi_ccb_list sc_ccb_t2i;
+ int sc_ccb_tag;
+ struct mutex sc_ccb_mtx;
+ struct rwlock sc_ccb_polling;
+
+ struct selinfo sc_sel;
+ struct mutex sc_sel_mtx;
+
+ struct rwlock sc_open;
+ volatile int sc_opened;
+};
+
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+#define DEV2SC(_d) ((struct vscsi_softc *)device_lookup(&vscsi_cd, minor(_d)))
+
+struct cfattach vscsi_ca = {
+ sizeof(struct vscsi_softc),
+ vscsi_match,
+ vscsi_attach
+};
+
+struct cfdriver vscsi_cd = {
+ NULL,
+ "vscsi",
+ DV_DULL
+};
+
+int vscsi_cmd(struct scsi_xfer *);
+int vscsi_probe(struct scsi_link *);
+
+struct scsi_adapter vscsi_switch = {
+ vscsi_cmd,
+ minphys,
+ vscsi_probe,
+ NULL
+};
+
+struct scsi_device vscsi_dev = {
+ NULL, NULL, NULL, NULL
+};
+
+void vscsi_xs_stuffup(struct scsi_xfer *);
+
+
+int vscsi_i2t(struct vscsi_softc *, struct vscsi_ioc_i2t *);
+int vscsi_data(struct vscsi_softc *, struct vscsi_ioc_data *, int);
+int vscsi_t2i(struct vscsi_softc *, struct vscsi_ioc_t2i *);
+
+struct vscsi_ccb * vscsi_ccb_get(struct vscsi_softc *, int);
+#define vscsi_ccb_put(_s, _c) pool_put(&(_s)->sc_ccb_pool, (_c))
+
+void filt_vscsidetach(struct knote *);
+int filt_vscsiread(struct knote *, long);
+
+struct filterops vscsi_filtops = {
+ 1,
+ NULL,
+ filt_vscsidetach,
+ filt_vscsiread
+};
+
+
+int
+vscsi_match(struct device *parent, void *match, void *aux)
+{
+ return (1);
+}
+
+void
+vscsi_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct vscsi_softc *sc = (struct vscsi_softc *)self;
+ struct scsibus_attach_args saa;
+
+ printf("\n");
+
+ rw_init(&sc->sc_open, DEVNAME(sc));
+ rw_init(&sc->sc_ccb_polling, DEVNAME(sc));
+
+ sc->sc_link.device = &vscsi_dev;
+ sc->sc_link.adapter = &vscsi_switch;
+ sc->sc_link.adapter_softc = sc;
+ sc->sc_link.adapter_target = 256;
+ sc->sc_link.adapter_buswidth = 256;
+ sc->sc_link.openings = 1;
+
+ bzero(&saa, sizeof(saa));
+ saa.saa_sc_link = &sc->sc_link;
+
+ sc->sc_scsibus = (struct scsibus_softc *)config_found(&sc->sc_dev,
+ &saa, scsiprint);
+}
+
+int
+vscsi_cmd(struct scsi_xfer *xs)
+{
+ struct scsi_link *link = xs->sc_link;
+ struct vscsi_softc *sc = link->adapter_softc;
+ struct vscsi_ccb *ccb;
+ int polled = ISSET(xs->flags, SCSI_POLL);
+
+ if (sc->sc_opened == 0) {
+ vscsi_xs_stuffup(xs);
+ return (COMPLETE);
+ }
+
+ if (ISSET(xs->flags, SCSI_POLL) && ISSET(xs->flags, SCSI_NOSLEEP)) {
+ printf("%s: POLL && NOSLEEP for 0x%02x\n", DEVNAME(sc),
+ xs->cmd->opcode);
+ vscsi_xs_stuffup(xs);
+ return (COMPLETE);
+ }
+
+ ccb = vscsi_ccb_get(sc, ISSET(xs->flags, SCSI_NOSLEEP) ? 0 : 1);
+ if (ccb == NULL) {
+ vscsi_xs_stuffup(xs);
+ return (COMPLETE);
+ }
+
+ ccb->ccb_xs = xs;
+ mtx_enter(&sc->sc_ccb_mtx);
+ TAILQ_INSERT_TAIL(&sc->sc_ccb_i2t, ccb, ccb_entry);
+ mtx_leave(&sc->sc_ccb_mtx);
+
+ selwakeup(&sc->sc_sel);
+ KNOTE(&sc->sc_sel.si_note, 0);
+
+ if (polled) {
+ rw_enter_read(&sc->sc_ccb_polling);
+ while (ccb->ccb_xs != NULL)
+ tsleep(ccb, PRIBIO, "vscsipoll", 0);
+ vscsi_ccb_put(sc, ccb);
+ rw_exit_read(&sc->sc_ccb_polling);
+ return (COMPLETE);
+ }
+
+ return (SUCCESSFULLY_QUEUED);
+}
+
+void
+vscsi_xs_stuffup(struct scsi_xfer *xs)
+{
+ int s;
+
+ xs->error = XS_DRIVER_STUFFUP;
+ xs->flags |= ITSDONE;
+ s = splbio();
+ scsi_done(xs);
+ splx(s);
+}
+
+int
+vscsi_probe(struct scsi_link *link)
+{
+ struct vscsi_softc *sc = link->adapter_softc;
+
+ if (sc->sc_opened == 0)
+ return (ENXIO);
+
+ return (0);
+}
+
+int
+vscsiopen(dev_t dev, int flags, int mode, struct proc *p)
+{
+ struct vscsi_softc *sc = DEV2SC(dev);
+ int rv;
+
+ if (sc == NULL)
+ return (ENXIO);
+
+ rv = rw_enter(&sc->sc_open, RW_WRITE | RW_NOSLEEP);
+ if (rv != 0)
+ return (rv);
+
+ pool_init(&sc->sc_ccb_pool, sizeof(struct vscsi_ccb), 0, 0, 0,
+ "vscsiccb", NULL);
+ pool_setipl(&sc->sc_ccb_pool, IPL_BIO);
+ TAILQ_INIT(&sc->sc_ccb_i2t);
+ TAILQ_INIT(&sc->sc_ccb_t2i);
+ mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
+ mtx_init(&sc->sc_sel_mtx, IPL_BIO);
+
+ sc->sc_opened = 1;
+
+ return (0);
+}
+
+int
+vscsiioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
+{
+ struct vscsi_softc *sc = DEV2SC(dev);
+ int read = 0;
+ int err = 0;
+
+ switch (cmd) {
+ case VSCSI_I2T:
+ err = vscsi_i2t(sc, (struct vscsi_ioc_i2t *)addr);
+ break;
+
+ case VSCSI_DATA_READ:
+ read = 1;
+ case VSCSI_DATA_WRITE:
+ err = vscsi_data(sc, (struct vscsi_ioc_data *)addr, read);
+ break;
+
+ case VSCSI_T2I:
+ err = vscsi_t2i(sc, (struct vscsi_ioc_t2i *)addr);
+ break;
+
+ default:
+ err = ENOTTY;
+ break;
+ }
+
+ return (err);
+}
+
+int
+vscsi_i2t(struct vscsi_softc *sc, struct vscsi_ioc_i2t *i2t)
+{
+ struct vscsi_ccb *ccb;
+ struct scsi_xfer *xs;
+ struct scsi_link *link;
+
+ mtx_enter(&sc->sc_ccb_mtx);
+ ccb = TAILQ_FIRST(&sc->sc_ccb_i2t);
+ if (ccb != NULL)
+ TAILQ_REMOVE(&sc->sc_ccb_i2t, ccb, ccb_entry);
+ mtx_leave(&sc->sc_ccb_mtx);
+
+ if (ccb == NULL)
+ return (EAGAIN);
+
+ xs = ccb->ccb_xs;
+ link = xs->sc_link;
+
+ i2t->tag = ccb->ccb_tag;
+ i2t->target = link->target;
+ i2t->lun = link->lun;
+ bcopy(xs->cmd, &i2t->cmd, xs->cmdlen);
+ i2t->cmdlen = xs->cmdlen;
+ i2t->datalen = xs->datalen;
+
+ switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
+ case SCSI_DATA_IN:
+ i2t->direction = VSCSI_DIR_READ;
+ break;
+ case SCSI_DATA_OUT:
+ i2t->direction = VSCSI_DIR_WRITE;
+ break;
+ default:
+ i2t->direction = VSCSI_DIR_NONE;
+ break;
+ }
+
+ TAILQ_INSERT_TAIL(&sc->sc_ccb_t2i, ccb, ccb_entry);
+
+ return (0);
+}
+
+int
+vscsi_data(struct vscsi_softc *sc, struct vscsi_ioc_data *data, int read)
+{
+ struct vscsi_ccb *ccb;
+ struct scsi_xfer *xs;
+ int xsread;
+ u_int8_t *buf;
+ int rv = EINVAL;
+
+ TAILQ_FOREACH(ccb, &sc->sc_ccb_t2i, ccb_entry) {
+ if (ccb->ccb_tag == data->tag)
+ break;
+ }
+ if (ccb == NULL)
+ return (EFAULT);
+
+ xs = ccb->ccb_xs;
+
+ if (data->datalen + ccb->ccb_datalen > xs->datalen)
+ return (ENOMEM);
+
+ switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
+ case SCSI_DATA_IN:
+ xsread = 1;
+ break;
+ case SCSI_DATA_OUT:
+ xsread = 0;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ if (read != xsread)
+ return (EINVAL);
+
+ buf = xs->data;
+ buf += ccb->ccb_datalen;
+
+ if (read)
+ rv = copyin(data->data, buf, data->datalen);
+ else
+ rv = copyout(buf, data->data, data->datalen);
+
+ if (rv == 0)
+ ccb->ccb_datalen += data->datalen;
+
+ return (rv);
+}
+
+int
+vscsi_t2i(struct vscsi_softc *sc, struct vscsi_ioc_t2i *t2i)
+{
+ struct vscsi_ccb *ccb;
+ struct scsi_xfer *xs;
+ struct scsi_link *link;
+ int rv = 0;
+ int polled;
+ int s;
+
+ TAILQ_FOREACH(ccb, &sc->sc_ccb_t2i, ccb_entry) {
+ if (ccb->ccb_tag == t2i->tag)
+ break;
+ }
+ if (ccb == NULL)
+ return (EFAULT);
+
+ TAILQ_REMOVE(&sc->sc_ccb_t2i, ccb, ccb_entry);
+
+ xs = ccb->ccb_xs;
+ link = xs->sc_link;
+
+ xs->resid = xs->datalen - ccb->ccb_datalen;
+ xs->status = SCSI_OK;
+
+ switch (t2i->status) {
+ case VSCSI_STAT_DONE:
+ xs->error = XS_NOERROR;
+ break;
+ case VSCSI_STAT_SENSE:
+ xs->error = XS_SENSE;
+ bcopy(&t2i->sense, &xs->sense, t2i->senselen);
+ xs->req_sense_length = t2i->senselen;
+ break;
+ case VSCSI_STAT_ERR:
+ default:
+ xs->error = XS_DRIVER_STUFFUP;
+ break;
+ }
+
+ polled = ISSET(xs->flags, SCSI_POLL);
+
+ xs->flags |= ITSDONE;
+ s = splbio();
+ scsi_done(xs);
+ splx(s);
+
+ if (polled) {
+ ccb->ccb_xs = NULL;
+ wakeup(ccb);
+ } else
+ vscsi_ccb_put(sc, ccb);
+
+ return (rv);
+}
+
+int
+vscsipoll(dev_t dev, int events, struct proc *p)
+{
+ struct vscsi_softc *sc = DEV2SC(dev);
+ int revents = 0;
+
+ if (events & (POLLIN | POLLRDNORM)) {
+ mtx_enter(&sc->sc_ccb_mtx);
+ if (!TAILQ_EMPTY(&sc->sc_ccb_i2t))
+ revents |= events & (POLLIN | POLLRDNORM);
+ mtx_leave(&sc->sc_ccb_mtx);
+ }
+
+ if (revents == 0) {
+ if (events & (POLLIN | POLLRDNORM))
+ selrecord(p, &sc->sc_sel);
+ }
+
+ return (revents);
+}
+
+int
+vscsikqfilter(dev_t dev, struct knote *kn)
+{
+ struct vscsi_softc *sc = DEV2SC(dev);
+ struct klist *klist = &sc->sc_sel.si_note;
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &vscsi_filtops;
+ break;
+ default:
+ return (1);
+ }
+
+ kn->kn_hook = (caddr_t)sc;
+
+ mtx_enter(&sc->sc_sel_mtx);
+ SLIST_INSERT_HEAD(klist, kn, kn_selnext);
+ mtx_leave(&sc->sc_sel_mtx);
+
+ return (0);
+}
+
+void
+filt_vscsidetach(struct knote *kn)
+{
+ struct vscsi_softc *sc = (struct vscsi_softc *)kn->kn_hook;
+ struct klist *klist = &sc->sc_sel.si_note;
+
+ mtx_enter(&sc->sc_sel_mtx);
+ SLIST_REMOVE(klist, kn, knote, kn_selnext);
+ mtx_leave(&sc->sc_sel_mtx);
+}
+
+int
+filt_vscsiread(struct knote *kn, long hint)
+{
+ struct vscsi_softc *sc = (struct vscsi_softc *)kn->kn_hook;
+ int event = 0;
+
+ mtx_enter(&sc->sc_ccb_mtx);
+ if (!TAILQ_EMPTY(&sc->sc_ccb_i2t))
+ event = 1;
+ mtx_leave(&sc->sc_ccb_mtx);
+
+ return (event);
+}
+
+int
+vscsiclose(dev_t dev, int flags, int mode, struct proc *p)
+{
+ struct vscsi_softc *sc = DEV2SC(dev);
+ struct vscsi_ccb *ccb;
+ int polled;
+ int i;
+
+ sc->sc_opened = 0;
+
+ while ((ccb = TAILQ_FIRST(&sc->sc_ccb_t2i)) != NULL) {
+ TAILQ_REMOVE(&sc->sc_ccb_i2t, ccb, ccb_entry);
+ polled = ISSET(ccb->ccb_xs->flags, SCSI_POLL);
+
+ vscsi_xs_stuffup(ccb->ccb_xs);
+
+ if (polled) {
+ ccb->ccb_xs = NULL;
+ wakeup(ccb);
+ } else
+ vscsi_ccb_put(sc, ccb);
+ }
+
+ while ((ccb = TAILQ_FIRST(&sc->sc_ccb_i2t)) != NULL) {
+ TAILQ_REMOVE(&sc->sc_ccb_i2t, ccb, ccb_entry);
+ polled = ISSET(ccb->ccb_xs->flags, SCSI_POLL);
+
+ vscsi_xs_stuffup(ccb->ccb_xs);
+
+ if (polled) {
+ ccb->ccb_xs = NULL;
+ wakeup(ccb);
+ } else
+ vscsi_ccb_put(sc, ccb);
+ }
+
+ rw_enter_write(&sc->sc_ccb_polling);
+ pool_destroy(&sc->sc_ccb_pool);
+ rw_exit_write(&sc->sc_ccb_polling);
+
+ for (i = 0; i < sc->sc_link.adapter_buswidth; i++)
+ scsi_detach_target(sc->sc_scsibus, i, DETACH_FORCE);
+
+ rw_exit(&sc->sc_open);
+
+ return (0);
+}
+
+struct vscsi_ccb *
+vscsi_ccb_get(struct vscsi_softc *sc, int waitok)
+{
+ struct vscsi_ccb *ccb;
+
+ ccb = pool_get(&sc->sc_ccb_pool, waitok ? PR_WAITOK : PR_NOWAIT);
+ if (ccb == NULL)
+ return (NULL);
+
+ ccb->ccb_tag = sc->sc_ccb_tag++;
+ ccb->ccb_datalen = 0;
+
+ return (ccb);
+}
diff --git a/sys/dev/vscsivar.h b/sys/dev/vscsivar.h
new file mode 100644
index 00000000000..143805e8c96
--- /dev/null
+++ b/sys/dev/vscsivar.h
@@ -0,0 +1,63 @@
+/* $OpenBSD: vscsivar.h,v 1.1 2008/12/03 23:39:32 dlg Exp $ */
+
+/*
+ * Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_DEV_VSCSIVAR_H
+#define _SYS_DEV_VSCSIVAR_H
+
+struct vscsi_ioc_i2t {
+ int tag;
+
+ u_int target;
+ u_int lun;
+
+ struct scsi_generic cmd;
+ size_t cmdlen;
+
+ size_t datalen;
+ int direction;
+#define VSCSI_DIR_NONE 0
+#define VSCSI_DIR_READ 1
+#define VSCSI_DIR_WRITE 2
+};
+
+#define VSCSI_I2T _IOR('I', 0, struct vscsi_ioc_i2t)
+
+struct vscsi_ioc_data {
+ int tag;
+
+ void * data;
+ size_t datalen;
+};
+
+#define VSCSI_DATA_READ _IOW('I', 1, struct vscsi_ioc_data)
+#define VSCSI_DATA_WRITE _IOW('I', 2, struct vscsi_ioc_data)
+
+struct vscsi_ioc_t2i {
+ int tag;
+
+ int status;
+#define VSCSI_STAT_DONE 0
+#define VSCSI_STAT_SENSE 1
+#define VSCSI_STAT_ERR 2
+ struct scsi_sense_data sense;
+ size_t senselen;
+};
+
+#define VSCSI_T2I _IOW('I', 3, struct vscsi_ioc_t2i)
+
+#endif /* _SYS_DEV_VSCSIVAR_H */
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 0226b96b3e1..5f8ec54df53 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.154 2008/10/15 23:23:51 deraadt Exp $ */
+/* $OpenBSD: init_main.c,v 1.155 2008/12/03 23:39:32 dlg Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -98,6 +98,7 @@
extern void nfs_init(void);
#endif
+#include "vscsi.h"
#include "softraid.h"
const char copyright[] =
@@ -440,6 +441,9 @@ main(void *framep)
dostartuphooks();
+#if NVSCSI > 0
+ config_rootfound("vscsi", NULL);
+#endif
#if NSOFTRAID > 0
config_rootfound("softraid", NULL);
#endif
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 7b228231ae2..cbdbdfb4738 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.91 2008/11/17 00:40:04 oga Exp $ */
+/* $OpenBSD: conf.h,v 1.92 2008/12/03 23:39:32 dlg Exp $ */
/* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */
/*-
@@ -305,6 +305,14 @@ extern struct cdevsw cdevsw[];
0, dev_init(c,n,poll), (dev_type_mmap((*))) enodev, \
0, D_KQFILTER, dev_init(c,n,kqfilter) }
+/* open, close, ioctl, poll, kqfilter -- XXX should be generic device */
+#define cdev_vscsi_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), \
+ (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \
+ dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
+ 0, dev_init(c,n,poll), (dev_type_mmap((*))) enodev, \
+ 0, D_KQFILTER, dev_init(c,n,kqfilter) }
+
/* open, close, read, write, ioctl, poll, kqfilter, cloning -- XXX should be generic device */
#define cdev_bpf_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
@@ -666,6 +674,7 @@ cdev_decl(crypto);
cdev_decl(systrace);
cdev_decl(bio);
+cdev_decl(vscsi);
cdev_decl(bthub);
cdev_decl(gpr);