pps.c
来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 178 行
C
178 行
/* * ---------------------------------------------------------------------------- * "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: pps.c,v 1.12.2.1 1999/03/22 13:09:34 phk Exp $ * * This driver implements a draft-mogul-pps-api-02.txt PPS source. * * The input pin is pin#10 * The echo output pin is pin#14 * */#include "opt_devfs.h"#include <sys/param.h>#include <sys/kernel.h>#include <sys/systm.h>#include <sys/conf.h>#include <sys/timepps.h>#ifdef DEVFS#include <sys/devfsext.h>#endif#include <sys/malloc.h>#include <dev/ppbus/ppbconf.h>#include "pps.h"#define PPS_NAME "lppps" /* our official name */static struct pps_data { int pps_unit; struct ppb_device pps_dev; struct pps_state pps;} *softc[NPPS];static int npps;/* * Make ourselves visible as a ppbus driver */static struct ppb_device *ppsprobe(struct ppb_data *ppb);static int ppsattach(struct ppb_device *dev);static void ppsintr(int unit);static void pps_drvinit(void *unused);static struct ppb_driver ppsdriver = { ppsprobe, ppsattach, PPS_NAME};DATA_SET(ppbdriver_set, ppsdriver);static d_open_t ppsopen;static d_close_t ppsclose;static d_ioctl_t ppsioctl;#define CDEV_MAJOR 89static struct cdevsw pps_cdevsw = { ppsopen, ppsclose, noread, nowrite, ppsioctl, nullstop, nullreset, nodevtotty, seltrue, nommap, nostrat, PPS_NAME, NULL, -1 };static struct ppb_device *ppsprobe(struct ppb_data *ppb){ struct pps_data *sc; sc = (struct pps_data *) malloc(sizeof(struct pps_data), M_TEMP, M_NOWAIT); if (!sc) { printf(PPS_NAME ": cannot malloc!\n"); return (0); } bzero(sc, sizeof(struct pps_data)); softc[npps] = sc; sc->pps_unit = npps++; sc->pps_dev.id_unit = sc->pps_unit; sc->pps_dev.ppb = ppb; sc->pps_dev.name = ppsdriver.name; sc->pps_dev.intr = ppsintr; sc->pps.ppscap = PPS_CAPTUREASSERT | PPS_ECHOASSERT; pps_init(&sc->pps); return (&sc->pps_dev);}static intppsattach(struct ppb_device *dev){ dev_t devt; /* * Report ourselves */ printf(PPS_NAME "%d: <Pulse per second Timing Interface> on ppbus %d\n", dev->id_unit, dev->ppb->ppb_link->adapter_unit);#ifdef DEVFS devfs_add_devswf(&pps_cdevsw, dev->id_unit, DV_CHR, UID_ROOT, GID_WHEEL, 0600, PPS_NAME "%d", dev->id_unit);#endif devt = makedev(CDEV_MAJOR, 0); cdevsw_add(&devt, &pps_cdevsw, NULL); return (1);}static intppsopen(dev_t dev, int flags, int fmt, struct proc *p){ struct pps_data *sc; u_int unit = minor(dev); if ((unit >= npps)) return (ENXIO); sc = softc[unit]; if (ppb_request_bus(&sc->pps_dev, PPB_WAIT|PPB_INTR)) return (EINTR); ppb_wctr(&sc->pps_dev, 0); ppb_wctr(&sc->pps_dev, IRQENABLE); return(0);}static intppsclose(dev_t dev, int flags, int fmt, struct proc *p){ struct pps_data *sc = softc[minor(dev)]; sc->pps.ppsparam.mode = 0; /* PHK ??? */ ppb_wdtr(&sc->pps_dev, 0); ppb_wctr(&sc->pps_dev, 0); ppb_release_bus(&sc->pps_dev); return(0);}static voidppsintr(int unit){ struct pps_data *sc = softc[unit]; struct timecounter *tc; unsigned count; tc = timecounter; count = timecounter->tc_get_timecount(tc); if (!(ppb_rstr(&sc->pps_dev) & nACK)) return; if (sc->pps.ppsparam.mode & PPS_ECHOASSERT) ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED); pps_event(&sc->pps, tc, count, PPS_CAPTUREASSERT); if (sc->pps.ppsparam.mode & PPS_ECHOASSERT) ppb_wctr(&sc->pps_dev, IRQENABLE);}static intppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p){ struct pps_data *sc = softc[minor(dev)]; return (pps_ioctl(cmd, data, &sc->pps));}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?