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 17 May 2005 07:56:37 -0000 @@ -6,6 +6,7 @@ * Written by Robert Pleh * 2.6 version by Tony Hoyle * Unified by Mark Spencer + * Converted to use RTC by Tony Mountifield * * Copyright (C) 2002, Hermes Softlab * Copyright (C) 2004, Digium, Inc. @@ -54,6 +55,7 @@ #include #endif #ifdef LINUX26 +#include #include #endif #include "ztdummy.h" @@ -76,10 +78,7 @@ static int debug = 0; -#ifdef LINUX26 -/* New 2.6 kernel timer stuff */ -static struct timer_list timer; -#else +#ifndef LINUX26 #if LINUX_VERSION_CODE < VERSION_CODE(2,4,5) # error "This kernel is too old: not supported by this file" #endif @@ -103,12 +102,24 @@ #ifdef LINUX26 -static void ztdummy_timer(unsigned long param) +/* rtc_interrupt - called at 1024Hz from hook in RTC handler */ +static void rtc_interrupt(void *private_data) { - zt_receive(&ztd->span); - zt_transmit(&ztd->span); - timer.expires = jiffies + 1; - add_timer(&timer); + 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 static void ztdummy_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -150,7 +161,9 @@ int init_module(void) { -#ifndef LINUX26 +#ifdef LINUX26 + int err; +#else int irq; spinlock_t mylock = SPIN_LOCK_UNLOCKED; @@ -180,10 +193,18 @@ } #ifdef LINUX26 - init_timer(&timer); - timer.function = ztdummy_timer; - timer.expires = jiffies + 1; - add_timer(&timer); + 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 irq=s->irq; spin_lock_irq(&mylock); @@ -214,7 +235,8 @@ void cleanup_module(void) { #ifdef LINUX26 - del_timer(&timer); + rtc_control(&ztd->rtc_task, RTC_PIE_OFF, 0); + rtc_unregister(&ztd->rtc_task); #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 17 May 2005 07:56:37 -0000 @@ -32,9 +32,14 @@ struct ztdummy { struct zt_span span; struct zt_chan chan; +#ifdef LINUX26 + atomic_t ticks; + rtc_task_t rtc_task; +#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 +146,4 @@ struct pci_pool *desc_pool; long last_error_time; // last error output in uhci_interrupt() } uhci_t, *puhci_t; +#endif