diff options
author | roberto <roberto@FreeBSD.org> | 2008-08-22 15:58:00 +0000 |
---|---|---|
committer | roberto <roberto@FreeBSD.org> | 2008-08-22 15:58:00 +0000 |
commit | b85c7169a740b2edf0106ad59fdaa1b0160f823c (patch) | |
tree | 2b9fb7f64eacb322e95695e412c923e97ba33e88 /contrib/ntp/ntpd/refclock_bancomm.c | |
parent | 1d197cfe9feac6bc29537d8e53c30b6435937b95 (diff) | |
parent | 7a6072eb585696f8856cd498c3fd194cf49f14c6 (diff) | |
download | FreeBSD-src-b85c7169a740b2edf0106ad59fdaa1b0160f823c.zip FreeBSD-src-b85c7169a740b2edf0106ad59fdaa1b0160f823c.tar.gz |
Merge ntpd & friends 4.2.4p5 from vendor/ntp/dist into head. Next commit
will update usr.sbin/ntp to match this.
MFC after: 2 weeks
Diffstat (limited to 'contrib/ntp/ntpd/refclock_bancomm.c')
-rw-r--r-- | contrib/ntp/ntpd/refclock_bancomm.c | 224 |
1 files changed, 129 insertions, 95 deletions
diff --git a/contrib/ntp/ntpd/refclock_bancomm.c b/contrib/ntp/ntpd/refclock_bancomm.c index a63be44..9fc8c82 100644 --- a/contrib/ntp/ntpd/refclock_bancomm.c +++ b/contrib/ntp/ntpd/refclock_bancomm.c @@ -25,6 +25,21 @@ * * Installation of the Datum/Bancomm driver creates the * device file /dev/btfp0 + * + * 04/28/2005 Rob Neal + * Modified to add support for Symmetricom bc637PCI-U Time & + * Frequency Processor. + * Card bus type (VME/VXI or PCI) and environment are specified via the + * "mode" keyword on the server command in ntp.conf. + * server 127.127.16.u prefer mode m (...) + * Modes currently supported are + * 1 : FreeBSD PCI 635/637. + * 2 : Linux or Windows PCI 635/637. + * not specified, or other number: + * : Assumed to be VME/VXI legacy Bancomm card on Solaris. + * Linux and Windows platforms require Symmetricoms' proprietary driver + * for the TFP card. + * Tested on FreeBSD 5.3 with a 637 card. */ #ifdef HAVE_CONFIG_H @@ -49,7 +64,6 @@ struct btfp_time /* Structure for reading 5 time words */ { unsigned short btfp_time[5]; /* Time words 0,1,2,3, and 4. (16bit)*/ }; - /* SunOS5 ioctl commands definitions.*/ #define BTFPIOC ( 'b'<< 8 ) #define IOCIO( l, n ) ( BTFPIOC | n ) @@ -61,11 +75,16 @@ struct btfp_time /* Structure for reading 5 time words */ #define RUNLOCK IOCIOR(b, 19, int ) /* Release Capture Lockout */ #define RCR0 IOCIOR(b, 22, int ) /* Read control register zero.*/ #define WCR0 IOCIOWN(b, 23, int) /* Write control register zero*/ - /***** Compound ioctl commands *****/ /* Read all 5 time words in one call. */ #define READTIME IOCIORN(b, 32, sizeof( struct btfp_time )) + +#if defined(__FreeBSD__) +#undef READTIME +#define READTIME _IOR('u', 5, struct btfp_time ) +#endif + #define VMEFD "/dev/btfp0" struct vmedate { /* structure returned by get_vmetime.c */ @@ -74,11 +93,12 @@ struct vmedate { /* structure returned by get_vmetime.c */ unsigned short hr; unsigned short mn; unsigned short sec; - unsigned long frac; + long frac; unsigned short status; }; /* END OF STUFF FROM RES */ +typedef void *SYMMT_PCI_HANDLE; /* * VME interface parameters. @@ -99,7 +119,7 @@ extern u_long current_time; /* current time(s) */ /* * Imported from ntpd module */ -extern int debug; /* global debug flag */ +extern volatile int debug; /* global debug flag */ /* * VME unit control structure. @@ -114,12 +134,20 @@ struct vmeunit { /* * Function prototypes */ -static void vme_init (void); static int vme_start (int, struct peer *); static void vme_shutdown (int, struct peer *); static void vme_receive (struct recvbuf *); static void vme_poll (int unit, struct peer *); -struct vmedate *get_datumtime(struct vmedate *); +struct vmedate *get_datumtime(struct vmedate *); +void tvme_fill(struct vmedate *, uint32_t btm[2]); +/* + * Define the bc*() functions as weak so we can compile/link without them. + * Only clients with the card will have the proprietary vendor device driver + * and interface library needed for use on Linux/Windows platforms. + */ +extern uint32_t __attribute__ ((weak)) bcReadBinTime(SYMMT_PCI_HANDLE, uint32_t *, uint32_t*, uint8_t*); +extern SYMMT_PCI_HANDLE __attribute__ ((weak)) bcStartPci(void); +extern void __attribute__ ((weak)) bcStopPci(SYMMT_PCI_HANDLE); /* * Transfer vector @@ -136,6 +164,8 @@ struct refclock refclock_bancomm = { int fd_vme; /* file descriptor for ioctls */ int regvalue; +int tfp_type; /* mode selector, indicate platform and driver interface */ +SYMMT_PCI_HANDLE stfp_handle; /* @@ -151,7 +181,17 @@ vme_start( struct refclockproc *pp; int dummy; char vmedev[20]; - + + tfp_type = (int)(peer->ttl); + switch (tfp_type) { + case 1: + break; + case 2: + stfp_handle = bcStartPci(); /* init the card in lin/win */ + break; + default: + break; + } /* * Open VME device */ @@ -163,13 +203,20 @@ vme_start( msyslog(LOG_ERR, "vme_start: failed open of %s: %m", vmedev); return (0); } - else { /* Release capture lockout in case it was set from before. */ - if( ioctl( fd_vme, RUNLOCK, &dummy ) ) - msyslog(LOG_ERR, "vme_start: RUNLOCK failed %m"); - - regvalue = 0; /* More esoteric stuff to do... */ - if( ioctl( fd_vme, WCR0, ®value ) ) - msyslog(LOG_ERR, "vme_start: WCR0 failed %m"); + else { + switch (tfp_type) { + case 1: break; + case 2: break; + default: + /* Release capture lockout in case it was set before. */ + if( ioctl( fd_vme, RUNLOCK, &dummy ) ) + msyslog(LOG_ERR, "vme_start: RUNLOCK failed %m"); + + regvalue = 0; /* More esoteric stuff to do... */ + if( ioctl( fd_vme, WCR0, ®value ) ) + msyslog(LOG_ERR, "vme_start: WCR0 failed %m"); + break; + } } /* @@ -222,6 +269,7 @@ vme_shutdown( io_closeclock(&pp->io); pp->unitptr = NULL; free(vme); + if (tfp_type == 2) bcStopPci(stfp_handle); } @@ -275,7 +323,6 @@ vme_poll( time(&tloc); tadr = gmtime(&tloc); tptr->year = (unsigned short)(tadr->tm_year + 1900); - sprintf(pp->a_lastcode, "%3.3d %2.2d:%2.2d:%2.2d.%.6ld %1d", @@ -292,13 +339,13 @@ vme_poll( pp->hour = tptr->hr; pp->minute = tptr->mn; pp->second = tptr->sec; - pp->usec = tptr->frac; + pp->nsec = tptr->frac; #ifdef DEBUG if (debug) printf("pp: %3d %02d:%02d:%02d.%06ld %1x\n", pp->day, pp->hour, pp->minute, pp->second, - pp->usec, tptr->status); + pp->nsec, tptr->status); #endif if (tptr->status ) { /* Status 0 is locked to ref., 1 is not */ refclock_report(peer, CEVNT_BADREPLY); @@ -325,108 +372,95 @@ vme_poll( struct vmedate * get_datumtime(struct vmedate *time_vme) { - unsigned short status; char cbuf[7]; struct btfp_time vts; + uint32_t btm[2]; + uint8_t dmy; if ( time_vme == (struct vmedate *)NULL) { time_vme = (struct vmedate *)malloc(sizeof(struct vmedate )); } - if( ioctl(fd_vme, READTIME, &vts)) - msyslog(LOG_ERR, "get_datumtime error: %m"); - - /* if you want to actually check the validity of these registers, do a - define of CHECK above this. I didn't find it necessary. - RES - */ - -#ifdef CHECK - - /* Get day */ - sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) + - ((vts.btfp_time[ 1 ] & 0xff00) >> 8)); - - if (isdigit(cbuf[0]) && isdigit(cbuf[1]) && isdigit(cbuf[2]) ) - time_vme->day = (unsigned short)atoi(cbuf); - else - time_vme->day = (unsigned short) 0; - - /* Get hour */ - sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff); - - if (isdigit(cbuf[0]) && isdigit(cbuf[1])) - time_vme->hr = (unsigned short)atoi(cbuf); - else - time_vme->hr = (unsigned short) 0; - - /* Get minutes */ - sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8); - if (isdigit(cbuf[0]) && isdigit(cbuf[1])) - time_vme->mn = (unsigned short)atoi(cbuf); - else - time_vme->mn = (unsigned short) 0; - - /* Get seconds */ - sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff); - - if (isdigit(cbuf[0]) && isdigit(cbuf[1])) - time_vme->sec = (unsigned short)atoi(cbuf); - else - time_vme->sec = (unsigned short) 0; - - /* Get microseconds. Yes, we ignore the 0.1 microsecond digit so we can - use the TVTOTSF function later on...*/ + switch (tfp_type) { + case 1: /* BSD, PCI, 2 32bit time words */ + if (ioctl(fd_vme, READTIME, &btm)) { + msyslog(LOG_ERR, "get_bc63x error: %m"); + return(NULL); + } + tvme_fill(time_vme, btm); + break; - sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ], - vts.btfp_time[ 4 ]>>8); + case 2: /* Linux/Windows, PCI, 2 32bit time words */ + if (bcReadBinTime(stfp_handle, &btm[1], &btm[0], &dmy) == 0) { + msyslog(LOG_ERR, "get_datumtime error: %m"); + return(NULL); + } + tvme_fill(time_vme, btm); + break; - if (isdigit(cbuf[0]) && isdigit(cbuf[1]) && isdigit(cbuf[2]) - && isdigit(cbuf[3]) && isdigit(cbuf[4]) && isdigit(cbuf[5])) - time_vme->frac = (u_long) atoi(cbuf); - else - time_vme->frac = (u_long) 0; -#else + default: /* legacy bancomm card */ - /* DONT CHECK just trust the card */ + if (ioctl(fd_vme, READTIME, &vts)) { + msyslog(LOG_ERR, "get_datumtime error: %m"); + return(NULL); + } + /* Get day */ + sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) + + ((vts.btfp_time[ 1 ] & 0xff00) >> 8)); + time_vme->day = (unsigned short)atoi(cbuf); - /* Get day */ - sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) + - ((vts.btfp_time[ 1 ] & 0xff00) >> 8)); - time_vme->day = (unsigned short)atoi(cbuf); + /* Get hour */ + sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff); - /* Get hour */ - sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff); + time_vme->hr = (unsigned short)atoi(cbuf); - time_vme->hr = (unsigned short)atoi(cbuf); + /* Get minutes */ + sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8); + time_vme->mn = (unsigned short)atoi(cbuf); - /* Get minutes */ - sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8); - time_vme->mn = (unsigned short)atoi(cbuf); + /* Get seconds */ + sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff); + time_vme->sec = (unsigned short)atoi(cbuf); - /* Get seconds */ - sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff); - time_vme->sec = (unsigned short)atoi(cbuf); + /* Get microseconds. Yes, we ignore the 0.1 microsecond digit so + we can use the TVTOTSF function later on...*/ - /* Get microseconds. Yes, we ignore the 0.1 microsecond digit so we can - use the TVTOTSF function later on...*/ + sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ], + vts.btfp_time[ 4 ]>>8); - sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ], - vts.btfp_time[ 4 ]>>8); + time_vme->frac = (u_long) atoi(cbuf); - time_vme->frac = (u_long) atoi(cbuf); + /* Get status bit */ + time_vme->status = (vts.btfp_time[0] & 0x0010) >>4; -#endif /* CHECK */ + break; + } - /* Get status bit */ - status = (vts.btfp_time[0] & 0x0010) >>4; - time_vme->status = status; /* Status=0 if locked to ref. */ - /* Status=1 if flywheeling */ - if (status) { /* lost lock ? */ + if (time_vme->status) return ((void *)NULL); - } else return (time_vme); } +/* Assign values to time_vme struct. Mostly for readability */ +void +tvme_fill(struct vmedate *time_vme, uint32_t btm[2]) +{ + struct tm maj; + uint32_t dmaj, dmin; + + dmaj = btm[1]; /* syntax sugar */ + dmin = btm[0]; + + gmtime_r(&dmaj, &maj); + time_vme->day = maj.tm_yday+1; + time_vme->hr = maj.tm_hour; + time_vme->mn = maj.tm_min; + time_vme->sec = maj.tm_sec; + time_vme->frac = (dmin & 0x000fffff) * 1000; + time_vme->frac += ((dmin & 0x00f00000) >> 20) * 100; + time_vme->status = (dmin & 0x01000000) >> 24; + return; +} #else int refclock_bancomm_bs; |