1/* $Id: timer.c,v 1.1.1.1 2008/10/15 03:26:34 james26_jang Exp $ 2 * 3 * Copyright (C) 1996 SpellCaster Telecommunications Inc. 4 * 5 * This software may be used and distributed according to the terms 6 * of the GNU General Public License, incorporated herein by reference. 7 * 8 * For more information, please contact gpl-info@spellcast.com or write: 9 * 10 * SpellCaster Telecommunications Inc. 11 * 5621 Finch Avenue East, Unit #3 12 * Scarborough, Ontario Canada 13 * M1B 2T9 14 * +1 (416) 297-8565 15 * +1 (416) 297-6433 Facsimile 16 */ 17 18#define __NO_VERSION__ 19#include "includes.h" 20#include "hardware.h" 21#include "message.h" 22#include "card.h" 23 24extern board *adapter[]; 25 26extern void flushreadfifo(int); 27extern int startproc(int); 28extern int indicate_status(int, int, unsigned long, char *); 29extern int sendmessage(int, unsigned int, unsigned int, unsigned int, 30 unsigned int, unsigned int, unsigned int, unsigned int *); 31 32 33/* 34 * Write the proper values into the I/O ports following a reset 35 */ 36void setup_ports(int card) 37{ 38 39 outb((adapter[card]->rambase >> 12), adapter[card]->ioport[EXP_BASE]); 40 41 /* And the IRQ */ 42 outb((adapter[card]->interrupt | 0x80), 43 adapter[card]->ioport[IRQ_SELECT]); 44} 45 46/* 47 * Timed function to check the status of a previous reset 48 * Must be very fast as this function runs in the context of 49 * an interrupt handler. 50 * 51 * Setup the ioports for the board that were cleared by the reset. 52 * Then, check to see if the signate has been set. Next, set the 53 * signature to a known value and issue a startproc if needed. 54 */ 55void check_reset(unsigned long data) 56{ 57 unsigned long flags; 58 unsigned long sig; 59 int card = (unsigned int) data; 60 61 pr_debug("%s: check_timer timer called\n", adapter[card]->devicename); 62 63 /* Setup the io ports */ 64 setup_ports(card); 65 66 save_flags(flags); 67 cli(); 68 outb(adapter[card]->ioport[adapter[card]->shmem_pgport], 69 (adapter[card]->shmem_magic>>14) | 0x80); 70 sig = (unsigned long) *((unsigned long *)(adapter[card]->rambase + SIG_OFFSET)); 71 72 /* check the signature */ 73 if(sig == SIGNATURE) { 74 flushreadfifo(card); 75 restore_flags(flags); 76 /* See if we need to do a startproc */ 77 if (adapter[card]->StartOnReset) 78 startproc(card); 79 } 80 else { 81 pr_debug("%s: No signature yet, waiting another %d jiffies.\n", 82 adapter[card]->devicename, CHECKRESET_TIME); 83 mod_timer(&adapter[card]->reset_timer, jiffies+CHECKRESET_TIME); 84 } 85 restore_flags(flags); 86 87} 88 89/* 90 * Timed function to check the status of a previous reset 91 * Must be very fast as this function runs in the context of 92 * an interrupt handler. 93 * 94 * Send check adapter->phystat to see if the channels are up 95 * If they are, tell ISDN4Linux that the board is up. If not, 96 * tell IADN4Linux that it is up. Always reset the timer to 97 * fire again (endless loop). 98 */ 99void check_phystat(unsigned long data) 100{ 101 unsigned long flags; 102 int card = (unsigned int) data; 103 104 pr_debug("%s: Checking status...\n", adapter[card]->devicename); 105 /* 106 * check the results of the last PhyStat and change only if 107 * has changed drastically 108 */ 109 if (adapter[card]->nphystat && !adapter[card]->phystat) { /* All is well */ 110 pr_debug("PhyStat transition to RUN\n"); 111 pr_info("%s: Switch contacted, transmitter enabled\n", 112 adapter[card]->devicename); 113 indicate_status(card, ISDN_STAT_RUN, 0, NULL); 114 } 115 else if (!adapter[card]->nphystat && adapter[card]->phystat) { /* All is not well */ 116 pr_debug("PhyStat transition to STOP\n"); 117 pr_info("%s: Switch connection lost, transmitter disabled\n", 118 adapter[card]->devicename); 119 120 indicate_status(card, ISDN_STAT_STOP, 0, NULL); 121 } 122 123 adapter[card]->phystat = adapter[card]->nphystat; 124 125 /* Reinitialize the timer */ 126 save_flags(flags); 127 cli(); 128 mod_timer(&adapter[card]->stat_timer, jiffies+CHECKSTAT_TIME); 129 restore_flags(flags); 130 131 /* Send a new cePhyStatus message */ 132 sendmessage(card, CEPID,ceReqTypePhy,ceReqClass2, 133 ceReqPhyStatus,0,0,NULL); 134} 135 136/* 137 * When in trace mode, this callback is used to swap the working shared 138 * RAM page to the trace page(s) and process all received messages. It 139 * must be called often enough to get all of the messages out of RAM before 140 * it loops around. 141 * Trace messages are \n terminated strings. 142 * We output the messages in 64 byte chunks through readstat. Each chunk 143 * is scanned for a \n followed by a time stamp. If the timerstamp is older 144 * than the current time, scanning stops and the page and offset are recorded 145 * as the starting point the next time the trace timer is called. The final 146 * step is to restore the working page and reset the timer. 147 */ 148void trace_timer(unsigned long data) 149{ 150 unsigned long flags; 151 152 /* 153 * Disable interrupts and swap the first page 154 */ 155 save_flags(flags); 156 cli(); 157} 158