305 lines
9.3 KiB
C
305 lines
9.3 KiB
C
/*
|
|
* Copyright (c) 1997-2020 Apple Inc. All rights reserved.
|
|
*
|
|
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. The rights granted to you under the License
|
|
* may not be used to create, or enable the creation or redistribution of,
|
|
* unlawful or unlicensed copies of an Apple operating system, or to
|
|
* circumvent, violate, or enable the circumvention or violation of, any
|
|
* terms of an Apple operating system software license agreement.
|
|
*
|
|
* Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
|
*/
|
|
/*
|
|
* Copyright (c) 1993 NeXT Computer, Inc.
|
|
*
|
|
* UNIX Device switch tables.
|
|
*
|
|
* HISTORY
|
|
*
|
|
* 30 July 1997 Umesh Vaishampayan (umeshv@apple.com)
|
|
* enabled file descriptor pseudo-device.
|
|
* 18 June 1993 ? at NeXT
|
|
* Cleaned up a lot of stuff in this file.
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/tty.h>
|
|
#include <sys/conf.h>
|
|
|
|
/* Prototypes that should be elsewhere: */
|
|
extern dev_t chrtoblk(dev_t dev);
|
|
extern int chrtoblk_set(int cdev, int bdev);
|
|
|
|
struct bdevsw bdevsw[] =
|
|
{
|
|
/*
|
|
* For block devices, every other block of 8 slots is
|
|
* reserved for Apple. The other slots are available for
|
|
* the user. This way we can both add new entries without
|
|
* running into each other. Be sure to fill in Apple's
|
|
* 8 reserved slots when you jump over us -- we'll do the
|
|
* same for you.
|
|
*/
|
|
|
|
/* 0 - 7 are reserved for Apple */
|
|
|
|
NO_BDEVICE, /* 0*/
|
|
NO_BDEVICE, /* 1*/
|
|
NO_BDEVICE, /* 2*/
|
|
NO_BDEVICE, /* 3*/
|
|
NO_BDEVICE, /* 4*/
|
|
NO_BDEVICE, /* 5*/
|
|
NO_BDEVICE, /* 6*/
|
|
NO_BDEVICE, /* 7*/
|
|
|
|
/* 8 - 15 are reserved to the user */
|
|
NO_BDEVICE, /* 8*/
|
|
NO_BDEVICE, /* 9*/
|
|
NO_BDEVICE, /*10*/
|
|
NO_BDEVICE, /*11*/
|
|
NO_BDEVICE, /*12*/
|
|
NO_BDEVICE, /*13*/
|
|
NO_BDEVICE, /*14*/
|
|
NO_BDEVICE, /*15*/
|
|
|
|
/* 16 - 23 are reserved for Apple */
|
|
NO_BDEVICE, /*16*/
|
|
NO_BDEVICE, /*17*/
|
|
NO_BDEVICE, /*18*/
|
|
NO_BDEVICE, /*18*/
|
|
NO_BDEVICE, /*20*/
|
|
NO_BDEVICE, /*21*/
|
|
NO_BDEVICE, /*22*/
|
|
NO_BDEVICE, /*23*/
|
|
};
|
|
|
|
const int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
|
|
|
|
extern struct tty *km_tty[];
|
|
extern d_open_t cnopen;
|
|
extern d_close_t cnclose;
|
|
extern d_read_t cnread;
|
|
extern d_write_t cnwrite;
|
|
extern d_ioctl_t cnioctl;
|
|
extern d_select_t cnselect;
|
|
extern d_open_t kmopen;
|
|
extern d_close_t kmclose;
|
|
extern d_read_t kmread;
|
|
extern d_write_t kmwrite;
|
|
extern d_ioctl_t kmioctl;
|
|
extern d_open_t sgopen;
|
|
extern d_close_t sgclose;
|
|
extern d_ioctl_t sgioctl;
|
|
|
|
#if NVOL > 0
|
|
extern d_open_t volopen;
|
|
extern d_close_t volclose;
|
|
extern d_ioctl_t volioctl;
|
|
#else
|
|
#define volopen eno_opcl
|
|
#define volclose eno_opcl
|
|
#define volioctl eno_ioctl
|
|
#endif
|
|
|
|
extern d_open_t cttyopen;
|
|
extern d_read_t cttyread;
|
|
extern d_write_t cttywrite;
|
|
extern d_ioctl_t cttyioctl;
|
|
extern d_select_t cttyselect;
|
|
|
|
extern d_read_t mmread;
|
|
extern d_write_t mmwrite;
|
|
extern d_ioctl_t mmioctl;
|
|
#define mmselect (select_fcn_t *)(void (*)(void))seltrue
|
|
#define mmmmap eno_mmap
|
|
|
|
#include <pty.h>
|
|
#if NPTY > 0
|
|
extern d_open_t ptsopen;
|
|
extern d_close_t ptsclose;
|
|
extern d_read_t ptsread;
|
|
extern d_write_t ptswrite;
|
|
extern d_stop_t ptsstop;
|
|
extern d_select_t ptsselect;
|
|
extern d_open_t ptcopen;
|
|
extern d_close_t ptcclose;
|
|
extern d_read_t ptcread;
|
|
extern d_write_t ptcwrite;
|
|
extern d_select_t ptcselect;
|
|
extern d_ioctl_t ptyioctl;
|
|
#else
|
|
#define ptsopen eno_opcl
|
|
#define ptsclose eno_opcl
|
|
#define ptsread eno_rdwrt
|
|
#define ptswrite eno_rdwrt
|
|
#define ptsstop nulldev
|
|
|
|
#define ptcopen eno_opcl
|
|
#define ptcclose eno_opcl
|
|
#define ptcread eno_rdwrt
|
|
#define ptcwrite eno_rdwrt
|
|
#define ptcselect eno_select
|
|
#define ptyioctl eno_ioctl
|
|
#endif
|
|
|
|
extern d_open_t logopen;
|
|
extern d_close_t logclose;
|
|
extern d_read_t logread;
|
|
extern d_ioctl_t logioctl;
|
|
extern d_select_t logselect;
|
|
|
|
extern d_open_t oslog_streamopen;
|
|
extern d_close_t oslog_streamclose;
|
|
extern d_read_t oslog_streamread;
|
|
extern d_ioctl_t oslog_streamioctl;
|
|
extern d_select_t oslog_streamselect;
|
|
|
|
extern d_open_t oslogopen;
|
|
extern d_close_t oslogclose;
|
|
extern d_select_t oslogselect;
|
|
extern d_ioctl_t oslogioctl;
|
|
|
|
#define nulldevfp (void (*)(void))&nulldev
|
|
|
|
#define nullopen (d_open_t *)nulldevfp
|
|
#define nullclose (d_close_t *)nulldevfp
|
|
#define nullread (d_read_t *)nulldevfp
|
|
#define nullwrite (d_write_t *)nulldevfp
|
|
#define nullioctl (d_ioctl_t *)nulldevfp
|
|
#define nullselect (d_select_t *)nulldevfp
|
|
#define nullstop (d_stop_t *)nulldevfp
|
|
#define nullreset (d_reset_t *)nulldevfp
|
|
|
|
struct cdevsw cdevsw[] = {
|
|
/*
|
|
* To add character devices to this table dynamically, use cdevsw_add.
|
|
*/
|
|
|
|
[0] = {
|
|
cnopen, cnclose, cnread, cnwrite,
|
|
cnioctl, nullstop, nullreset, 0, cnselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
|
|
},
|
|
[1] = NO_CDEVICE,
|
|
[2] = {
|
|
cttyopen, nullclose, cttyread, cttywrite,
|
|
cttyioctl, nullstop, nullreset, 0, cttyselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
|
|
},
|
|
[3] = {
|
|
nullopen, nullclose, mmread, mmwrite,
|
|
mmioctl, nullstop, nullreset, 0, mmselect,
|
|
mmmmap, eno_strat, eno_getc, eno_putc, D_DISK
|
|
},
|
|
[PTC_MAJOR] = {
|
|
ptsopen, ptsclose, ptsread, ptswrite,
|
|
ptyioctl, ptsstop, nullreset, 0, ptsselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
|
|
},
|
|
[PTS_MAJOR] = {
|
|
ptcopen, ptcclose, ptcread, ptcwrite,
|
|
ptyioctl, nullstop, nullreset, 0, ptcselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY
|
|
},
|
|
[6] = {
|
|
logopen, logclose, logread, eno_rdwrt,
|
|
logioctl, eno_stop, nullreset, 0, logselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, 0
|
|
},
|
|
[7] = {
|
|
oslogopen, oslogclose, eno_rdwrt, eno_rdwrt,
|
|
oslogioctl, eno_stop, nullreset, 0, oslogselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, 0
|
|
},
|
|
[8] = {
|
|
oslog_streamopen, oslog_streamclose, oslog_streamread, eno_rdwrt,
|
|
oslog_streamioctl, eno_stop, nullreset, 0, oslog_streamselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, 0
|
|
},
|
|
[9 ... 11] = NO_CDEVICE,
|
|
[12] = {
|
|
kmopen, kmclose, kmread, kmwrite,
|
|
kmioctl, nullstop, nullreset, km_tty, ttselect,
|
|
eno_mmap, eno_strat, eno_getc, eno_putc, 0
|
|
},
|
|
[13 ... 63] = NO_CDEVICE,
|
|
};
|
|
const int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
|
|
|
|
uint64_t cdevsw_flags[sizeof(cdevsw) / sizeof(cdevsw[0])];
|
|
|
|
#include <sys/vnode.h> /* for VCHR and VBLK */
|
|
/*
|
|
* return true if a disk
|
|
*/
|
|
int
|
|
isdisk(dev_t dev, int type)
|
|
{
|
|
dev_t maj = major(dev);
|
|
|
|
switch (type) {
|
|
case VCHR:
|
|
maj = chrtoblk(dev);
|
|
if (maj == NODEV) {
|
|
break;
|
|
}
|
|
OS_FALLTHROUGH;
|
|
case VBLK:
|
|
if (bdevsw[maj].d_type == D_DISK) {
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int chrtoblktab[] = {[0 ... nchrdev] = NODEV };
|
|
|
|
/*
|
|
* convert chr dev to blk dev
|
|
*/
|
|
dev_t
|
|
chrtoblk(dev_t dev)
|
|
{
|
|
int blkmaj;
|
|
|
|
if (major(dev) >= nchrdev) {
|
|
return NODEV;
|
|
}
|
|
blkmaj = chrtoblktab[major(dev)];
|
|
if (blkmaj == NODEV) {
|
|
return NODEV;
|
|
}
|
|
return makedev(blkmaj, minor(dev));
|
|
}
|
|
|
|
int
|
|
chrtoblk_set(int cdev, int bdev)
|
|
{
|
|
if (cdev >= nchrdev) {
|
|
return -1;
|
|
}
|
|
if (bdev != NODEV && bdev >= nblkdev) {
|
|
return -1;
|
|
}
|
|
chrtoblktab[cdev] = bdev;
|
|
return 0;
|
|
}
|