From 86f7da92483e4eaba01249f78c04cea68b99edfc Mon Sep 17 00:00:00 2001 From: imp Date: Fri, 11 Mar 2005 07:03:46 +0000 Subject: [PATCH] Make the pps interrupt register as MPSAFE and FAST. Use a spin lock to syncrhonize access to the data as a result. This makes the pps less likely to miss the 1ms pulse that I'm feeding it, but not entirely reliable yet on my 133MHz P5. Reviewed by: phk --- sys/dev/ppbus/pps.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c index 2582aa1a13b0..c66e39d5ef0f 100644 --- a/sys/dev/ppbus/pps.c +++ b/sys/dev/ppbus/pps.c @@ -46,6 +46,7 @@ struct pps_data { struct callout_handle timeout; int lastdata; + struct mtx mtx; struct resource *intr_resource; /* interrupt resource */ void *intr_cookie; /* interrupt registration cookie */ }; @@ -64,7 +65,6 @@ static d_ioctl_t ppsioctl; static struct cdevsw pps_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = ppsopen, .d_close = ppsclose, .d_ioctl = ppsioctl, @@ -110,6 +110,7 @@ ppsattach(device_t dev) intptr_t irq; int i, unit, zero = 0; + mtx_init(&sc->mtx, device_get_nameunit(dev), "pps", MTX_SPIN); /* retrieve the ppbus irq */ BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq); @@ -203,9 +204,9 @@ ppsopen(struct cdev *dev, int flags, int fmt, struct thread *td) return (EINTR); /* attach the interrupt handler */ - if ((error = BUS_SETUP_INTR(ppbus, ppsdev, sc->intr_resource, - INTR_TYPE_TTY, ppsintr, ppsdev, - &sc->intr_cookie))) { + if ((error = bus_setup_intr(ppsdev, sc->intr_resource, + (INTR_TYPE_TTY | INTR_MPSAFE | INTR_FAST), ppsintr, + ppsdev, &sc->intr_cookie))) { ppb_release_bus(ppbus, ppsdev); return (error); } @@ -280,14 +281,18 @@ ppsintr(void *arg) struct pps_data *sc = DEVTOSOFTC(ppsdev); device_t ppbus = sc->ppbus; + mtx_lock(&sc->mtx); pps_capture(&sc->pps[0]); - if (!(ppb_rstr(ppbus) & nACK)) + if (!(ppb_rstr(ppbus) & nACK)) { + mtx_unlock(&sc->mtx); return; + } if (sc->pps[0].ppsparam.mode & PPS_ECHOASSERT) ppb_wctr(ppbus, IRQENABLE | AUTOFEED); pps_event(&sc->pps[0], PPS_CAPTUREASSERT); if (sc->pps[0].ppsparam.mode & PPS_ECHOASSERT) ppb_wctr(ppbus, IRQENABLE); + mtx_unlock(&sc->mtx); } static int @@ -295,8 +300,12 @@ ppsioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t { struct pps_data *sc = dev->si_drv1; int subdev = (intptr_t)dev->si_drv2; + int err; - return (pps_ioctl(cmd, data, &sc->pps[subdev])); + mtx_lock(&sc->mtx); + err = pps_ioctl(cmd, data, &sc->pps[subdev]); + mtx_unlock(&sc->mtx); + return (err); } static device_method_t pps_methods[] = {