cregit-Linux how code gets into the kernel

Release 4.11 drivers/isdn/mISDN/layer1.c

/*
 *
 * Author       Karsten Keil <kkeil@novell.com>
 *
 * Copyright 2008  by Karsten Keil <kkeil@novell.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */


#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mISDNhw.h>
#include "core.h"
#include "layer1.h"
#include "fsm.h"


static u_int *debug;


struct layer1 {
	
u_long Flags;
	
struct FsmInst l1m;
	
struct FsmTimer timer3;
	
struct FsmTimer timerX;
	
int delay;
	
int t3_value;
	
struct dchannel *dch;
	
dchannel_l1callback *dcb;
};


#define TIMER3_DEFAULT_VALUE	7000

static

struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL};

enum {
	
ST_L1_F2,
	
ST_L1_F3,
	
ST_L1_F4,
	
ST_L1_F5,
	
ST_L1_F6,
	
ST_L1_F7,
	
ST_L1_F8,
};


#define L1S_STATE_COUNT (ST_L1_F8 + 1)


static char *strL1SState[] =
{
	"ST_L1_F2",
	"ST_L1_F3",
	"ST_L1_F4",
	"ST_L1_F5",
	"ST_L1_F6",
	"ST_L1_F7",
	"ST_L1_F8",
};

enum {
	
EV_PH_ACTIVATE,
	
EV_PH_DEACTIVATE,
	
EV_RESET_IND,
	
EV_DEACT_CNF,
	
EV_DEACT_IND,
	
EV_POWER_UP,
	
EV_ANYSIG_IND,
	
EV_INFO2_IND,
	
EV_INFO4_IND,
	
EV_TIMER_DEACT,
	
EV_TIMER_ACT,
	
EV_TIMER3,
};


#define L1_EVENT_COUNT (EV_TIMER3 + 1)


static char *strL1Event[] =
{
	"EV_PH_ACTIVATE",
	"EV_PH_DEACTIVATE",
	"EV_RESET_IND",
	"EV_DEACT_CNF",
	"EV_DEACT_IND",
	"EV_POWER_UP",
	"EV_ANYSIG_IND",
	"EV_INFO2_IND",
	"EV_INFO4_IND",
	"EV_TIMER_DEACT",
	"EV_TIMER_ACT",
	"EV_TIMER3",
};


static void l1m_debug(struct FsmInst *fi, char *fmt, ...) { struct layer1 *l1 = fi->userdata; struct va_format vaf; va_list va; va_start(va, fmt); vaf.fmt = fmt; vaf.va = &va; printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); va_end(va); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil5468.35%133.33%
Joe Perches2025.32%133.33%
Matthias Urlichs56.33%133.33%
Total79100.00%3100.00%


static void l1_reset(struct FsmInst *fi, int event, void *arg) { mISDN_FsmChangeState(fi, ST_L1_F3); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil25100.00%1100.00%
Total25100.00%1100.00%


static void l1_deact_cnf(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; mISDN_FsmChangeState(fi, ST_L1_F3); if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) l1->dcb(l1->dch, HW_POWERUP_REQ); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil57100.00%1100.00%
Total57100.00%1100.00%


static void l1_deact_req_s(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; mISDN_FsmChangeState(fi, ST_L1_F3); mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2); test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil60100.00%2100.00%
Total60100.00%2100.00%


static void l1_power_up_s(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { mISDN_FsmChangeState(fi, ST_L1_F4); l1->dcb(l1->dch, INFO3_P8); } else mISDN_FsmChangeState(fi, ST_L1_F3); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil67100.00%1100.00%
Total67100.00%1100.00%


static void l1_go_F5(struct FsmInst *fi, int event, void *arg) { mISDN_FsmChangeState(fi, ST_L1_F5); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil25100.00%1100.00%
Total25100.00%1100.00%


static void l1_go_F8(struct FsmInst *fi, int event, void *arg) { mISDN_FsmChangeState(fi, ST_L1_F8); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil25100.00%1100.00%
Total25100.00%1100.00%


static void l1_info2_ind(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; mISDN_FsmChangeState(fi, ST_L1_F6); l1->dcb(l1->dch, INFO3_P8); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil45100.00%1100.00%
Total45100.00%1100.00%


static void l1_info4_ind(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; mISDN_FsmChangeState(fi, ST_L1_F7); l1->dcb(l1->dch, INFO3_P8); if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) mISDN_FsmDelTimer(&l1->timerX, 4); if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) mISDN_FsmDelTimer(&l1->timer3, 3); mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2); test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); } }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil130100.00%2100.00%
Total130100.00%2100.00%


static void l1_timer3(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) l1->dcb(l1->dch, HW_D_NOBLOCKED); l1->dcb(l1->dch, PH_DEACTIVATE_IND); } if (l1->l1m.state != ST_L1_F6) { mISDN_FsmChangeState(fi, ST_L1_F3); /* do not force anything here, we need send INFO 0 */ } }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil105100.00%2100.00%
Total105100.00%2100.00%


static void l1_timer_act(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); l1->dcb(l1->dch, PH_ACTIVATE_IND); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil58100.00%1100.00%
Total58100.00%1100.00%


static void l1_timer_deact(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) l1->dcb(l1->dch, HW_D_NOBLOCKED); l1->dcb(l1->dch, PH_DEACTIVATE_IND); l1->dcb(l1->dch, HW_DEACT_REQ); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil92100.00%1100.00%
Total92100.00%1100.00%


static void l1_activate_s(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2); test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); /* Tell HW to send INFO 1 */ l1->dcb(l1->dch, HW_RESET_REQ); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil67100.00%3100.00%
Total67100.00%3100.00%


static void l1_activate_no(struct FsmInst *fi, int event, void *arg) { struct layer1 *l1 = fi->userdata; if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) l1->dcb(l1->dch, HW_D_NOBLOCKED); l1->dcb(l1->dch, PH_DEACTIVATE_IND); } }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil101100.00%1100.00%
Total101100.00%1100.00%

static struct FsmNode L1SFnList[] = { {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, {ST_L1_F3, EV_RESET_IND, l1_reset}, {ST_L1_F4, EV_RESET_IND, l1_reset}, {ST_L1_F5, EV_RESET_IND, l1_reset}, {ST_L1_F6, EV_RESET_IND, l1_reset}, {ST_L1_F7, EV_RESET_IND, l1_reset}, {ST_L1_F8, EV_RESET_IND, l1_reset}, {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, {ST_L1_F3, EV_TIMER3, l1_timer3}, {ST_L1_F4, EV_TIMER3, l1_timer3}, {ST_L1_F5, EV_TIMER3, l1_timer3}, {ST_L1_F6, EV_TIMER3, l1_timer3}, {ST_L1_F8, EV_TIMER3, l1_timer3}, {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, };
static void release_l1(struct layer1 *l1) { mISDN_FsmDelTimer(&l1->timerX, 0); mISDN_FsmDelTimer(&l1->timer3, 0); if (l1->dch) l1->dch->l1 = NULL; module_put(THIS_MODULE); kfree(l1); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil55100.00%2100.00%
Total55100.00%2100.00%


int l1_event(struct layer1 *l1, u_int event) { int err = 0; if (!l1) return -EINVAL; switch (event) { case HW_RESET_IND: mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); break; case HW_DEACT_IND: mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); break; case HW_POWERUP_IND: mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); break; case HW_DEACT_CNF: mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); break; case ANYSIGNAL: mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); break; case LOSTFRAMING: mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); break; case INFO2: mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); break; case INFO4_P8: mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); break; case INFO4_P10: mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); break; case PH_ACTIVATE_REQ: if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) l1->dcb(l1->dch, PH_ACTIVATE_IND); else { test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); } break; case CLOSE_CHANNEL: release_l1(l1); break; default: if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { int val = event & HW_TIMER3_VMASK; if (val < 5) val = 5; if (val > 30) val = 30; l1->t3_value = val; break; } if (*debug & DEBUG_L1) printk(KERN_DEBUG "%s %x unhandled\n", __func__, event); err = -EINVAL; } return err; }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil311100.00%2100.00%
Total311100.00%2100.00%

EXPORT_SYMBOL(l1_event);
int create_l1(struct dchannel *dch, dchannel_l1callback *dcb) { struct layer1 *nl1; nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); if (!nl1) { printk(KERN_ERR "kmalloc struct layer1 failed\n"); return -ENOMEM; } nl1->l1m.fsm = &l1fsm_s; nl1->l1m.state = ST_L1_F3; nl1->Flags = 0; nl1->t3_value = TIMER3_DEFAULT_VALUE; nl1->l1m.debug = *debug & DEBUG_L1_FSM; nl1->l1m.userdata = nl1; nl1->l1m.userint = 0; nl1->l1m.printdebug = l1m_debug; nl1->dch = dch; nl1->dcb = dcb; mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3); mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX); __module_get(THIS_MODULE); dch->l1 = nl1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil165100.00%3100.00%
Total165100.00%3100.00%

EXPORT_SYMBOL(create_l1);
int l1_init(u_int *deb) { debug = deb; l1fsm_s.state_count = L1S_STATE_COUNT; l1fsm_s.event_count = L1_EVENT_COUNT; l1fsm_s.strEvent = strL1Event; l1fsm_s.strState = strL1SState; mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil53100.00%1100.00%
Total53100.00%1100.00%


void l1_cleanup(void) { mISDN_FsmFree(&l1fsm_s); }

Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil13100.00%1100.00%
Total13100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Karsten Keil205698.42%333.33%
Joe Perches211.01%222.22%
Matthias Urlichs50.24%111.11%
Hannes Eder40.19%222.22%
Tejun Heo30.14%111.11%
Total2089100.00%9100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.