xref: /xnu-12377.41.6/bsd/dev/i386/conf.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 /*
2  * Copyright (c) 1997-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * Copyright (c) 1993 NeXT Computer, Inc.
30  *
31  * UNIX Device switch tables.
32  *
33  * HISTORY
34  *
35  * 30 July 1997 Umesh Vaishampayan ([email protected])
36  *      enabled file descriptor pseudo-device.
37  * 18 June 1993 ? at NeXT
38  *	Cleaned up a lot of stuff in this file.
39  */
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/ioctl.h>
44 #include <sys/tty.h>
45 #include <sys/conf.h>
46 
47 /* Prototypes that should be elsewhere: */
48 extern dev_t    chrtoblk(dev_t dev);
49 extern int      chrtoblk_set(int cdev, int bdev);
50 
51 struct bdevsw   bdevsw[] =
52 {
53 	/*
54 	 *	For block devices, every other block of 8 slots is
55 	 *	reserved for Apple.  The other slots are available for
56 	 *	the user.  This way we can both add new entries without
57 	 *	running into each other.  Be sure to fill in Apple's
58 	 *	8 reserved slots when you jump over us -- we'll do the
59 	 *	same for you.
60 	 */
61 
62 	/* 0 - 7 are reserved for Apple */
63 
64 	NO_BDEVICE,                                                     /* 0*/
65 	NO_BDEVICE,                                                     /* 1*/
66 	NO_BDEVICE,                                                     /* 2*/
67 	NO_BDEVICE,                                                     /* 3*/
68 	NO_BDEVICE,                                                     /* 4*/
69 	NO_BDEVICE,                                                     /* 5*/
70 	NO_BDEVICE,                                                     /* 6*/
71 	NO_BDEVICE,                                                     /* 7*/
72 
73 	/* 8 - 15 are reserved to the user */
74 	NO_BDEVICE,                                                     /* 8*/
75 	NO_BDEVICE,                                                     /* 9*/
76 	NO_BDEVICE,                                                     /*10*/
77 	NO_BDEVICE,                                                     /*11*/
78 	NO_BDEVICE,                                                     /*12*/
79 	NO_BDEVICE,                                                     /*13*/
80 	NO_BDEVICE,                                                     /*14*/
81 	NO_BDEVICE,                                                     /*15*/
82 
83 	/* 16 - 23 are reserved for Apple */
84 	NO_BDEVICE,                                                     /*16*/
85 	NO_BDEVICE,                                                     /*17*/
86 	NO_BDEVICE,                                                     /*18*/
87 	NO_BDEVICE,                                                     /*18*/
88 	NO_BDEVICE,                                                     /*20*/
89 	NO_BDEVICE,                                                     /*21*/
90 	NO_BDEVICE,                                                     /*22*/
91 	NO_BDEVICE,                                                     /*23*/
92 };
93 
94 const int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
95 
96 extern struct tty *km_tty[];
97 extern d_open_t         cnopen;
98 extern d_close_t        cnclose;
99 extern d_read_t         cnread;
100 extern d_write_t        cnwrite;
101 extern d_ioctl_t        cnioctl;
102 extern d_select_t       cnselect;
103 extern d_open_t         kmopen;
104 extern d_close_t        kmclose;
105 extern d_read_t         kmread;
106 extern d_write_t        kmwrite;
107 extern d_ioctl_t        kmioctl;
108 extern d_open_t         sgopen;
109 extern d_close_t        sgclose;
110 extern d_ioctl_t        sgioctl;
111 
112 #if NVOL > 0
113 extern d_open_t         volopen;
114 extern d_close_t        volclose;
115 extern d_ioctl_t        volioctl;
116 #else
117 #define volopen         eno_opcl
118 #define volclose        eno_opcl
119 #define volioctl        eno_ioctl
120 #endif
121 
122 extern d_open_t         cttyopen;
123 extern d_read_t         cttyread;
124 extern d_write_t        cttywrite;
125 extern d_ioctl_t        cttyioctl;
126 extern d_select_t       cttyselect;
127 
128 extern d_read_t         mmread;
129 extern d_write_t        mmwrite;
130 extern d_ioctl_t        mmioctl;
131 #define mmselect        (select_fcn_t *)(void (*)(void))seltrue
132 #define mmmmap          eno_mmap
133 
134 #include <pty.h>
135 #if NPTY > 0
136 extern d_open_t         ptsopen;
137 extern d_close_t        ptsclose;
138 extern d_read_t         ptsread;
139 extern d_write_t        ptswrite;
140 extern d_stop_t         ptsstop;
141 extern d_select_t       ptsselect;
142 extern d_open_t         ptcopen;
143 extern d_close_t        ptcclose;
144 extern d_read_t         ptcread;
145 extern d_write_t        ptcwrite;
146 extern d_select_t       ptcselect;
147 extern d_ioctl_t        ptyioctl;
148 #else
149 #define ptsopen         eno_opcl
150 #define ptsclose        eno_opcl
151 #define ptsread         eno_rdwrt
152 #define ptswrite        eno_rdwrt
153 #define ptsstop         nulldev
154 
155 #define ptcopen         eno_opcl
156 #define ptcclose        eno_opcl
157 #define ptcread         eno_rdwrt
158 #define ptcwrite        eno_rdwrt
159 #define ptcselect       eno_select
160 #define ptyioctl        eno_ioctl
161 #endif
162 
163 extern d_open_t         logopen;
164 extern d_close_t        logclose;
165 extern d_read_t         logread;
166 extern d_ioctl_t        logioctl;
167 extern d_select_t       logselect;
168 
169 extern d_open_t         oslog_streamopen;
170 extern d_close_t        oslog_streamclose;
171 extern d_read_t         oslog_streamread;
172 extern d_ioctl_t        oslog_streamioctl;
173 extern d_select_t       oslog_streamselect;
174 
175 extern d_open_t         oslogopen;
176 extern d_close_t        oslogclose;
177 extern d_select_t       oslogselect;
178 extern d_ioctl_t        oslogioctl;
179 
180 #define nulldevfp        (void (*)(void))&nulldev
181 
182 #define nullopen        (d_open_t *)nulldevfp
183 #define nullclose       (d_close_t *)nulldevfp
184 #define nullread        (d_read_t *)nulldevfp
185 #define nullwrite       (d_write_t *)nulldevfp
186 #define nullioctl       (d_ioctl_t *)nulldevfp
187 #define nullselect      (d_select_t *)nulldevfp
188 #define nullstop        (d_stop_t *)nulldevfp
189 #define nullreset       (d_reset_t *)nulldevfp
190 
191 struct cdevsw cdevsw[] = {
192 	/*
193 	 * To add character devices to this table dynamically, use cdevsw_add.
194 	 */
195 
196 	[0] = {
197 		cnopen, cnclose, cnread, cnwrite,
198 		cnioctl, nullstop, nullreset, 0, cnselect,
199 		eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
200 	},
201 	[1] = NO_CDEVICE,
202 	[2] = {
203 		cttyopen, nullclose, cttyread, cttywrite,
204 		cttyioctl, nullstop, nullreset, 0, cttyselect,
205 		eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
206 	},
207 	[3] = {
208 		nullopen, nullclose, mmread, mmwrite,
209 		mmioctl, nullstop, nullreset, 0, mmselect,
210 		mmmmap, eno_strat, eno_getc, eno_putc, D_DISK
211 	},
212 	[PTC_MAJOR] = {
213 		ptsopen, ptsclose, ptsread, ptswrite,
214 		ptyioctl, ptsstop, nullreset, 0, ptsselect,
215 		eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
216 	},
217 	[PTS_MAJOR] = {
218 		ptcopen, ptcclose, ptcread, ptcwrite,
219 		ptyioctl, nullstop, nullreset, 0, ptcselect,
220 		eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
221 	},
222 	[6] = {
223 		logopen, logclose, logread, eno_rdwrt,
224 		logioctl, eno_stop, nullreset, 0, logselect,
225 		eno_mmap, eno_strat, eno_getc, eno_putc, 0
226 	},
227 	[7] = {
228 		oslogopen, oslogclose, eno_rdwrt, eno_rdwrt,
229 		oslogioctl, eno_stop, nullreset, 0, oslogselect,
230 		eno_mmap, eno_strat, eno_getc, eno_putc, 0
231 	},
232 	[8] = {
233 		oslog_streamopen, oslog_streamclose, oslog_streamread, eno_rdwrt,
234 		oslog_streamioctl, eno_stop, nullreset, 0, oslog_streamselect,
235 		eno_mmap, eno_strat, eno_getc, eno_putc, 0
236 	},
237 	[9 ... 11] = NO_CDEVICE,
238 	[12] = {
239 		kmopen, kmclose, kmread, kmwrite,
240 		kmioctl, nullstop, nullreset, km_tty, ttselect,
241 		eno_mmap, eno_strat, eno_getc, eno_putc, 0
242 	},
243 	[13 ... 63] = NO_CDEVICE,
244 };
245 const int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
246 
247 uint64_t cdevsw_flags[sizeof(cdevsw) / sizeof(cdevsw[0])];
248 
249 #include        <sys/vnode.h> /* for VCHR and VBLK */
250 /*
251  * return true if a disk
252  */
253 int
isdisk(dev_t dev,int type)254 isdisk(dev_t dev, int type)
255 {
256 	dev_t   maj = major(dev);
257 
258 	switch (type) {
259 	case VCHR:
260 		maj = chrtoblk(dev);
261 		if (maj == NODEV) {
262 			break;
263 		}
264 		OS_FALLTHROUGH;
265 	case VBLK:
266 		if (bdevsw[maj].d_type == D_DISK) {
267 			return 1;
268 		}
269 		break;
270 	}
271 	return 0;
272 }
273 
274 static int chrtoblktab[] = {[0 ... nchrdev] = NODEV };
275 
276 /*
277  * convert chr dev to blk dev
278  */
279 dev_t
chrtoblk(dev_t dev)280 chrtoblk(dev_t dev)
281 {
282 	int blkmaj;
283 
284 	if (major(dev) >= nchrdev) {
285 		return NODEV;
286 	}
287 	blkmaj = chrtoblktab[major(dev)];
288 	if (blkmaj == NODEV) {
289 		return NODEV;
290 	}
291 	return makedev(blkmaj, minor(dev));
292 }
293 
294 int
chrtoblk_set(int cdev,int bdev)295 chrtoblk_set(int cdev, int bdev)
296 {
297 	if (cdev >= nchrdev) {
298 		return -1;
299 	}
300 	if (bdev != NODEV && bdev >= nblkdev) {
301 		return -1;
302 	}
303 	chrtoblktab[cdev] = bdev;
304 	return 0;
305 }
306