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