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