summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/snp/snp.c101
-rw-r--r--sys/kern/tty_snoop.c101
2 files changed, 168 insertions, 34 deletions
diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c
index 8560928..8019418 100644
--- a/sys/dev/snp/snp.c
+++ b/sys/dev/snp/snp.c
@@ -15,7 +15,6 @@
* $FreeBSD$
*/
-#include "opt_compat.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/filio.h>
@@ -29,6 +28,7 @@
#include <sys/kernel.h>
#include <sys/snoop.h>
#include <sys/vnode.h>
+#include <sys/conf.h>
static d_open_t snpopen;
static d_close_t snpclose;
@@ -61,9 +61,63 @@ static struct cdevsw snp_cdevsw = {
static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data");
+#define ttytosnp(t) (struct snoop *)(t)->t_sc
static struct tty *snpdevtotty __P((dev_t dev));
static int snp_detach __P((struct snoop *snp));
+/*
+ * The number of the "snoop" line discipline. This gets determined at
+ * module load time.
+ */
+static int mylinedisc;
+
+static int
+dsnwrite(struct tty *tp, struct uio *uio, int flag)
+{
+ struct snoop *snp = ttytosnp(tp);
+ int error = 0;
+ char ibuf[1024];
+ int ilen;
+ struct iovec iov;
+ struct uio uio2;
+
+ while (uio->uio_resid) {
+ ilen = MIN(sizeof(ibuf), uio->uio_resid);
+ error = uiomove(ibuf, ilen, uio);
+ if (error)
+ break;
+ snpin(snp, ibuf, ilen);
+ /* Hackish, but I think it's the least of all evils. */
+ iov.iov_base = ibuf;
+ iov.iov_len = ilen;
+ uio2.uio_iov = &iov;
+ uio2.uio_iovcnt = 1;
+ uio2.uio_offset = 0;
+ uio2.uio_resid = ilen;
+ uio2.uio_segflg = UIO_SYSSPACE;
+ uio2.uio_rw = UIO_WRITE;
+ uio2.uio_procp = uio->uio_procp;
+ error = ttwrite(tp, &uio2, flag);
+ if (error)
+ break;
+ }
+ return (error);
+}
+
+/*
+ * XXX should there be a global version of this?
+ */
+static int
+l_nullioctl(struct tty *tp, u_long cmd, char *data, int flags, struct proc *p)
+{
+
+ return (ENOIOCTL);
+}
+
+static struct linesw snpdisc = {
+ ttyopen, ttylclose, ttread, dsnwrite,
+ l_nullioctl, ttyinput, ttstart, ttymodem };
+
static struct tty *
snpdevtotty (dev)
dev_t dev;
@@ -98,7 +152,7 @@ snpwrite(dev, uio, flag)
tp = snp->snp_tty;
if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
- (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC))
+ tp->t_line == mylinedisc)
goto tty_input;
printf("Snoop: attempt to write to bad tty.\n");
@@ -334,9 +388,10 @@ snp_detach(snp)
tp = snp->snp_tty;
if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
- (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC)) {
+ tp->t_line == mylinedisc) {
tp->t_sc = NULL;
tp->t_state &= ~TS_SNOOP;
+ tp->t_line = snp->snp_olddisc;
} else
printf("Snoop: bad attached tty data.\n");
@@ -409,12 +464,6 @@ snpioctl(dev, cmd, data, flags, p)
if (!tp)
return (EINVAL);
- if ((tp->t_sc != (caddr_t)snp) && (tp->t_state & TS_SNOOP))
- return (EBUSY);
-
- if ((tp->t_line != OTTYDISC) && (tp->t_line != NTTYDISC))
- return (EBUSY);
-
s = spltty();
if (snp->snp_target == NODEV) {
@@ -425,6 +474,8 @@ snpioctl(dev, cmd, data, flags, p)
tp->t_sc = (caddr_t)snp;
tp->t_state |= TS_SNOOP;
+ snp->snp_olddisc = tp->t_line;
+ tp->t_line = mylinedisc;
snp->snp_tty = tp;
snp->snp_target = tdev;
@@ -503,8 +554,6 @@ snppoll(dev, events, p)
return (revents);
}
-static void snp_drvinit __P((void *unused));
-
static void
snp_clone(void *arg, char *name, int namelen, dev_t *dev)
{
@@ -519,13 +568,31 @@ snp_clone(void *arg, char *name, int namelen, dev_t *dev)
return;
}
-static void
-snp_drvinit(unused)
- void *unused;
+static int
+snp_modevent(module_t mod, int type, void *data)
{
+ static eventhandler_tag eh_tag = NULL;
- EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000);
- cdevsw_add(&snp_cdevsw);
+ switch (type) {
+ case MOD_LOAD:
+ eh_tag = EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000);
+ mylinedisc = ldisc_register(LDISC_LOAD, &snpdisc);
+ cdevsw_add(&snp_cdevsw);
+ break;
+ case MOD_UNLOAD:
+ EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
+ ldisc_deregister(mylinedisc);
+ cdevsw_remove(&snp_cdevsw);
+ break;
+ default:
+ break;
+ }
+ return 0;
}
-SYSINIT(snpdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,snp_drvinit,NULL)
+static moduledata_t snp_mod = {
+ "snp",
+ snp_modevent,
+ NULL
+};
+DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR);
diff --git a/sys/kern/tty_snoop.c b/sys/kern/tty_snoop.c
index 8560928..8019418 100644
--- a/sys/kern/tty_snoop.c
+++ b/sys/kern/tty_snoop.c
@@ -15,7 +15,6 @@
* $FreeBSD$
*/
-#include "opt_compat.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/filio.h>
@@ -29,6 +28,7 @@
#include <sys/kernel.h>
#include <sys/snoop.h>
#include <sys/vnode.h>
+#include <sys/conf.h>
static d_open_t snpopen;
static d_close_t snpclose;
@@ -61,9 +61,63 @@ static struct cdevsw snp_cdevsw = {
static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data");
+#define ttytosnp(t) (struct snoop *)(t)->t_sc
static struct tty *snpdevtotty __P((dev_t dev));
static int snp_detach __P((struct snoop *snp));
+/*
+ * The number of the "snoop" line discipline. This gets determined at
+ * module load time.
+ */
+static int mylinedisc;
+
+static int
+dsnwrite(struct tty *tp, struct uio *uio, int flag)
+{
+ struct snoop *snp = ttytosnp(tp);
+ int error = 0;
+ char ibuf[1024];
+ int ilen;
+ struct iovec iov;
+ struct uio uio2;
+
+ while (uio->uio_resid) {
+ ilen = MIN(sizeof(ibuf), uio->uio_resid);
+ error = uiomove(ibuf, ilen, uio);
+ if (error)
+ break;
+ snpin(snp, ibuf, ilen);
+ /* Hackish, but I think it's the least of all evils. */
+ iov.iov_base = ibuf;
+ iov.iov_len = ilen;
+ uio2.uio_iov = &iov;
+ uio2.uio_iovcnt = 1;
+ uio2.uio_offset = 0;
+ uio2.uio_resid = ilen;
+ uio2.uio_segflg = UIO_SYSSPACE;
+ uio2.uio_rw = UIO_WRITE;
+ uio2.uio_procp = uio->uio_procp;
+ error = ttwrite(tp, &uio2, flag);
+ if (error)
+ break;
+ }
+ return (error);
+}
+
+/*
+ * XXX should there be a global version of this?
+ */
+static int
+l_nullioctl(struct tty *tp, u_long cmd, char *data, int flags, struct proc *p)
+{
+
+ return (ENOIOCTL);
+}
+
+static struct linesw snpdisc = {
+ ttyopen, ttylclose, ttread, dsnwrite,
+ l_nullioctl, ttyinput, ttstart, ttymodem };
+
static struct tty *
snpdevtotty (dev)
dev_t dev;
@@ -98,7 +152,7 @@ snpwrite(dev, uio, flag)
tp = snp->snp_tty;
if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
- (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC))
+ tp->t_line == mylinedisc)
goto tty_input;
printf("Snoop: attempt to write to bad tty.\n");
@@ -334,9 +388,10 @@ snp_detach(snp)
tp = snp->snp_tty;
if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
- (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC)) {
+ tp->t_line == mylinedisc) {
tp->t_sc = NULL;
tp->t_state &= ~TS_SNOOP;
+ tp->t_line = snp->snp_olddisc;
} else
printf("Snoop: bad attached tty data.\n");
@@ -409,12 +464,6 @@ snpioctl(dev, cmd, data, flags, p)
if (!tp)
return (EINVAL);
- if ((tp->t_sc != (caddr_t)snp) && (tp->t_state & TS_SNOOP))
- return (EBUSY);
-
- if ((tp->t_line != OTTYDISC) && (tp->t_line != NTTYDISC))
- return (EBUSY);
-
s = spltty();
if (snp->snp_target == NODEV) {
@@ -425,6 +474,8 @@ snpioctl(dev, cmd, data, flags, p)
tp->t_sc = (caddr_t)snp;
tp->t_state |= TS_SNOOP;
+ snp->snp_olddisc = tp->t_line;
+ tp->t_line = mylinedisc;
snp->snp_tty = tp;
snp->snp_target = tdev;
@@ -503,8 +554,6 @@ snppoll(dev, events, p)
return (revents);
}
-static void snp_drvinit __P((void *unused));
-
static void
snp_clone(void *arg, char *name, int namelen, dev_t *dev)
{
@@ -519,13 +568,31 @@ snp_clone(void *arg, char *name, int namelen, dev_t *dev)
return;
}
-static void
-snp_drvinit(unused)
- void *unused;
+static int
+snp_modevent(module_t mod, int type, void *data)
{
+ static eventhandler_tag eh_tag = NULL;
- EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000);
- cdevsw_add(&snp_cdevsw);
+ switch (type) {
+ case MOD_LOAD:
+ eh_tag = EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000);
+ mylinedisc = ldisc_register(LDISC_LOAD, &snpdisc);
+ cdevsw_add(&snp_cdevsw);
+ break;
+ case MOD_UNLOAD:
+ EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
+ ldisc_deregister(mylinedisc);
+ cdevsw_remove(&snp_cdevsw);
+ break;
+ default:
+ break;
+ }
+ return 0;
}
-SYSINIT(snpdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,snp_drvinit,NULL)
+static moduledata_t snp_mod = {
+ "snp",
+ snp_modevent,
+ NULL
+};
+DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR);
OpenPOWER on IntegriCloud