1*1525749fSvisa /* $OpenBSD: mpath_sym.c,v 1.28 2022/07/02 08:50:42 visa Exp $ */
27e24ec3eSdlg
37e24ec3eSdlg /*
47e24ec3eSdlg * Copyright (c) 2010 David Gwynne <dlg@openbsd.org>
57e24ec3eSdlg *
67e24ec3eSdlg * Permission to use, copy, modify, and distribute this software for any
77e24ec3eSdlg * purpose with or without fee is hereby granted, provided that the above
87e24ec3eSdlg * copyright notice and this permission notice appear in all copies.
97e24ec3eSdlg *
107e24ec3eSdlg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
117e24ec3eSdlg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
127e24ec3eSdlg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
137e24ec3eSdlg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
147e24ec3eSdlg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
157e24ec3eSdlg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
167e24ec3eSdlg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
177e24ec3eSdlg */
187e24ec3eSdlg
197e24ec3eSdlg #include <sys/param.h>
207e24ec3eSdlg #include <sys/systm.h>
217e24ec3eSdlg #include <sys/kernel.h>
227e24ec3eSdlg #include <sys/malloc.h>
237e24ec3eSdlg #include <sys/device.h>
247e24ec3eSdlg #include <sys/conf.h>
257e24ec3eSdlg #include <sys/queue.h>
267e24ec3eSdlg #include <sys/rwlock.h>
277e24ec3eSdlg #include <sys/pool.h>
287e24ec3eSdlg #include <sys/ioctl.h>
297e24ec3eSdlg
307e24ec3eSdlg #include <scsi/scsi_all.h>
317e24ec3eSdlg #include <scsi/scsiconf.h>
327e24ec3eSdlg #include <scsi/mpathvar.h>
337e24ec3eSdlg
347e24ec3eSdlg struct sym_softc {
357e24ec3eSdlg struct device sc_dev;
367e24ec3eSdlg struct mpath_path sc_path;
377e24ec3eSdlg };
387e24ec3eSdlg #define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
397e24ec3eSdlg
407e24ec3eSdlg int sym_match(struct device *, void *, void *);
417e24ec3eSdlg void sym_attach(struct device *, struct device *, void *);
427e24ec3eSdlg int sym_detach(struct device *, int);
437e24ec3eSdlg int sym_activate(struct device *, int);
447e24ec3eSdlg
459eaf72d1Smpi const struct cfattach sym_ca = {
467e24ec3eSdlg sizeof(struct sym_softc),
477e24ec3eSdlg sym_match,
487e24ec3eSdlg sym_attach,
497e24ec3eSdlg sym_detach,
507e24ec3eSdlg sym_activate
517e24ec3eSdlg };
527e24ec3eSdlg
537e24ec3eSdlg struct cfdriver sym_cd = {
547e24ec3eSdlg NULL,
557e24ec3eSdlg "sym",
567e24ec3eSdlg DV_DULL
577e24ec3eSdlg };
587e24ec3eSdlg
597e24ec3eSdlg void sym_mpath_start(struct scsi_xfer *);
607e24ec3eSdlg int sym_mpath_checksense(struct scsi_xfer *);
619ce0d10eSdlg void sym_mpath_status(struct scsi_link *);
627e24ec3eSdlg
63c32a5b15Sdlg const struct mpath_ops sym_mpath_sym_ops = {
647e24ec3eSdlg "sym",
657e24ec3eSdlg sym_mpath_checksense,
668f5a0873Sdlg sym_mpath_status
67c32a5b15Sdlg };
68c32a5b15Sdlg
69c32a5b15Sdlg const struct mpath_ops sym_mpath_asym_ops = {
70c32a5b15Sdlg "sym",
71c32a5b15Sdlg sym_mpath_checksense,
728f5a0873Sdlg sym_mpath_status
737e24ec3eSdlg };
747e24ec3eSdlg
757e24ec3eSdlg struct sym_device {
767e24ec3eSdlg char *vendor;
777e24ec3eSdlg char *product;
787e24ec3eSdlg };
797e24ec3eSdlg
807e24ec3eSdlg struct sym_device sym_devices[] = {
817e24ec3eSdlg /* " vendor " " device " */
827e24ec3eSdlg /* "01234567" "0123456789012345" */
83695fbb94Sdlg { "TOSHIBA ", "MBF" },
84b69f3ac9Sdlg { "SEAGATE ", "ST" },
8558113bb5Sdlg { "SGI ", "ST" },
869c73f834Sdlg { "FUJITSU ", "MBD" },
87e5246649Sdlg { "FUJITSU ", "MA" }
887e24ec3eSdlg };
897e24ec3eSdlg
90c32a5b15Sdlg struct sym_device asym_devices[] = {
91c32a5b15Sdlg /* " vendor " " device " */
92c32a5b15Sdlg /* "01234567" "0123456789012345" */
93c32a5b15Sdlg { "DELL ", "MD1220 " },
94e3053d7cSdlg { "DELL ", "MD3060e " },
959c73f834Sdlg { "SUN ", "StorEdge 3510F D" },
96074a3725Sdlg { "SUNW ", "SUNWGS INT FCBPL" },
97ffa1abd2Sclaudio { "Transtec", "PROVIGO1100" },
98ffa1abd2Sclaudio { "NetBSD", "NetBSD iSCSI" }
99c32a5b15Sdlg };
100c32a5b15Sdlg
1017e24ec3eSdlg int
sym_match(struct device * parent,void * match,void * aux)1027e24ec3eSdlg sym_match(struct device *parent, void *match, void *aux)
1037e24ec3eSdlg {
1047e24ec3eSdlg struct scsi_attach_args *sa = aux;
1050fbd355cSkrw struct scsi_inquiry_data *inq = &sa->sa_sc_link->inqdata;
1067e24ec3eSdlg struct sym_device *s;
1077e24ec3eSdlg int i;
1087e24ec3eSdlg
1097e24ec3eSdlg if (mpath_path_probe(sa->sa_sc_link) != 0)
1107e24ec3eSdlg return (0);
1117e24ec3eSdlg
1127e24ec3eSdlg for (i = 0; i < nitems(sym_devices); i++) {
1137e24ec3eSdlg s = &sym_devices[i];
1147e24ec3eSdlg
1157e24ec3eSdlg if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
1167e24ec3eSdlg bcmp(s->product, inq->product, strlen(s->product)) == 0)
117b2d08956Sdlg return (8);
1187e24ec3eSdlg }
119c32a5b15Sdlg for (i = 0; i < nitems(asym_devices); i++) {
120c32a5b15Sdlg s = &asym_devices[i];
121c32a5b15Sdlg
122c32a5b15Sdlg if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
123c32a5b15Sdlg bcmp(s->product, inq->product, strlen(s->product)) == 0)
124b2d08956Sdlg return (8);
125c32a5b15Sdlg }
1267e24ec3eSdlg
1277e24ec3eSdlg return (0);
1287e24ec3eSdlg }
1297e24ec3eSdlg
1307e24ec3eSdlg void
sym_attach(struct device * parent,struct device * self,void * aux)1317e24ec3eSdlg sym_attach(struct device *parent, struct device *self, void *aux)
1327e24ec3eSdlg {
1337e24ec3eSdlg struct sym_softc *sc = (struct sym_softc *)self;
1347e24ec3eSdlg struct scsi_attach_args *sa = aux;
1357e24ec3eSdlg struct scsi_link *link = sa->sa_sc_link;
1360fbd355cSkrw struct scsi_inquiry_data *inq = &link->inqdata;
137c32a5b15Sdlg const struct mpath_ops *ops = &sym_mpath_sym_ops;
138c32a5b15Sdlg struct sym_device *s;
139bba3b8d8Sdlg u_int id = 0;
140c32a5b15Sdlg int i;
1417e24ec3eSdlg
1427e24ec3eSdlg printf("\n");
1437e24ec3eSdlg
14484f3acfdSjsg /* check if we're an asymmetric access device */
145c32a5b15Sdlg for (i = 0; i < nitems(asym_devices); i++) {
146c32a5b15Sdlg s = &asym_devices[i];
147c32a5b15Sdlg
148c32a5b15Sdlg if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 &&
149c32a5b15Sdlg bcmp(s->product, inq->product, strlen(s->product)) == 0) {
150c32a5b15Sdlg ops = &sym_mpath_asym_ops;
151bba3b8d8Sdlg id = sc->sc_dev.dv_unit;
152c32a5b15Sdlg break;
153c32a5b15Sdlg }
154c32a5b15Sdlg }
155c32a5b15Sdlg
1567e24ec3eSdlg /* init link */
1577e24ec3eSdlg link->device_softc = sc;
1587e24ec3eSdlg
1597e24ec3eSdlg /* init path */
1607e24ec3eSdlg scsi_xsh_set(&sc->sc_path.p_xsh, link, sym_mpath_start);
1617e24ec3eSdlg sc->sc_path.p_link = link;
1627e24ec3eSdlg
163bba3b8d8Sdlg if (mpath_path_attach(&sc->sc_path, id, ops) != 0)
1647e24ec3eSdlg printf("%s: unable to attach path\n", DEVNAME(sc));
1657e24ec3eSdlg }
1667e24ec3eSdlg
1677e24ec3eSdlg int
sym_detach(struct device * self,int flags)1687e24ec3eSdlg sym_detach(struct device *self, int flags)
1697e24ec3eSdlg {
1707e24ec3eSdlg return (0);
1717e24ec3eSdlg }
1727e24ec3eSdlg
1737e24ec3eSdlg int
sym_activate(struct device * self,int act)1747e24ec3eSdlg sym_activate(struct device *self, int act)
1757e24ec3eSdlg {
1767e24ec3eSdlg struct sym_softc *sc = (struct sym_softc *)self;
1777e24ec3eSdlg
1787e24ec3eSdlg switch (act) {
1797e24ec3eSdlg case DVACT_DEACTIVATE:
1805a08a2c9Sdlg if (sc->sc_path.p_group != NULL)
1817e24ec3eSdlg mpath_path_detach(&sc->sc_path);
1827e24ec3eSdlg break;
1837e24ec3eSdlg }
184f7a04f0fSkrw return (0);
1857e24ec3eSdlg }
1867e24ec3eSdlg
1877e24ec3eSdlg void
sym_mpath_start(struct scsi_xfer * xs)1887e24ec3eSdlg sym_mpath_start(struct scsi_xfer *xs)
1897e24ec3eSdlg {
1907e24ec3eSdlg struct sym_softc *sc = xs->sc_link->device_softc;
1917e24ec3eSdlg
1927e24ec3eSdlg mpath_start(&sc->sc_path, xs);
1937e24ec3eSdlg }
1947e24ec3eSdlg
1957e24ec3eSdlg int
sym_mpath_checksense(struct scsi_xfer * xs)1967e24ec3eSdlg sym_mpath_checksense(struct scsi_xfer *xs)
1977e24ec3eSdlg {
198cdf96446Sdlg return (MPATH_SENSE_DECLINED);
1997e24ec3eSdlg }
2007e24ec3eSdlg
2019ce0d10eSdlg void
sym_mpath_status(struct scsi_link * link)2029ce0d10eSdlg sym_mpath_status(struct scsi_link *link)
2037e24ec3eSdlg {
2049ce0d10eSdlg struct sym_softc *sc = link->device_softc;
2057e24ec3eSdlg
20645e59be9Sdlg mpath_path_status(&sc->sc_path, MPATH_S_ACTIVE);
2077e24ec3eSdlg }
208