Index: ztdummy.c =================================================================== RCS file: /usr/cvsroot/zaptel/ztdummy.c,v retrieving revision 1.4.2.4 diff -u -r1.4.2.4 ztdummy.c --- ztdummy.c 21 Jan 2005 05:05:18 -0000 1.4.2.4 +++ ztdummy.c 21 May 2005 21:53:28 -0000 @@ -6,6 +6,7 @@ * Written by Robert Pleh * 2.6 version by Tony Hoyle * Unified by Mark Spencer + * Converted to use RTC on i386 by Tony Mountifield * * Copyright (C) 2002, Hermes Softlab * Copyright (C) 2004, Digium, Inc. @@ -38,6 +39,15 @@ # error "This kernel is too old: not supported by this file" #endif +/* + * NOTE: (only applies to kernel 2.6) + * If using an i386 architecture without a PC real-time clock, + * the #define USE_RTC should be commented out. + */ +#if defined(__i386__) +#define USE_RTC +#endif + #include #include #include @@ -54,6 +64,9 @@ #include #endif #ifdef LINUX26 +#ifdef USE_RTC +#include +#endif #include #endif #include "ztdummy.h" @@ -77,8 +90,10 @@ static int debug = 0; #ifdef LINUX26 +#ifndef USE_RTC /* New 2.6 kernel timer stuff */ static struct timer_list timer; +#endif #else #if LINUX_VERSION_CODE < VERSION_CODE(2,4,5) # error "This kernel is too old: not supported by this file" @@ -103,6 +118,28 @@ #ifdef LINUX26 +#ifdef USE_RTC +/* rtc_interrupt - called at 1024Hz from hook in RTC handler */ +static void rtc_interrupt(void *private_data) +{ + struct ztdummy *ztd = private_data; + unsigned int ticks; + + atomic_inc(&ztd->ticks); + ticks = atomic_read(&ztd->ticks); + if (ticks == 42 || ticks == 85) { + /* skip it */ + } else if (ticks >= 128) { + /* skip and restart count */ + atomic_set(&ztd->ticks, 0); + } else { + /* zaptel timing - called in 125 of every 128 interrupts = 1000Hz */ + zt_receive(&ztd->span); + zt_transmit(&ztd->span); + } +} +#else +/* use kernel system tick timer if PC architecture RTC is not available */ static void ztdummy_timer(unsigned long param) { zt_receive(&ztd->span); @@ -110,6 +147,7 @@ timer.expires = jiffies + 1; add_timer(&timer); } +#endif #else static void ztdummy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -150,7 +188,11 @@ int init_module(void) { -#ifndef LINUX26 +#ifdef LINUX26 +#ifdef USE_RTC + int err; +#endif +#else int irq; spinlock_t mylock = SPIN_LOCK_UNLOCKED; @@ -180,10 +222,25 @@ } #ifdef LINUX26 +#ifdef USE_RTC + atomic_set(&ztd->ticks, 0); + ztd->rtc_task.func = rtc_interrupt; + ztd->rtc_task.private_data = ztd; + err = rtc_register(&ztd->rtc_task); + if (err < 0) { + printk("ztdummy: Unable to register zaptel rtc driver\n"); + zt_unregister(&ztd->span); + kfree(ztd); + return err; + } + rtc_control(&ztd->rtc_task, RTC_IRQP_SET, 1024); /* 1024 Hz */ + rtc_control(&ztd->rtc_task, RTC_PIE_ON, 0); +#else init_timer(&timer); timer.function = ztdummy_timer; timer.expires = jiffies + 1; add_timer(&timer); +#endif #else irq=s->irq; spin_lock_irq(&mylock); @@ -214,7 +271,12 @@ void cleanup_module(void) { #ifdef LINUX26 +#ifdef USE_RTC + rtc_control(&ztd->rtc_task, RTC_PIE_OFF, 0); + rtc_unregister(&ztd->rtc_task); +#else del_timer(&timer); +#endif #else free_irq(s->irq, ztd); /* disable interrupts */ #endif Index: ztdummy.h =================================================================== RCS file: /usr/cvsroot/zaptel/ztdummy.h,v retrieving revision 1.2 diff -u -r1.2 ztdummy.h --- ztdummy.h 24 Feb 2003 06:00:31 -0000 1.2 +++ ztdummy.h 21 May 2005 21:53:28 -0000 @@ -32,9 +32,16 @@ struct ztdummy { struct zt_span span; struct zt_chan chan; +#ifdef LINUX26 +#ifdef USE_RTC + atomic_t ticks; + rtc_task_t rtc_task; +#endif +#endif }; +#ifndef LINUX26 /* Uhci definitions and structures - from file usb-uhci.h */ #define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ #define USBSTS 2 @@ -141,3 +148,4 @@ struct pci_pool *desc_pool; long last_error_time; // last error output in uhci_interrupt() } uhci_t, *puhci_t; +#endif