summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/scsi/mpath.c26
-rw-r--r--sys/scsi/mpath_emc.c8
-rw-r--r--sys/scsi/mpath_hds.c10
-rw-r--r--sys/scsi/mpath_rdac.c8
-rw-r--r--sys/scsi/mpath_sym.c47
-rw-r--r--sys/scsi/mpathvar.h11
6 files changed, 79 insertions, 31 deletions
diff --git a/sys/scsi/mpath.c b/sys/scsi/mpath.c
index 799d8d2ed9a..9e50a970fe6 100644
--- a/sys/scsi/mpath.c
+++ b/sys/scsi/mpath.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpath.c,v 1.23 2011/07/08 22:09:27 matthew Exp $ */
+/* $OpenBSD: mpath.c,v 1.24 2011/07/11 01:02:48 dlg Exp $ */
/*
* Copyright (c) 2009 David Gwynne <dlg@openbsd.org>
@@ -58,6 +58,7 @@ struct mpath_dev {
u_int d_path_count;
+ const struct mpath_ops *d_ops;
struct devid *d_id;
};
@@ -89,7 +90,7 @@ 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 *);
+struct mpath_path *mpath_next_path(struct mpath_dev *, int);
void mpath_done(struct scsi_xfer *);
struct scsi_adapter mpath_switch = {
@@ -161,7 +162,7 @@ mpath_probe(struct scsi_link *link)
}
struct mpath_path *
-mpath_next_path(struct mpath_dev *d)
+mpath_next_path(struct mpath_dev *d, int next)
{
struct mpath_path *p;
@@ -169,7 +170,7 @@ mpath_next_path(struct mpath_dev *d)
panic("%s: d is NULL", __func__);
p = d->d_next_path;
- if (p != NULL) {
+ if (p != NULL && next == MPATH_NEXT) {
d->d_next_path = TAILQ_NEXT(p, p_entry);
if (d->d_next_path == NULL)
d->d_next_path = TAILQ_FIRST(&d->d_paths);
@@ -194,7 +195,7 @@ mpath_cmd(struct scsi_xfer *xs)
if (ISSET(xs->flags, SCSI_POLL)) {
mtx_enter(&d->d_mtx);
- p = mpath_next_path(d);
+ p = mpath_next_path(d, d->d_ops->op_schedule);
mtx_leave(&d->d_mtx);
if (p == NULL) {
mpath_xs_stuffup(xs);
@@ -232,7 +233,7 @@ mpath_cmd(struct scsi_xfer *xs)
mtx_enter(&d->d_mtx);
SIMPLEQ_INSERT_TAIL(&d->d_ccbs, ccb, c_entry);
- p = mpath_next_path(d);
+ p = mpath_next_path(d, d->d_ops->op_schedule);
mtx_leave(&d->d_mtx);
if (p != NULL)
@@ -294,11 +295,15 @@ mpath_done(struct scsi_xfer *mxs)
struct mpath_ccb *ccb = xs->io;
struct mpath_dev *d = mpath_devs[link->target];
struct mpath_path *p;
+ int next = d->d_ops->op_schedule;
- if (mxs->error == XS_RESET || mxs->error == XS_SELTIMEOUT) {
+ switch (mxs->error) {
+ case XS_SELTIMEOUT: /* physical path is gone, try the next */
+ next = MPATH_NEXT;
+ case XS_RESET:
mtx_enter(&d->d_mtx);
SIMPLEQ_INSERT_HEAD(&d->d_ccbs, ccb, c_entry);
- p = mpath_next_path(d);
+ p = mpath_next_path(d, next);
mtx_leave(&d->d_mtx);
scsi_xs_put(mxs);
@@ -363,7 +368,7 @@ mpath_path_probe(struct scsi_link *link)
}
int
-mpath_path_attach(struct mpath_path *p)
+mpath_path_attach(struct mpath_path *p, const struct mpath_ops *ops)
{
struct scsi_link *link = p->p_link;
struct mpath_dev *d = NULL;
@@ -381,7 +386,7 @@ mpath_path_attach(struct mpath_path *p)
if ((d = mpath_devs[target]) == NULL)
continue;
- if (DEVID_CMP(d->d_id, link->id))
+ if (DEVID_CMP(d->d_id, link->id) && d->d_ops == ops)
break;
d = NULL;
@@ -404,6 +409,7 @@ mpath_path_attach(struct mpath_path *p)
TAILQ_INIT(&d->d_paths);
SIMPLEQ_INIT(&d->d_ccbs);
d->d_id = devid_copy(link->id);
+ d->d_ops = ops;
mpath_devs[target] = d;
newdev = 1;
diff --git a/sys/scsi/mpath_emc.c b/sys/scsi/mpath_emc.c
index 240f62ef571..aa55f875a67 100644
--- a/sys/scsi/mpath_emc.c
+++ b/sys/scsi/mpath_emc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpath_emc.c,v 1.7 2011/07/03 15:47:18 matthew Exp $ */
+/* $OpenBSD: mpath_emc.c,v 1.8 2011/07/11 01:02:48 dlg Exp $ */
/*
* Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
@@ -94,11 +94,12 @@ 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 = {
+const struct mpath_ops emc_mpath_ops = {
"emc",
emc_mpath_checksense,
emc_mpath_online,
emc_mpath_offline,
+ MPATH_ROUNDROBIN
};
struct emc_device {
@@ -156,7 +157,6 @@ emc_attach(struct device *parent, struct device *self, void *aux)
/* 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));
@@ -172,7 +172,7 @@ emc_attach(struct device *parent, struct device *self, void *aux)
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)
+ if (mpath_path_attach(&sc->sc_path, &emc_mpath_ops) != 0)
printf("%s: unable to attach path\n", DEVNAME(sc));
}
}
diff --git a/sys/scsi/mpath_hds.c b/sys/scsi/mpath_hds.c
index 2c0aae8e334..8eb1c046fc7 100644
--- a/sys/scsi/mpath_hds.c
+++ b/sys/scsi/mpath_hds.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpath_hds.c,v 1.5 2011/07/03 15:47:18 matthew Exp $ */
+/* $OpenBSD: mpath_hds.c,v 1.6 2011/07/11 01:02:48 dlg Exp $ */
/*
* Copyright (c) 2011 David Gwynne <dlg@openbsd.org>
@@ -89,11 +89,12 @@ int hds_mpath_checksense(struct scsi_xfer *);
int hds_mpath_online(struct scsi_link *);
int hds_mpath_offline(struct scsi_link *);
-struct mpath_ops hds_mpath_ops = {
+const struct mpath_ops hds_mpath_ops = {
"hds",
hds_mpath_checksense,
hds_mpath_online,
- hds_mpath_offline
+ hds_mpath_offline,
+ MPATH_ROUNDROBIN
};
struct hds_device {
@@ -152,7 +153,6 @@ hds_attach(struct device *parent, struct device *self, void *aux)
/* init path */
scsi_xsh_set(&sc->sc_path.p_xsh, link, hds_mpath_start);
sc->sc_path.p_link = link;
- sc->sc_path.p_ops = &hds_mpath_ops;
if (hds_inquiry(link, &sc->sc_mode) != 0) {
printf("%s: unable to query controller mode\n");
@@ -172,7 +172,7 @@ hds_attach(struct device *parent, struct device *self, void *aux)
if (!preferred)
return;
- if (mpath_path_attach(&sc->sc_path) != 0)
+ if (mpath_path_attach(&sc->sc_path, &hds_mpath_ops) != 0)
printf("%s: unable to attach path\n", DEVNAME(sc));
}
diff --git a/sys/scsi/mpath_rdac.c b/sys/scsi/mpath_rdac.c
index 6420e942e4a..21c7d0692d2 100644
--- a/sys/scsi/mpath_rdac.c
+++ b/sys/scsi/mpath_rdac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpath_rdac.c,v 1.6 2011/07/03 15:47:18 matthew Exp $ */
+/* $OpenBSD: mpath_rdac.c,v 1.7 2011/07/11 01:02:48 dlg Exp $ */
/*
* Copyright (c) 2010 David Gwynne <dlg@openbsd.org>
@@ -146,11 +146,12 @@ 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 = {
+const struct mpath_ops rdac_mpath_ops = {
"rdac",
rdac_mpath_checksense,
rdac_mpath_online,
rdac_mpath_offline,
+ MPATH_ROUNDROBIN
};
int rdac_c8(struct rdac_softc *);
@@ -208,7 +209,6 @@ rdac_attach(struct device *parent, struct device *self, void *aux)
/* 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;
@@ -216,7 +216,7 @@ rdac_attach(struct device *parent, struct device *self, void *aux)
if (rdac_c9(sc) != 0)
return;
- if (mpath_path_attach(&sc->sc_path) != 0)
+ if (mpath_path_attach(&sc->sc_path, &rdac_mpath_ops) != 0)
printf("%s: unable to attach path\n", DEVNAME(sc));
}
diff --git a/sys/scsi/mpath_sym.c b/sys/scsi/mpath_sym.c
index 8839540a991..461370c1047 100644
--- a/sys/scsi/mpath_sym.c
+++ b/sys/scsi/mpath_sym.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpath_sym.c,v 1.5 2011/07/03 15:47:18 matthew Exp $ */
+/* $OpenBSD: mpath_sym.c,v 1.6 2011/07/11 01:02:48 dlg Exp $ */
/*
* Copyright (c) 2010 David Gwynne <dlg@openbsd.org>
@@ -65,11 +65,20 @@ 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 = {
+const struct mpath_ops sym_mpath_sym_ops = {
"sym",
sym_mpath_checksense,
sym_mpath_online,
- sym_mpath_offline
+ sym_mpath_offline,
+ MPATH_ROUNDROBIN
+};
+
+const struct mpath_ops sym_mpath_asym_ops = {
+ "sym",
+ sym_mpath_checksense,
+ sym_mpath_online,
+ sym_mpath_offline,
+ MPATH_MRU
};
struct sym_device {
@@ -84,6 +93,13 @@ struct sym_device sym_devices[] = {
{ "FUJITSU ", "MBD" }
};
+struct sym_device asym_devices[] = {
+/* " vendor " " device " */
+/* "01234567" "0123456789012345" */
+ { "DELL ", "MD1220 " },
+ { "Transtec", "PROVIGO1100" }
+};
+
int
sym_match(struct device *parent, void *match, void *aux)
{
@@ -102,6 +118,13 @@ sym_match(struct device *parent, void *match, void *aux)
bcmp(s->product, inq->product, strlen(s->product)) == 0)
return (3);
}
+ for (i = 0; i < nitems(asym_devices); i++) {
+ s = &asym_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);
}
@@ -112,18 +135,32 @@ 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;
+ struct scsi_inquiry_data *inq = sa->sa_inqbuf;
+ const struct mpath_ops *ops = &sym_mpath_sym_ops;
+ struct sym_device *s;
+ int i;
printf("\n");
+ /* check if we're an assymetric access device */
+ for (i = 0; i < nitems(asym_devices); i++) {
+ s = &asym_devices[i];
+
+ if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
+ bcmp(s->product, inq->product, strlen(s->product)) == 0) {
+ ops = &sym_mpath_asym_ops;
+ break;
+ }
+ }
+
/* 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)
+ if (mpath_path_attach(&sc->sc_path, ops) != 0)
printf("%s: unable to attach path\n", DEVNAME(sc));
}
diff --git a/sys/scsi/mpathvar.h b/sys/scsi/mpathvar.h
index bff517ea52d..b826ff34e90 100644
--- a/sys/scsi/mpathvar.h
+++ b/sys/scsi/mpathvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpathvar.h,v 1.2 2011/04/28 10:43:36 dlg Exp $ */
+/* $OpenBSD: mpathvar.h,v 1.3 2011/07/11 01:02:48 dlg Exp $ */
/*
* Copyright (c) 2010 David Gwynne <dlg@openbsd.org>
@@ -27,13 +27,17 @@ struct mpath_ops {
int (*op_checksense)(struct scsi_xfer *);
int (*op_online)(struct scsi_link *);
int (*op_offline)(struct scsi_link *);
+ int op_schedule;
};
+#define MPATH_ROUNDROBIN 0 /* use all active paths */
+#define MPATH_NEXT MPATH_ROUNDROBIN
+#define MPATH_MRU 1 /* use most recently used path */
+
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 */
@@ -43,7 +47,8 @@ struct mpath_path {
};
int mpath_path_probe(struct scsi_link *);
-int mpath_path_attach(struct mpath_path *);
+int mpath_path_attach(struct mpath_path *,
+ const struct mpath_ops *);
void mpath_path_state(struct mpath_path *, int);
int mpath_path_detach(struct mpath_path *);