* vme_control() and vme_buginfo() have been deleted because
* they are no longer being used.
*
- * The time on the bc635 TFP must be set to GMT due to the
- * fact that NTP makes use of GMT for all its calculations.
- *
- * 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.
+ * 2/21/2007 Ali Ghorashi
+ * Modified to add support for Symmetricom bc637PCI-U Time &
+ * Frequency Processor on Solaris.
+ * Tested on Solaris 10 with a bc635 card.
+ *
* 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
+ * server 127.127.16.u prefer mode M
+ * where u is the id (usually 0) of the entry in /dev (/dev/stfp0)
+ *
+ * and M is one of the following modes:
* 1 : FreeBSD PCI 635/637.
* 2 : Linux or Windows PCI 635/637.
+ * 3 : Solaris 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.
+ * for the TFP card.
+ * Solaris requires Symmetricom's driver and its header file (freely distributed) to
+ * be installed and running.
*/
#ifdef HAVE_CONFIG_H
#include <syslog.h>
#include <ctype.h>
-/* STUFF BY RES */
struct btfp_time /* Structure for reading 5 time words */
/* in one ioctl(2) operation. */
{
#define READTIME _IOR('u', 5, struct btfp_time )
#endif
-#define VMEFD "/dev/btfp0"
+/* Solaris specific section */
+struct stfp_tm {
+ int32_t tm_sec;
+ int32_t tm_min;
+ int32_t tm_hour;
+ int32_t tm_mday;
+ int32_t tm_mon;
+ int32_t tm_year;
+ int32_t tm_wday;
+ int32_t tm_yday;
+ int32_t tm_isdst;
+};
+
+struct stfp_time {
+ struct stfp_tm tm;
+ int32_t usec; /* usec 0 - 999999 */
+ int32_t hnsec; /* hnsec 0 - 9 (hundreds of nsecs) */
+ int32_t status;
+};
-struct vmedate { /* structure returned by get_vmetime.c */
+#define SELTIMEFORMAT 2
+# define TIME_DECIMAL 0
+# define TIME_BINARY 1
+
+#if defined(__sun__)
+#undef READTIME
+#define READTIME 9
+#endif /** __sun___ **/
+/* end solaris specific section */
+
+struct vmedate { /* structure returned by get_vmetime.c */
unsigned short year;
unsigned short day;
unsigned short hr;
unsigned short status;
};
-/* END OF STUFF FROM RES */
typedef void *SYMMT_PCI_HANDLE;
/*
static void vme_receive (struct recvbuf *);
static void vme_poll (int unit, struct peer *);
struct vmedate *get_datumtime(struct vmedate *);
-void tvme_fill(struct vmedate *, uint32_t btm[2]);
+void tvme_fill(struct vmedate *, uint32_t btm[2]);
+void stfp_time2tvme(struct vmedate *time_vme, struct stfp_time *stfp);
+inline const char *DEVICE_NAME(int n);
+
+
/*
* 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
int tfp_type; /* mode selector, indicate platform and driver interface */
SYMMT_PCI_HANDLE stfp_handle;
+/**
+ * this macro returns the device name based on
+ * the platform we are running on and the device number
+ */
+#if defined(__sun__)
+inline const char *DEVICE_NAME(int n) {static char s[20]={0}; snprintf(s,19,"/dev/stfp%d",n);return s;}
+#else
+inline const char* DEVICE_NAME(int n) {static char s[20]={0}; snprintf(s,19,"/dev/btfp%d",n);return s;}
+#endif /**__sun__**/
/*
* vme_start - open the VME device and initialize data for processing
tfp_type = (int)(peer->ttl);
switch (tfp_type) {
case 1:
+ case 3:
break;
case 2:
stfp_handle = bcStartPci(); /* init the card in lin/win */
*/
#ifdef DEBUG
- printf("Opening DATUM VME DEVICE \n");
+ printf("Opening DATUM DEVICE %s\n",DEVICE_NAME(peer->refclkunit));
#endif
- if ( (fd_vme = open(VMEFD, O_RDWR)) < 0) {
+ if ( (fd_vme = open(DEVICE_NAME(peer->refclkunit), O_RDWR)) < 0) {
msyslog(LOG_ERR, "vme_start: failed open of %s: %m", vmedev);
return (0);
}
switch (tfp_type) {
case 1: break;
case 2: break;
+ case 3:break;
default:
/* Release capture lockout in case it was set before. */
if( ioctl( fd_vme, RUNLOCK, &dummy ) )
struct btfp_time vts;
uint32_t btm[2];
uint8_t dmy;
+ struct stfp_time stfpm;
if ( time_vme == (struct vmedate *)NULL) {
time_vme = (struct vmedate *)malloc(sizeof(struct vmedate ));
}
tvme_fill(time_vme, btm);
break;
+
+ case 3: /** solaris **/
+ memset(&stfpm,0,sizeof(stfpm));
+
+ /* we need the time in decimal format */
+ /* Here we rudely assume that we are the only user of the driver.
+ * Other programs will have to set their own time format before reading
+ * the time.
+ */
+ if(ioctl (fd_vme, SELTIMEFORMAT, TIME_DECIMAL)){
+ msyslog(LOG_ERR, "Could not set time format\n");
+ return (NULL);
+ }
+ /* read the time */
+ if (ioctl(fd_vme, READTIME, &stfpm)) {
+ msyslog(LOG_ERR, "ioctl error: %m");
+ return(NULL);
+ }
+ stfp_time2tvme(time_vme, &stfpm);
+ break;
default: /* legacy bancomm card */
return;
}
+
+/* Assign values to time_vme struct. Mostly for readability */
+void
+stfp_time2tvme(struct vmedate *time_vme, struct stfp_time *stfp)
+{
+
+ time_vme->day = stfp->tm.tm_yday+1;
+ time_vme->hr = stfp->tm.tm_hour;
+ time_vme->mn = stfp->tm.tm_min;
+ time_vme->sec = stfp->tm.tm_sec;
+ time_vme->frac = stfp->usec*1000;
+ time_vme->frac += stfp->hnsec * 100;
+ time_vme->status = stfp->status;
+ return;
+}
#else
int refclock_bancomm_bs;
#endif /* REFCLOCK */