[BACK]Return to com.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / ic

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/ic/com.c between version 1.267.4.3 and 1.268

version 1.267.4.3, 2008/01/23 19:27:33 version 1.268, 2007/12/14 03:36:54
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*-  /*-
  * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc.   * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
  * All rights reserved.   * All rights reserved.
  *   *
  * This code is derived from software contributed to The NetBSD Foundation   * This code is derived from software contributed to The NetBSD Foundation
Line 228  static int comconsrate;
Line 228  static int comconsrate;
 static tcflag_t comconscflag;  static tcflag_t comconscflag;
 static struct cnm_state com_cnm_state;  static struct cnm_state com_cnm_state;
   
   #ifndef __HAVE_TIMECOUNTER
   static int ppscap =
           PPS_TSFMT_TSPEC |
           PPS_CAPTUREASSERT |
           PPS_CAPTURECLEAR |
           PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
   #endif /* !__HAVE_TIMECOUNTER */
   
 #ifdef KGDB  #ifdef KGDB
 #include <sys/kgdb.h>  #include <sys/kgdb.h>
   
Line 642  com_activate(struct device *self, enum d
Line 650  com_activate(struct device *self, enum d
         struct com_softc *sc = (struct com_softc *)self;          struct com_softc *sc = (struct com_softc *)self;
         int rv = 0;          int rv = 0;
   
           mutex_spin_enter(&sc->sc_lock);
         switch (act) {          switch (act) {
         case DVACT_ACTIVATE:          case DVACT_ACTIVATE:
                 rv = EOPNOTSUPP;                  rv = EOPNOTSUPP;
Line 660  com_activate(struct device *self, enum d
Line 669  com_activate(struct device *self, enum d
                 break;                  break;
         }          }
   
           mutex_spin_exit(&sc->sc_lock);
         return (rv);          return (rv);
 }  }
   
Line 677  com_shutdown(struct com_softc *sc)
Line 687  com_shutdown(struct com_softc *sc)
         /* Clear any break condition set with TIOCSBRK. */          /* Clear any break condition set with TIOCSBRK. */
         com_break(sc, 0);          com_break(sc, 0);
   
   #ifndef __HAVE_TIMECOUNTER
           /* Turn off PPS capture on last close. */
           sc->sc_ppsmask = 0;
           sc->ppsparam.mode = 0;
   #endif /* !__HAVE_TIMECOUNTER */
   
         /*          /*
          * Hang up if necessary.  Wait a bit, so the other side has time to           * Hang up if necessary.  Wait a bit, so the other side has time to
          * notice even if we immediately open the port again.           * notice even if we immediately open the port again.
Line 703  com_shutdown(struct com_softc *sc)
Line 719  com_shutdown(struct com_softc *sc)
   
         CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier);          CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier);
   
         mutex_spin_exit(&sc->sc_lock);  
   
         if (sc->disable) {          if (sc->disable) {
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
                 if (!sc->enabled)                  if (!sc->enabled)
Line 713  com_shutdown(struct com_softc *sc)
Line 727  com_shutdown(struct com_softc *sc)
                 (*sc->disable)(sc);                  (*sc->disable)(sc);
                 sc->enabled = 0;                  sc->enabled = 0;
         }          }
           mutex_spin_exit(&sc->sc_lock);
 }  }
   
 int  int
Line 754  comopen(dev_t dev, int flag, int mode, s
Line 769  comopen(dev_t dev, int flag, int mode, s
   
                 tp->t_dev = dev;                  tp->t_dev = dev;
   
                   mutex_spin_enter(&sc->sc_lock);
   
                 if (sc->enable) {                  if (sc->enable) {
                         if ((*sc->enable)(sc)) {                          if ((*sc->enable)(sc)) {
                                   mutex_spin_exit(&sc->sc_lock);
                                 splx(s);                                  splx(s);
                                 printf("%s: device enable failed\n",                                  printf("%s: device enable failed\n",
                                        sc->sc_dev.dv_xname);                                         sc->sc_dev.dv_xname);
                                 return (EIO);                                  return (EIO);
                         }                          }
                         mutex_spin_enter(&sc->sc_lock);  
                         sc->enabled = 1;                          sc->enabled = 1;
                         com_config(sc);                          com_config(sc);
                 } else {  
                         mutex_spin_enter(&sc->sc_lock);  
                 }                  }
   
                 /* Turn on interrupts. */                  /* Turn on interrupts. */
Line 779  comopen(dev_t dev, int flag, int mode, s
Line 793  comopen(dev_t dev, int flag, int mode, s
                 sc->sc_msr = CSR_READ_1(&sc->sc_regs, COM_REG_MSR);                  sc->sc_msr = CSR_READ_1(&sc->sc_regs, COM_REG_MSR);
   
                 /* Clear PPS capture state on first open. */                  /* Clear PPS capture state on first open. */
   #ifdef __HAVE_TIMECOUNTER
                 memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state));                  memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state));
                 sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;                  sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
                 pps_init(&sc->sc_pps_state);                  pps_init(&sc->sc_pps_state);
   #else /* !__HAVE_TIMECOUNTER */
                   sc->sc_ppsmask = 0;
                   sc->ppsparam.mode = 0;
   #endif /* !__HAVE_TIMECOUNTER */
   
                 mutex_spin_exit(&sc->sc_lock);                  mutex_spin_exit(&sc->sc_lock);
   
Line 1004  comioctl(dev_t dev, u_long cmd, void *da
Line 1023  comioctl(dev_t dev, u_long cmd, void *da
                 *(int *)data = com_to_tiocm(sc);                  *(int *)data = com_to_tiocm(sc);
                 break;                  break;
   
   #ifdef __HAVE_TIMECOUNTER
         case PPS_IOC_CREATE:          case PPS_IOC_CREATE:
         case PPS_IOC_DESTROY:          case PPS_IOC_DESTROY:
         case PPS_IOC_GETPARAMS:          case PPS_IOC_GETPARAMS:
Line 1015  comioctl(dev_t dev, u_long cmd, void *da
Line 1035  comioctl(dev_t dev, u_long cmd, void *da
 #endif  #endif
                 error = pps_ioctl(cmd, data, &sc->sc_pps_state);                  error = pps_ioctl(cmd, data, &sc->sc_pps_state);
                 break;                  break;
   #else /* !__HAVE_TIMECOUNTER */
           case PPS_IOC_CREATE:
                   break;
   
           case PPS_IOC_DESTROY:
                   break;
   
           case PPS_IOC_GETPARAMS: {
                   pps_params_t *pp;
                   pp = (pps_params_t *)data;
                   *pp = sc->ppsparam;
                   break;
           }
   
           case PPS_IOC_SETPARAMS: {
                   pps_params_t *pp;
                   int mode;
                   pp = (pps_params_t *)data;
                   if (pp->mode & ~ppscap) {
                           error = EINVAL;
                           break;
                   }
                   sc->ppsparam = *pp;
                   /*
                    * Compute msr masks from user-specified timestamp state.
                    */
                   mode = sc->ppsparam.mode;
                   switch (mode & PPS_CAPTUREBOTH) {
                   case 0:
                           sc->sc_ppsmask = 0;
                           break;
   
                   case PPS_CAPTUREASSERT:
                           sc->sc_ppsmask = MSR_DCD;
                           sc->sc_ppsassert = MSR_DCD;
                           sc->sc_ppsclear = -1;
                           break;
   
                   case PPS_CAPTURECLEAR:
                           sc->sc_ppsmask = MSR_DCD;
                           sc->sc_ppsassert = -1;
                           sc->sc_ppsclear = 0;
                           break;
   
                   case PPS_CAPTUREBOTH:
                           sc->sc_ppsmask = MSR_DCD;
                           sc->sc_ppsassert = MSR_DCD;
                           sc->sc_ppsclear = 0;
                           break;
   
                   default:
                           error = EINVAL;
                           break;
                   }
                   break;
           }
   
           case PPS_IOC_GETCAP:
                   *(int*)data = ppscap;
                   break;
   
           case PPS_IOC_FETCH: {
                   pps_info_t *pi;
                   pi = (pps_info_t *)data;
                   *pi = sc->ppsinfo;
                   break;
           }
   
   #ifdef PPS_SYNC
           case PPS_IOC_KCBIND: {
                   int edge = (*(int *)data) & PPS_CAPTUREBOTH;
   
                   if (edge == 0) {
                           /*
                            * remove binding for this source; ignore
                            * the request if this is not the current
                            * hardpps source
                            */
                           if (pps_kc_hardpps_source == sc) {
                                   pps_kc_hardpps_source = NULL;
                                   pps_kc_hardpps_mode = 0;
                           }
                   } else {
                           /*
                            * bind hardpps to this source, replacing any
                            * previously specified source or edges
                            */
                           pps_kc_hardpps_source = sc;
                           pps_kc_hardpps_mode = edge;
                   }
                   break;
           }
   #endif /* PPS_SYNC */
   #endif /* !__HAVE_TIMECOUNTER */
   
         case TIOCDCDTIMESTAMP:  /* XXX old, overloaded  API used by xntpd v3 */          case TIOCDCDTIMESTAMP:  /* XXX old, overloaded  API used by xntpd v3 */
   #ifdef __HAVE_TIMECOUNTER
 #ifndef PPS_TRAILING_EDGE  #ifndef PPS_TRAILING_EDGE
                 TIMESPEC_TO_TIMEVAL((struct timeval *)data,                  TIMESPEC_TO_TIMEVAL((struct timeval *)data,
                     &sc->sc_pps_state.ppsinfo.assert_timestamp);                      &sc->sc_pps_state.ppsinfo.assert_timestamp);
Line 1024  comioctl(dev_t dev, u_long cmd, void *da
Line 1139  comioctl(dev_t dev, u_long cmd, void *da
                 TIMESPEC_TO_TIMEVAL((struct timeval *)data,                  TIMESPEC_TO_TIMEVAL((struct timeval *)data,
                     &sc->sc_pps_state.ppsinfo.clear_timestamp);                      &sc->sc_pps_state.ppsinfo.clear_timestamp);
 #endif  #endif
   #else /* !__HAVE_TIMECOUNTER */
                   /*
                    * Some GPS clocks models use the falling rather than
                    * rising edge as the on-the-second signal.
                    * The old API has no way to specify PPS polarity.
                    */
                   sc->sc_ppsmask = MSR_DCD;
   #ifndef PPS_TRAILING_EDGE
                   sc->sc_ppsassert = MSR_DCD;
                   sc->sc_ppsclear = -1;
                   TIMESPEC_TO_TIMEVAL((struct timeval *)data,
                       &sc->ppsinfo.assert_timestamp);
   #else
                   sc->sc_ppsassert = -1;
                   sc->sc_ppsclear = 0;
                   TIMESPEC_TO_TIMEVAL((struct timeval *)data,
                       &sc->ppsinfo.clear_timestamp);
   #endif
   #endif /* !__HAVE_TIMECOUNTER */
                 break;                  break;
   
         default:          default:
Line 1880  again: do {
Line 2014  again: do {
                 msr = CSR_READ_1(regsp, COM_REG_MSR);                  msr = CSR_READ_1(regsp, COM_REG_MSR);
                 delta = msr ^ sc->sc_msr;                  delta = msr ^ sc->sc_msr;
                 sc->sc_msr = msr;                  sc->sc_msr = msr;
   #ifdef __HAVE_TIMECOUNTER
                 if ((sc->sc_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) &&                  if ((sc->sc_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) &&
                     (delta & MSR_DCD)) {                      (delta & MSR_DCD)) {
                         pps_capture(&sc->sc_pps_state);                          pps_capture(&sc->sc_pps_state);
Line 1888  again: do {
Line 2023  again: do {
                             PPS_CAPTUREASSERT :                              PPS_CAPTUREASSERT :
                             PPS_CAPTURECLEAR);                              PPS_CAPTURECLEAR);
                 }                  }
   #else /* !__HAVE_TIMECOUNTER */
                   /*
                    * Pulse-per-second (PSS) signals on edge of DCD?
                    * Process these even if line discipline is ignoring DCD.
                    */
                   if (delta & sc->sc_ppsmask) {
                           struct timeval tv;
                           if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) {
                                   /* XXX nanotime() */
                                   microtime(&tv);
                                   TIMEVAL_TO_TIMESPEC(&tv,
                                       &sc->ppsinfo.assert_timestamp);
                                   if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
                                           timespecadd(&sc->ppsinfo.assert_timestamp,
                                               &sc->ppsparam.assert_offset,
                                                       &sc->ppsinfo.assert_timestamp);
                                   }
   
   #ifdef PPS_SYNC
                                   if (pps_kc_hardpps_source == sc &&
                                       pps_kc_hardpps_mode & PPS_CAPTUREASSERT) {
                                           hardpps(&tv, tv.tv_usec);
                                   }
   #endif
                                   sc->ppsinfo.assert_sequence++;
                                   sc->ppsinfo.current_mode = sc->ppsparam.mode;
   
                           } else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) {
                                   /* XXX nanotime() */
                                   microtime(&tv);
                                   TIMEVAL_TO_TIMESPEC(&tv,
                                       &sc->ppsinfo.clear_timestamp);
                                   if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
                                           timespecadd(&sc->ppsinfo.clear_timestamp,
                                               &sc->ppsparam.clear_offset,
                                               &sc->ppsinfo.clear_timestamp);
                                   }
   
   #ifdef PPS_SYNC
                                   if (pps_kc_hardpps_source == sc &&
                                       pps_kc_hardpps_mode & PPS_CAPTURECLEAR) {
                                           hardpps(&tv, tv.tv_usec);
                                   }
   #endif
                                   sc->ppsinfo.clear_sequence++;
                                   sc->ppsinfo.current_mode = sc->ppsparam.mode;
                           }
                   }
   #endif /* !__HAVE_TIMECOUNTER */
   
                 /*                  /*
                  * Process normal status changes                   * Process normal status changes

Legend:
Removed from v.1.267.4.3  
changed lines
  Added in v.1.268

CVSweb <webmaster@jp.NetBSD.org>