diff options
-rw-r--r-- | sys/scsi/mpath.c | 26 | ||||
-rw-r--r-- | sys/scsi/mpath_emc.c | 8 | ||||
-rw-r--r-- | sys/scsi/mpath_hds.c | 10 | ||||
-rw-r--r-- | sys/scsi/mpath_rdac.c | 8 | ||||
-rw-r--r-- | sys/scsi/mpath_sym.c | 47 | ||||
-rw-r--r-- | sys/scsi/mpathvar.h | 11 |
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 *); |