1/* 2 * Copyright (c) 1997-2012 Apple Computer, 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 (umeshv@apple.com) 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: */ 48extern dev_t chrtoblk(dev_t dev); 49extern int chrtoblk_set(int cdev, int bdev); 50 51struct 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 94int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]); 95 96extern struct tty *km_tty[]; 97extern d_open_t cnopen; 98extern d_close_t cnclose; 99extern d_read_t cnread; 100extern d_write_t cnwrite; 101extern d_ioctl_t cnioctl; 102extern d_select_t cnselect; 103extern d_open_t kmopen; 104extern d_close_t kmclose; 105extern d_read_t kmread; 106extern d_write_t kmwrite; 107extern d_ioctl_t kmioctl; 108extern d_open_t sgopen; 109extern d_close_t sgclose; 110extern d_ioctl_t sgioctl; 111 112#if NVOL > 0 113extern d_open_t volopen; 114extern d_close_t volclose; 115extern d_ioctl_t volioctl; 116#else 117#define volopen eno_opcl 118#define volclose eno_opcl 119#define volioctl eno_ioctl 120#endif 121 122extern d_open_t cttyopen; 123extern d_read_t cttyread; 124extern d_write_t cttywrite; 125extern d_ioctl_t cttyioctl; 126extern d_select_t cttyselect; 127 128extern d_read_t mmread; 129extern d_write_t mmwrite; 130extern d_ioctl_t mmioctl; 131#define mmselect (select_fcn_t *)seltrue 132#define mmmmap eno_mmap 133 134#include <pty.h> 135#if NPTY > 0 136extern d_open_t ptsopen; 137extern d_close_t ptsclose; 138extern d_read_t ptsread; 139extern d_write_t ptswrite; 140extern d_stop_t ptsstop; 141extern d_select_t ptsselect; 142extern d_open_t ptcopen; 143extern d_close_t ptcclose; 144extern d_read_t ptcread; 145extern d_write_t ptcwrite; 146extern d_select_t ptcselect; 147extern 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 163extern d_open_t logopen; 164extern d_close_t logclose; 165extern d_read_t logread; 166extern d_ioctl_t logioctl; 167extern d_select_t logselect; 168extern d_open_t fdesc_open; 169extern d_read_t fdesc_read; 170extern d_write_t fdesc_write; 171extern d_ioctl_t fdesc_ioctl; 172extern d_select_t fdesc_select; 173 174#define nullopen (d_open_t *)&nulldev 175#define nullclose (d_close_t *)&nulldev 176#define nullread (d_read_t *)&nulldev 177#define nullwrite (d_write_t *)&nulldev 178#define nullioctl (d_ioctl_t *)&nulldev 179#define nullselect (d_select_t *)&nulldev 180#define nullstop (d_stop_t *)&nulldev 181#define nullreset (d_reset_t *)&nulldev 182 183struct cdevsw cdevsw[] = 184{ 185 /* 186 * For character devices, every other block of 16 slots is 187 * reserved for Apple. The other slots are available for 188 * the user. This way we can both add new entries without 189 * running into each other. Be sure to fill in Apple's 190 * 16 reserved slots when you jump over us -- we'll do the 191 * same for you. 192 */ 193 194 /* 0 - 15 are reserved for Apple */ 195 196 { 197 cnopen, cnclose, cnread, cnwrite, /* 0*/ 198 cnioctl, nullstop, nullreset, 0, cnselect, 199 eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY 200 }, 201 NO_CDEVICE, /* 1*/ 202 { 203 cttyopen, nullclose, cttyread, cttywrite, /* 2*/ 204 cttyioctl, nullstop, nullreset, 0, cttyselect, 205 eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY 206 }, 207 { 208 nullopen, nullclose, mmread, mmwrite, /* 3*/ 209 mmioctl, nullstop, nullreset, 0, mmselect, 210 mmmmap, eno_strat, eno_getc, eno_putc, D_DISK 211 }, 212 { 213 ptsopen, ptsclose, ptsread, ptswrite, /* 4*/ 214 ptyioctl, ptsstop, nullreset, 0, ptsselect, 215 eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY 216 }, 217 { 218 ptcopen, ptcclose, ptcread, ptcwrite, /* 5*/ 219 ptyioctl, nullstop, nullreset, 0, ptcselect, 220 eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY 221 }, 222 { 223 logopen, logclose, logread, eno_rdwrt, /* 6*/ 224 logioctl, eno_stop, nullreset, 0, logselect, 225 eno_mmap, eno_strat, eno_getc, eno_putc, 0 226 }, 227 NO_CDEVICE, /* 7*/ 228 NO_CDEVICE, /* 8*/ 229 NO_CDEVICE, /* 9*/ 230 NO_CDEVICE, /*10*/ 231 NO_CDEVICE, /*11*/ 232 { 233 kmopen, kmclose, kmread, kmwrite, /*12*/ 234 kmioctl, nullstop, nullreset, km_tty, ttselect, 235 eno_mmap, eno_strat, eno_getc, eno_putc, 0 236 }, 237 NO_CDEVICE, /*13*/ 238 NO_CDEVICE, /*14*/ 239 NO_CDEVICE, /*15*/ 240 241 /* 16 - 31 are reserved to the user */ 242 NO_CDEVICE, /*16*/ 243 NO_CDEVICE, /*17*/ 244 NO_CDEVICE, /*18*/ 245 NO_CDEVICE, /*19*/ 246 NO_CDEVICE, /*20*/ 247 NO_CDEVICE, /*21*/ 248 NO_CDEVICE, /*22*/ 249 NO_CDEVICE, /*23*/ 250 NO_CDEVICE, /*24*/ 251 NO_CDEVICE, /*25*/ 252 NO_CDEVICE, /*26*/ 253 NO_CDEVICE, /*27*/ 254 NO_CDEVICE, /*28*/ 255 NO_CDEVICE, /*29*/ 256 NO_CDEVICE, /*30*/ 257 NO_CDEVICE, /*31*/ 258 259 /* 32 - 47 are reserved to NeXT */ 260 { 261 fdesc_open, eno_opcl, fdesc_read, fdesc_write, /*32*/ 262 fdesc_ioctl, eno_stop, eno_reset, 0, fdesc_select, 263 eno_mmap, eno_strat, eno_getc, eno_putc, 0 264 }, 265#if 1 266 NO_CDEVICE, 267#else 268 { 269 sgopen, sgclose, eno_rdwrt, eno_rdwrt, /*33*/ 270 sgioctl, eno_stop, eno_reset, 0, eno_select, 271 eno_mmap, eno_strat, eno_getc, eno_putc, D_TAPE 272 }, 273#endif 274 NO_CDEVICE, /*34*/ 275 NO_CDEVICE, /*35*/ 276 NO_CDEVICE, /*36*/ 277 NO_CDEVICE, /*37*/ 278 NO_CDEVICE, /*38*/ 279 NO_CDEVICE, /*39*/ 280 NO_CDEVICE, /*40*/ 281 NO_CDEVICE, /*41*/ 282 { 283 volopen, volclose, eno_rdwrt, eno_rdwrt, /*42*/ 284 volioctl, eno_stop, eno_reset, 0, (select_fcn_t *)seltrue, 285 eno_mmap, eno_strat, eno_getc, eno_putc, 0 286 }, 287}; 288int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]); 289 290uint64_t cdevsw_flags[sizeof (cdevsw) / sizeof (cdevsw[0])]; 291 292#include <sys/vnode.h> /* for VCHR and VBLK */ 293/* 294 * return true if a disk 295 */ 296int 297isdisk(dev_t dev, int type) 298{ 299 dev_t maj = major(dev); 300 301 switch (type) { 302 case VCHR: 303 maj = chrtoblk(maj); 304 if (maj == NODEV) { 305 break; 306 } 307 /* FALL THROUGH */ 308 case VBLK: 309 if (bdevsw[maj].d_type == D_DISK) { 310 return (1); 311 } 312 break; 313 } 314 return(0); 315} 316 317static int chrtoblktab[] = { 318 /* CHR*/ /* BLK*/ /* CHR*/ /* BLK*/ 319 /* 0 */ NODEV, /* 1 */ NODEV, 320 /* 2 */ NODEV, /* 3 */ NODEV, 321 /* 4 */ NODEV, /* 5 */ NODEV, 322 /* 6 */ NODEV, /* 7 */ NODEV, 323 /* 8 */ NODEV, /* 9 */ NODEV, 324 /* 10 */ NODEV, /* 11 */ NODEV, 325 /* 12 */ NODEV, /* 13 */ NODEV, 326 /* 14 */ NODEV, /* 15 */ NODEV, 327 /* 16 */ NODEV, /* 17 */ NODEV, 328 /* 18 */ NODEV, /* 19 */ NODEV, 329 /* 20 */ NODEV, /* 21 */ NODEV, 330 /* 22 */ NODEV, /* 23 */ NODEV, 331 /* 24 */ NODEV, /* 25 */ NODEV, 332 /* 26 */ NODEV, /* 27 */ NODEV, 333 /* 28 */ NODEV, /* 29 */ NODEV, 334 /* 30 */ NODEV, /* 31 */ NODEV, 335 /* 32 */ NODEV, /* 33 */ NODEV, 336 /* 34 */ NODEV, /* 35 */ NODEV, 337 /* 36 */ NODEV, /* 37 */ NODEV, 338 /* 38 */ NODEV, /* 39 */ NODEV, 339 /* 40 */ NODEV, /* 41 */ NODEV, 340 /* 42 */ NODEV, /* 43 */ NODEV, 341 /* 44 */ NODEV, 342}; 343 344/* 345 * convert chr dev to blk dev 346 */ 347dev_t 348chrtoblk(dev_t dev) 349{ 350 int blkmaj; 351 352 if (major(dev) >= nchrdev) 353 return(NODEV); 354 blkmaj = chrtoblktab[major(dev)]; 355 if (blkmaj == NODEV) 356 return(NODEV); 357 return(makedev(blkmaj, minor(dev))); 358} 359 360int 361chrtoblk_set(int cdev, int bdev) 362{ 363 if (cdev >= nchrdev) 364 return (-1); 365 if (bdev != NODEV && bdev >= nblkdev) 366 return (-1); 367 chrtoblktab[cdev] = bdev; 368 return 0; 369} 370 371