11b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil/* 21b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * 31b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * Author Karsten Keil <kkeil@novell.com> 41b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * 51b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * Copyright 2008 by Karsten Keil <kkeil@novell.com> 61b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * 71b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * This program is free software; you can redistribute it and/or modify 81b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * it under the terms of the GNU General Public License version 2 as 91b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * published by the Free Software Foundation. 101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * 111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * This program is distributed in the hope that it will be useful, 121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * but WITHOUT ANY WARRANTY; without even the implied warranty of 131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * GNU General Public License for more details. 151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil * 161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil */ 171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 195a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil#include <linux/module.h> 211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil#include <linux/mISDNhw.h> 225b8343540a3d27f87a4d9d72bb39b7d4cc3dd95eHannes Eder#include "core.h" 231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil#include "layer1.h" 241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil#include "fsm.h" 251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 26dfa96ec1bb83641242c48883c2bae8f1f30483b2Hannes Ederstatic u_int *debug; 271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstruct layer1 { 29475be4d85a274d0961593db41cf85689db1d583cJoe Perches u_long Flags; 30475be4d85a274d0961593db41cf85689db1d583cJoe Perches struct FsmInst l1m; 311ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil struct FsmTimer timer3; 321ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil struct FsmTimer timerX; 33475be4d85a274d0961593db41cf85689db1d583cJoe Perches int delay; 34c626c127279b265ab293348763e043864d58d42cKarsten Keil int t3_value; 35475be4d85a274d0961593db41cf85689db1d583cJoe Perches struct dchannel *dch; 36475be4d85a274d0961593db41cf85689db1d583cJoe Perches dchannel_l1callback *dcb; 371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 381b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 39c626c127279b265ab293348763e043864d58d42cKarsten Keil#define TIMER3_DEFAULT_VALUE 7000 401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic 421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstruct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilenum { 451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F2, 461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F3, 471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F4, 481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F5, 491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F6, 501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F7, 511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F8, 521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 54475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define L1S_STATE_COUNT (ST_L1_F8 + 1) 551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic char *strL1SState[] = 571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F2", 591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F3", 601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F4", 611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F5", 621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F6", 631b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F7", 641b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F8", 651b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 661b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 671b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilenum { 681b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_PH_ACTIVATE, 691b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_PH_DEACTIVATE, 701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_RESET_IND, 711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_DEACT_CNF, 721b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_DEACT_IND, 731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_POWER_UP, 741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_ANYSIG_IND, 751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_INFO2_IND, 761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_INFO4_IND, 771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_TIMER_DEACT, 781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_TIMER_ACT, 791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_TIMER3, 801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil#define L1_EVENT_COUNT (EV_TIMER3 + 1) 831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic char *strL1Event[] = 851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_PH_ACTIVATE", 871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_PH_DEACTIVATE", 881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_RESET_IND", 891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_DEACT_CNF", 901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_DEACT_IND", 911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_POWER_UP", 921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_ANYSIG_IND", 931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_INFO2_IND", 941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_INFO4_IND", 951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_TIMER_DEACT", 961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_TIMER_ACT", 971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_TIMER3", 981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1m_debug(struct FsmInst *fi, char *fmt, ...) 1021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1031b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 104020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches struct va_format vaf; 1051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil va_list va; 1061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1071b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil va_start(va, fmt); 108020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches 109020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches vaf.fmt = fmt; 110020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches vaf.va = &va; 111020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches 112020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); 113020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches 1141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil va_end(va); 1151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_reset(struct FsmInst *fi, int event, void *arg) 1191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_deact_cnf(struct FsmInst *fi, int event, void *arg) 1251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1261b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1291b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) 1301b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 1311b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1321b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1331b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1341b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_deact_req_s(struct FsmInst *fi, int event, void *arg) 1351b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1381b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1391ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2); 1401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 1411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_power_up_s(struct FsmInst *fi, int event, void *arg) 1451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F4); 1501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } else 1521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_go_F5(struct FsmInst *fi, int event, void *arg) 1571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F5); 1591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_go_F8(struct FsmInst *fi, int event, void *arg) 1631b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1641b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F8); 1651b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1661b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1671b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1681b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_info2_ind(struct FsmInst *fi, int event, void *arg) 1691b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1721b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F6); 1731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_info4_ind(struct FsmInst *fi, int event, void *arg) 1781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F7); 1821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 1841ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmDelTimer(&l1->timerX, 4); 1851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 1861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 1871ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmDelTimer(&l1->timer3, 3); 1881ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2); 1891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 1901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 1911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_timer3(struct FsmInst *fi, int event, void *arg) 1951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); 1991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 2001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2031b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 2041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (l1->l1m.state != ST_L1_F6) { 2051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 2061ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil /* do not force anything here, we need send INFO 0 */ 2071b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 2081b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2091b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_timer_act(struct FsmInst *fi, int event, void *arg) 2121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); 2161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); 2171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 2181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_timer_deact(struct FsmInst *fi, int event, void *arg) 2221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); 2261b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); 2271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2291b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2301b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_DEACT_REQ); 2311b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2321b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2331b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2341b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_activate_s(struct FsmInst *fi, int event, void *arg) 2351b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2381ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2); 2391b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); 2401ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil /* Tell HW to send INFO 1 */ 2411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_RESET_REQ); 2421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_activate_no(struct FsmInst *fi, int event, void *arg) 2461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && 2501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { 2511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); 2521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 2561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic struct FsmNode L1SFnList[] = 2591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, 2611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, 2621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, 2631b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_RESET_IND, l1_reset}, 2641b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_RESET_IND, l1_reset}, 2651b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_RESET_IND, l1_reset}, 2661b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_RESET_IND, l1_reset}, 2671b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_RESET_IND, l1_reset}, 2681b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_RESET_IND, l1_reset}, 2691b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, 2701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, 2711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, 2721b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, 2731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, 2741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, 2751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, 2761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, 2771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, 2781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, 2791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, 2801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, 2811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, 2821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, 2831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, 2841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, 2851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, 2861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, 2871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, 2881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, 2891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, 2901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, 2911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, 2921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_TIMER3, l1_timer3}, 2931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_TIMER3, l1_timer3}, 2941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_TIMER3, l1_timer3}, 2951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_TIMER3, l1_timer3}, 2961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_TIMER3, l1_timer3}, 2971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, 2981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, 2991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, 3001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, 3011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, 3021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, 3031b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 3041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 3051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 3071b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilrelease_l1(struct layer1 *l1) { 3081ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmDelTimer(&l1->timerX, 0); 3091ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmDelTimer(&l1->timer3, 0); 3101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (l1->dch) 3111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dch->l1 = NULL; 3121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil module_put(THIS_MODULE); 3131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil kfree(l1); 3141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 3151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilint 3171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_event(struct layer1 *l1, u_int event) 3181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 3191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil int err = 0; 3201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (!l1) 3221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return -EINVAL; 3231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil switch (event) { 3241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_RESET_IND: 3251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); 3261b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_DEACT_IND: 3281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); 3291b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3301b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_POWERUP_IND: 3311b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); 3321b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3331b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_DEACT_CNF: 3341b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); 3351b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case ANYSIGNAL: 3371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3381b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3391b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case LOSTFRAMING: 3401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case INFO2: 3431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); 3441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case INFO4_P8: 3461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case INFO4_P10: 3491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case PH_ACTIVATE_REQ: 3521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) 3531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 3541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil else { 3551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); 3561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); 3571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 3581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case CLOSE_CHANNEL: 3601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil release_l1(l1); 3611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil default: 363c626c127279b265ab293348763e043864d58d42cKarsten Keil if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { 364c626c127279b265ab293348763e043864d58d42cKarsten Keil int val = event & HW_TIMER3_VMASK; 365c626c127279b265ab293348763e043864d58d42cKarsten Keil 366c626c127279b265ab293348763e043864d58d42cKarsten Keil if (val < 5) 367c626c127279b265ab293348763e043864d58d42cKarsten Keil val = 5; 368c626c127279b265ab293348763e043864d58d42cKarsten Keil if (val > 30) 369c626c127279b265ab293348763e043864d58d42cKarsten Keil val = 30; 370c626c127279b265ab293348763e043864d58d42cKarsten Keil l1->t3_value = val; 371c626c127279b265ab293348763e043864d58d42cKarsten Keil break; 372c626c127279b265ab293348763e043864d58d42cKarsten Keil } 3731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (*debug & DEBUG_L1) 3741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil printk(KERN_DEBUG "%s %x unhandled\n", 375475be4d85a274d0961593db41cf85689db1d583cJoe Perches __func__, event); 3761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil err = -EINVAL; 3771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 3781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return err; 3791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 3801b2b03f8e514e4f68e293846ba511a948b80243cKarsten KeilEXPORT_SYMBOL(l1_event); 3811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilint 3831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilcreate_l1(struct dchannel *dch, dchannel_l1callback *dcb) { 3841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *nl1; 3851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); 3871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (!nl1) { 3881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil printk(KERN_ERR "kmalloc struct layer1 failed\n"); 3891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return -ENOMEM; 3901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 3911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.fsm = &l1fsm_s; 3921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.state = ST_L1_F3; 3931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->Flags = 0; 394c626c127279b265ab293348763e043864d58d42cKarsten Keil nl1->t3_value = TIMER3_DEFAULT_VALUE; 3951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.debug = *debug & DEBUG_L1_FSM; 3961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.userdata = nl1; 3971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.userint = 0; 3981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.printdebug = l1m_debug; 3991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->dch = dch; 4001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->dcb = dcb; 4011ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3); 4021ea52fbda1629216182a0b0fbee9d65e8bcedd1eKarsten Keil mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX); 4031b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil __module_get(THIS_MODULE); 4041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil dch->l1 = nl1; 4051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return 0; 4061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 4071b2b03f8e514e4f68e293846ba511a948b80243cKarsten KeilEXPORT_SYMBOL(create_l1); 4081b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 4091b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilint 4101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_init(u_int *deb) 4111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 4121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil debug = deb; 4131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.state_count = L1S_STATE_COUNT; 4141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.event_count = L1_EVENT_COUNT; 4151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.strEvent = strL1Event; 4161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.strState = strL1SState; 4171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); 4181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return 0; 4191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 4201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 4211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilvoid 4221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_cleanup(void) 4231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 4241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmFree(&l1fsm_s); 4251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 426