xref: /openbsd-src/sys/scsi/mpath_sym.c (revision 1525749fb89da5e6992ed4d61159727e5f0e49b5)
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