From 83147351eb0bbf5f17df47c6ab3d9cd2ae91f971 Mon Sep 17 00:00:00 2001 From: markster Date: Wed, 25 May 2005 17:58:36 +0000 Subject: ztdummy fixes (bug #4301) git-svn-id: http://svn.digium.com/svn/zaptel/trunk@655 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- ztdummy.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) (limited to 'ztdummy.c') diff --git a/ztdummy.c b/ztdummy.c index 92a41d7..1631c45 100755 --- a/ztdummy.c +++ b/ztdummy.c @@ -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 struct ztdummy *ztd; 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 @@ extern uhci_t **uhci_devices; #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 @@ static void ztdummy_timer(unsigned long param) 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 @@ static int ztdummy_initialize(struct ztdummy *ztd) 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 @@ int init_module(void) } #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 @@ int init_module(void) 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 -- cgit v1.2.3