Reintroduce the cioctl() hook in the TTY layer for digi(4).
The cioctl() hook can be used by drivers to add ioctls to the *.init and *.lock devices. This commit breaks the ttydevsw ABI, since this structure didn't provide any padding. To prevent ABI breakage in the future, add a tsw_spare. Submitted by: Peter Jeremy <peter jeremy alcatel lucent com> Obtained from: kern/152254 (slightly modified)
This commit is contained in:
parent
df41287464
commit
18f5477167
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=223722
@ -91,7 +91,7 @@ static const char *dev_console_filename;
|
||||
HUPCL|CLOCAL|CCTS_OFLOW|CRTS_IFLOW|CDTR_IFLOW|\
|
||||
CDSR_OFLOW|CCAR_OFLOW)
|
||||
|
||||
#define TTY_CALLOUT(tp,d) ((d) != (tp)->t_dev && (d) != dev_console)
|
||||
#define TTY_CALLOUT(tp,d) (dev2unit(d) & TTYUNIT_CALLOUT)
|
||||
|
||||
/*
|
||||
* Set TTY buffer sizes.
|
||||
@ -772,6 +772,10 @@ ttyil_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
goto done;
|
||||
}
|
||||
|
||||
error = ttydevsw_cioctl(tp, dev2unit(dev), cmd, data, td);
|
||||
if (error != ENOIOCTL)
|
||||
goto done;
|
||||
|
||||
switch (cmd) {
|
||||
case TIOCGETA:
|
||||
/* Obtain terminal flags through tcgetattr(). */
|
||||
@ -877,6 +881,13 @@ ttydevsw_defioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
|
||||
static int
|
||||
ttydevsw_defcioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
|
||||
{
|
||||
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
|
||||
static int
|
||||
ttydevsw_defparam(struct tty *tp, struct termios *t)
|
||||
{
|
||||
@ -955,6 +966,7 @@ tty_alloc_mutex(struct ttydevsw *tsw, void *sc, struct mtx *mutex)
|
||||
PATCH_FUNC(outwakeup);
|
||||
PATCH_FUNC(inwakeup);
|
||||
PATCH_FUNC(ioctl);
|
||||
PATCH_FUNC(cioctl);
|
||||
PATCH_FUNC(param);
|
||||
PATCH_FUNC(modem);
|
||||
PATCH_FUNC(mmap);
|
||||
@ -1190,13 +1202,13 @@ tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...)
|
||||
|
||||
/* Slave call-in devices. */
|
||||
if (tp->t_flags & TF_INITLOCK) {
|
||||
dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
|
||||
dev = make_dev_cred(&ttyil_cdevsw, TTYUNIT_INIT, cred,
|
||||
uid, gid, mode, "%s%s.init", prefix, name);
|
||||
dev_depends(tp->t_dev, dev);
|
||||
dev->si_drv1 = tp;
|
||||
dev->si_drv2 = &tp->t_termios_init_in;
|
||||
|
||||
dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
|
||||
dev = make_dev_cred(&ttyil_cdevsw, TTYUNIT_LOCK, cred,
|
||||
uid, gid, mode, "%s%s.lock", prefix, name);
|
||||
dev_depends(tp->t_dev, dev);
|
||||
dev->si_drv1 = tp;
|
||||
@ -1205,20 +1217,22 @@ tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...)
|
||||
|
||||
/* Call-out devices. */
|
||||
if (tp->t_flags & TF_CALLOUT) {
|
||||
dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
|
||||
dev = make_dev_cred(&ttydev_cdevsw, TTYUNIT_CALLOUT, cred,
|
||||
UID_UUCP, GID_DIALER, 0660, "cua%s", name);
|
||||
dev_depends(tp->t_dev, dev);
|
||||
dev->si_drv1 = tp;
|
||||
|
||||
/* Slave call-out devices. */
|
||||
if (tp->t_flags & TF_INITLOCK) {
|
||||
dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
|
||||
dev = make_dev_cred(&ttyil_cdevsw,
|
||||
TTYUNIT_CALLOUT | TTYUNIT_INIT, cred,
|
||||
UID_UUCP, GID_DIALER, 0660, "cua%s.init", name);
|
||||
dev_depends(tp->t_dev, dev);
|
||||
dev->si_drv1 = tp;
|
||||
dev->si_drv2 = &tp->t_termios_init_out;
|
||||
|
||||
dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
|
||||
dev = make_dev_cred(&ttyil_cdevsw,
|
||||
TTYUNIT_CALLOUT | TTYUNIT_LOCK, cred,
|
||||
UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name);
|
||||
dev_depends(tp->t_dev, dev);
|
||||
dev->si_drv1 = tp;
|
||||
|
@ -152,6 +152,11 @@ struct xtty {
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/* Used to distinguish between normal, callout, lock and init devices. */
|
||||
#define TTYUNIT_INIT 0x1
|
||||
#define TTYUNIT_LOCK 0x2
|
||||
#define TTYUNIT_CALLOUT 0x4
|
||||
|
||||
/* Allocation and deallocation. */
|
||||
struct tty *tty_alloc(struct ttydevsw *tsw, void *softc);
|
||||
struct tty *tty_alloc_mutex(struct ttydevsw *tsw, void *softc, struct mtx *mtx);
|
||||
|
@ -46,6 +46,8 @@ typedef void tsw_outwakeup_t(struct tty *tp);
|
||||
typedef void tsw_inwakeup_t(struct tty *tp);
|
||||
typedef int tsw_ioctl_t(struct tty *tp, u_long cmd, caddr_t data,
|
||||
struct thread *td);
|
||||
typedef int tsw_cioctl_t(struct tty *tp, int unit, u_long cmd, caddr_t data,
|
||||
struct thread *td);
|
||||
typedef int tsw_param_t(struct tty *tp, struct termios *t);
|
||||
typedef int tsw_modem_t(struct tty *tp, int sigon, int sigoff);
|
||||
typedef int tsw_mmap_t(struct tty *tp, vm_ooffset_t offset,
|
||||
@ -63,6 +65,7 @@ struct ttydevsw {
|
||||
tsw_inwakeup_t *tsw_inwakeup; /* Input can be stored again. */
|
||||
|
||||
tsw_ioctl_t *tsw_ioctl; /* ioctl() hooks. */
|
||||
tsw_cioctl_t *tsw_cioctl; /* ioctl() on control devices. */
|
||||
tsw_param_t *tsw_param; /* TIOCSETA device parameter setting. */
|
||||
tsw_modem_t *tsw_modem; /* Modem sigon/sigoff. */
|
||||
|
||||
@ -70,6 +73,8 @@ struct ttydevsw {
|
||||
tsw_pktnotify_t *tsw_pktnotify; /* TIOCPKT events. */
|
||||
|
||||
tsw_free_t *tsw_free; /* Destructor. */
|
||||
|
||||
void *tsw_spare[4]; /* For future use. */
|
||||
};
|
||||
|
||||
static __inline int
|
||||
@ -125,6 +130,15 @@ ttydevsw_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
|
||||
return tp->t_devsw->tsw_ioctl(tp, cmd, data, td);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
ttydevsw_cioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
|
||||
{
|
||||
tty_lock_assert(tp, MA_OWNED);
|
||||
MPASS(!tty_gone(tp));
|
||||
|
||||
return tp->t_devsw->tsw_cioctl(tp, unit, cmd, data, td);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
ttydevsw_param(struct tty *tp, struct termios *t)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user