11b2b03f8SKarsten Keil /* 21b2b03f8SKarsten Keil * 31b2b03f8SKarsten Keil * Author Karsten Keil <kkeil@novell.com> 41b2b03f8SKarsten Keil * 51b2b03f8SKarsten Keil * Copyright 2008 by Karsten Keil <kkeil@novell.com> 61b2b03f8SKarsten Keil * 71b2b03f8SKarsten Keil * This program is free software; you can redistribute it and/or modify 81b2b03f8SKarsten Keil * it under the terms of the GNU General Public License version 2 as 91b2b03f8SKarsten Keil * published by the Free Software Foundation. 101b2b03f8SKarsten Keil * 111b2b03f8SKarsten Keil * This program is distributed in the hope that it will be useful, 121b2b03f8SKarsten Keil * but WITHOUT ANY WARRANTY; without even the implied warranty of 131b2b03f8SKarsten Keil * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141b2b03f8SKarsten Keil * GNU General Public License for more details. 151b2b03f8SKarsten Keil * 161b2b03f8SKarsten Keil */ 171b2b03f8SKarsten Keil 181b2b03f8SKarsten Keil 191b2b03f8SKarsten Keil #include <linux/module.h> 201b2b03f8SKarsten Keil #include <linux/mISDNhw.h> 215b834354SHannes Eder #include "core.h" 221b2b03f8SKarsten Keil #include "layer1.h" 231b2b03f8SKarsten Keil #include "fsm.h" 241b2b03f8SKarsten Keil 25dfa96ec1SHannes Eder static u_int *debug; 261b2b03f8SKarsten Keil 271b2b03f8SKarsten Keil struct layer1 { 281b2b03f8SKarsten Keil u_long Flags; 291b2b03f8SKarsten Keil struct FsmInst l1m; 301b2b03f8SKarsten Keil struct FsmTimer timer; 311b2b03f8SKarsten Keil int delay; 321b2b03f8SKarsten Keil struct dchannel *dch; 331b2b03f8SKarsten Keil dchannel_l1callback *dcb; 341b2b03f8SKarsten Keil }; 351b2b03f8SKarsten Keil 361b2b03f8SKarsten Keil #define TIMER3_VALUE 7000 371b2b03f8SKarsten Keil 381b2b03f8SKarsten Keil static 391b2b03f8SKarsten Keil struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 401b2b03f8SKarsten Keil 411b2b03f8SKarsten Keil enum { 421b2b03f8SKarsten Keil ST_L1_F2, 431b2b03f8SKarsten Keil ST_L1_F3, 441b2b03f8SKarsten Keil ST_L1_F4, 451b2b03f8SKarsten Keil ST_L1_F5, 461b2b03f8SKarsten Keil ST_L1_F6, 471b2b03f8SKarsten Keil ST_L1_F7, 481b2b03f8SKarsten Keil ST_L1_F8, 491b2b03f8SKarsten Keil }; 501b2b03f8SKarsten Keil 511b2b03f8SKarsten Keil #define L1S_STATE_COUNT (ST_L1_F8+1) 521b2b03f8SKarsten Keil 531b2b03f8SKarsten Keil static char *strL1SState[] = 541b2b03f8SKarsten Keil { 551b2b03f8SKarsten Keil "ST_L1_F2", 561b2b03f8SKarsten Keil "ST_L1_F3", 571b2b03f8SKarsten Keil "ST_L1_F4", 581b2b03f8SKarsten Keil "ST_L1_F5", 591b2b03f8SKarsten Keil "ST_L1_F6", 601b2b03f8SKarsten Keil "ST_L1_F7", 611b2b03f8SKarsten Keil "ST_L1_F8", 621b2b03f8SKarsten Keil }; 631b2b03f8SKarsten Keil 641b2b03f8SKarsten Keil enum { 651b2b03f8SKarsten Keil EV_PH_ACTIVATE, 661b2b03f8SKarsten Keil EV_PH_DEACTIVATE, 671b2b03f8SKarsten Keil EV_RESET_IND, 681b2b03f8SKarsten Keil EV_DEACT_CNF, 691b2b03f8SKarsten Keil EV_DEACT_IND, 701b2b03f8SKarsten Keil EV_POWER_UP, 711b2b03f8SKarsten Keil EV_ANYSIG_IND, 721b2b03f8SKarsten Keil EV_INFO2_IND, 731b2b03f8SKarsten Keil EV_INFO4_IND, 741b2b03f8SKarsten Keil EV_TIMER_DEACT, 751b2b03f8SKarsten Keil EV_TIMER_ACT, 761b2b03f8SKarsten Keil EV_TIMER3, 771b2b03f8SKarsten Keil }; 781b2b03f8SKarsten Keil 791b2b03f8SKarsten Keil #define L1_EVENT_COUNT (EV_TIMER3 + 1) 801b2b03f8SKarsten Keil 811b2b03f8SKarsten Keil static char *strL1Event[] = 821b2b03f8SKarsten Keil { 831b2b03f8SKarsten Keil "EV_PH_ACTIVATE", 841b2b03f8SKarsten Keil "EV_PH_DEACTIVATE", 851b2b03f8SKarsten Keil "EV_RESET_IND", 861b2b03f8SKarsten Keil "EV_DEACT_CNF", 871b2b03f8SKarsten Keil "EV_DEACT_IND", 881b2b03f8SKarsten Keil "EV_POWER_UP", 891b2b03f8SKarsten Keil "EV_ANYSIG_IND", 901b2b03f8SKarsten Keil "EV_INFO2_IND", 911b2b03f8SKarsten Keil "EV_INFO4_IND", 921b2b03f8SKarsten Keil "EV_TIMER_DEACT", 931b2b03f8SKarsten Keil "EV_TIMER_ACT", 941b2b03f8SKarsten Keil "EV_TIMER3", 951b2b03f8SKarsten Keil }; 961b2b03f8SKarsten Keil 971b2b03f8SKarsten Keil static void 981b2b03f8SKarsten Keil l1m_debug(struct FsmInst *fi, char *fmt, ...) 991b2b03f8SKarsten Keil { 1001b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1011b2b03f8SKarsten Keil va_list va; 1021b2b03f8SKarsten Keil 1031b2b03f8SKarsten Keil va_start(va, fmt); 104837468d1SMatthias Urlichs printk(KERN_DEBUG "%s: ", dev_name(&l1->dch->dev.dev)); 1051b2b03f8SKarsten Keil vprintk(fmt, va); 1061b2b03f8SKarsten Keil printk("\n"); 1071b2b03f8SKarsten Keil va_end(va); 1081b2b03f8SKarsten Keil } 1091b2b03f8SKarsten Keil 1101b2b03f8SKarsten Keil static void 1111b2b03f8SKarsten Keil l1_reset(struct FsmInst *fi, int event, void *arg) 1121b2b03f8SKarsten Keil { 1131b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1141b2b03f8SKarsten Keil } 1151b2b03f8SKarsten Keil 1161b2b03f8SKarsten Keil static void 1171b2b03f8SKarsten Keil l1_deact_cnf(struct FsmInst *fi, int event, void *arg) 1181b2b03f8SKarsten Keil { 1191b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1201b2b03f8SKarsten Keil 1211b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1221b2b03f8SKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) 1231b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 1241b2b03f8SKarsten Keil } 1251b2b03f8SKarsten Keil 1261b2b03f8SKarsten Keil static void 1271b2b03f8SKarsten Keil l1_deact_req_s(struct FsmInst *fi, int event, void *arg) 1281b2b03f8SKarsten Keil { 1291b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1301b2b03f8SKarsten Keil 1311b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1321b2b03f8SKarsten Keil mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2); 1331b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 1341b2b03f8SKarsten Keil } 1351b2b03f8SKarsten Keil 1361b2b03f8SKarsten Keil static void 1371b2b03f8SKarsten Keil l1_power_up_s(struct FsmInst *fi, int event, void *arg) 1381b2b03f8SKarsten Keil { 1391b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1401b2b03f8SKarsten Keil 1411b2b03f8SKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1421b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F4); 1431b2b03f8SKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1441b2b03f8SKarsten Keil } else 1451b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1461b2b03f8SKarsten Keil } 1471b2b03f8SKarsten Keil 1481b2b03f8SKarsten Keil static void 1491b2b03f8SKarsten Keil l1_go_F5(struct FsmInst *fi, int event, void *arg) 1501b2b03f8SKarsten Keil { 1511b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F5); 1521b2b03f8SKarsten Keil } 1531b2b03f8SKarsten Keil 1541b2b03f8SKarsten Keil static void 1551b2b03f8SKarsten Keil l1_go_F8(struct FsmInst *fi, int event, void *arg) 1561b2b03f8SKarsten Keil { 1571b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F8); 1581b2b03f8SKarsten Keil } 1591b2b03f8SKarsten Keil 1601b2b03f8SKarsten Keil static void 1611b2b03f8SKarsten Keil l1_info2_ind(struct FsmInst *fi, int event, void *arg) 1621b2b03f8SKarsten Keil { 1631b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1641b2b03f8SKarsten Keil 1651b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F6); 1661b2b03f8SKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1671b2b03f8SKarsten Keil } 1681b2b03f8SKarsten Keil 1691b2b03f8SKarsten Keil static void 1701b2b03f8SKarsten Keil l1_info4_ind(struct FsmInst *fi, int event, void *arg) 1711b2b03f8SKarsten Keil { 1721b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1731b2b03f8SKarsten Keil 1741b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F7); 1751b2b03f8SKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1761b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 1771b2b03f8SKarsten Keil mISDN_FsmDelTimer(&l1->timer, 4); 1781b2b03f8SKarsten Keil if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 1791b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 1801b2b03f8SKarsten Keil mISDN_FsmDelTimer(&l1->timer, 3); 1811b2b03f8SKarsten Keil mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2); 1821b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 1831b2b03f8SKarsten Keil } 1841b2b03f8SKarsten Keil } 1851b2b03f8SKarsten Keil 1861b2b03f8SKarsten Keil static void 1871b2b03f8SKarsten Keil l1_timer3(struct FsmInst *fi, int event, void *arg) 1881b2b03f8SKarsten Keil { 1891b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1901b2b03f8SKarsten Keil 1911b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); 1921b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1931b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 1941b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 1951b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 1961b2b03f8SKarsten Keil } 1971b2b03f8SKarsten Keil if (l1->l1m.state != ST_L1_F6) { 1981b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1991b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 2001b2b03f8SKarsten Keil } 2011b2b03f8SKarsten Keil } 2021b2b03f8SKarsten Keil 2031b2b03f8SKarsten Keil static void 2041b2b03f8SKarsten Keil l1_timer_act(struct FsmInst *fi, int event, void *arg) 2051b2b03f8SKarsten Keil { 2061b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2071b2b03f8SKarsten Keil 2081b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); 2091b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); 2101b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 2111b2b03f8SKarsten Keil } 2121b2b03f8SKarsten Keil 2131b2b03f8SKarsten Keil static void 2141b2b03f8SKarsten Keil l1_timer_deact(struct FsmInst *fi, int event, void *arg) 2151b2b03f8SKarsten Keil { 2161b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2171b2b03f8SKarsten Keil 2181b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); 2191b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); 2201b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2211b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2221b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2231b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_DEACT_REQ); 2241b2b03f8SKarsten Keil } 2251b2b03f8SKarsten Keil 2261b2b03f8SKarsten Keil static void 2271b2b03f8SKarsten Keil l1_activate_s(struct FsmInst *fi, int event, void *arg) 2281b2b03f8SKarsten Keil { 2291b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2301b2b03f8SKarsten Keil 2311b2b03f8SKarsten Keil mISDN_FsmRestartTimer(&l1->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); 2321b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); 2331b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_RESET_REQ); 2341b2b03f8SKarsten Keil } 2351b2b03f8SKarsten Keil 2361b2b03f8SKarsten Keil static void 2371b2b03f8SKarsten Keil l1_activate_no(struct FsmInst *fi, int event, void *arg) 2381b2b03f8SKarsten Keil { 2391b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2401b2b03f8SKarsten Keil 2411b2b03f8SKarsten Keil if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && 2421b2b03f8SKarsten Keil (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { 2431b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); 2441b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2451b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2461b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2471b2b03f8SKarsten Keil } 2481b2b03f8SKarsten Keil } 2491b2b03f8SKarsten Keil 2501b2b03f8SKarsten Keil static struct FsmNode L1SFnList[] = 2511b2b03f8SKarsten Keil { 2521b2b03f8SKarsten Keil {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, 2531b2b03f8SKarsten Keil {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, 2541b2b03f8SKarsten Keil {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, 2551b2b03f8SKarsten Keil {ST_L1_F3, EV_RESET_IND, l1_reset}, 2561b2b03f8SKarsten Keil {ST_L1_F4, EV_RESET_IND, l1_reset}, 2571b2b03f8SKarsten Keil {ST_L1_F5, EV_RESET_IND, l1_reset}, 2581b2b03f8SKarsten Keil {ST_L1_F6, EV_RESET_IND, l1_reset}, 2591b2b03f8SKarsten Keil {ST_L1_F7, EV_RESET_IND, l1_reset}, 2601b2b03f8SKarsten Keil {ST_L1_F8, EV_RESET_IND, l1_reset}, 2611b2b03f8SKarsten Keil {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, 2621b2b03f8SKarsten Keil {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, 2631b2b03f8SKarsten Keil {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, 2641b2b03f8SKarsten Keil {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, 2651b2b03f8SKarsten Keil {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, 2661b2b03f8SKarsten Keil {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, 2671b2b03f8SKarsten Keil {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, 2681b2b03f8SKarsten Keil {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, 2691b2b03f8SKarsten Keil {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, 2701b2b03f8SKarsten Keil {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, 2711b2b03f8SKarsten Keil {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, 2721b2b03f8SKarsten Keil {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, 2731b2b03f8SKarsten Keil {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, 2741b2b03f8SKarsten Keil {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, 2751b2b03f8SKarsten Keil {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, 2761b2b03f8SKarsten Keil {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, 2771b2b03f8SKarsten Keil {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, 2781b2b03f8SKarsten Keil {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, 2791b2b03f8SKarsten Keil {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, 2801b2b03f8SKarsten Keil {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, 2811b2b03f8SKarsten Keil {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, 2821b2b03f8SKarsten Keil {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, 2831b2b03f8SKarsten Keil {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, 2841b2b03f8SKarsten Keil {ST_L1_F3, EV_TIMER3, l1_timer3}, 2851b2b03f8SKarsten Keil {ST_L1_F4, EV_TIMER3, l1_timer3}, 2861b2b03f8SKarsten Keil {ST_L1_F5, EV_TIMER3, l1_timer3}, 2871b2b03f8SKarsten Keil {ST_L1_F6, EV_TIMER3, l1_timer3}, 2881b2b03f8SKarsten Keil {ST_L1_F8, EV_TIMER3, l1_timer3}, 2891b2b03f8SKarsten Keil {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, 2901b2b03f8SKarsten Keil {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, 2911b2b03f8SKarsten Keil {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, 2921b2b03f8SKarsten Keil {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, 2931b2b03f8SKarsten Keil {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, 2941b2b03f8SKarsten Keil {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, 2951b2b03f8SKarsten Keil {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 2961b2b03f8SKarsten Keil }; 2971b2b03f8SKarsten Keil 2981b2b03f8SKarsten Keil static void 2991b2b03f8SKarsten Keil release_l1(struct layer1 *l1) { 3001b2b03f8SKarsten Keil mISDN_FsmDelTimer(&l1->timer, 0); 3011b2b03f8SKarsten Keil if (l1->dch) 3021b2b03f8SKarsten Keil l1->dch->l1 = NULL; 3031b2b03f8SKarsten Keil module_put(THIS_MODULE); 3041b2b03f8SKarsten Keil kfree(l1); 3051b2b03f8SKarsten Keil } 3061b2b03f8SKarsten Keil 3071b2b03f8SKarsten Keil int 3081b2b03f8SKarsten Keil l1_event(struct layer1 *l1, u_int event) 3091b2b03f8SKarsten Keil { 3101b2b03f8SKarsten Keil int err = 0; 3111b2b03f8SKarsten Keil 3121b2b03f8SKarsten Keil if (!l1) 3131b2b03f8SKarsten Keil return -EINVAL; 3141b2b03f8SKarsten Keil switch (event) { 3151b2b03f8SKarsten Keil case HW_RESET_IND: 3161b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); 3171b2b03f8SKarsten Keil break; 3181b2b03f8SKarsten Keil case HW_DEACT_IND: 3191b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); 3201b2b03f8SKarsten Keil break; 3211b2b03f8SKarsten Keil case HW_POWERUP_IND: 3221b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); 3231b2b03f8SKarsten Keil break; 3241b2b03f8SKarsten Keil case HW_DEACT_CNF: 3251b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); 3261b2b03f8SKarsten Keil break; 3271b2b03f8SKarsten Keil case ANYSIGNAL: 3281b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3291b2b03f8SKarsten Keil break; 3301b2b03f8SKarsten Keil case LOSTFRAMING: 3311b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3321b2b03f8SKarsten Keil break; 3331b2b03f8SKarsten Keil case INFO2: 3341b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); 3351b2b03f8SKarsten Keil break; 3361b2b03f8SKarsten Keil case INFO4_P8: 3371b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3381b2b03f8SKarsten Keil break; 3391b2b03f8SKarsten Keil case INFO4_P10: 3401b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3411b2b03f8SKarsten Keil break; 3421b2b03f8SKarsten Keil case PH_ACTIVATE_REQ: 3431b2b03f8SKarsten Keil if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) 3441b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 3451b2b03f8SKarsten Keil else { 3461b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); 3471b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); 3481b2b03f8SKarsten Keil } 3491b2b03f8SKarsten Keil break; 3501b2b03f8SKarsten Keil case CLOSE_CHANNEL: 3511b2b03f8SKarsten Keil release_l1(l1); 3521b2b03f8SKarsten Keil break; 3531b2b03f8SKarsten Keil default: 3541b2b03f8SKarsten Keil if (*debug & DEBUG_L1) 3551b2b03f8SKarsten Keil printk(KERN_DEBUG "%s %x unhandled\n", 3561b2b03f8SKarsten Keil __func__, event); 3571b2b03f8SKarsten Keil err = -EINVAL; 3581b2b03f8SKarsten Keil } 3591b2b03f8SKarsten Keil return err; 3601b2b03f8SKarsten Keil } 3611b2b03f8SKarsten Keil EXPORT_SYMBOL(l1_event); 3621b2b03f8SKarsten Keil 3631b2b03f8SKarsten Keil int 3641b2b03f8SKarsten Keil create_l1(struct dchannel *dch, dchannel_l1callback *dcb) { 3651b2b03f8SKarsten Keil struct layer1 *nl1; 3661b2b03f8SKarsten Keil 3671b2b03f8SKarsten Keil nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); 3681b2b03f8SKarsten Keil if (!nl1) { 3691b2b03f8SKarsten Keil printk(KERN_ERR "kmalloc struct layer1 failed\n"); 3701b2b03f8SKarsten Keil return -ENOMEM; 3711b2b03f8SKarsten Keil } 3721b2b03f8SKarsten Keil nl1->l1m.fsm = &l1fsm_s; 3731b2b03f8SKarsten Keil nl1->l1m.state = ST_L1_F3; 3741b2b03f8SKarsten Keil nl1->Flags = 0; 3751b2b03f8SKarsten Keil nl1->l1m.debug = *debug & DEBUG_L1_FSM; 3761b2b03f8SKarsten Keil nl1->l1m.userdata = nl1; 3771b2b03f8SKarsten Keil nl1->l1m.userint = 0; 3781b2b03f8SKarsten Keil nl1->l1m.printdebug = l1m_debug; 3791b2b03f8SKarsten Keil nl1->dch = dch; 3801b2b03f8SKarsten Keil nl1->dcb = dcb; 3811b2b03f8SKarsten Keil mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); 3821b2b03f8SKarsten Keil __module_get(THIS_MODULE); 3831b2b03f8SKarsten Keil dch->l1 = nl1; 3841b2b03f8SKarsten Keil return 0; 3851b2b03f8SKarsten Keil } 3861b2b03f8SKarsten Keil EXPORT_SYMBOL(create_l1); 3871b2b03f8SKarsten Keil 3881b2b03f8SKarsten Keil int 3891b2b03f8SKarsten Keil l1_init(u_int *deb) 3901b2b03f8SKarsten Keil { 3911b2b03f8SKarsten Keil debug = deb; 3921b2b03f8SKarsten Keil l1fsm_s.state_count = L1S_STATE_COUNT; 3931b2b03f8SKarsten Keil l1fsm_s.event_count = L1_EVENT_COUNT; 3941b2b03f8SKarsten Keil l1fsm_s.strEvent = strL1Event; 3951b2b03f8SKarsten Keil l1fsm_s.strState = strL1SState; 3961b2b03f8SKarsten Keil mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); 3971b2b03f8SKarsten Keil return 0; 3981b2b03f8SKarsten Keil } 3991b2b03f8SKarsten Keil 4001b2b03f8SKarsten Keil void 4011b2b03f8SKarsten Keil l1_cleanup(void) 4021b2b03f8SKarsten Keil { 4031b2b03f8SKarsten Keil mISDN_FsmFree(&l1fsm_s); 4041b2b03f8SKarsten Keil } 405