summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/scsi/files.scsi15
-rw-r--r--sys/scsi/mpath.c348
-rw-r--r--sys/scsi/mpath_emc.c298
-rw-r--r--sys/scsi/mpath_rdac.c335
-rw-r--r--sys/scsi/mpath_sym.c179
-rw-r--r--sys/scsi/mpathvar.h55
-rw-r--r--sys/scsi/scsiconf.c36
-rw-r--r--sys/scsi/scsiconf.h11
8 files changed, 1153 insertions, 124 deletions
diff --git a/sys/scsi/files.scsi b/sys/scsi/files.scsi
index 2066b8f9579..e5e5a70ba5a 100644
--- a/sys/scsi/files.scsi
+++ b/sys/scsi/files.scsi
@@ -1,4 +1,4 @@
-# $OpenBSD: files.scsi,v 1.22 2010/07/03 03:59:17 krw Exp $
+# $OpenBSD: files.scsi,v 1.23 2011/04/05 14:25:42 dlg Exp $
# $NetBSD: files.scsi,v 1.4 1996/05/16 04:01:08 mycroft Exp $
#
# Config.new file and device description for machine-independent SCSI code.
@@ -39,3 +39,16 @@ file scsi/safte.c safte needs-flag
device ses: disk
attach ses at scsibus
file scsi/ses.c ses needs-flag
+
+
+device sym
+attach sym at scsibus
+file scsi/mpath_sym.c sym
+
+device rdac
+attach rdac at scsibus
+file scsi/mpath_rdac.c rdac
+
+device emc
+attach emc at scsibus
+file scsi/mpath_emc.c emc
diff --git a/sys/scsi/mpath.c b/sys/scsi/mpath.c
index 239b2bb5c09..02389cb518b 100644
--- a/sys/scsi/mpath.c
+++ b/sys/scsi/mpath.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpath.c,v 1.18 2010/07/21 21:34:12 todd Exp $ */
+/* $OpenBSD: mpath.c,v 1.19 2011/04/05 14:25:42 dlg Exp $ */
/*
* Copyright (c) 2009 David Gwynne <dlg@openbsd.org>
@@ -33,6 +33,7 @@
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+#include <scsi/mpathvar.h>
#define MPATH_BUSWIDTH 256
@@ -40,27 +41,37 @@ int mpath_match(struct device *, void *, void *);
void mpath_attach(struct device *, struct device *, void *);
void mpath_shutdown(void *);
-struct mpath_path {
- struct scsi_link *path_link;
- TAILQ_ENTRY(mpath_path) path_entry;
-};
TAILQ_HEAD(mpath_paths, mpath_path);
-struct mpath_node {
- struct devid *node_id;
- struct mpath_paths node_paths;
+struct mpath_ccb {
+ struct scsi_xfer *c_xs;
+ SIMPLEQ_ENTRY(mpath_ccb) c_entry;
+};
+SIMPLEQ_HEAD(mpath_ccbs, mpath_ccb);
+
+struct mpath_dev {
+ struct mutex d_mtx;
+
+ struct mpath_ccbs d_ccbs;
+ struct mpath_paths d_paths;
+ struct mpath_path *d_next_path;
+
+ u_int d_path_count;
+
+ struct devid *d_id;
};
struct mpath_softc {
struct device sc_dev;
struct scsi_link sc_link;
+ struct pool sc_ccb_pool;
+ struct scsi_iopool sc_iopool;
struct scsibus_softc *sc_scsibus;
};
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
struct mpath_softc *mpath;
-struct mpath_node *mpath_nodes[MPATH_BUSWIDTH];
-
-#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+struct mpath_dev *mpath_devs[MPATH_BUSWIDTH];
struct cfattach mpath_ca = {
sizeof(struct mpath_softc),
@@ -78,17 +89,20 @@ void mpath_cmd(struct scsi_xfer *);
void mpath_minphys(struct buf *, struct scsi_link *);
int mpath_probe(struct scsi_link *);
+struct mpath_path *mpath_next_path(struct mpath_dev *);
void mpath_done(struct scsi_xfer *);
struct scsi_adapter mpath_switch = {
mpath_cmd,
scsi_minphys,
- mpath_probe,
- NULL
+ mpath_probe
};
void mpath_xs_stuffup(struct scsi_xfer *);
+void * mpath_ccb_get(void *);
+void mpath_ccb_put(void *, void *);
+
int
mpath_match(struct device *parent, void *match, void *aux)
{
@@ -105,11 +119,19 @@ mpath_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
+ pool_init(&sc->sc_ccb_pool, sizeof(struct mpath_ccb), 0, 0, 0,
+ "mpathccb", NULL);
+ pool_setipl(&sc->sc_ccb_pool, IPL_BIO);
+
+ scsi_iopool_init(&sc->sc_iopool, sc, mpath_ccb_get, mpath_ccb_put);
+
sc->sc_link.adapter = &mpath_switch;
sc->sc_link.adapter_softc = sc;
sc->sc_link.adapter_target = MPATH_BUSWIDTH;
sc->sc_link.adapter_buswidth = MPATH_BUSWIDTH;
- sc->sc_link.openings = 1;
+ sc->sc_link.luns = 1;
+ sc->sc_link.openings = 1024; /* XXX magical */
+ sc->sc_link.pool = &sc->sc_iopool;
bzero(&saa, sizeof(saa));
saa.saa_sc_link = &sc->sc_link;
@@ -128,34 +150,119 @@ mpath_xs_stuffup(struct scsi_xfer *xs)
int
mpath_probe(struct scsi_link *link)
{
- struct mpath_node *n = mpath_nodes[link->target];
+ struct mpath_dev *d = mpath_devs[link->target];
- if (link->lun != 0 || n == NULL)
+ if (link->lun != 0 || d == NULL)
return (ENXIO);
- link->id = devid_copy(n->node_id);
+ link->id = devid_copy(d->d_id);
return (0);
}
+struct mpath_path *
+mpath_next_path(struct mpath_dev *d)
+{
+ struct mpath_path *p;
+
+ if (d == NULL)
+ panic("%s: d is NULL", __func__);
+
+ p = d->d_next_path;
+ if (p != NULL) {
+ d->d_next_path = TAILQ_NEXT(p, p_entry);
+ if (d->d_next_path == NULL)
+ d->d_next_path = TAILQ_FIRST(&d->d_paths);
+ }
+
+ return (p);
+}
+
void
mpath_cmd(struct scsi_xfer *xs)
{
struct scsi_link *link = xs->sc_link;
- struct mpath_node *n = mpath_nodes[link->target];
- struct mpath_path *p = TAILQ_FIRST(&n->node_paths);
+ struct mpath_dev *d = mpath_devs[link->target];
+ struct mpath_ccb *ccb = xs->io;
+ struct mpath_path *p;
struct scsi_xfer *mxs;
- if (n == NULL || p == NULL) {
- mpath_xs_stuffup(xs);
+#ifdef DIAGNOSTIC
+ if (d == NULL)
+ panic("mpath_cmd issued against nonexistant device");
+#endif
+
+ if (ISSET(xs->flags, SCSI_POLL)) {
+ mtx_enter(&d->d_mtx);
+ p = mpath_next_path(d);
+ mtx_leave(&d->d_mtx);
+ if (p == NULL) {
+ mpath_xs_stuffup(xs);
+ return;
+ }
+
+ mxs = scsi_xs_get(p->p_link, xs->flags);
+ if (mxs == NULL) {
+ mpath_xs_stuffup(xs);
+ return;
+ }
+
+ memcpy(mxs->cmd, xs->cmd, xs->cmdlen);
+ mxs->cmdlen = xs->cmdlen;
+ mxs->data = xs->data;
+ mxs->datalen = xs->datalen;
+ mxs->retries = xs->retries;
+ mxs->timeout = xs->timeout;
+ mxs->bp = xs->bp;
+
+ scsi_xs_sync(mxs);
+
+ xs->error = mxs->error;
+ xs->status = mxs->status;
+ xs->resid = mxs->resid;
+
+ memcpy(&xs->sense, &mxs->sense, sizeof(xs->sense));
+
+ scsi_xs_put(mxs);
+ scsi_done(xs);
return;
}
- mxs = scsi_xs_get(p->path_link, xs->flags);
- if (mxs == NULL) {
- mpath_xs_stuffup(xs);
- return;
+ ccb->c_xs = xs;
+
+ mtx_enter(&d->d_mtx);
+ SIMPLEQ_INSERT_TAIL(&d->d_ccbs, ccb, c_entry);
+ p = mpath_next_path(d);
+ mtx_leave(&d->d_mtx);
+
+ if (p != NULL)
+ scsi_xsh_add(&p->p_xsh);
+}
+
+void
+mpath_start(struct mpath_path *p, struct scsi_xfer *mxs)
+{
+ struct mpath_dev *d = p->p_dev;
+ struct mpath_ccb *ccb;
+ struct scsi_xfer *xs;
+ int addxsh = 0;
+
+ if (ISSET(p->p_link->state, SDEV_S_DYING) || d == NULL)
+ goto fail;
+
+ mtx_enter(&d->d_mtx);
+ ccb = SIMPLEQ_FIRST(&d->d_ccbs);
+ if (ccb != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&d->d_ccbs, c_entry);
+ if (!SIMPLEQ_EMPTY(&d->d_ccbs))
+ addxsh = 1;
}
+ mtx_leave(&d->d_mtx);
+
+ if (ccb == NULL)
+ goto fail;
+
+ xs = ccb->c_xs;
memcpy(mxs->cmd, xs->cmd, xs->cmdlen);
mxs->cmdlen = xs->cmdlen;
@@ -164,21 +271,46 @@ mpath_cmd(struct scsi_xfer *xs)
mxs->retries = xs->retries;
mxs->timeout = xs->timeout;
mxs->bp = xs->bp;
+ mxs->flags = xs->flags;
mxs->cookie = xs;
mxs->done = mpath_done;
scsi_xs_exec(mxs);
+
+ if (addxsh)
+ scsi_xsh_add(&p->p_xsh);
+
+ return;
+fail:
+ scsi_xs_put(mxs);
}
void
mpath_done(struct scsi_xfer *mxs)
{
struct scsi_xfer *xs = mxs->cookie;
+ struct scsi_link *link = xs->sc_link;
+ struct mpath_ccb *ccb = xs->io;
+ struct mpath_dev *d = mpath_devs[link->target];
+ struct mpath_path *p;
+
+ if (mxs->error == XS_RESET) {
+ mtx_enter(&d->d_mtx);
+ SIMPLEQ_INSERT_HEAD(&d->d_ccbs, ccb, c_entry);
+ p = mpath_next_path(d);
+ mtx_leave(&d->d_mtx);
+
+ scsi_xs_put(mxs);
+
+ if (p != NULL)
+ scsi_xsh_add(&p->p_xsh);
+
+ return;
+ }
xs->error = mxs->error;
xs->status = mxs->status;
- xs->flags = mxs->flags;
xs->resid = mxs->resid;
memcpy(&xs->sense, &mxs->sense, sizeof(xs->sense));
@@ -191,56 +323,74 @@ mpath_done(struct scsi_xfer *mxs)
void
mpath_minphys(struct buf *bp, struct scsi_link *link)
{
- struct mpath_node *n = mpath_nodes[link->target];
+ struct mpath_dev *d = mpath_devs[link->target];
struct mpath_path *p;
- if (n == NULL)
- return;
+#ifdef DIAGNOSTIC
+ if (d == NULL)
+ panic("mpath_minphys against nonexistant device");
+#endif
- TAILQ_FOREACH(p, &n->node_paths, path_entry)
- p->path_link->adapter->scsi_minphys(bp, p->path_link);
+ TAILQ_FOREACH(p, &d->d_paths, p_entry)
+ p->p_link->adapter->scsi_minphys(bp, p->p_link);
}
int
-mpath_path_attach(struct scsi_link *link)
+mpath_path_probe(struct scsi_link *link)
{
- struct mpath_node *n;
- struct mpath_path *p;
- int probe = 0;
- int target;
-
- if (mpath != NULL && link->adapter_softc == mpath)
- return (ENODEV);
+ if (link->id == NULL)
+ return (EINVAL);
- /* XXX this is dumb. should check inq shizz */
- if (ISSET(link->flags, SDEV_VIRTUAL) || link->id == NULL)
+ if (mpath != NULL && mpath == link->adapter_softc)
return (ENXIO);
+ return (0);
+}
+
+int
+mpath_path_attach(struct mpath_path *p)
+{
+ struct scsi_link *link = p->p_link;
+ struct mpath_dev *d = NULL;
+ int newdev = 0, addxsh = 0;
+ int target;
+
+#ifdef DIAGNOSTIC
+ if (p->p_link == NULL)
+ panic("mpath_path_attach: NULL link");
+ if (p->p_dev != NULL)
+ panic("mpath_path_attach: dev is not NULL");
+#endif
+
for (target = 0; target < MPATH_BUSWIDTH; target++) {
- if ((n = mpath_nodes[target]) == NULL)
+ if ((d = mpath_devs[target]) == NULL)
continue;
- if (DEVID_CMP(n->node_id, link->id))
+ if (DEVID_CMP(d->d_id, link->id))
break;
- n = NULL;
+ d = NULL;
}
- if (n == NULL) {
+ if (d == NULL) {
for (target = 0; target < MPATH_BUSWIDTH; target++) {
- if (mpath_nodes[target] == NULL)
+ if (mpath_devs[target] == NULL)
break;
}
if (target >= MPATH_BUSWIDTH)
return (ENXIO);
- n = malloc(sizeof(*n), M_DEVBUF, M_WAITOK | M_ZERO);
- TAILQ_INIT(&n->node_paths);
+ d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (d == NULL)
+ return (ENOMEM);
- n->node_id = devid_copy(link->id);
+ mtx_init(&d->d_mtx, IPL_BIO);
+ TAILQ_INIT(&d->d_paths);
+ SIMPLEQ_INIT(&d->d_ccbs);
+ d->d_id = devid_copy(link->id);
- mpath_nodes[target] = n;
- probe = 1;
+ mpath_devs[target] = d;
+ newdev = 1;
} else {
/*
* instead of carrying identical values in different devid
@@ -248,60 +398,94 @@ mpath_path_attach(struct scsi_link *link)
* the new scsi_link.
*/
devid_free(link->id);
- link->id = devid_copy(n->node_id);
+ link->id = devid_copy(d->d_id);
}
- p = malloc(sizeof(*p), M_DEVBUF, M_WAITOK);
-
- p->path_link = link;
- TAILQ_INSERT_TAIL(&n->node_paths, p, path_entry);
-
- if (mpath != NULL && probe)
+ p->p_dev = d;
+ mtx_enter(&d->d_mtx);
+ if (TAILQ_EMPTY(&d->d_paths))
+ d->d_next_path = p;
+ TAILQ_INSERT_TAIL(&d->d_paths, p, p_entry);
+ d->d_path_count++;
+ if (!SIMPLEQ_EMPTY(&d->d_ccbs))
+ addxsh = 1;
+ mtx_leave(&d->d_mtx);
+
+ if (newdev && mpath != NULL)
scsi_probe_target(mpath->sc_scsibus, target);
+ else if (addxsh)
+ scsi_xsh_add(&p->p_xsh);
return (0);
}
int
-mpath_path_detach(struct scsi_link *link, int flags)
+mpath_path_detach(struct mpath_path *p)
{
- struct mpath_node *n;
- struct mpath_path *p;
- int target;
+ struct mpath_dev *d = p->p_dev;
+ struct mpath_path *np = NULL;
- for (target = 0; target < MPATH_BUSWIDTH; target++) {
- if ((n = mpath_nodes[target]) == NULL)
- continue;
+#ifdef DIAGNOSTIC
+ if (d == NULL)
+ panic("mpath: detaching a path from a nonexistant bus");
+#endif
+ p->p_dev = NULL;
- if (DEVID_CMP(n->node_id, link->id))
- break;
+ mtx_enter(&d->d_mtx);
+ TAILQ_REMOVE(&d->d_paths, p, p_entry);
+ if (d->d_next_path == p)
+ d->d_next_path = TAILQ_FIRST(&d->d_paths);
- n = NULL;
- }
+ d->d_path_count--;
+ if (!SIMPLEQ_EMPTY(&d->d_ccbs))
+ np = d->d_next_path;
+ mtx_leave(&d->d_mtx);
- if (n == NULL)
- panic("mpath: detaching a path from a nonexistant bus");
+ scsi_xsh_del(&p->p_xsh);
- TAILQ_FOREACH(p, &n->node_paths, path_entry) {
- if (p->path_link == link) {
- TAILQ_REMOVE(&n->node_paths, p, path_entry);
- free(p, M_DEVBUF);
- return (0);
- }
- }
+ if (np != NULL)
+ scsi_xsh_add(&np->p_xsh);
- panic("mpath: unable to locate path for detach");
+ return (0);
}
-void
-mpath_path_activate(struct scsi_link *link)
+void *
+mpath_ccb_get(void *cookie)
{
+ struct mpath_softc *sc = cookie;
+ return (pool_get(&sc->sc_ccb_pool, PR_NOWAIT));
}
void
-mpath_path_deactivate(struct scsi_link *link)
+mpath_ccb_put(void *cookie, void *io)
{
+ struct mpath_softc *sc = cookie;
+ pool_put(&sc->sc_ccb_pool, io);
}
+struct device *
+mpath_bootdv(struct device *dev)
+{
+ struct mpath_dev *d;
+ struct mpath_path *p;
+ int target;
+
+ if (mpath == NULL)
+ return (dev);
+
+ for (target = 0; target < MPATH_BUSWIDTH; target++) {
+ if ((d = mpath_devs[target]) == NULL)
+ continue;
+
+ TAILQ_FOREACH(p, &d->d_paths, p_entry) {
+ if (p->p_link->device_softc == dev) {
+ return (scsi_get_link(mpath->sc_scsibus,
+ target, 0)->device_softc);
+ }
+ }
+ }
+
+ return (dev);
+}
diff --git a/sys/scsi/mpath_emc.c b/sys/scsi/mpath_emc.c
new file mode 100644
index 00000000000..cb77e0c079b
--- /dev/null
+++ b/sys/scsi/mpath_emc.c
@@ -0,0 +1,298 @@
+/* $OpenBSD: mpath_emc.c,v 1.1 2011/04/05 14:25:42 dlg Exp $ */
+
+/*
+ * Copyright (c) 2011 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.
+ */
+
+/* EMC CLARiiON AX/CX support for mpath(4) */
+
+#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 <scsi/mpathvar.h>
+
+#define EMC_VPD_SP_INFO 0xc0
+
+struct emc_vpd_sp_info {
+ struct scsi_vpd_hdr hdr; /* EMC_VPD_SP_INFO */
+
+ u_int8_t lun_state;
+#define EMC_SP_INFO_LUN_STATE_UNBOUND 0x00
+#define EMC_SP_INFO_LUN_STATE_BOUND 0x01
+#define EMC_SP_INFO_LUN_STATE_OWNED 0x02
+ u_int8_t default_sp;
+ u_int8_t _reserved1[1];
+ u_int8_t port;
+ u_int8_t current_sp;
+ u_int8_t _reserved2[1];
+ u_int8_t unique_id[16];
+ u_int8_t _reserved3[1];
+ u_int8_t type;
+ u_int8_t failover_mode;
+ u_int8_t _reserved4[21];
+ u_int8_t serial[16];
+} __packed;
+
+struct emc_softc {
+ struct device sc_dev;
+ struct mpath_path sc_path;
+ u_int sc_flags;
+ u_int8_t sc_sp;
+ u_int8_t sc_port;
+ u_int8_t sc_lun_state;
+
+};
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+
+int emc_match(struct device *, void *, void *);
+void emc_attach(struct device *, struct device *, void *);
+int emc_detach(struct device *, int);
+int emc_activate(struct device *, int);
+
+struct cfattach emc_ca = {
+ sizeof(struct emc_softc),
+ emc_match,
+ emc_attach,
+ emc_detach,
+ emc_activate
+};
+
+struct cfdriver emc_cd = {
+ NULL,
+ "emc",
+ DV_DULL
+};
+
+void emc_mpath_start(struct scsi_xfer *);
+int emc_mpath_checksense(struct scsi_xfer *);
+int emc_mpath_online(struct scsi_link *);
+int emc_mpath_offline(struct scsi_link *);
+
+struct mpath_ops emc_mpath_ops = {
+ "emc",
+ emc_mpath_start,
+ emc_mpath_checksense,
+ emc_mpath_online,
+ emc_mpath_offline,
+};
+
+struct emc_device {
+ char *vendor;
+ char *product;
+};
+
+int emc_inquiry(struct emc_softc *, char *, char *);
+int emc_sp_info(struct emc_softc *);
+
+struct emc_device emc_devices[] = {
+/* " vendor " " device " */
+/* "01234567" "0123456789012345" */
+ { "DGC ", "LUNZ" },
+ { "DGC ", "RAID" },
+ { "DGC ", "DISK" },
+ { "DGC ", "VRAID" }
+};
+
+int
+emc_match(struct device *parent, void *match, void *aux)
+{
+ struct scsi_attach_args *sa = aux;
+ struct scsi_inquiry_data *inq = sa->sa_inqbuf;
+ struct emc_device *s;
+ int i;
+
+ if (mpath_path_probe(sa->sa_sc_link) != 0)
+ return (0);
+
+ for (i = 0; i < nitems(emc_devices); i++) {
+ s = &emc_devices[i];
+
+ if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
+ bcmp(s->product, inq->product, strlen(s->product)) == 0)
+ return (3);
+ }
+
+ return (0);
+}
+
+void
+emc_attach(struct device *parent, struct device *self, void *aux)
+{
+ char model[256], serial[256];
+ struct emc_softc *sc = (struct emc_softc *)self;
+ struct scsi_attach_args *sa = aux;
+ struct scsi_link *link = sa->sa_sc_link;
+
+ printf("\n");
+
+ /* init link */
+ link->device_softc = sc;
+
+ /* init path */
+ scsi_xsh_set(&sc->sc_path.p_xsh, link, emc_mpath_start);
+ sc->sc_path.p_link = link;
+ sc->sc_path.p_ops = &emc_mpath_ops;
+
+ if (emc_sp_info(sc)) {
+ printf("%s: unable to get sp info\n", DEVNAME(sc));
+ return;
+ }
+
+ if (emc_inquiry(sc, model, serial) != 0) {
+ printf("%s: unable to get inquiry data\n", DEVNAME(sc));
+ return;
+ }
+
+ printf("%s: %s %s SP-%c port %d\n", DEVNAME(sc), model, serial,
+ sc->sc_sp + 'A', sc->sc_port);
+
+ if (sc->sc_lun_state == EMC_SP_INFO_LUN_STATE_OWNED) {
+ if (mpath_path_attach(&sc->sc_path) != 0)
+ printf("%s: unable to attach path\n", DEVNAME(sc));
+ }
+}
+
+int
+emc_detach(struct device *self, int flags)
+{
+ return (0);
+}
+
+int
+emc_activate(struct device *self, int act)
+{
+ struct emc_softc *sc = (struct emc_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ case DVACT_SUSPEND:
+ case DVACT_RESUME:
+ break;
+ case DVACT_DEACTIVATE:
+ if (sc->sc_path.p_dev != NULL)
+ mpath_path_detach(&sc->sc_path);
+ break;
+ }
+ return (rv);
+}
+
+void
+emc_mpath_start(struct scsi_xfer *xs)
+{
+ struct emc_softc *sc = xs->sc_link->device_softc;
+
+ mpath_start(&sc->sc_path, xs);
+}
+
+int
+emc_mpath_checksense(struct scsi_xfer *xs)
+{
+ return (0);
+}
+
+int
+emc_mpath_online(struct scsi_link *link)
+{
+ return (0);
+}
+
+int
+emc_mpath_offline(struct scsi_link *link)
+{
+ return (0);
+}
+
+int
+emc_inquiry(struct emc_softc *sc, char *model, char *serial)
+{
+ u_int8_t buffer[255];
+ struct scsi_inquiry *cdb;
+ struct scsi_xfer *xs;
+ size_t length;
+ int error;
+ u_int8_t slen, mlen;
+
+ length = MIN(sc->sc_path.p_link->inqdata.additional_length + 5,
+ sizeof(buffer));
+ if (length < 160) {
+ printf("%s: FC (Legacy)\n");
+ return (0);
+ }
+
+ xs = scsi_xs_get(sc->sc_path.p_link, scsi_autoconf);
+ if (xs == NULL)
+ return (EBUSY);
+
+ cdb = (struct scsi_inquiry *)xs->cmd;
+ cdb->opcode = INQUIRY;
+ _lto2b(length, cdb->length);
+
+ xs->cmdlen = sizeof(*cdb);
+ xs->flags |= SCSI_DATA_IN;
+ xs->data = buffer;
+ xs->datalen = length;
+
+ error = scsi_xs_sync(xs);
+ scsi_xs_put(xs);
+
+ if (error != 0)
+ return (error);
+
+ slen = buffer[160];
+ if (slen == 0 || slen + 161 > length)
+ return (EIO);
+
+ mlen = buffer[99];
+ if (mlen == 0 || slen + mlen + 161 > length)
+ return (EIO);
+
+ scsi_strvis(serial, buffer + 161, slen);
+ scsi_strvis(model, buffer + 161 + slen, mlen);
+
+ return (0);
+}
+
+int
+emc_sp_info(struct emc_softc *sc)
+{
+ struct emc_vpd_sp_info pg;
+ int error;
+
+ error = scsi_inquire_vpd(sc->sc_path.p_link, &pg, sizeof(pg),
+ EMC_VPD_SP_INFO, scsi_autoconf);
+ if (error != 0)
+ return (error);
+
+ sc->sc_sp = pg.current_sp;
+ sc->sc_port = pg.port;
+ sc->sc_lun_state = pg.lun_state;
+
+ return (0);
+}
diff --git a/sys/scsi/mpath_rdac.c b/sys/scsi/mpath_rdac.c
new file mode 100644
index 00000000000..493912ead7e
--- /dev/null
+++ b/sys/scsi/mpath_rdac.c
@@ -0,0 +1,335 @@
+/* $OpenBSD: mpath_rdac.c,v 1.1 2011/04/05 14:25:42 dlg Exp $ */
+
+/*
+ * Copyright (c) 2010 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.
+ */
+
+/* Redundant Disk Array Controller support for mpath(4) */
+
+#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 <scsi/mpathvar.h>
+
+struct rdac_common_mode_page {
+ u_int8_t controller_serial[16];
+ u_int8_t alt_controller_serial[16];
+ u_int8_t mode[2];
+ u_int8_t alt_mode[2];
+ u_int8_t timeout;
+ u_int8_t options;
+};
+
+/*
+ * RDAC VPD pages
+ */
+#define RDAC_VPD_HDWVER 0xc0 /* Hardware Version */
+#define RDAC_VPD_SERNUM 0xc1 /* Serial Numbers */
+#define RDAC_VPD_SFWVER 0xc2
+#define RDAC_VPD_FEAPAR 0xc3 /* Feature Parameters */
+#define RDAC_VPD_SUBSYS 0xc4
+#define RDAC_VPD_HSTINT 0xc5
+#define RDAC_VPD_DGM 0xc6
+#define RDAC_VPD_HSTINT2 0xc7
+#define RDAC_VPD_EXTDEVID 0xc8
+#define RDAC_VPD_VOLACCESSCTL 0xc9
+
+struct rdac_vpd_hdwver {
+ struct scsi_vpd_hdr hdr; /* RDAC_VPD_HDWVER */
+ u_int8_t pg_id[4];
+#define RDAC_VPD_ID_HDWVER 0x68777234 /* "hwr4" */
+ u_int8_t num_channels;
+ u_int8_t flags;
+ u_int8_t proc_memory_size;
+ u_int8_t _reserved1[5];
+ u_int8_t board_name[64];
+ u_int8_t board_part_number[16];
+ u_int8_t schematic_number[12];
+ u_int8_t schematic_revision[4];
+ u_int8_t serial_number[16];
+ u_int8_t _reserved2[16];
+ u_int8_t date_manufactured[8];
+ u_int8_t board_revision[2];
+ u_int8_t board_identifier[4];
+};
+
+struct rdac_vpd_subsys {
+ struct scsi_vpd_hdr hdr; /* RDAC_VPD_SUBSYS */
+ u_int8_t pg_id[4];
+#define RDAC_VPD_ID_SUBSYS 0x73756273 /* "subs" */
+ u_int8_t subsystem_id[16];
+ u_int8_t subsystem_revision[4];
+ u_int8_t controller_slot_id[2];
+ u_int8_t _reserved[2];
+};
+
+struct rdac_vpd_extdevid {
+ struct scsi_vpd_hdr hdr; /* RDAC_VPD_EXTDEVID */
+ u_int8_t pg_id[4];
+#define RDAC_VPD_ID_EXTDEVID 0x65646964 /* "edid" */
+ u_int8_t _reserved[3];
+ u_int8_t vol_id_len;
+ u_int8_t vol_id[16];
+ u_int8_t vol_label_len;
+ u_int8_t vol_label[60];
+ u_int8_t array_id_len;
+ u_int8_t array_id[16];
+ u_int8_t array_label_len;
+ u_int8_t array_label[60];
+ u_int8_t lun[8];
+};
+
+struct rdac_vpd_volaccessctl {
+ struct scsi_vpd_hdr hdr; /* RDAC_VPD_VOLACCESSCTL */
+ u_int8_t pg_id[4];
+#define RDAC_VPD_ID_VOLACCESSCTL 0x76616331 /* "vac1" */
+ u_int8_t avtcvp;
+#define RDAC_VOLACCESSCTL_OWNER 0x01
+#define RDAC_VOLACCESSCTL_AVT 0x70
+ u_int8_t path_priority;
+ u_int8_t _reserved[38];
+};
+
+struct rdac_softc {
+ struct device sc_dev;
+ struct mpath_path sc_path;
+};
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+
+int rdac_match(struct device *, void *, void *);
+void rdac_attach(struct device *, struct device *, void *);
+int rdac_detach(struct device *, int);
+int rdac_activate(struct device *, int);
+
+struct cfattach rdac_ca = {
+ sizeof(struct rdac_softc),
+ rdac_match,
+ rdac_attach,
+ rdac_detach,
+ rdac_activate
+};
+
+struct cfdriver rdac_cd = {
+ NULL,
+ "rdac",
+ DV_DULL
+};
+
+void rdac_mpath_start(struct scsi_xfer *);
+int rdac_mpath_checksense(struct scsi_xfer *);
+int rdac_mpath_online(struct scsi_link *);
+int rdac_mpath_offline(struct scsi_link *);
+
+struct mpath_ops rdac_mpath_ops = {
+ "rdac",
+ rdac_mpath_start,
+ rdac_mpath_checksense,
+ rdac_mpath_online,
+ rdac_mpath_offline,
+};
+
+int rdac_c8(struct rdac_softc *);
+int rdac_c9(struct rdac_softc *);
+
+struct rdac_device {
+ char *vendor;
+ char *product;
+};
+
+struct rdac_device rdac_devices[] = {
+/* " vendor " " device " */
+/* "01234567" "0123456789012345" */
+ { "SUN ", "CSM200_" },
+ { "DELL ", "MD3000i " }
+};
+
+int
+rdac_match(struct device *parent, void *match, void *aux)
+{
+ struct scsi_attach_args *sa = aux;
+ struct scsi_inquiry_data *inq = sa->sa_inqbuf;
+ struct rdac_device *s;
+ int i;
+
+ if (mpath_path_probe(sa->sa_sc_link) != 0)
+ return (0);
+
+ for (i = 0; i < nitems(rdac_devices); i++) {
+ s = &rdac_devices[i];
+
+ if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
+ bcmp(s->product, inq->product, strlen(s->product)) == 0)
+ return (3);
+ }
+
+ return (0);
+}
+
+void
+rdac_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct rdac_softc *sc = (struct rdac_softc *)self;
+ struct scsi_attach_args *sa = aux;
+ struct scsi_link *link = sa->sa_sc_link;
+
+ printf("\n");
+
+ /* init link */
+ link->device_softc = sc;
+
+ /* init path */
+ scsi_xsh_set(&sc->sc_path.p_xsh, link, rdac_mpath_start);
+ sc->sc_path.p_link = link;
+ sc->sc_path.p_ops = &rdac_mpath_ops;
+
+ if (rdac_c8(sc) != 0)
+ return;
+
+ if (rdac_c9(sc) != 0)
+ return;
+
+ if (mpath_path_attach(&sc->sc_path) != 0)
+ printf("%s: unable to attach path\n", DEVNAME(sc));
+}
+
+int
+rdac_detach(struct device *self, int flags)
+{
+ return (0);
+}
+
+int
+rdac_activate(struct device *self, int act)
+{
+ struct rdac_softc *sc = (struct rdac_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ case DVACT_SUSPEND:
+ case DVACT_RESUME:
+ break;
+ case DVACT_DEACTIVATE:
+ if (sc->sc_path.p_dev != NULL)
+ mpath_path_detach(&sc->sc_path);
+ break;
+ }
+ return (rv);
+
+}
+
+void
+rdac_mpath_start(struct scsi_xfer *xs)
+{
+ struct rdac_softc *sc = xs->sc_link->device_softc;
+
+ mpath_start(&sc->sc_path, xs);
+}
+
+int
+rdac_mpath_checksense(struct scsi_xfer *xs)
+{
+ return (0);
+}
+
+int
+rdac_mpath_online(struct scsi_link *link)
+{
+ return (0);
+}
+
+int
+rdac_mpath_offline(struct scsi_link *link)
+{
+ return (0);
+}
+
+int
+rdac_c8(struct rdac_softc *sc)
+{
+ struct rdac_vpd_extdevid pg;
+ char array[31];
+ char vol[31];
+ int i;
+
+ if (scsi_inquire_vpd(sc->sc_path.p_link, &pg, sizeof(pg), 0xc8,
+ scsi_autoconf) != 0) {
+ printf("%s: unable to fetch vpd page c8\n", DEVNAME(sc));
+ return (1);
+ }
+
+ if (_4btol(pg.pg_id) != RDAC_VPD_ID_EXTDEVID) {
+ printf("%s: extended hardware id page is invalid\n",
+ DEVNAME(sc));
+ return (1);
+ }
+
+ memset(array, 0, sizeof(array));
+ for (i = 0; i < sizeof(pg.array_label) / 2; i++)
+ array[i] = pg.array_label[i * 2 + 1];
+
+ memset(vol, 0, sizeof(vol));
+ for (i = 0; i < sizeof(pg.vol_label) / 2; i++)
+ vol[i] = pg.vol_label[i * 2 + 1];
+
+ printf("%s: array %s, volume %s\n", DEVNAME(sc), array, vol);
+
+ return (0);
+}
+
+int
+rdac_c9(struct rdac_softc *sc)
+{
+ struct rdac_vpd_volaccessctl pg;
+
+ if (scsi_inquire_vpd(sc->sc_path.p_link, &pg, sizeof(pg),
+ RDAC_VPD_VOLACCESSCTL, scsi_autoconf) != 0) {
+ printf("%s: unable to fetch vpd page c9\n", DEVNAME(sc));
+ return (1);
+ }
+
+ if (_4btol(pg.pg_id) != RDAC_VPD_ID_VOLACCESSCTL) {
+ printf("%s: volume access control page id is invalid\n",
+ DEVNAME(sc));
+ return (1);
+ }
+
+ if (ISSET(pg.avtcvp, RDAC_VOLACCESSCTL_AVT)) {
+ printf("%s: avt\n", DEVNAME(sc));
+ return (0);
+ }
+ if (ISSET(pg.avtcvp, RDAC_VOLACCESSCTL_OWNER)) {
+ printf("%s: owner\n", DEVNAME(sc));
+ return (0);
+ }
+
+ printf("%s: unowned\n", DEVNAME(sc));
+ return (1);
+}
+
diff --git a/sys/scsi/mpath_sym.c b/sys/scsi/mpath_sym.c
new file mode 100644
index 00000000000..8eb5ecaefdf
--- /dev/null
+++ b/sys/scsi/mpath_sym.c
@@ -0,0 +1,179 @@
+/* $OpenBSD: mpath_sym.c,v 1.1 2011/04/05 14:25:42 dlg Exp $ */
+
+/*
+ * Copyright (c) 2010 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 <scsi/mpathvar.h>
+
+struct sym_softc {
+ struct device sc_dev;
+ struct mpath_path sc_path;
+};
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+
+int sym_match(struct device *, void *, void *);
+void sym_attach(struct device *, struct device *, void *);
+int sym_detach(struct device *, int);
+int sym_activate(struct device *, int);
+
+struct cfattach sym_ca = {
+ sizeof(struct sym_softc),
+ sym_match,
+ sym_attach,
+ sym_detach,
+ sym_activate
+};
+
+struct cfdriver sym_cd = {
+ NULL,
+ "sym",
+ DV_DULL
+};
+
+void sym_mpath_start(struct scsi_xfer *);
+int sym_mpath_checksense(struct scsi_xfer *);
+int sym_mpath_online(struct scsi_link *);
+int sym_mpath_offline(struct scsi_link *);
+
+struct mpath_ops sym_mpath_ops = {
+ "sym",
+ sym_mpath_start,
+ sym_mpath_checksense,
+ sym_mpath_online,
+ sym_mpath_offline
+};
+
+struct sym_device {
+ char *vendor;
+ char *product;
+};
+
+struct sym_device sym_devices[] = {
+/* " vendor " " device " */
+/* "01234567" "0123456789012345" */
+ { "SEAGATE ", "ST" }
+};
+
+int
+sym_match(struct device *parent, void *match, void *aux)
+{
+ struct scsi_attach_args *sa = aux;
+ struct scsi_inquiry_data *inq = sa->sa_inqbuf;
+ struct sym_device *s;
+ int i;
+
+ if (mpath_path_probe(sa->sa_sc_link) != 0)
+ return (0);
+
+ for (i = 0; i < nitems(sym_devices); i++) {
+ s = &sym_devices[i];
+
+ if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
+ bcmp(s->product, inq->product, strlen(s->product)) == 0)
+ return (3);
+ }
+
+ return (0);
+}
+
+void
+sym_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct sym_softc *sc = (struct sym_softc *)self;
+ struct scsi_attach_args *sa = aux;
+ struct scsi_link *link = sa->sa_sc_link;
+
+ printf("\n");
+
+ /* init link */
+ link->device_softc = sc;
+
+ /* init path */
+ scsi_xsh_set(&sc->sc_path.p_xsh, link, sym_mpath_start);
+ sc->sc_path.p_link = link;
+ sc->sc_path.p_ops = &sym_mpath_ops;
+
+ if (mpath_path_attach(&sc->sc_path) != 0)
+ printf("%s: unable to attach path\n", DEVNAME(sc));
+}
+
+int
+sym_detach(struct device *self, int flags)
+{
+ return (0);
+}
+
+int
+sym_activate(struct device *self, int act)
+{
+ struct sym_softc *sc = (struct sym_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ case DVACT_SUSPEND:
+ case DVACT_RESUME:
+ break;
+ case DVACT_DEACTIVATE:
+ if (sc->sc_path.p_dev != NULL)
+ mpath_path_detach(&sc->sc_path);
+ break;
+ }
+ return (rv);
+}
+
+void
+sym_mpath_start(struct scsi_xfer *xs)
+{
+ struct sym_softc *sc = xs->sc_link->device_softc;
+
+ mpath_start(&sc->sc_path, xs);
+}
+
+int
+sym_mpath_checksense(struct scsi_xfer *xs)
+{
+ return (0);
+}
+
+int
+sym_mpath_online(struct scsi_link *link)
+{
+ return (0);
+}
+
+int
+sym_mpath_offline(struct scsi_link *link)
+{
+ return (0);
+}
diff --git a/sys/scsi/mpathvar.h b/sys/scsi/mpathvar.h
new file mode 100644
index 00000000000..8a1357a500b
--- /dev/null
+++ b/sys/scsi/mpathvar.h
@@ -0,0 +1,55 @@
+/* $OpenBSD: mpathvar.h,v 1.1 2011/04/05 14:25:42 dlg Exp $ */
+
+/*
+ * Copyright (c) 2010 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_SCSI_MPATH_H_
+#define _SYS_SCSI_MPATH_H_
+
+struct mpath_dev;
+struct mpath_group;
+
+struct mpath_ops {
+ char op_name[16];
+ void (*op_start)(struct scsi_xfer *);
+ int (*op_checksense)(struct scsi_xfer *);
+ int (*op_online)(struct scsi_link *);
+ int (*op_offline)(struct scsi_link *);
+};
+
+struct mpath_path {
+ /* the path driver must set these */
+ struct scsi_xshandler p_xsh;
+ struct scsi_link *p_link;
+ struct mpath_ops *p_ops;
+ int p_gid;
+
+ /* the follwoing are private to mpath.c */
+ TAILQ_ENTRY(mpath_path) p_entry;
+ struct mpath_dev *p_dev;
+ int p_state;
+};
+
+int mpath_path_probe(struct scsi_link *);
+int mpath_path_attach(struct mpath_path *);
+void mpath_path_state(struct mpath_path *, int);
+int mpath_path_detach(struct mpath_path *);
+
+void mpath_start(struct mpath_path *, struct scsi_xfer *);
+
+struct device *mpath_bootdv(struct device *);
+
+#endif /* _SYS_SCSI_MPATH_H_ */
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index 9fa6900e761..778c42a701b 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.c,v 1.169 2011/03/31 18:42:48 jasper Exp $ */
+/* $OpenBSD: scsiconf.c,v 1.170 2011/04/05 14:25:42 dlg Exp $ */
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/*
@@ -61,6 +61,7 @@
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+#include <scsi/mpathvar.h>
#if NBIO > 0
#include <sys/ioctl.h>
@@ -248,12 +249,7 @@ scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act)
switch (act) {
case DVACT_ACTIVATE:
atomic_clearbits_int(&link->state, SDEV_S_DYING);
-#if NMPATH > 0
- if (dev == NULL)
- mpath_path_activate(link);
- else
-#endif /* NMPATH */
- config_activate(dev);
+ config_activate(dev);
break;
case DVACT_QUIESCE:
case DVACT_SUSPEND:
@@ -262,12 +258,7 @@ scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act)
break;
case DVACT_DEACTIVATE:
atomic_setbits_int(&link->state, SDEV_S_DYING);
-#if NMPATH > 0
- if (dev == NULL)
- mpath_path_deactivate(link);
- else
-#endif /* NMPATH */
- config_deactivate(dev);
+ config_deactivate(dev);
break;
default:
break;
@@ -502,12 +493,7 @@ scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags)
scsi_link_shutdown(link);
/* 2. detach the device */
-#if NMPATH > 0
- if (link->device_softc == NULL)
- rv = mpath_path_detach(link, flags);
- else
-#endif /* NMPATH */
- rv = config_detach(link->device_softc, flags);
+ rv = config_detach(link->device_softc, flags);
if (rv != 0)
return (rv);
@@ -970,18 +956,6 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
goto free_devid;
}
-#if NMPATH > 0
- /* should multipathing steal the link? */
- if (mpath_path_attach(sc_link) == 0) {
- printf("%s: path to", scsi->sc_dev.dv_xname);
- scsibus_printlink(sc_link);
- printf("\n");
-
- scsi_add_link(scsi, sc_link);
- return (0);
- }
-#endif /* NMPATH */
-
finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch(
inqbuf, scsi_quirk_patterns,
nitems(scsi_quirk_patterns),
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index 73a67f13c19..e9a5f80e8b5 100644
--- a/sys/scsi/scsiconf.h
+++ b/sys/scsi/scsiconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.h,v 1.142 2010/12/24 02:45:33 krw Exp $ */
+/* $OpenBSD: scsiconf.h,v 1.143 2011/04/05 14:25:42 dlg Exp $ */
/* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
/*
@@ -627,15 +627,6 @@ void scsi_xsh_add(struct scsi_xshandler *);
void scsi_xsh_del(struct scsi_xshandler *);
/*
- * Entrypoints for multipathing
- */
-int mpath_path_attach(struct scsi_link *);
-int mpath_path_detach(struct scsi_link *, int);
-
-void mpath_path_activate(struct scsi_link *);
-void mpath_path_deactivate(struct scsi_link *);
-
-/*
* Utility functions for SCSI HBA emulation.
*/
void scsi_cmd_rw_decode(struct scsi_generic *, u_int64_t *, u_int32_t *);