xref: /netbsd-src/sys/dev/scsipi/uk.c (revision 5f7096188587a2c7c95fa3c69b78e1ec9c7923d0)
1 
2 /*
3  * Dummy driver for a device we can't identify.
4  * by Julian Elischer (julian@tfs.com)
5  *
6  *      $Id: uk.c,v 1.1 1993/11/24 04:52:53 mycroft Exp $
7  */
8 
9 
10 #include <sys/types.h>
11 #include <sys/param.h>
12 #include <sys/errno.h>
13 #include <sys/ioctl.h>
14 #include <scsi/scsi_all.h>
15 #include <scsi/scsiconf.h>
16 #define NUK 16
17 
18 /*
19  * This driver is so simple it uses all the default services
20  */
21 struct scsi_device uk_switch =
22 {
23     NULL,
24     NULL,
25     NULL,
26     NULL,
27     "uk",
28     0,
29     0, 0
30 };
31 
32 struct uk_data {
33 	u_int32 flags;
34 	struct scsi_link *sc_link;	/* all the inter level info */
35 } uk_data[NUK];
36 
37 #define UK_KNOWN	0x02
38 
39 static u_int32 next_uk_unit = 0;
40 
41 /*
42  * The routine called by the low level scsi routine when it discovers
43  * a device suitable for this driver.
44  */
45 errval
46 ukattach(sc_link)
47 	struct scsi_link *sc_link;
48 {
49 	u_int32 unit, i, stat;
50 	unsigned char *tbl;
51 
52 	SC_DEBUG(sc_link, SDEV_DB2, ("ukattach: "));
53 	/*
54 	 * Check we have the resources for another drive
55 	 */
56 	unit = next_uk_unit++;
57 	if (unit >= NUK) {
58 		printf("Too many unknown devices..(%d > %d) reconfigure kernel\n",
59 				(unit + 1), NUK);
60 		return (0);
61 	}
62 	/*
63 	 * Store information needed to contact our base driver
64 	 */
65 	uk_data[unit].sc_link = sc_link;
66 	sc_link->device = &uk_switch;
67 	sc_link->dev_unit = unit;
68 
69 	printf("uk%d: unknown device\n", unit);
70 	uk_data[unit].flags = UK_KNOWN;
71 
72 	return;
73 
74 }
75 
76 /*
77  *    open the device.
78  */
79 errval
80 ukopen(dev)
81 {
82 	errval  errcode = 0;
83 	u_int32 unit, mode;
84 	struct scsi_link *sc_link;
85 	unit = minor(dev);
86 
87 	/*
88 	 * Check the unit is legal
89 	 */
90 	if (unit >= NUK) {
91 		printf("uk%d: uk %d  > %d\n", unit, unit, NUK);
92 		return ENXIO;
93 	}
94 
95 	/*
96 	 * Make sure the device has been initialised
97 	 */
98 	if((uk_data[unit].flags & UK_KNOWN) == 0) {
99 		printf("uk%d: not set up\n", unit);
100 		return ENXIO;
101 	}
102 
103 	/*
104 	 * Only allow one at a time
105 	 */
106 	sc_link = uk_data[unit].sc_link;
107 	if (sc_link->flags & SDEV_OPEN) {
108 		printf("uk%d: already open\n", unit);
109 		return ENXIO;
110 	}
111 	sc_link->flags |= SDEV_OPEN;
112 	SC_DEBUG(sc_link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n"
113 		,dev, unit, NUK));
114 	/*
115 	 * Catch any unit attention errors.
116 	 */
117 	return 0;
118 }
119 
120 /*
121  * close the device.. only called if we are the LAST
122  * occurence of an open device
123  */
124 errval
125 ukclose(dev)
126 {
127 	unsigned char unit, mode;
128 	struct scsi_link *sc_link;
129 
130 	sc_link = uk_data[unit].sc_link;
131 
132 	SC_DEBUG(sc_link, SDEV_DB1, ("Closing device"));
133 	sc_link->flags &= ~SDEV_OPEN;
134 	return (0);
135 }
136 
137 /*
138  * Perform special action on behalf of the user
139  * Only does generic scsi ioctls.
140  */
141 errval
142 ukioctl(dev, cmd, arg, mode)
143 	dev_t   dev;
144 	u_int32 cmd;
145 	caddr_t arg;
146 {
147 	unsigned char unit;
148 	struct scsi_link *sc_link;
149 
150 	/*
151 	 * Find the device that the user is talking about
152 	 */
153 	unit = minor(dev);
154 	sc_link = uk_data[unit].sc_link;
155 	return(scsi_do_ioctl(sc_link,cmd,arg,mode));
156 }
157 
158