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