layer1.c revision c626c127279b265ab293348763e043864d58d42c
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; 31475be4d85a274d0961593db41cf85689db1d583cJoe Perches struct FsmTimer timer; 32475be4d85a274d0961593db41cf85689db1d583cJoe Perches int delay; 33c626c127279b265ab293348763e043864d58d42cKarsten Keil int t3_value; 34475be4d85a274d0961593db41cf85689db1d583cJoe Perches struct dchannel *dch; 35475be4d85a274d0961593db41cf85689db1d583cJoe Perches dchannel_l1callback *dcb; 361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 38c626c127279b265ab293348763e043864d58d42cKarsten Keil#define TIMER3_DEFAULT_VALUE 7000 391b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic 411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstruct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilenum { 441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F2, 451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F3, 461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F4, 471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F5, 481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F6, 491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F7, 501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil ST_L1_F8, 511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 53475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define L1S_STATE_COUNT (ST_L1_F8 + 1) 541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic char *strL1SState[] = 561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F2", 581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F3", 591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F4", 601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F5", 611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F6", 621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F7", 631b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "ST_L1_F8", 641b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 651b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 661b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilenum { 671b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_PH_ACTIVATE, 681b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_PH_DEACTIVATE, 691b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_RESET_IND, 701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_DEACT_CNF, 711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_DEACT_IND, 721b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_POWER_UP, 731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_ANYSIG_IND, 741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_INFO2_IND, 751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_INFO4_IND, 761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_TIMER_DEACT, 771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_TIMER_ACT, 781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil EV_TIMER3, 791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil#define L1_EVENT_COUNT (EV_TIMER3 + 1) 821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic char *strL1Event[] = 841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_PH_ACTIVATE", 861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_PH_DEACTIVATE", 871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_RESET_IND", 881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_DEACT_CNF", 891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_DEACT_IND", 901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_POWER_UP", 911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_ANYSIG_IND", 921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_INFO2_IND", 931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_INFO4_IND", 941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_TIMER_DEACT", 951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_TIMER_ACT", 961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil "EV_TIMER3", 971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1m_debug(struct FsmInst *fi, char *fmt, ...) 1011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 103020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches struct va_format vaf; 1041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil va_list va; 1051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil va_start(va, fmt); 107020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches 108020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches vaf.fmt = fmt; 109020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches vaf.va = &va; 110020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches 111020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); 112020f01ebd04f3429c32586d90598c9f59e54ca7dJoe Perches 1131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil va_end(va); 1141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_reset(struct FsmInst *fi, int event, void *arg) 1181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_deact_cnf(struct FsmInst *fi, int event, void *arg) 1241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1261b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) 1291b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 1301b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1311b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1321b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1331b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_deact_req_s(struct FsmInst *fi, int event, void *arg) 1341b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1351b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1381b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2); 1391b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 1401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_power_up_s(struct FsmInst *fi, int event, void *arg) 1441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F4); 1491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } else 1511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_go_F5(struct FsmInst *fi, int event, void *arg) 1561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F5); 1581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_go_F8(struct FsmInst *fi, int event, void *arg) 1621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1631b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F8); 1641b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1651b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1661b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1671b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_info2_ind(struct FsmInst *fi, int event, void *arg) 1681b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1691b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F6); 1721b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_info4_ind(struct FsmInst *fi, int event, void *arg) 1771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F7); 1811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 1831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmDelTimer(&l1->timer, 4); 1841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 1851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 1861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmDelTimer(&l1->timer, 3); 1871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2); 1881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 1891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 1901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 1911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 1931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_timer3(struct FsmInst *fi, int event, void *arg) 1941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 1951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 1961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 1971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); 1981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 2031b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (l1->l1m.state != ST_L1_F6) { 2041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 2051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 2061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 2071b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2081b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2091b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_timer_act(struct FsmInst *fi, int event, void *arg) 2111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); 2151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); 2161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 2171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_timer_deact(struct FsmInst *fi, int event, void *arg) 2211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); 2251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); 2261b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2291b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_DEACT_REQ); 2301b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2311b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2321b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2331b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_activate_s(struct FsmInst *fi, int event, void *arg) 2341b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2351b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 237c626c127279b265ab293348763e043864d58d42cKarsten Keil mISDN_FsmRestartTimer(&l1->timer, l1->t3_value, EV_TIMER3, NULL, 2); 2381b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); 2391b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_RESET_REQ); 2401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 2431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_activate_no(struct FsmInst *fi, int event, void *arg) 2441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *l1 = fi->userdata; 2461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && 2481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { 2491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); 2501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 2541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 2551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 2561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic struct FsmNode L1SFnList[] = 2571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 2581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, 2591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, 2601b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, 2611b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_RESET_IND, l1_reset}, 2621b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_RESET_IND, l1_reset}, 2631b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_RESET_IND, l1_reset}, 2641b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_RESET_IND, l1_reset}, 2651b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_RESET_IND, l1_reset}, 2661b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_RESET_IND, l1_reset}, 2671b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, 2681b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, 2691b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, 2701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, 2711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, 2721b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, 2731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, 2741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, 2751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, 2761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, 2771b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, 2781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, 2791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, 2801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, 2811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, 2821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, 2831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, 2841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, 2851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, 2861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, 2871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, 2881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, 2891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, 2901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_TIMER3, l1_timer3}, 2911b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_TIMER3, l1_timer3}, 2921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_TIMER3, l1_timer3}, 2931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_TIMER3, l1_timer3}, 2941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_TIMER3, l1_timer3}, 2951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, 2961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, 2971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, 2981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, 2991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, 3001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, 3011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 3021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil}; 3031b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilstatic void 3051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilrelease_l1(struct layer1 *l1) { 3061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmDelTimer(&l1->timer, 0); 3071b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (l1->dch) 3081b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dch->l1 = NULL; 3091b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil module_put(THIS_MODULE); 3101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil kfree(l1); 3111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 3121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilint 3141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_event(struct layer1 *l1, u_int event) 3151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 3161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil int err = 0; 3171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (!l1) 3191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return -EINVAL; 3201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil switch (event) { 3211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_RESET_IND: 3221b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); 3231b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3241b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_DEACT_IND: 3251b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); 3261b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3271b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_POWERUP_IND: 3281b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); 3291b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3301b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case HW_DEACT_CNF: 3311b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); 3321b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3331b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case ANYSIGNAL: 3341b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3351b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3361b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case LOSTFRAMING: 3371b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3381b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3391b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case INFO2: 3401b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); 3411b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3421b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case INFO4_P8: 3431b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3441b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3451b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case INFO4_P10: 3461b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3471b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3481b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case PH_ACTIVATE_REQ: 3491b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) 3501b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 3511b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil else { 3521b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); 3531b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); 3541b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 3551b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3561b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil case CLOSE_CHANNEL: 3571b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil release_l1(l1); 3581b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil break; 3591b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil default: 360c626c127279b265ab293348763e043864d58d42cKarsten Keil if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { 361c626c127279b265ab293348763e043864d58d42cKarsten Keil int val = event & HW_TIMER3_VMASK; 362c626c127279b265ab293348763e043864d58d42cKarsten Keil 363c626c127279b265ab293348763e043864d58d42cKarsten Keil if (val < 5) 364c626c127279b265ab293348763e043864d58d42cKarsten Keil val = 5; 365c626c127279b265ab293348763e043864d58d42cKarsten Keil if (val > 30) 366c626c127279b265ab293348763e043864d58d42cKarsten Keil val = 30; 367c626c127279b265ab293348763e043864d58d42cKarsten Keil l1->t3_value = val; 368c626c127279b265ab293348763e043864d58d42cKarsten Keil break; 369c626c127279b265ab293348763e043864d58d42cKarsten Keil } 3701b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (*debug & DEBUG_L1) 3711b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil printk(KERN_DEBUG "%s %x unhandled\n", 372475be4d85a274d0961593db41cf85689db1d583cJoe Perches __func__, event); 3731b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil err = -EINVAL; 3741b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 3751b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return err; 3761b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 3771b2b03f8e514e4f68e293846ba511a948b80243cKarsten KeilEXPORT_SYMBOL(l1_event); 3781b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3791b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilint 3801b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilcreate_l1(struct dchannel *dch, dchannel_l1callback *dcb) { 3811b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil struct layer1 *nl1; 3821b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 3831b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); 3841b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil if (!nl1) { 3851b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil printk(KERN_ERR "kmalloc struct layer1 failed\n"); 3861b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return -ENOMEM; 3871b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil } 3881b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.fsm = &l1fsm_s; 3891b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.state = ST_L1_F3; 3901b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->Flags = 0; 391c626c127279b265ab293348763e043864d58d42cKarsten Keil nl1->t3_value = TIMER3_DEFAULT_VALUE; 3921b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.debug = *debug & DEBUG_L1_FSM; 3931b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.userdata = nl1; 3941b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.userint = 0; 3951b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->l1m.printdebug = l1m_debug; 3961b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->dch = dch; 3971b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil nl1->dcb = dcb; 3981b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); 3991b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil __module_get(THIS_MODULE); 4001b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil dch->l1 = nl1; 4011b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return 0; 4021b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 4031b2b03f8e514e4f68e293846ba511a948b80243cKarsten KeilEXPORT_SYMBOL(create_l1); 4041b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 4051b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilint 4061b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_init(u_int *deb) 4071b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 4081b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil debug = deb; 4091b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.state_count = L1S_STATE_COUNT; 4101b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.event_count = L1_EVENT_COUNT; 4111b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.strEvent = strL1Event; 4121b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil l1fsm_s.strState = strL1SState; 4131b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); 4141b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil return 0; 4151b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 4161b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil 4171b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keilvoid 4181b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keill1_cleanup(void) 4191b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil{ 4201b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil mISDN_FsmFree(&l1fsm_s); 4211b2b03f8e514e4f68e293846ba511a948b80243cKarsten Keil} 422