11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: timer.c,v 1.3.6.1 2001/09/23 22:24:59 kai Exp $ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1996 SpellCaster Telecommunications Inc. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For more information, please contact gpl-info@spellcast.com or write: 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SpellCaster Telecommunications Inc. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5621 Finch Avenue East, Unit #3 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Scarborough, Ontario Canada 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * M1B 2T9 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +1 (416) 297-8565 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +1 (416) 297-6433 Facsimile 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "includes.h" 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hardware.h" 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "message.h" 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "card.h" 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Write the proper values into the I/O ports following a reset 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 27e3ca5e762c2aca373f1762cbc622ebe20fd20869Adrian Bunkstatic void setup_ports(int card) 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]); 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* And the IRQ */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((sc_adapter[card]->interrupt | 0x80), 34475be4d85a274d0961593db41cf85689db1d583cJoe Perches sc_adapter[card]->ioport[IRQ_SELECT]); 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Timed function to check the status of a previous reset 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Must be very fast as this function runs in the context of 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * an interrupt handler. 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup the ioports for the board that were cleared by the reset. 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Then, check to see if the signate has been set. Next, set the 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * signature to a known value and issue a startproc if needed. 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 46e3aded3cc289113c7bc729ef4cb75e56d9aa71beAlexey Dobriyanvoid sc_check_reset(unsigned long data) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long sig; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int card = (unsigned int) data; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr_debug("%s: check_timer timer called\n", 53475be4d85a274d0961593db41cf85689db1d583cJoe Perches sc_adapter[card]->devicename); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup the io ports */ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup_ports(card); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&sc_adapter[card]->lock, flags); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport], 60475be4d85a274d0961593db41cf85689db1d583cJoe Perches (sc_adapter[card]->shmem_magic >> 14) | 0x80); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sig = (unsigned long) *((unsigned long *)(sc_adapter[card]->rambase + SIG_OFFSET)); 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check the signature */ 64475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (sig == SIGNATURE) { 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flushreadfifo(card); 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* See if we need to do a startproc */ 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sc_adapter[card]->StartOnReset) 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds startproc(card); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 713879b6b6a8ee39b50559b2c2dd083c557d39e0f8Andrew Morton pr_debug("%s: No signature yet, waiting another %lu jiffies.\n", 72475be4d85a274d0961593db41cf85689db1d583cJoe Perches sc_adapter[card]->devicename, CHECKRESET_TIME); 73475be4d85a274d0961593db41cf85689db1d583cJoe Perches mod_timer(&sc_adapter[card]->reset_timer, jiffies + CHECKRESET_TIME); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Timed function to check the status of a previous reset 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Must be very fast as this function runs in the context of 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * an interrupt handler. 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send check sc_adapter->phystat to see if the channels are up 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If they are, tell ISDN4Linux that the board is up. If not, 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tell IADN4Linux that it is up. Always reset the timer to 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * fire again (endless loop). 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid check_phystat(unsigned long data) 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int card = (unsigned int) data; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr_debug("%s: Checking status...\n", sc_adapter[card]->devicename); 94475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * check the results of the last PhyStat and change only if 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * has changed drastically 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sc_adapter[card]->nphystat && !sc_adapter[card]->phystat) { /* All is well */ 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr_debug("PhyStat transition to RUN\n"); 100475be4d85a274d0961593db41cf85689db1d583cJoe Perches pr_info("%s: Switch contacted, transmitter enabled\n", 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sc_adapter[card]->devicename); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds indicate_status(card, ISDN_STAT_RUN, 0, NULL); 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (!sc_adapter[card]->nphystat && sc_adapter[card]->phystat) { /* All is not well */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr_debug("PhyStat transition to STOP\n"); 106475be4d85a274d0961593db41cf85689db1d583cJoe Perches pr_info("%s: Switch connection lost, transmitter disabled\n", 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sc_adapter[card]->devicename); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds indicate_status(card, ISDN_STAT_STOP, 0, NULL); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sc_adapter[card]->phystat = sc_adapter[card]->nphystat; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reinitialize the timer */ 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&sc_adapter[card]->lock, flags); 116475be4d85a274d0961593db41cf85689db1d583cJoe Perches mod_timer(&sc_adapter[card]->stat_timer, jiffies + CHECKSTAT_TIME); 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Send a new cePhyStatus message */ 120475be4d85a274d0961593db41cf85689db1d583cJoe Perches sendmessage(card, CEPID, ceReqTypePhy, ceReqClass2, 121475be4d85a274d0961593db41cf85689db1d583cJoe Perches ceReqPhyStatus, 0, 0, NULL); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 123