pps.c (43433) | pps.c (44666) |
---|---|
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 * | 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 * $Id: pps.c,v 1.12 1998/12/07 21:58:16 archie Exp $ | 9 * $Id: pps.c,v 1.13 1999/01/30 15:35:39 nsouch Exp $ |
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" | 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#include "opt_ntp.h" | |
20 21#include <sys/param.h> 22#include <sys/kernel.h> 23#include <sys/systm.h> 24#include <sys/conf.h> 25#include <sys/timepps.h> 26#ifdef DEVFS 27#include <sys/devfsext.h> 28#endif 29#include <sys/malloc.h> 30 31#include <dev/ppbus/ppbconf.h> 32#include "pps.h" 33 34#define PPS_NAME "lppps" /* our official name */ 35 36static struct pps_data { 37 int pps_unit; 38 struct ppb_device pps_dev; | 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 35static struct pps_data { 36 int pps_unit; 37 struct ppb_device pps_dev; |
39 pps_params_t ppsparam; 40 pps_info_t ppsinfo; | 38 struct pps_state pps; |
41} *softc[NPPS]; 42 | 39} *softc[NPPS]; 40 |
43static int ppscap = 44 PPS_CAPTUREASSERT | 45#ifdef PPS_SYNC 46 PPS_HARDPPSONASSERT | 47#endif /* PPS_SYNC */ 48 PPS_OFFSETASSERT | 49 PPS_ECHOASSERT | 50 PPS_TSFMT_TSPEC; 51 | |
52static int npps; | 41static int npps; |
42static pps_devsw_installed = 0; |
|
53 54/* 55 * Make ourselves visible as a ppbus driver 56 */ 57 58static struct ppb_device *ppsprobe(struct ppb_data *ppb); 59static int ppsattach(struct ppb_device *dev); 60static void ppsintr(int unit); --- 11 unchanged lines hidden (view full) --- 72 73#define CDEV_MAJOR 89 74static struct cdevsw pps_cdevsw = 75 { ppsopen, ppsclose, noread, nowrite, 76 ppsioctl, nullstop, nullreset, nodevtotty, 77 seltrue, nommap, nostrat, PPS_NAME, 78 NULL, -1 }; 79 | 43 44/* 45 * Make ourselves visible as a ppbus driver 46 */ 47 48static struct ppb_device *ppsprobe(struct ppb_data *ppb); 49static int ppsattach(struct ppb_device *dev); 50static void ppsintr(int unit); --- 11 unchanged lines hidden (view full) --- 62 63#define CDEV_MAJOR 89 64static struct cdevsw pps_cdevsw = 65 { ppsopen, ppsclose, noread, nowrite, 66 ppsioctl, nullstop, nullreset, nodevtotty, 67 seltrue, nommap, nostrat, PPS_NAME, 68 NULL, -1 }; 69 |
70 |
|
80static struct ppb_device * 81ppsprobe(struct ppb_data *ppb) 82{ 83 struct pps_data *sc; 84 85 sc = (struct pps_data *) malloc(sizeof(struct pps_data), 86 M_TEMP, M_NOWAIT); 87 if (!sc) { --- 6 unchanged lines hidden (view full) --- 94 95 sc->pps_unit = npps++; 96 97 sc->pps_dev.id_unit = sc->pps_unit; 98 sc->pps_dev.ppb = ppb; 99 sc->pps_dev.name = ppsdriver.name; 100 sc->pps_dev.intr = ppsintr; 101 | 71static struct ppb_device * 72ppsprobe(struct ppb_data *ppb) 73{ 74 struct pps_data *sc; 75 76 sc = (struct pps_data *) malloc(sizeof(struct pps_data), 77 M_TEMP, M_NOWAIT); 78 if (!sc) { --- 6 unchanged lines hidden (view full) --- 85 86 sc->pps_unit = npps++; 87 88 sc->pps_dev.id_unit = sc->pps_unit; 89 sc->pps_dev.ppb = ppb; 90 sc->pps_dev.name = ppsdriver.name; 91 sc->pps_dev.intr = ppsintr; 92 |
93 sc->pps.ppscap = PPS_CAPTUREASSERT | PPS_ECHOASSERT; 94 pps_init(&sc->pps); |
|
102 return (&sc->pps_dev); 103} 104 105static int 106ppsattach(struct ppb_device *dev) 107{ | 95 return (&sc->pps_dev); 96} 97 98static int 99ppsattach(struct ppb_device *dev) 100{ |
101 dev_t devt; 102 |
|
108 /* 109 * Report ourselves 110 */ 111 printf(PPS_NAME "%d: <Pulse per second Timing Interface> on ppbus %d\n", 112 dev->id_unit, dev->ppb->ppb_link->adapter_unit); 113 114#ifdef DEVFS 115 devfs_add_devswf(&pps_cdevsw, 116 dev->id_unit, DV_CHR, 117 UID_ROOT, GID_WHEEL, 0600, PPS_NAME "%d", dev->id_unit); 118#endif | 103 /* 104 * Report ourselves 105 */ 106 printf(PPS_NAME "%d: <Pulse per second Timing Interface> on ppbus %d\n", 107 dev->id_unit, dev->ppb->ppb_link->adapter_unit); 108 109#ifdef DEVFS 110 devfs_add_devswf(&pps_cdevsw, 111 dev->id_unit, DV_CHR, 112 UID_ROOT, GID_WHEEL, 0600, PPS_NAME "%d", dev->id_unit); 113#endif |
119 | 114 if( ! pps_devsw_installed ) { 115 devt = makedev(CDEV_MAJOR, 0); 116 cdevsw_add(&devt, &pps_cdevsw, NULL); 117 pps_devsw_installed = 1; 118 } |
120 return (1); 121} 122 123static int 124ppsopen(dev_t dev, int flags, int fmt, struct proc *p) 125{ 126 struct pps_data *sc; 127 u_int unit = minor(dev); --- 12 unchanged lines hidden (view full) --- 140 return(0); 141} 142 143static int 144ppsclose(dev_t dev, int flags, int fmt, struct proc *p) 145{ 146 struct pps_data *sc = softc[minor(dev)]; 147 | 119 return (1); 120} 121 122static int 123ppsopen(dev_t dev, int flags, int fmt, struct proc *p) 124{ 125 struct pps_data *sc; 126 u_int unit = minor(dev); --- 12 unchanged lines hidden (view full) --- 139 return(0); 140} 141 142static int 143ppsclose(dev_t dev, int flags, int fmt, struct proc *p) 144{ 145 struct pps_data *sc = softc[minor(dev)]; 146 |
148 sc->ppsparam.mode = 0; | 147 sc->pps.ppsparam.mode = 0; /* PHK ??? */ |
149 150 ppb_wdtr(&sc->pps_dev, 0); 151 ppb_wctr(&sc->pps_dev, 0); 152 153 ppb_release_bus(&sc->pps_dev); 154 return(0); 155} 156 157static void 158ppsintr(int unit) 159{ 160 struct pps_data *sc = softc[unit]; | 148 149 ppb_wdtr(&sc->pps_dev, 0); 150 ppb_wctr(&sc->pps_dev, 0); 151 152 ppb_release_bus(&sc->pps_dev); 153 return(0); 154} 155 156static void 157ppsintr(int unit) 158{ 159 struct pps_data *sc = softc[unit]; |
161 struct timespec tc; | 160 struct timecounter *tc; 161 unsigned count; |
162 | 162 |
163 nanotime(&tc); | 163 tc = timecounter; 164 count = timecounter->tc_get_timecount(tc); |
164 if (!(ppb_rstr(&sc->pps_dev) & nACK)) 165 return; | 165 if (!(ppb_rstr(&sc->pps_dev) & nACK)) 166 return; |
166 if (sc->ppsparam.mode & PPS_ECHOASSERT) | 167 if (sc->pps.ppsparam.mode & PPS_ECHOASSERT) |
167 ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED); | 168 ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED); |
168 if (sc->ppsparam.mode & PPS_OFFSETASSERT) { 169 timespecadd(&tc, &sc->ppsparam.assert_offset); 170 if (tc.tv_nsec < 0) { 171 tc.tv_sec--; 172 tc.tv_nsec += 1000000000; 173 } 174 } 175 sc->ppsinfo.assert_timestamp = tc; 176 sc->ppsinfo.assert_sequence++; 177#ifdef PPS_SYNC 178 if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) { 179 struct timeval tv; 180 181 tv.tv_sec = tc.tv_sec; 182 tv.tv_usec = tc.tv_nsec / 1000; 183 hardpps(&tv, tv.tv_usec); 184 } 185#endif /* PPS_SYNC */ 186 if (sc->ppsparam.mode & PPS_ECHOASSERT) | 169 pps_event(&sc->pps, tc, count, PPS_CAPTUREASSERT); 170 if (sc->pps.ppsparam.mode & PPS_ECHOASSERT) |
187 ppb_wctr(&sc->pps_dev, IRQENABLE); 188} 189 190static int 191ppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 192{ 193 struct pps_data *sc = softc[minor(dev)]; 194 | 171 ppb_wctr(&sc->pps_dev, IRQENABLE); 172} 173 174static int 175ppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 176{ 177 struct pps_data *sc = softc[minor(dev)]; 178 |
195 return (std_pps_ioctl(cmd, data, &sc->ppsparam, &sc->ppsinfo, ppscap)); | 179 return (pps_ioctl(cmd, data, &sc->pps)); |
196} 197 | 180} 181 |
198static pps_devsw_installed = 0; 199 200static void 201pps_drvinit(void *unused) 202{ 203 dev_t dev; 204 205 if( ! pps_devsw_installed ) { 206 dev = makedev(CDEV_MAJOR, 0); 207 cdevsw_add(&dev, &pps_cdevsw, NULL); 208 pps_devsw_installed = 1; 209 } 210} 211 212SYSINIT(ppsdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,pps_drvinit,NULL) | |