1/* $Id: timer.c,v 1.3.6.1 2001/09/23 22:24:59 kai 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#include "includes.h" 19#include "hardware.h" 20#include "message.h" 21#include "card.h" 22 23 24/* 25 * Write the proper values into the I/O ports following a reset 26 */ 27static void setup_ports(int card) 28{ 29 30 outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]); 31 32 /* And the IRQ */ 33 outb((sc_adapter[card]->interrupt | 0x80), 34 sc_adapter[card]->ioport[IRQ_SELECT]); 35} 36 37/* 38 * Timed function to check the status of a previous reset 39 * Must be very fast as this function runs in the context of 40 * an interrupt handler. 41 * 42 * Setup the ioports for the board that were cleared by the reset. 43 * Then, check to see if the signate has been set. Next, set the 44 * signature to a known value and issue a startproc if needed. 45 */ 46void sc_check_reset(unsigned long data) 47{ 48 unsigned long flags; 49 unsigned long sig; 50 int card = (unsigned int) data; 51 52 pr_debug("%s: check_timer timer called\n", 53 sc_adapter[card]->devicename); 54 55 /* Setup the io ports */ 56 setup_ports(card); 57 58 spin_lock_irqsave(&sc_adapter[card]->lock, flags); 59 outb(sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport], 60 (sc_adapter[card]->shmem_magic >> 14) | 0x80); 61 sig = (unsigned long) *((unsigned long *)(sc_adapter[card]->rambase + SIG_OFFSET)); 62 63 /* check the signature */ 64 if (sig == SIGNATURE) { 65 flushreadfifo(card); 66 spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); 67 /* See if we need to do a startproc */ 68 if (sc_adapter[card]->StartOnReset) 69 startproc(card); 70 } else { 71 pr_debug("%s: No signature yet, waiting another %lu jiffies.\n", 72 sc_adapter[card]->devicename, CHECKRESET_TIME); 73 mod_timer(&sc_adapter[card]->reset_timer, jiffies + CHECKRESET_TIME); 74 spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); 75 } 76} 77 78/* 79 * Timed function to check the status of a previous reset 80 * Must be very fast as this function runs in the context of 81 * an interrupt handler. 82 * 83 * Send check sc_adapter->phystat to see if the channels are up 84 * If they are, tell ISDN4Linux that the board is up. If not, 85 * tell IADN4Linux that it is up. Always reset the timer to 86 * fire again (endless loop). 87 */ 88void check_phystat(unsigned long data) 89{ 90 unsigned long flags; 91 int card = (unsigned int) data; 92 93 pr_debug("%s: Checking status...\n", sc_adapter[card]->devicename); 94 /* 95 * check the results of the last PhyStat and change only if 96 * has changed drastically 97 */ 98 if (sc_adapter[card]->nphystat && !sc_adapter[card]->phystat) { /* All is well */ 99 pr_debug("PhyStat transition to RUN\n"); 100 pr_info("%s: Switch contacted, transmitter enabled\n", 101 sc_adapter[card]->devicename); 102 indicate_status(card, ISDN_STAT_RUN, 0, NULL); 103 } 104 else if (!sc_adapter[card]->nphystat && sc_adapter[card]->phystat) { /* All is not well */ 105 pr_debug("PhyStat transition to STOP\n"); 106 pr_info("%s: Switch connection lost, transmitter disabled\n", 107 sc_adapter[card]->devicename); 108 109 indicate_status(card, ISDN_STAT_STOP, 0, NULL); 110 } 111 112 sc_adapter[card]->phystat = sc_adapter[card]->nphystat; 113 114 /* Reinitialize the timer */ 115 spin_lock_irqsave(&sc_adapter[card]->lock, flags); 116 mod_timer(&sc_adapter[card]->stat_timer, jiffies + CHECKSTAT_TIME); 117 spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); 118 119 /* Send a new cePhyStatus message */ 120 sendmessage(card, CEPID, ceReqTypePhy, ceReqClass2, 121 ceReqPhyStatus, 0, 0, NULL); 122} 123