diff options
| -rw-r--r-- | sys/conf/NOTES | 3 | ||||
| -rw-r--r-- | sys/conf/files | 1 | ||||
| -rw-r--r-- | sys/conf/majors | 3 | ||||
| -rw-r--r-- | sys/dev/ppbus/pps.c | 222 | ||||
| -rw-r--r-- | sys/i386/conf/LINT | 3 | ||||
| -rw-r--r-- | sys/i386/conf/NOTES | 3 | ||||
| -rw-r--r-- | sys/i386/conf/majors.i386 | 3 |
7 files changed, 233 insertions, 5 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 42f34b7e10af..a551633bc4ab 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.405 1998/02/11 17:37:55 yokota Exp $ +# $Id: LINT,v 1.406 1998/02/11 20:47:42 dima Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -1361,6 +1361,7 @@ controller ppbus0 controller vpo0 at ppbus? device nlpt0 at ppbus? device ppi0 at ppbus? +device pps0 at ppbus? controller ppc0 at isa? disable port ? irq 7 vector ppcintr diff --git a/sys/conf/files b/sys/conf/files index 59da1772412a..9195b6d91b2b 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -43,6 +43,7 @@ dev/ppbus/ppb_base.c optional ppbus dev/ppbus/ppb_1284.c optional ppbus dev/ppbus/ppbconf.c optional ppbus dev/ppbus/ppi.c optional ppi +dev/ppbus/pps.c optional pps dev/ppbus/vpo.c optional vpo dev/vn/vn.c optional vn dev/vx/if_vx.c optional vx device-driver diff --git a/sys/conf/majors b/sys/conf/majors index bbdd91dc5802..656a5d383aca 100644 --- a/sys/conf/majors +++ b/sys/conf/majors @@ -1,4 +1,4 @@ -$Id: majors.i386,v 1.24 1998/01/16 22:13:01 pst Exp $ +$Id: majors.i386,v 1.25 1998/01/26 06:11:14 julian Exp $ Hopefully, this list will one day be obsoleted by DEVFS, but for now this is the current allocation of device major numbers. @@ -128,3 +128,4 @@ chrdev name comments 86 alog Industrial Computer Source AIO8-P driver 87 wfd ATAPI floppy client of "ata" 88 dpt DPT RAID Controller <shimon@i-connect.net> +89 pps Pulse-Per-Second timing interface diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c new file mode 100644 index 000000000000..805d227a8bce --- /dev/null +++ b/sys/dev/ppbus/pps.c @@ -0,0 +1,222 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/sysctl.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/buf.h> +#include <sys/uio.h> +#include <sys/syslog.h> +#ifdef DEVFS +#include <sys/devfsext.h> +#endif /*DEVFS*/ +#include <sys/malloc.h> + +#include <machine/clock.h> +#include <machine/lpt.h> + +#include <dev/ppbus/ppbconf.h> +#include "ppps.h" + +#define PPPPS_NAME "pps" /* our official name */ + +static struct ppps_data { + int ppps_unit; + struct ppb_device ppps_dev; + struct ppsclockev { + struct timespec timestamp; + u_int serial; + } ev; + int sawtooth; +} *softc[NPPPPS]; + +static int nppps; +static int sawtooth; + +/* + * Make ourselves visible as a ppbus driver + */ + +static struct ppb_device *pppsprobe(struct ppb_data *ppb); +static int pppsattach(struct ppb_device *dev); +static void pppsintr(int unit); +static void ppps_drvinit(void *unused); + +static struct ppb_driver pppsdriver = { + pppsprobe, pppsattach, PPPPS_NAME +}; + +DATA_SET(ppbdriver_set, pppsdriver); + +static d_open_t pppsopen; +static d_close_t pppsclose; +static d_read_t pppsread; +static d_write_t pppswrite; + +#define CDEV_MAJOR 89 +static struct cdevsw ppps_cdevsw = + { pppsopen, pppsclose, pppsread, pppswrite, + noioctl, nullstop, nullreset, nodevtotty, + seltrue, nommap, nostrat, PPPPS_NAME, + NULL, -1 }; + +static struct ppb_device * +pppsprobe(struct ppb_data *ppb) +{ + struct ppps_data *sc; + + sc = (struct ppps_data *) malloc(sizeof(struct ppps_data), + M_TEMP, M_NOWAIT); + if (!sc) { + printf(PPPPS_NAME ": cannot malloc!\n"); + return (0); + } + bzero(sc, sizeof(struct ppps_data)); + + softc[nppps] = sc; + + sc->ppps_unit = nppps++; + + sc->ppps_dev.id_unit = sc->ppps_unit; + sc->ppps_dev.ppb = ppb; + sc->ppps_dev.intr = pppsintr; + + return (&sc->ppps_dev); +} + +static int +pppsattach(struct ppb_device *dev) +{ + /* + * Report ourselves + */ + printf(PPPPS_NAME "%d: <Pulse per second Timing Interface> on ppbus %d\n", + dev->id_unit, dev->ppb->ppb_link->adapter_unit); + +#ifdef DEVFS + sc->devfs_token = devfs_add_devswf(&ppps_cdevsw, + dev->id_unit, DV_CHR, + UID_ROOT, GID_WHEEL, 0600, PPPPS_NAME "%d", dev->id_unit); + sc->devfs_token_ctl = devfs_add_devswf(&ppps_cdevsw, + dev->id_unit | LP_BYPASS, DV_CHR, + UID_ROOT, GID_WHEEL, 0600, PPPPS_NAME "%d.ctl", dev->id_unit); +#endif + + return (1); +} + +static int +pppsopen(dev_t dev, int flags, int fmt, struct proc *p) +{ + struct ppps_data *sc; + u_int unit = minor(dev); + + if ((unit >= nppps)) + return (ENXIO); + + sc = softc[unit]; + + if (ppb_request_bus(&sc->ppps_dev, PPB_WAIT|PPB_INTR)) + return (EINTR); + + ppb_wctr(&sc->ppps_dev, 0x10); + + return(0); +} + +static int +pppsclose(dev_t dev, int flags, int fmt, struct proc *p) +{ + struct ppps_data *sc = softc[minor(dev)]; + + ppb_release_bus(&sc->ppps_dev); + return(0); +} + +static void +pppsintr(int unit) +{ +/* + * XXX: You want to thing carefully about what you actually want to do + * here. + */ +#if 0 + struct ppps_data *sc = softc[unit]; + struct timespec tc; +#if 1 + struct timeval tv; +#endif + + nanotime(&tc); + if (!(ppb_rstr(&sc->ppps_dev) & nACK)) + return; + tc.tv_nsec -= sc->sawtooth; + tc.tv_nsec += 10000; + sc->sawtooth = 0; + if (tc.tv_nsec > 1000000000) { + tc.tv_sec++; + tc.tv_nsec -= 1000000000; + } else if (tc.tv_nsec < 0) { + tc.tv_sec--; + tc.tv_nsec += 1000000000; + } + sc->ev.timestamp = tc; + sc->ev.serial++; +#if 1 + tv.tv_sec = tc.tv_sec; + tv.tv_usec = tc.tv_nsec / 1000; + hardpps(&tv, tv.tv_usec); +#endif +#endif +} + +static int +pppsread(dev_t dev, struct uio *uio, int ioflag) +{ + struct ppps_data *sc = softc[minor(dev)]; + int err, c; + + c = imin(uio->uio_resid, sizeof sc->ev); + err = uiomove(&sc->ev, c, uio); + return(err); +} + +static int +pppswrite(dev_t dev, struct uio *uio, int ioflag) +{ + struct ppps_data *sc = softc[minor(dev)]; + int err, c; + + c = imin(uio->uio_resid, sizeof sc->sawtooth); + err = uiomove(&sc->sawtooth, c, uio); + return(err); +} + + + +static ppps_devsw_installed = 0; + +static void +ppps_drvinit(void *unused) +{ + dev_t dev; + + if( ! ppps_devsw_installed ) { + dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev,&ppps_cdevsw, NULL); + ppps_devsw_installed = 1; + } +} + +SYSINIT(pppsdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ppps_drvinit,NULL) diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 42f34b7e10af..a551633bc4ab 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.405 1998/02/11 17:37:55 yokota Exp $ +# $Id: LINT,v 1.406 1998/02/11 20:47:42 dima Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -1361,6 +1361,7 @@ controller ppbus0 controller vpo0 at ppbus? device nlpt0 at ppbus? device ppi0 at ppbus? +device pps0 at ppbus? controller ppc0 at isa? disable port ? irq 7 vector ppcintr diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 42f34b7e10af..a551633bc4ab 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.405 1998/02/11 17:37:55 yokota Exp $ +# $Id: LINT,v 1.406 1998/02/11 20:47:42 dima Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -1361,6 +1361,7 @@ controller ppbus0 controller vpo0 at ppbus? device nlpt0 at ppbus? device ppi0 at ppbus? +device pps0 at ppbus? controller ppc0 at isa? disable port ? irq 7 vector ppcintr diff --git a/sys/i386/conf/majors.i386 b/sys/i386/conf/majors.i386 index bbdd91dc5802..656a5d383aca 100644 --- a/sys/i386/conf/majors.i386 +++ b/sys/i386/conf/majors.i386 @@ -1,4 +1,4 @@ -$Id: majors.i386,v 1.24 1998/01/16 22:13:01 pst Exp $ +$Id: majors.i386,v 1.25 1998/01/26 06:11:14 julian Exp $ Hopefully, this list will one day be obsoleted by DEVFS, but for now this is the current allocation of device major numbers. @@ -128,3 +128,4 @@ chrdev name comments 86 alog Industrial Computer Source AIO8-P driver 87 wfd ATAPI floppy client of "ata" 88 dpt DPT RAID Controller <shimon@i-connect.net> +89 pps Pulse-Per-Second timing interface |
