xref: /openbsd/sys/scsi/uk.c (revision 9eaf72d1)
1 /*	$OpenBSD: uk.c,v 1.26 2021/10/24 16:57:30 mpi Exp $	*/
2 /*	$NetBSD: uk.c,v 1.15 1996/03/17 00:59:57 thorpej Exp $	*/
3 
4 /*
5  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Charles Hannum.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Dummy driver for a device we can't identify.
35  * Originally by Julian Elischer (julian@tfs.com)
36  */
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/errno.h>
41 #include <sys/ioctl.h>
42 #include <sys/conf.h>
43 #include <sys/device.h>
44 #include <sys/vnode.h>
45 
46 #include <scsi/scsi_all.h>
47 #include <scsi/scsi_debug.h>
48 #include <scsi/scsiconf.h>
49 
50 #define	UKUNIT(z)	(minor(z))
51 
52 struct uk_softc {
53 	struct device		sc_dev;
54 	struct scsi_link	*sc_link; /* all the inter level info */
55 };
56 
57 int	ukmatch(struct device *, void *, void *);
58 void	ukattach(struct device *, struct device *, void *);
59 int	ukdetach(struct device *, int);
60 
61 const struct cfattach uk_ca = {
62 	sizeof(struct uk_softc), ukmatch, ukattach, ukdetach
63 };
64 
65 struct cfdriver uk_cd = {
66 	NULL, "uk", DV_DULL
67 };
68 
69 #define uklookup(unit) (struct uk_softc *)device_lookup(&uk_cd, (unit))
70 
71 int
ukmatch(struct device * parent,void * match,void * aux)72 ukmatch(struct device *parent, void *match, void *aux)
73 {
74 	return 1;
75 }
76 
77 /*
78  * The routine called by the low level scsi routine when it discovers
79  * a device suitable for this driver.
80  */
81 void
ukattach(struct device * parent,struct device * self,void * aux)82 ukattach(struct device *parent, struct device *self, void *aux)
83 {
84 	struct uk_softc			*sc = (void *)self;
85 	struct scsi_attach_args		*sa = aux;
86 	struct scsi_link		*link = sa->sa_sc_link;
87 
88 	SC_DEBUG(link, SDEV_DB2, ("ukattach: "));
89 
90 	/* Store information needed to contact our base driver. */
91 	sc->sc_link = link;
92 	link->device_softc = sc;
93 	link->openings = 1;
94 
95 	printf("\n");
96 }
97 
98 int
ukdetach(struct device * self,int flags)99 ukdetach(struct device *self, int flags)
100 {
101 	int				bmaj, cmaj, mn;
102 
103 	mn = self->dv_unit;
104 
105 	for (bmaj = 0; bmaj < nblkdev; bmaj++)
106 		if (bdevsw[bmaj].d_open == ukopen)
107 			vdevgone(bmaj, mn, mn, VBLK);
108 	for (cmaj = 0; cmaj < nchrdev; cmaj++)
109 		if (cdevsw[cmaj].d_open == ukopen)
110 			vdevgone(cmaj, mn, mn, VCHR);
111 
112 	return 0;
113 }
114 
115 /*
116  * Open the device.
117  */
118 int
ukopen(dev_t dev,int flag,int fmt,struct proc * p)119 ukopen(dev_t dev, int flag, int fmt, struct proc *p)
120 {
121 	struct uk_softc			*sc;
122 	struct scsi_link		*link;
123 	int				 unit;
124 
125 	unit = UKUNIT(dev);
126 	sc = uklookup(unit);
127 	if (sc == NULL)
128 		return ENXIO;
129 
130 	link = sc->sc_link;
131 
132 	SC_DEBUG(link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n",
133 	    dev, unit, uk_cd.cd_ndevs));
134 
135 	/* Only allow one at a time. */
136 	if (ISSET(link->flags, SDEV_OPEN)) {
137 		device_unref(&sc->sc_dev);
138 		return EBUSY;
139 	}
140 
141 	SET(link->flags, SDEV_OPEN);
142 
143 	SC_DEBUG(link, SDEV_DB3, ("open complete\n"));
144 
145 	device_unref(&sc->sc_dev);
146 	return 0;
147 }
148 
149 /*
150  * Close the device. Called only if we are the LAST
151  * occurrence of an open device.
152  */
153 int
ukclose(dev_t dev,int flag,int fmt,struct proc * p)154 ukclose(dev_t dev, int flag, int fmt, struct proc *p)
155 {
156 	struct uk_softc			*sc;
157 
158 	sc = uklookup(UKUNIT(dev));
159 	if (sc == NULL)
160 		return ENXIO;
161 
162 	SC_DEBUG(sc->sc_link, SDEV_DB1, ("closing\n"));
163 	CLR(sc->sc_link->flags, SDEV_OPEN);
164 
165 	device_unref(&sc->sc_dev);
166 	return 0;
167 }
168 
169 /*
170  * Perform special action on behalf of the user
171  * Only does generic scsi ioctls.
172  */
173 int
ukioctl(dev_t dev,u_long cmd,caddr_t addr,int flag,struct proc * p)174 ukioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
175 {
176 	struct uk_softc			*sc;
177 	int				 rv;
178 
179 	sc = uklookup(UKUNIT(dev));
180 	if (sc == NULL)
181 		return ENXIO;
182 
183 	rv = scsi_do_ioctl(sc->sc_link, cmd, addr, flag);
184 
185 	device_unref(&sc->sc_dev);
186 	return rv;
187 }
188