The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ppbus/pps.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * ----------------------------------------------------------------------------
    3  * "THE BEER-WARE LICENSE" (Revision 42):
    4  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
    5  * can do whatever you want with this stuff. If we meet some day, and you think
    6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
    7  * ----------------------------------------------------------------------------
    8  *
    9  * $FreeBSD$
   10  *
   11  * This driver implements a draft-mogul-pps-api-02.txt PPS source.
   12  *
   13  * The input pin is pin#10 
   14  * The echo output pin is pin#14
   15  *
   16  */
   17 
   18 #include "opt_devfs.h"
   19 
   20 #include <sys/param.h>
   21 #include <sys/kernel.h>
   22 #include <sys/systm.h>
   23 #include <sys/conf.h>
   24 #include <sys/timepps.h>
   25 #ifdef DEVFS
   26 #include <sys/devfsext.h>
   27 #endif
   28 #include <sys/malloc.h>
   29 
   30 #include <dev/ppbus/ppbconf.h>
   31 #include "pps.h"
   32 
   33 #define PPS_NAME        "lppps"         /* our official name */
   34 
   35 static struct pps_data {
   36         int     pps_unit;
   37         struct  ppb_device pps_dev;     
   38         struct  pps_state pps;
   39 } *softc[NPPS];
   40 
   41 static int npps;
   42 
   43 /*
   44  * Make ourselves visible as a ppbus driver
   45  */
   46 
   47 static struct ppb_device        *ppsprobe(struct ppb_data *ppb);
   48 static int                      ppsattach(struct ppb_device *dev);
   49 static void                     ppsintr(int unit);
   50 static void                     pps_drvinit(void *unused);
   51 
   52 static struct ppb_driver ppsdriver = {
   53     ppsprobe, ppsattach, PPS_NAME
   54 };
   55 
   56 DATA_SET(ppbdriver_set, ppsdriver);
   57 
   58 static  d_open_t        ppsopen;
   59 static  d_close_t       ppsclose;
   60 static  d_ioctl_t       ppsioctl;
   61 
   62 #define CDEV_MAJOR 89
   63 static struct cdevsw pps_cdevsw = 
   64         { ppsopen,      ppsclose,       noread,         nowrite,
   65           ppsioctl,     nullstop,       nullreset,      nodevtotty,
   66           seltrue,      nommap,         nostrat,        PPS_NAME,
   67           NULL,         -1 };
   68 
   69 
   70 static struct ppb_device *
   71 ppsprobe(struct ppb_data *ppb)
   72 {
   73         struct pps_data *sc;
   74 
   75         sc = (struct pps_data *) malloc(sizeof(struct pps_data),
   76                                                         M_TEMP, M_NOWAIT);
   77         if (!sc) {
   78                 printf(PPS_NAME ": cannot malloc!\n");
   79                 return (0);
   80         }
   81         bzero(sc, sizeof(struct pps_data));
   82 
   83         softc[npps] = sc;
   84 
   85         sc->pps_unit = npps++;
   86 
   87         sc->pps_dev.id_unit = sc->pps_unit;
   88         sc->pps_dev.ppb = ppb;
   89         sc->pps_dev.name = ppsdriver.name;
   90         sc->pps_dev.intr = ppsintr;
   91 
   92         sc->pps.ppscap = PPS_CAPTUREASSERT | PPS_ECHOASSERT;
   93         pps_init(&sc->pps);
   94         return (&sc->pps_dev);
   95 }
   96 
   97 static int
   98 ppsattach(struct ppb_device *dev)
   99 {
  100         dev_t devt;
  101 
  102         /*
  103          * Report ourselves
  104          */
  105         printf(PPS_NAME "%d: <Pulse per second Timing Interface> on ppbus %d\n",
  106                dev->id_unit, dev->ppb->ppb_link->adapter_unit);
  107 
  108 #ifdef DEVFS
  109         devfs_add_devswf(&pps_cdevsw,
  110                 dev->id_unit, DV_CHR,
  111                 UID_ROOT, GID_WHEEL, 0600, PPS_NAME "%d", dev->id_unit);
  112 #endif
  113         devt = makedev(CDEV_MAJOR, 0);
  114         cdevsw_add(&devt, &pps_cdevsw, NULL);
  115         return (1);
  116 }
  117 
  118 static  int
  119 ppsopen(dev_t dev, int flags, int fmt, struct proc *p)
  120 {
  121         struct pps_data *sc;
  122         u_int unit = minor(dev);
  123 
  124         if ((unit >= npps))
  125                 return (ENXIO);
  126 
  127         sc = softc[unit];
  128 
  129         if (ppb_request_bus(&sc->pps_dev, PPB_WAIT|PPB_INTR))
  130                 return (EINTR);
  131 
  132         ppb_wctr(&sc->pps_dev, 0);
  133         ppb_wctr(&sc->pps_dev, IRQENABLE);
  134 
  135         return(0);
  136 }
  137 
  138 static  int
  139 ppsclose(dev_t dev, int flags, int fmt, struct proc *p)
  140 {
  141         struct pps_data *sc = softc[minor(dev)];
  142 
  143         sc->pps.ppsparam.mode = 0;      /* PHK ??? */
  144 
  145         ppb_wdtr(&sc->pps_dev, 0);
  146         ppb_wctr(&sc->pps_dev, 0);
  147 
  148         ppb_release_bus(&sc->pps_dev);
  149         return(0);
  150 }
  151 
  152 static void
  153 ppsintr(int unit)
  154 {
  155         struct pps_data *sc = softc[unit];
  156         struct timecounter *tc;
  157         unsigned count;
  158 
  159         tc = timecounter;
  160         count = timecounter->tc_get_timecount(tc);
  161         if (!(ppb_rstr(&sc->pps_dev) & nACK))
  162                 return;
  163         if (sc->pps.ppsparam.mode & PPS_ECHOASSERT) 
  164                 ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED);
  165         pps_event(&sc->pps, tc, count, PPS_CAPTUREASSERT);
  166         if (sc->pps.ppsparam.mode & PPS_ECHOASSERT) 
  167                 ppb_wctr(&sc->pps_dev, IRQENABLE);
  168 }
  169 
  170 static int
  171 ppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
  172 {
  173         struct pps_data *sc = softc[minor(dev)];
  174 
  175         return (pps_ioctl(cmd, data, &sc->pps));
  176 }
  177 

Cache object: c4e912f1ed6ec0cd007eb9dae6a2308d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.