xref: /openbsd/sys/scsi/uk.c (revision 404b540a)
1 /*	$OpenBSD: uk.c,v 1.13 2007/11/27 16:22:14 martynas 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/types.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/errno.h>
42 #include <sys/ioctl.h>
43 #include <sys/conf.h>
44 #include <sys/device.h>
45 
46 #include <scsi/scsi_all.h>
47 #include <scsi/scsiconf.h>
48 
49 #define	UKUNIT(z)	(minor(z))
50 
51 struct uk_softc {
52 	struct device		sc_dev;
53 	struct scsi_link	*sc_link; /* all the inter level info */
54 };
55 
56 int	ukmatch(struct device *, void *, void *);
57 void	ukattach(struct device *, struct device *, void *);
58 
59 struct cfattach uk_ca = {
60 	sizeof(struct uk_softc), ukmatch, ukattach
61 };
62 
63 struct cfdriver uk_cd = {
64 	NULL, "uk", DV_DULL
65 };
66 
67 /*
68  * This driver is so simple it uses all the default services
69  */
70 struct scsi_device uk_switch = {
71 	NULL,
72 	NULL,
73 	NULL,
74 	NULL,
75 };
76 
77 int
78 ukmatch(struct device *parent, void *match, void *aux)
79 {
80 	return (1);
81 }
82 
83 /*
84  * The routine called by the low level scsi routine when it discovers
85  * a device suitable for this driver.
86  */
87 void
88 ukattach(struct device *parent, struct device *self, void *aux)
89 {
90 	struct uk_softc			*uk = (void *)self;
91 	struct scsi_attach_args		*sa = aux;
92 	struct scsi_link		*sc_link = sa->sa_sc_link;
93 
94 	SC_DEBUG(sc_link, SDEV_DB2, ("ukattach: "));
95 
96 	/* Store information needed to contact our base driver */
97 	uk->sc_link = sc_link;
98 	sc_link->device = &uk_switch;
99 	sc_link->device_softc = uk;
100 	sc_link->openings = 1;
101 
102 	printf("\n");
103 }
104 
105 /*
106  * open the device.
107  */
108 int
109 ukopen(dev_t dev, int flag, int fmt, struct proc *p)
110 {
111 	int				unit;
112 	struct uk_softc			*uk;
113 	struct scsi_link		*sc_link;
114 
115 	unit = UKUNIT(dev);
116 	if (unit >= uk_cd.cd_ndevs)
117 		return (ENXIO);
118 
119 	uk = uk_cd.cd_devs[unit];
120 	if (uk == NULL)
121 		return (ENXIO);
122 
123 	sc_link = uk->sc_link;
124 
125 	SC_DEBUG(sc_link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n",
126 	    dev, unit, uk_cd.cd_ndevs));
127 
128 	/* Only allow one at a time */
129 	if (sc_link->flags & SDEV_OPEN)
130 		return (EBUSY);
131 
132 	sc_link->flags |= SDEV_OPEN;
133 
134 	SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
135 
136 	return (0);
137 }
138 
139 /*
140  * close the device.. only called if we are the LAST
141  * occurrence of an open device
142  */
143 int
144 ukclose(dev_t dev, int flag, int fmt, struct proc *p)
145 {
146 	struct uk_softc			*uk = uk_cd.cd_devs[UKUNIT(dev)];
147 
148 	SC_DEBUG(uk->sc_link, SDEV_DB1, ("closing\n"));
149 	uk->sc_link->flags &= ~SDEV_OPEN;
150 
151 	return (0);
152 }
153 
154 /*
155  * Perform special action on behalf of the user
156  * Only does generic scsi ioctls.
157  */
158 int
159 ukioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
160 {
161 	struct uk_softc			*uk = uk_cd.cd_devs[UKUNIT(dev)];
162 
163 	return (scsi_do_ioctl(uk->sc_link, dev, cmd, addr, flag, p));
164 }
165