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