~ubuntu-branches/ubuntu/gutsy/ntp/gutsy

« back to all changes in this revision

Viewing changes to ntpd/refclock_bancomm.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-05-18 22:41:56 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070518224156-563ruqxsxvqvoy8h
Tags: 1:4.2.4p0+dfsg-1ubuntu1
* Merge from Debian unstable.
* Remaining Ubuntu changes:
  - Update version in conflicts/replaces to that which was shipped in edgy,
    which was later than that in Debian (due to the ubuntuX).
  - Change default server to ntp.ubuntu.com.
  - Remove stop links from rc0 and rc6
  - Call dh_installinit with --error-handler
  - Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 *
26
26
 *              Installation of the Datum/Bancomm driver creates the 
27
27
 *              device file /dev/btfp0 
 
28
 *
 
29
 *      04/28/2005 Rob Neal 
 
30
 *              Modified to add support for Symmetricom bc637PCI-U Time & 
 
31
 *              Frequency Processor. 
 
32
 *              Card bus type (VME/VXI or PCI) and environment are specified via the
 
33
 *              "mode" keyword on the server command in ntp.conf.
 
34
 *              server 127.127.16.u prefer mode m (...) 
 
35
 *              Modes currently supported are 
 
36
 *              1               : FreeBSD PCI 635/637.
 
37
 *              2               : Linux or Windows PCI 635/637.
 
38
 *              not specified, or other number: 
 
39
 *                              : Assumed to be VME/VXI legacy Bancomm card on Solaris.
 
40
 *              Linux and Windows platforms require Symmetricoms' proprietary driver
 
41
 *              for the TFP card. 
 
42
 *              Tested on FreeBSD 5.3 with a 637 card. 
28
43
 */
29
44
 
30
45
#ifdef HAVE_CONFIG_H
49
64
{
50
65
        unsigned short btfp_time[5];  /* Time words 0,1,2,3, and 4. (16bit)*/
51
66
};
52
 
 
53
67
/* SunOS5 ioctl commands definitions.*/
54
68
#define BTFPIOC            ( 'b'<< 8 )
55
69
#define IOCIO( l, n )      ( BTFPIOC | n )
61
75
#define RUNLOCK         IOCIOR(b, 19, int )  /* Release Capture Lockout */
62
76
#define RCR0            IOCIOR(b, 22, int )  /* Read control register zero.*/
63
77
#define WCR0            IOCIOWN(b, 23, int)          /* Write control register zero*/
64
 
 
65
78
/***** Compound ioctl commands *****/
66
79
 
67
80
/* Read all 5 time words in one call.   */
68
81
#define READTIME        IOCIORN(b, 32, sizeof( struct btfp_time ))
 
82
 
 
83
#if defined(__FreeBSD__) 
 
84
#undef  READTIME
 
85
#define READTIME        _IOR('u', 5, struct btfp_time )
 
86
#endif 
 
87
 
69
88
#define VMEFD "/dev/btfp0"
70
89
 
71
90
struct vmedate {               /* structure returned by get_vmetime.c */
74
93
        unsigned short hr;
75
94
        unsigned short mn;
76
95
        unsigned short sec;
77
 
        unsigned long frac;
 
96
        long frac;
78
97
        unsigned short status;
79
98
};
80
99
 
81
100
/* END OF STUFF FROM RES */
 
101
typedef void *SYMMT_PCI_HANDLE;
82
102
 
83
103
/*
84
104
 * VME interface parameters. 
99
119
/*
100
120
 * Imported from ntpd module
101
121
 */
102
 
extern int debug;               /* global debug flag */
 
122
extern volatile int debug;               /* global debug flag */
103
123
 
104
124
/*
105
125
 * VME unit control structure.
114
134
/*
115
135
 * Function prototypes
116
136
 */
117
 
static  void    vme_init        (void);
118
137
static  int     vme_start       (int, struct peer *);
119
138
static  void    vme_shutdown    (int, struct peer *);
120
139
static  void    vme_receive     (struct recvbuf *);
121
140
static  void    vme_poll        (int unit, struct peer *);
122
 
struct vmedate *get_datumtime(struct vmedate *);
 
141
struct vmedate *get_datumtime(struct vmedate *);        
 
142
void    tvme_fill(struct vmedate *, uint32_t btm[2]);
 
143
/*
 
144
 * Define the bc*() functions as weak so we can compile/link without them.
 
145
 * Only clients with the card will have the proprietary vendor device driver
 
146
 * and interface library needed for use on Linux/Windows platforms.
 
147
 */
 
148
extern uint32_t __attribute__ ((weak)) bcReadBinTime(SYMMT_PCI_HANDLE, uint32_t *, uint32_t*, uint8_t*);
 
149
extern SYMMT_PCI_HANDLE __attribute__ ((weak)) bcStartPci(void);
 
150
extern void __attribute__ ((weak)) bcStopPci(SYMMT_PCI_HANDLE);
123
151
 
124
152
/*
125
153
 * Transfer vector
136
164
 
137
165
int fd_vme;  /* file descriptor for ioctls */
138
166
int regvalue;
 
167
int tfp_type;   /* mode selector, indicate platform and driver interface */
 
168
SYMMT_PCI_HANDLE stfp_handle;
139
169
 
140
170
 
141
171
/*
151
181
        struct refclockproc *pp;
152
182
        int dummy;
153
183
        char vmedev[20];
154
 
 
 
184
        
 
185
        tfp_type = (int)(peer->ttl);
 
186
        switch (tfp_type) {             
 
187
                case 1:
 
188
                        break;
 
189
                case 2:
 
190
                        stfp_handle = bcStartPci();     /* init the card in lin/win */
 
191
                        break;
 
192
                default:
 
193
                        break;
 
194
        }
155
195
        /*
156
196
         * Open VME device
157
197
         */
163
203
                msyslog(LOG_ERR, "vme_start: failed open of %s: %m", vmedev);
164
204
                return (0);
165
205
        }
166
 
        else  { /* Release capture lockout in case it was set from before. */
167
 
                if( ioctl( fd_vme, RUNLOCK, &dummy ) )
168
 
                    msyslog(LOG_ERR, "vme_start: RUNLOCK failed %m");
 
206
        else  { 
 
207
                switch (tfp_type) {
 
208
                        case 1: break;
 
209
                        case 2: break;
 
210
                        default: 
 
211
                                /* Release capture lockout in case it was set before. */
 
212
                                if( ioctl( fd_vme, RUNLOCK, &dummy ) )
 
213
                                msyslog(LOG_ERR, "vme_start: RUNLOCK failed %m");
169
214
 
170
 
                regvalue = 0; /* More esoteric stuff to do... */
171
 
                if( ioctl( fd_vme, WCR0, &regvalue ) )
172
 
                    msyslog(LOG_ERR, "vme_start: WCR0 failed %m");
 
215
                                regvalue = 0; /* More esoteric stuff to do... */
 
216
                                if( ioctl( fd_vme, WCR0, &regvalue ) )
 
217
                                msyslog(LOG_ERR, "vme_start: WCR0 failed %m");
 
218
                                break;
 
219
                }
173
220
        }
174
221
 
175
222
        /*
222
269
        io_closeclock(&pp->io);
223
270
        pp->unitptr = NULL;
224
271
        free(vme);
 
272
        if (tfp_type == 2) bcStopPci(stfp_handle); 
225
273
}
226
274
 
227
275
 
275
323
          time(&tloc);
276
324
          tadr = gmtime(&tloc);
277
325
          tptr->year = (unsigned short)(tadr->tm_year + 1900);
278
 
        
279
326
 
280
327
        sprintf(pp->a_lastcode, 
281
328
                "%3.3d %2.2d:%2.2d:%2.2d.%.6ld %1d",
292
339
        pp->hour =   tptr->hr;
293
340
        pp->minute =  tptr->mn;
294
341
        pp->second =  tptr->sec;
295
 
        pp->usec =   tptr->frac;        
 
342
        pp->nsec =   tptr->frac;        
296
343
 
297
344
#ifdef DEBUG
298
345
        if (debug)
299
346
            printf("pp: %3d %02d:%02d:%02d.%06ld %1x\n",
300
347
                   pp->day, pp->hour, pp->minute, pp->second,
301
 
                   pp->usec, tptr->status);
 
348
                   pp->nsec, tptr->status);
302
349
#endif
303
350
        if (tptr->status ) {       /*  Status 0 is locked to ref., 1 is not */
304
351
                refclock_report(peer, CEVNT_BADREPLY);
325
372
struct vmedate *
326
373
get_datumtime(struct vmedate *time_vme)
327
374
{
328
 
        unsigned short  status;
329
375
        char cbuf[7];
330
376
        struct btfp_time vts;
 
377
        uint32_t btm[2];
 
378
        uint8_t dmy;
331
379
        
332
380
        if ( time_vme == (struct vmedate *)NULL) {
333
381
          time_vme = (struct vmedate *)malloc(sizeof(struct vmedate ));
334
382
        }
335
383
 
336
 
        if( ioctl(fd_vme, READTIME, &vts))
337
 
            msyslog(LOG_ERR, "get_datumtime error: %m");
338
 
 
339
 
        /* if you want to actually check the validity of these registers, do a 
340
 
           define of CHECK   above this.  I didn't find it necessary. - RES
341
 
        */
342
 
 
343
 
#ifdef CHECK            
344
 
 
345
 
        /* Get day */
346
 
        sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) +
347
 
                ((vts.btfp_time[ 1 ] & 0xff00) >> 8));  
348
 
 
349
 
        if (isdigit(cbuf[0]) && isdigit(cbuf[1]) && isdigit(cbuf[2]) )
350
 
            time_vme->day = (unsigned short)atoi(cbuf);
351
 
        else
352
 
            time_vme->day = (unsigned short) 0;
353
 
 
354
 
        /* Get hour */
355
 
        sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff);
356
 
 
357
 
        if (isdigit(cbuf[0]) && isdigit(cbuf[1]))
358
 
            time_vme->hr = (unsigned short)atoi(cbuf);
359
 
        else
360
 
            time_vme->hr = (unsigned short) 0;
361
 
 
362
 
        /* Get minutes */
363
 
        sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8);
364
 
        if (isdigit(cbuf[0]) && isdigit(cbuf[1]))
365
 
            time_vme->mn = (unsigned short)atoi(cbuf);
366
 
        else
367
 
            time_vme->mn = (unsigned short) 0;
368
 
 
369
 
        /* Get seconds */
370
 
        sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff);
371
 
 
372
 
        if (isdigit(cbuf[0]) && isdigit(cbuf[1]))
373
 
            time_vme->sec = (unsigned short)atoi(cbuf);
374
 
        else
375
 
            time_vme->sec = (unsigned short) 0;
376
 
 
377
 
        /* Get microseconds.  Yes, we ignore the 0.1 microsecond digit so we can
378
 
           use the TVTOTSF function  later on...*/
379
 
 
380
 
        sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ],
381
 
                vts.btfp_time[ 4 ]>>8);
382
 
 
383
 
        if (isdigit(cbuf[0]) && isdigit(cbuf[1]) && isdigit(cbuf[2])
384
 
            && isdigit(cbuf[3]) && isdigit(cbuf[4]) && isdigit(cbuf[5]))
385
 
            time_vme->frac = (u_long) atoi(cbuf);
386
 
        else
387
 
            time_vme->frac = (u_long) 0;
388
 
#else
389
 
 
390
 
        /* DONT CHECK  just trust the card */
391
 
 
392
 
        /* Get day */
393
 
        sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) +
394
 
                ((vts.btfp_time[ 1 ] & 0xff00) >> 8));  
395
 
        time_vme->day = (unsigned short)atoi(cbuf);
396
 
 
397
 
        /* Get hour */
398
 
        sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff);
399
 
 
400
 
        time_vme->hr = (unsigned short)atoi(cbuf);
401
 
 
402
 
        /* Get minutes */
403
 
        sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8);
404
 
        time_vme->mn = (unsigned short)atoi(cbuf);
405
 
 
406
 
        /* Get seconds */
407
 
        sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff);
408
 
        time_vme->sec = (unsigned short)atoi(cbuf);
409
 
 
410
 
        /* Get microseconds.  Yes, we ignore the 0.1 microsecond digit so we can
411
 
           use the TVTOTSF function  later on...*/
412
 
 
413
 
        sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ],
414
 
                vts.btfp_time[ 4 ]>>8);
415
 
 
416
 
        time_vme->frac = (u_long) atoi(cbuf);
417
 
 
418
 
#endif /* CHECK */
419
 
 
420
 
        /* Get status bit */
421
 
        status = (vts.btfp_time[0] & 0x0010) >>4;
422
 
        time_vme->status = status;  /* Status=0 if locked to ref. */
423
 
        /* Status=1 if flywheeling */
424
 
        if (status) {        /* lost lock ? */
 
384
        switch (tfp_type) {
 
385
                case 1:                         /* BSD, PCI, 2 32bit time words */
 
386
                        if (ioctl(fd_vme, READTIME, &btm)) {
 
387
                        msyslog(LOG_ERR, "get_bc63x error: %m");
 
388
                                return(NULL);
 
389
                        }
 
390
                        tvme_fill(time_vme, btm);
 
391
                        break;
 
392
 
 
393
                case 2:                         /* Linux/Windows, PCI, 2 32bit time words */
 
394
                        if (bcReadBinTime(stfp_handle, &btm[1], &btm[0], &dmy) == 0) {
 
395
                        msyslog(LOG_ERR, "get_datumtime error: %m"); 
 
396
                                return(NULL);
 
397
                        }
 
398
                        tvme_fill(time_vme, btm);
 
399
                        break;
 
400
 
 
401
                default:                        /* legacy bancomm card */
 
402
 
 
403
                        if (ioctl(fd_vme, READTIME, &vts)) {
 
404
                        msyslog(LOG_ERR, "get_datumtime error: %m");
 
405
                                return(NULL);
 
406
                        }
 
407
                        /* Get day */
 
408
                        sprintf(cbuf,"%3.3x", ((vts.btfp_time[ 0 ] & 0x000f) <<8) +
 
409
                                ((vts.btfp_time[ 1 ] & 0xff00) >> 8));  
 
410
                        time_vme->day = (unsigned short)atoi(cbuf);
 
411
 
 
412
                        /* Get hour */
 
413
                        sprintf(cbuf,"%2.2x", vts.btfp_time[ 1 ] & 0x00ff);
 
414
 
 
415
                        time_vme->hr = (unsigned short)atoi(cbuf);
 
416
 
 
417
                        /* Get minutes */
 
418
                        sprintf(cbuf,"%2.2x", (vts.btfp_time[ 2 ] & 0xff00) >>8);
 
419
                        time_vme->mn = (unsigned short)atoi(cbuf);
 
420
 
 
421
                        /* Get seconds */
 
422
                        sprintf(cbuf,"%2.2x", vts.btfp_time[ 2 ] & 0x00ff);
 
423
                        time_vme->sec = (unsigned short)atoi(cbuf);
 
424
 
 
425
                        /* Get microseconds.  Yes, we ignore the 0.1 microsecond digit so
 
426
                                 we can use the TVTOTSF function  later on...*/
 
427
 
 
428
                        sprintf(cbuf,"%4.4x%2.2x", vts.btfp_time[ 3 ],
 
429
                        vts.btfp_time[ 4 ]>>8);
 
430
 
 
431
                        time_vme->frac = (u_long) atoi(cbuf);
 
432
 
 
433
                        /* Get status bit */
 
434
                        time_vme->status = (vts.btfp_time[0] & 0x0010) >>4;
 
435
 
 
436
                        break;
 
437
        }
 
438
 
 
439
        if (time_vme->status) 
425
440
                return ((void *)NULL);
426
 
        }
427
441
        else
428
442
            return (time_vme);
429
443
}
 
444
/* Assign values to time_vme struct. Mostly for readability */
 
445
void
 
446
tvme_fill(struct vmedate *time_vme, uint32_t btm[2])
 
447
{
 
448
        struct tm maj;
 
449
        uint32_t dmaj, dmin;
 
450
 
 
451
        dmaj = btm[1];                  /* syntax sugar */
 
452
        dmin = btm[0];
 
453
 
 
454
        gmtime_r(&dmaj, &maj);
 
455
        time_vme->day  = maj.tm_yday+1;
 
456
        time_vme->hr   = maj.tm_hour;
 
457
        time_vme->mn   = maj.tm_min;
 
458
        time_vme->sec  = maj.tm_sec;
 
459
        time_vme->frac = (dmin & 0x000fffff) * 1000; 
 
460
        time_vme->frac += ((dmin & 0x00f00000) >> 20) * 100;
 
461
        time_vme->status = (dmin & 0x01000000) >> 24;
 
462
        return;
 
463
}
430
464
 
431
465
#else
432
466
int refclock_bancomm_bs;