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