cregit-Linux how code gets into the kernel

Release 4.7 drivers/isdn/hisax/tei.c

/* $Id: tei.c,v 2.20.2.3 2004/01/13 14:31:26 keil Exp $
 *
 * Author       Karsten Keil
 *              based on the teles driver from Jan den Ouden
 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * For changes and modifications please read
 * Documentation/isdn/HiSax.cert
 *
 * Thanks to    Jan den Ouden
 *              Fritz Elfert
 *
 */

#include "hisax.h"
#include "isdnl2.h"
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/random.h>


const char *tei_revision = "$Revision: 2.20.2.3 $";


#define ID_REQUEST	1

#define ID_ASSIGNED	2

#define ID_DENIED	3

#define ID_CHK_REQ	4

#define ID_CHK_RES	5

#define ID_REMOVE	6

#define ID_VERIFY	7


#define TEI_ENTITY_ID	0xf


static struct Fsm teifsm;

void tei_handler(struct PStack *st, u_char pr, struct sk_buff *skb);

enum {
	
ST_TEI_NOP,
	
ST_TEI_IDREQ,
	
ST_TEI_IDVERIFY,
};


#define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)


static char *strTeiState[] =
{
	"ST_TEI_NOP",
	"ST_TEI_IDREQ",
	"ST_TEI_IDVERIFY",
};

enum {
	
EV_IDREQ,
	
EV_ASSIGN,
	
EV_DENIED,
	
EV_CHKREQ,
	
EV_REMOVE,
	
EV_VERIFY,
	
EV_T202,
};


#define TEI_EVENT_COUNT (EV_T202 + 1)


static char *strTeiEvent[] =
{
	"EV_IDREQ",
	"EV_ASSIGN",
	"EV_DENIED",
	"EV_CHKREQ",
	"EV_REMOVE",
	"EV_VERIFY",
	"EV_T202",
};


static unsigned int random_ri(void) { unsigned int x; get_random_bytes(&x, sizeof(x)); return (x & 0xffff); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git3096.77%266.67%
adrian bunkadrian bunk13.23%133.33%
Total31100.00%3100.00%


static struct PStack * findtei(struct PStack *st, int tei) { struct PStack *ptr = *(st->l1.stlistp); if (tei == 127) return (NULL); while (ptr) if (ptr->l2.tei == tei) return (ptr); else ptr = ptr->next; return (NULL); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git72100.00%1100.00%
Total72100.00%1100.00%


static void put_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei) { struct sk_buff *skb; u_char *bp; if (!(skb = alloc_skb(8, GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No skb for TEI manager\n"); return; } bp = skb_put(skb, 3); bp[0] = (TEI_SAPI << 2); bp[1] = (GROUP_TEI << 1) | 0x1; bp[2] = UI; bp = skb_put(skb, 5); bp[0] = TEI_ENTITY_ID; bp[1] = ri >> 8; bp[2] = ri & 0xff; bp[3] = m_id; bp[4] = (tei << 1) | 1; st->l2.l2l1(st, PH_DATA | REQUEST, skb); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git15495.06%480.00%
andrew mortonandrew morton84.94%120.00%
Total162100.00%5100.00%


static void tei_id_request(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; if (st->l2.tei != -1) { st->ma.tei_m.printdebug(&st->ma.tei_m, "assign request for already assigned tei %d", st->l2.tei); return; } st->ma.ri = random_ri(); if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "assign request ri %d", st->ma.ri); put_tei_msg(st, ID_REQUEST, st->ma.ri, 127); FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ); FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1); st->ma.N202 = 3; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git16299.39%375.00%
masanari iidamasanari iida10.61%125.00%
Total163100.00%4100.00%


static void tei_id_assign(struct FsmInst *fi, int event, void *arg) { struct PStack *ost, *st = fi->userdata; struct sk_buff *skb = arg; struct IsdnCardState *cs; int ri, tei; ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; tei = skb->data[4] >> 1; if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "identity assign ri %d tei %d", ri, tei); if ((ost = findtei(st, tei))) { /* same tei is in use */ if (ri != ost->ma.ri) { st->ma.tei_m.printdebug(&st->ma.tei_m, "possible duplicate assignment tei %d", tei); ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL); } } else if (ri == st->ma.ri) { FsmDelTimer(&st->ma.t202, 1); FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei); cs = (struct IsdnCardState *) st->l1.hardware; cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git24694.62%375.00%
andrew mortonandrew morton145.38%125.00%
Total260100.00%4100.00%


static void tei_id_test_dup(struct FsmInst *fi, int event, void *arg) { struct PStack *ost, *st = fi->userdata; struct sk_buff *skb = arg; int tei, ri; ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; tei = skb->data[4] >> 1; if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "foreign identity assign ri %d tei %d", ri, tei); if ((ost = findtei(st, tei))) { /* same tei is in use */ if (ri != ost->ma.ri) { /* and it wasn't our request */ st->ma.tei_m.printdebug(&st->ma.tei_m, "possible duplicate assignment tei %d", tei); FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL); } } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git170100.00%3100.00%
Total170100.00%3100.00%


static void tei_id_denied(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int ri, tei; ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; tei = skb->data[4] >> 1; if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "identity denied ri %d tei %d", ri, tei); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git104100.00%4100.00%
Total104100.00%4100.00%


static void tei_id_chk_req(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; int tei; tei = skb->data[4] >> 1; if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "identity check req tei %d", tei); if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) { FsmDelTimer(&st->ma.t202, 4); FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); put_tei_msg(st, ID_CHK_RES, random_ri(), st->l2.tei); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git149100.00%3100.00%
Total149100.00%3100.00%


static void tei_id_remove(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; struct IsdnCardState *cs; int tei; tei = skb->data[4] >> 1; if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "identity remove tei %d", tei); if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) { FsmDelTimer(&st->ma.t202, 5); FsmChangeState(&st->ma.tei_m, ST_TEI_NOP); st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL); cs = (struct IsdnCardState *) st->l1.hardware; cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git16491.62%360.00%
andrew mortonandrew morton147.82%120.00%
al viroal viro10.56%120.00%
Total179100.00%5100.00%


static void tei_id_verify(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "id verify request for tei %d", st->l2.tei); put_tei_msg(st, ID_VERIFY, 0, st->l2.tei); FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY); FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2); st->ma.N202 = 2; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git116100.00%3100.00%
Total116100.00%3100.00%


static void tei_id_req_tout(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct IsdnCardState *cs; if (--st->ma.N202) { st->ma.ri = random_ri(); if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req(%d) ri %d", 4 - st->ma.N202, st->ma.ri); put_tei_msg(st, ID_REQUEST, st->ma.ri, 127); FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3); } else { st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed"); st->l3.l3l2(st, MDL_ERROR | RESPONSE, NULL); cs = (struct IsdnCardState *) st->l1.hardware; cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); FsmChangeState(fi, ST_TEI_NOP); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git18392.42%250.00%
andrew mortonandrew morton147.07%125.00%
al viroal viro10.51%125.00%
Total198100.00%4100.00%


static void tei_id_ver_tout(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct IsdnCardState *cs; if (--st->ma.N202) { if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "id verify req(%d) for tei %d", 3 - st->ma.N202, st->l2.tei); put_tei_msg(st, ID_VERIFY, 0, st->l2.tei); FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4); } else { st->ma.tei_m.printdebug(&st->ma.tei_m, "verify req for tei %d failed", st->l2.tei); st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL); cs = (struct IsdnCardState *) st->l1.hardware; cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL); FsmChangeState(fi, ST_TEI_NOP); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git18092.31%250.00%
andrew mortonandrew morton147.18%125.00%
al viroal viro10.51%125.00%
Total195100.00%4100.00%


static void tei_l1l2(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; int mt; if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { dev_kfree_skb(skb); return; } if (pr == (PH_DATA | INDICATION)) { if (skb->len < 3) { st->ma.tei_m.printdebug(&st->ma.tei_m, "short mgr frame %ld/3", skb->len); } else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) || (skb->data[1] != ((GROUP_TEI << 1) | 1))) { st->ma.tei_m.printdebug(&st->ma.tei_m, "wrong mgr sapi/tei %x/%x", skb->data[0], skb->data[1]); } else if ((skb->data[2] & 0xef) != UI) { st->ma.tei_m.printdebug(&st->ma.tei_m, "mgr frame is not ui %x", skb->data[2]); } else { skb_pull(skb, 3); if (skb->len < 5) { st->ma.tei_m.printdebug(&st->ma.tei_m, "short mgr frame %ld/5", skb->len); } else if (skb->data[0] != TEI_ENTITY_ID) { /* wrong management entity identifier, ignore */ st->ma.tei_m.printdebug(&st->ma.tei_m, "tei handler wrong entity id %x", skb->data[0]); } else { mt = skb->data[3]; if (mt == ID_ASSIGNED) FsmEvent(&st->ma.tei_m, EV_ASSIGN, skb); else if (mt == ID_DENIED) FsmEvent(&st->ma.tei_m, EV_DENIED, skb); else if (mt == ID_CHK_REQ) FsmEvent(&st->ma.tei_m, EV_CHKREQ, skb); else if (mt == ID_REMOVE) FsmEvent(&st->ma.tei_m, EV_REMOVE, skb); else { st->ma.tei_m.printdebug(&st->ma.tei_m, "tei handler wrong mt %x\n", mt); } } } } else { st->ma.tei_m.printdebug(&st->ma.tei_m, "tei handler wrong pr %x\n", pr); } dev_kfree_skb(skb); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git440100.00%6100.00%
Total440100.00%6100.00%


static void tei_l2tei(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs; if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { if (pr == (MDL_ASSIGN | INDICATION)) { if (st->ma.debug) st->ma.tei_m.printdebug(&st->ma.tei_m, "fixed assign tei %d", st->l2.tei); st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei); cs = (struct IsdnCardState *) st->l1.hardware; cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); } return; } switch (pr) { case (MDL_ASSIGN | INDICATION): FsmEvent(&st->ma.tei_m, EV_IDREQ, arg); break; case (MDL_ERROR | REQUEST): FsmEvent(&st->ma.tei_m, EV_VERIFY, arg); break; default: break; } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git17492.55%375.00%
andrew mortonandrew morton147.45%125.00%
Total188100.00%4100.00%


static void tei_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; struct PStack *st = fi->userdata; va_start(args, fmt); VHiSax_putstatus(st->l1.hardware, "tei ", fmt, args); va_end(args); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git56100.00%3100.00%
Total56100.00%3100.00%


void setstack_tei(struct PStack *st) { st->l2.l2tei = tei_l2tei; st->ma.T202 = 2000; /* T202 2000 milliseconds */ st->l1.l1tei = tei_l1l2; st->ma.debug = 1; st->ma.tei_m.fsm = &teifsm; st->ma.tei_m.state = ST_TEI_NOP; st->ma.tei_m.debug = 1; st->ma.tei_m.userdata = st; st->ma.tei_m.userint = 0; st->ma.tei_m.printdebug = tei_debug; FsmInitTimer(&st->ma.tei_m, &st->ma.t202); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git121100.00%2100.00%
Total121100.00%2100.00%


void init_tei(struct IsdnCardState *cs, int protocol) { }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git12100.00%3100.00%
Total12100.00%3100.00%


void release_tei(struct IsdnCardState *cs) { struct PStack *st = cs->stlist; while (st) { FsmDelTimer(&st->ma.t202, 1); st = st->next; } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git43100.00%2100.00%
Total43100.00%2100.00%

static struct FsmNode TeiFnList[] __initdata = { {ST_TEI_NOP, EV_IDREQ, tei_id_request}, {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup}, {ST_TEI_NOP, EV_VERIFY, tei_id_verify}, {ST_TEI_NOP, EV_REMOVE, tei_id_remove}, {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req}, {ST_TEI_IDREQ, EV_T202, tei_id_req_tout}, {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign}, {ST_TEI_IDREQ, EV_DENIED, tei_id_denied}, {ST_TEI_IDVERIFY, EV_T202, tei_id_ver_tout}, {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove}, {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req}, };
int __init TeiNew(void) { teifsm.state_count = TEI_STATE_COUNT; teifsm.event_count = TEI_EVENT_COUNT; teifsm.strEvent = strTeiEvent; teifsm.strState = strTeiState; return FsmNew(&teifsm, TeiFnList, ARRAY_SIZE(TeiFnList)); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git3984.78%360.00%
karsten keilkarsten keil48.70%120.00%
linus torvaldslinus torvalds36.52%120.00%
Total46100.00%5100.00%


void TeiFree(void) { FsmFree(&teifsm); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git13100.00%2100.00%
Total13100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git286496.69%850.00%
andrew mortonandrew morton802.70%16.25%
karsten keilkarsten keil40.14%16.25%
joe perchesjoe perches30.10%16.25%
tejun heotejun heo30.10%16.25%
al viroal viro30.10%16.25%
linus torvaldslinus torvalds30.10%16.25%
masanari iidamasanari iida10.03%16.25%
adrian bunkadrian bunk10.03%16.25%
Total2962100.00%16100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}