cregit-Linux how code gets into the kernel

Release 4.14 drivers/isdn/hisax/hisax_isac.c

/*
 * Driver for ISAC-S and ISAC-SX
 * ISDN Subscriber Access Controller for Terminals
 *
 * Author       Kai Germaschewski
 * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
 *              2001 by Karsten Keil       <keil@isdn4linux.de>
 *
 * based upon Karsten Keil's original isac.c driver
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * Thanks to Wizard Computersysteme GmbH, Bremervoerde and
 *           SoHaNet Technology GmbH, Berlin
 * for supporting the development of this driver
 */

/* TODO:
 * specifically handle level vs edge triggered?
 */

#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include "hisax_isac.h"

// debugging cruft


#define __debug_variable debug
#include "hisax_debug.h"

#ifdef CONFIG_HISAX_DEBUG

static int debug = 1;
module_param(debug, int, 0);


static char *ISACVer[] = {
	"2086/2186 V1.1",
	"2085 B1",
	"2085 B2",
	"2085 V2.3"
};
#endif

MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
MODULE_DESCRIPTION("ISAC/ISAC-SX driver");
MODULE_LICENSE("GPL");


#define DBG_WARN      0x0001

#define DBG_IRQ       0x0002

#define DBG_L1M       0x0004

#define DBG_PR        0x0008

#define DBG_RFIFO     0x0100

#define DBG_RPACKET   0x0200

#define DBG_XFIFO     0x1000

#define DBG_XPACKET   0x2000

// we need to distinguish ISAC-S and ISAC-SX

#define TYPE_ISAC        0x00

#define TYPE_ISACSX      0x01

// registers etc.

#define ISAC_MASK        0x20

#define ISAC_ISTA        0x20

#define ISAC_ISTA_EXI    0x01

#define ISAC_ISTA_SIN    0x02

#define ISAC_ISTA_CISQ   0x04

#define ISAC_ISTA_XPR    0x10

#define ISAC_ISTA_RSC    0x20

#define ISAC_ISTA_RPF    0x40

#define ISAC_ISTA_RME    0x80


#define ISAC_STAR        0x21

#define ISAC_CMDR        0x21

#define ISAC_CMDR_XRES   0x01

#define ISAC_CMDR_XME    0x02

#define ISAC_CMDR_XTF    0x08

#define ISAC_CMDR_RRES   0x40

#define ISAC_CMDR_RMC    0x80


#define ISAC_EXIR        0x24

#define ISAC_EXIR_MOS    0x04

#define ISAC_EXIR_XDU    0x40

#define ISAC_EXIR_XMR    0x80


#define ISAC_ADF2        0x39

#define ISAC_SPCR        0x30

#define ISAC_ADF1        0x38


#define ISAC_CIR0        0x31

#define ISAC_CIX0        0x31

#define ISAC_CIR0_CIC0   0x02

#define ISAC_CIR0_CIC1   0x01


#define ISAC_CIR1        0x33

#define ISAC_CIX1        0x33

#define ISAC_STCR        0x37

#define ISAC_MODE        0x22


#define ISAC_RSTA        0x27

#define ISAC_RSTA_RDO    0x40

#define ISAC_RSTA_CRC    0x20

#define ISAC_RSTA_RAB    0x10


#define ISAC_RBCL 0x25

#define ISAC_RBCH 0x2A

#define ISAC_TIMR 0x23

#define ISAC_SQXR 0x3b

#define ISAC_MOSR 0x3a

#define ISAC_MOCR 0x3a

#define ISAC_MOR0 0x32

#define ISAC_MOX0 0x32

#define ISAC_MOR1 0x34

#define ISAC_MOX1 0x34


#define ISAC_RBCH_XAC 0x80


#define ISAC_CMD_TIM    0x0

#define ISAC_CMD_RES    0x1

#define ISAC_CMD_SSP    0x2

#define ISAC_CMD_SCP    0x3

#define ISAC_CMD_AR8    0x8

#define ISAC_CMD_AR10   0x9

#define ISAC_CMD_ARL    0xa

#define ISAC_CMD_DI     0xf


#define ISACSX_MASK       0x60

#define ISACSX_ISTA       0x60

#define ISACSX_ISTA_ICD   0x01

#define ISACSX_ISTA_CIC   0x10


#define ISACSX_MASKD      0x20

#define ISACSX_ISTAD      0x20

#define ISACSX_ISTAD_XDU  0x04

#define ISACSX_ISTAD_XMR  0x08

#define ISACSX_ISTAD_XPR  0x10

#define ISACSX_ISTAD_RFO  0x20

#define ISACSX_ISTAD_RPF  0x40

#define ISACSX_ISTAD_RME  0x80


#define ISACSX_CMDRD      0x21

#define ISACSX_CMDRD_XRES 0x01

#define ISACSX_CMDRD_XME  0x02

#define ISACSX_CMDRD_XTF  0x08

#define ISACSX_CMDRD_RRES 0x40

#define ISACSX_CMDRD_RMC  0x80


#define ISACSX_MODED      0x22


#define ISACSX_RBCLD      0x26


#define ISACSX_RSTAD      0x28

#define ISACSX_RSTAD_RAB  0x10

#define ISACSX_RSTAD_CRC  0x20

#define ISACSX_RSTAD_RDO  0x40

#define ISACSX_RSTAD_VFR  0x80


#define ISACSX_CIR0       0x2e

#define ISACSX_CIR0_CIC0  0x08

#define ISACSX_CIX0       0x2e


#define ISACSX_TR_CONF0   0x30


#define ISACSX_TR_CONF2   0x32


static struct Fsm l1fsm;

enum {
	
ST_L1_RESET,
	
ST_L1_F3_PDOWN,
	
ST_L1_F3_PUP,
	
ST_L1_F3_PEND_DEACT,
	
ST_L1_F4,
	
ST_L1_F5,
	
ST_L1_F6,
	
ST_L1_F7,
	
ST_L1_F8,
};


#define L1_STATE_COUNT (ST_L1_F8 + 1)


static char *strL1State[] =
{
	"ST_L1_RESET",
	"ST_L1_F3_PDOWN",
	"ST_L1_F3_PUP",
	"ST_L1_F3_PEND_DEACT",
	"ST_L1_F4",
	"ST_L1_F5",
	"ST_L1_F6",
	"ST_L1_F7",
	"ST_L1_F8",
};

enum {
	
EV_PH_DR,           // 0000
	
EV_PH_RES,          // 0001
	
EV_PH_TMA,          // 0010
	
EV_PH_SLD,          // 0011
	
EV_PH_RSY,          // 0100
	
EV_PH_DR6,          // 0101
	
EV_PH_EI,           // 0110
	
EV_PH_PU,           // 0111
	
EV_PH_AR,           // 1000
	
EV_PH_9,            // 1001
	
EV_PH_ARL,          // 1010
	
EV_PH_CVR,          // 1011
	
EV_PH_AI8,          // 1100
	
EV_PH_AI10,         // 1101
	
EV_PH_AIL,          // 1110
	
EV_PH_DC,           // 1111
	
EV_PH_ACTIVATE_REQ,
	
EV_PH_DEACTIVATE_REQ,
	
EV_TIMER3,
};


#define L1_EVENT_COUNT (EV_TIMER3 + 1)


static char *strL1Event[] =
{
	"EV_PH_DR",           // 0000
	"EV_PH_RES",          // 0001
	"EV_PH_TMA",          // 0010
	"EV_PH_SLD",          // 0011
	"EV_PH_RSY",          // 0100
	"EV_PH_DR6",          // 0101
	"EV_PH_EI",           // 0110
	"EV_PH_PU",           // 0111
	"EV_PH_AR",           // 1000
	"EV_PH_9",            // 1001
	"EV_PH_ARL",          // 1010
	"EV_PH_CVR",          // 1011
	"EV_PH_AI8",          // 1100
	"EV_PH_AI10",         // 1101
	"EV_PH_AIL",          // 1110
	"EV_PH_DC",           // 1111
	"EV_PH_ACTIVATE_REQ",
	"EV_PH_DEACTIVATE_REQ",
	"EV_TIMER3",
};


static inline void D_L1L2(struct isac *isac, int pr, void *arg) { struct hisax_if *ifc = (struct hisax_if *) &isac->hisax_d_if; DBG(DBG_PR, "pr %#x", pr); ifc->l1l2(ifc, pr, arg); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds54100.00%1100.00%
Total54100.00%1100.00%


static void ph_command(struct isac *isac, unsigned int command) { DBG(DBG_L1M, "ph_command %#x", command); switch (isac->type) { case TYPE_ISAC: isac->write_isac(isac, ISAC_CIX0, (command << 2) | 3); break; case TYPE_ISACSX: isac->write_isac(isac, ISACSX_CIX0, (command << 4) | (7 << 1)); break; } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds78100.00%1100.00%
Total78100.00%1100.00%

// ----------------------------------------------------------------------
static void l1_di(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_RESET); ph_command(isac, ISAC_CMD_DI); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds41100.00%1100.00%
Total41100.00%1100.00%


static void l1_di_deact_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_RESET); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); ph_command(isac, ISAC_CMD_DI); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds52100.00%1100.00%
Total52100.00%1100.00%


static void l1_go_f3pdown(struct FsmInst *fi, int event, void *arg) { FsmChangeState(fi, ST_L1_F3_PDOWN); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds25100.00%1100.00%
Total25100.00%1100.00%


static void l1_go_f3pend_deact_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_F3_PEND_DEACT); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); ph_command(isac, ISAC_CMD_DI); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds52100.00%1100.00%
Total52100.00%1100.00%


static void l1_go_f3pend(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_F3_PEND_DEACT); ph_command(isac, ISAC_CMD_DI); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds41100.00%1100.00%
Total41100.00%1100.00%


static void l1_go_f4(struct FsmInst *fi, int event, void *arg) { FsmChangeState(fi, ST_L1_F4); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds25100.00%1100.00%
Total25100.00%1100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds25100.00%1100.00%
Total25100.00%1100.00%


static void l1_go_f6(struct FsmInst *fi, int event, void *arg) { FsmChangeState(fi, ST_L1_F6); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds25100.00%1100.00%
Total25100.00%1100.00%


static void l1_go_f6_deact_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_F6); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds45100.00%1100.00%
Total45100.00%1100.00%


static void l1_go_f7_act_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmDelTimer(&isac->timer, 0); FsmChangeState(fi, ST_L1_F7); ph_command(isac, ISAC_CMD_AR8); D_L1L2(isac, PH_ACTIVATE | INDICATION, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds62100.00%1100.00%
Total62100.00%1100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds25100.00%1100.00%
Total25100.00%1100.00%


static void l1_go_f8_deact_ind(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmChangeState(fi, ST_L1_F8); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds45100.00%1100.00%
Total45100.00%1100.00%


static void l1_ar8(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; FsmRestartTimer(&isac->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); ph_command(isac, ISAC_CMD_AR8); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds50100.00%1100.00%
Total50100.00%1100.00%


static void l1_timer3(struct FsmInst *fi, int event, void *arg) { struct isac *isac = fi->userdata; ph_command(isac, ISAC_CMD_DI); D_L1L2(isac, PH_DEACTIVATE | INDICATION, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds45100.00%1100.00%
Total45100.00%1100.00%

// state machines according to data sheet PSB 2186 / 3186 static struct FsmNode L1FnList[] __initdata = { {ST_L1_RESET, EV_PH_RES, l1_di}, {ST_L1_RESET, EV_PH_EI, l1_di}, {ST_L1_RESET, EV_PH_DC, l1_go_f3pdown}, {ST_L1_RESET, EV_PH_AR, l1_go_f6}, {ST_L1_RESET, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F3_PDOWN, EV_PH_RES, l1_di}, {ST_L1_F3_PDOWN, EV_PH_EI, l1_di}, {ST_L1_F3_PDOWN, EV_PH_AR, l1_go_f6}, {ST_L1_F3_PDOWN, EV_PH_RSY, l1_go_f5}, {ST_L1_F3_PDOWN, EV_PH_PU, l1_go_f4}, {ST_L1_F3_PDOWN, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F3_PDOWN, EV_PH_ACTIVATE_REQ, l1_ar8}, {ST_L1_F3_PDOWN, EV_TIMER3, l1_timer3}, {ST_L1_F3_PEND_DEACT, EV_PH_RES, l1_di}, {ST_L1_F3_PEND_DEACT, EV_PH_EI, l1_di}, {ST_L1_F3_PEND_DEACT, EV_PH_DC, l1_go_f3pdown}, {ST_L1_F3_PEND_DEACT, EV_PH_RSY, l1_go_f5}, {ST_L1_F3_PEND_DEACT, EV_PH_AR, l1_go_f6}, {ST_L1_F3_PEND_DEACT, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F4, EV_PH_RES, l1_di}, {ST_L1_F4, EV_PH_EI, l1_di}, {ST_L1_F4, EV_PH_RSY, l1_go_f5}, {ST_L1_F4, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F4, EV_TIMER3, l1_timer3}, {ST_L1_F4, EV_PH_DC, l1_go_f3pdown}, {ST_L1_F5, EV_PH_RES, l1_di}, {ST_L1_F5, EV_PH_EI, l1_di}, {ST_L1_F5, EV_PH_AR, l1_go_f6}, {ST_L1_F5, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F5, EV_TIMER3, l1_timer3}, {ST_L1_F5, EV_PH_DR, l1_go_f3pend}, {ST_L1_F5, EV_PH_DC, l1_go_f3pdown}, {ST_L1_F6, EV_PH_RES, l1_di}, {ST_L1_F6, EV_PH_EI, l1_di}, {ST_L1_F6, EV_PH_RSY, l1_go_f8}, {ST_L1_F6, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F6, EV_PH_DR6, l1_go_f3pend}, {ST_L1_F6, EV_TIMER3, l1_timer3}, {ST_L1_F6, EV_PH_DC, l1_go_f3pdown}, {ST_L1_F7, EV_PH_RES, l1_di_deact_ind}, {ST_L1_F7, EV_PH_EI, l1_di_deact_ind}, {ST_L1_F7, EV_PH_AR, l1_go_f6_deact_ind}, {ST_L1_F7, EV_PH_RSY, l1_go_f8_deact_ind}, {ST_L1_F7, EV_PH_DR, l1_go_f3pend_deact_ind}, {ST_L1_F8, EV_PH_RES, l1_di}, {ST_L1_F8, EV_PH_EI, l1_di}, {ST_L1_F8, EV_PH_AR, l1_go_f6}, {ST_L1_F8, EV_PH_DR, l1_go_f3pend}, {ST_L1_F8, EV_PH_AI8, l1_go_f7_act_ind}, {ST_L1_F8, EV_TIMER3, l1_timer3}, {ST_L1_F8, EV_PH_DC, l1_go_f3pdown}, };
static void l1m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; char buf[256]; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); DBG(DBG_L1M, "%s", buf); va_end(args); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds5590.16%150.00%
Alexey Dobriyan69.84%150.00%
Total61100.00%2100.00%


static void isac_version(struct isac *cs) { int val; val = cs->read_isac(cs, ISAC_RBCH); DBG(1, "ISAC version (%x): %s", val, ISACVer[(val >> 5) & 3]); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds45100.00%1100.00%
Total45100.00%1100.00%


static void isac_empty_fifo(struct isac *isac, int count) { // this also works for isacsx, since // CMDR(D) register works the same u_char *ptr; DBG(DBG_IRQ, "count %d", count); if ((isac->rcvidx + count) >= MAX_DFRAME_LEN_L1) { DBG(DBG_WARN, "overrun %d", isac->rcvidx + count); isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); isac->rcvidx = 0; return; } ptr = isac->rcvbuf + isac->rcvidx; isac->rcvidx += count; isac->read_isac_fifo(isac, ptr, count); isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); DBG_PACKET(DBG_RFIFO, ptr, count); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds12099.17%150.00%
Andrew Morton10.83%150.00%
Total121100.00%2100.00%


static void isac_fill_fifo(struct isac *isac) { // this also works for isacsx, since // CMDR(D) register works the same int count; unsigned char cmd; u_char *ptr; BUG_ON(!isac->tx_skb); count = isac->tx_skb->len; BUG_ON(count <= 0); DBG(DBG_IRQ, "count %d", count); if (count > 0x20) { count = 0x20; cmd = ISAC_CMDR_XTF; } else { cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME; } ptr = isac->tx_skb->data; skb_pull(isac->tx_skb, count); isac->tx_cnt += count; DBG_PACKET(DBG_XFIFO, ptr, count); isac->write_isac_fifo(isac, ptr, count); isac->write_isac(isac, ISAC_CMDR, cmd); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds12894.81%133.33%
Eric Sesterhenn / Snakebyte64.44%133.33%
Andrew Morton10.74%133.33%
Total135100.00%3100.00%


static void isac_retransmit(struct isac *isac) { if (!isac->tx_skb) { DBG(DBG_WARN, "no skb"); return; } skb_push(isac->tx_skb, isac->tx_cnt); isac->tx_cnt = 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds45100.00%1100.00%
Total45100.00%1100.00%


static inline void isac_cisq_interrupt(struct isac *isac) { unsigned char val; val = isac->read_isac(isac, ISAC_CIR0); DBG(DBG_IRQ, "CIR0 %#x", val); if (val & ISAC_CIR0_CIC0) { DBG(DBG_IRQ, "CODR0 %#x", (val >> 2) & 0xf); FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL); } if (val & ISAC_CIR0_CIC1) { val = isac->read_isac(isac, ISAC_CIR1); DBG(DBG_WARN, "ISAC CIR1 %#x", val); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds105100.00%1100.00%
Total105100.00%1100.00%


static inline void isac_rme_interrupt(struct isac *isac) { unsigned char val; int count; struct sk_buff *skb; val = isac->read_isac(isac, ISAC_RSTA); if ((val & (ISAC_RSTA_RDO | ISAC_RSTA_CRC | ISAC_RSTA_RAB)) != ISAC_RSTA_CRC) { DBG(DBG_WARN, "RSTA %#x, dropped", val); isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); goto out; } count = isac->read_isac(isac, ISAC_RBCL) & 0x1f; DBG(DBG_IRQ, "RBCL %#x", count); if (count == 0) count = 0x20; isac_empty_fifo(isac, count); count = isac->rcvidx; if (count < 1) { DBG(DBG_WARN, "count %d < 1", count); goto out; } skb = alloc_skb(count, GFP_ATOMIC); if (!skb) { DBG(DBG_WARN, "no memory, dropping\n"); goto out; } skb_put_data(skb, isac->rcvbuf, count); DBG_SKB(DBG_RPACKET, skb); D_L1L2(isac, PH_DATA | INDICATION, skb); out: isac->rcvidx = 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds20399.51%150.00%
Johannes Berg10.49%150.00%
Total204100.00%2100.00%


static inline void isac_xpr_interrupt(struct isac *isac) { if (!isac->tx_skb) return; if (isac->tx_skb->len > 0) { isac_fill_fifo(isac); return; } dev_kfree_skb_irq(isac->tx_skb); isac->tx_cnt = 0; isac->tx_skb = NULL; D_L1L2(isac, PH_DATA | CONFIRM, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds68100.00%1100.00%
Total68100.00%1100.00%


static inline void isac_exi_interrupt(struct isac *isac) { unsigned char val; val = isac->read_isac(isac, ISAC_EXIR); DBG(2, "EXIR %#x", val); if (val & ISAC_EXIR_XMR) { DBG(DBG_WARN, "ISAC XMR"); isac_retransmit(isac); } if (val & ISAC_EXIR_XDU) { DBG(DBG_WARN, "ISAC XDU"); isac_retransmit(isac); } if (val & ISAC_EXIR_MOS) { /* MOS */ DBG(DBG_WARN, "MOS"); val = isac->read_isac(isac, ISAC_MOSR); DBG(2, "ISAC MOSR %#x", val); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds112100.00%1100.00%
Total112100.00%1100.00%


void isac_irq(struct isac *isac) { unsigned char val; val = isac->read_isac(isac, ISAC_ISTA); DBG(DBG_IRQ, "ISTA %#x", val); if (val & ISAC_ISTA_EXI) { DBG(DBG_IRQ, "EXI"); isac_exi_interrupt(isac); } if (val & ISAC_ISTA_XPR) { DBG(DBG_IRQ, "XPR"); isac_xpr_interrupt(isac); } if (val & ISAC_ISTA_RME) { DBG(DBG_IRQ, "RME"); isac_rme_interrupt(isac); } if (val & ISAC_ISTA_RPF) { DBG(DBG_IRQ, "RPF"); isac_empty_fifo(isac, 0x20); } if (val & ISAC_ISTA_CISQ) { DBG(DBG_IRQ, "CISQ"); isac_cisq_interrupt(isac); } if (val & ISAC_ISTA_RSC) { DBG(DBG_WARN, "RSC"); } if (val & ISAC_ISTA_SIN) { DBG(DBG_WARN, "SIN"); } isac->write_isac(isac, ISAC_MASK, 0xff); isac->write_isac(isac, ISAC_MASK, 0x00); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds188100.00%2100.00%
Total188100.00%2100.00%

// ======================================================================
static inline void isacsx_cic_interrupt(struct isac *isac) { unsigned char val; val = isac->read_isac(isac, ISACSX_CIR0); DBG(DBG_IRQ, "CIR0 %#x", val); if (val & ISACSX_CIR0_CIC0) { DBG(DBG_IRQ, "CODR0 %#x", val >> 4); FsmEvent(&isac->l1m, val >> 4, NULL); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds69100.00%1100.00%
Total69100.00%1100.00%


static inline void isacsx_rme_interrupt(struct isac *isac) { int count; struct sk_buff *skb; unsigned char val; val = isac->read_isac(isac, ISACSX_RSTAD); if ((val & (ISACSX_RSTAD_VFR | ISACSX_RSTAD_RDO | ISACSX_RSTAD_CRC | ISACSX_RSTAD_RAB)) != (ISACSX_RSTAD_VFR | ISACSX_RSTAD_CRC)) { DBG(DBG_WARN, "RSTAD %#x, dropped", val); isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC); goto out; } count = isac->read_isac(isac, ISACSX_RBCLD) & 0x1f; DBG(DBG_IRQ, "RBCLD %#x", count); if (count == 0) count = 0x20; isac_empty_fifo(isac, count); // strip trailing status byte count = isac->rcvidx - 1; if (count < 1) { DBG(DBG_WARN, "count %d < 1", count); goto out; } skb = dev_alloc_skb(count); if (!skb) { DBG(DBG_WARN, "no memory, dropping"); goto out; } skb_put_data(skb, isac->rcvbuf, count); DBG_SKB(DBG_RPACKET, skb); D_L1L2(isac, PH_DATA | INDICATION, skb); out: isac->rcvidx = 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds21099.53%150.00%
Johannes Berg10.47%150.00%
Total211100.00%2100.00%


static inline void isacsx_xpr_interrupt(struct isac *isac) { if (!isac->tx_skb) return; if (isac->tx_skb->len > 0) { isac_fill_fifo(isac); return; } dev_kfree_skb_irq(isac->tx_skb); isac->tx_skb = NULL; isac->tx_cnt = 0; D_L1L2(isac, PH_DATA | CONFIRM, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds68100.00%1100.00%
Total68100.00%1100.00%


static inline void isacsx_icd_interrupt(struct isac *isac) { unsigned char val; val = isac->read_isac(isac, ISACSX_ISTAD); DBG(DBG_IRQ, "ISTAD %#x", val); if (val & ISACSX_ISTAD_XDU) { DBG(DBG_WARN, "ISTAD XDU"); isac_retransmit(isac); } if (val & ISACSX_ISTAD_XMR) { DBG(DBG_WARN, "ISTAD XMR"); isac_retransmit(isac); } if (val & ISACSX_ISTAD_XPR) { DBG(DBG_IRQ, "ISTAD XPR"); isacsx_xpr_interrupt(isac); } if (val & ISACSX_ISTAD_RFO) { DBG(DBG_WARN, "ISTAD RFO"); isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC); } if (val & ISACSX_ISTAD_RME) { DBG(DBG_IRQ, "ISTAD RME"); isacsx_rme_interrupt(isac); } if (val & ISACSX_ISTAD_RPF) { DBG(DBG_IRQ, "ISTAD RPF"); isac_empty_fifo(isac, 0x20); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds164100.00%1100.00%
Total164100.00%1100.00%


void isacsx_irq(struct isac *isac) { unsigned char val; val = isac->read_isac(isac, ISACSX_ISTA); DBG(DBG_IRQ, "ISTA %#x", val); if (val & ISACSX_ISTA_ICD) isacsx_icd_interrupt(isac); if (val & ISACSX_ISTA_CIC) isacsx_cic_interrupt(isac); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds56100.00%2100.00%
Total56100.00%2100.00%


void isac_init(struct isac *isac) { isac->tx_skb = NULL; isac->l1m.fsm = &l1fsm; isac->l1m.state = ST_L1_RESET; #ifdef CONFIG_HISAX_DEBUG isac->l1m.debug = 1; #else isac->l1m.debug = 0; #endif isac->l1m.userdata = isac; isac->l1m.printdebug = l1m_debug; FsmInitTimer(&isac->l1m, &isac->timer); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds85100.00%1100.00%
Total85100.00%1100.00%


void isac_setup(struct isac *isac) { int val, eval; isac->type = TYPE_ISAC; isac_version(isac); ph_command(isac, ISAC_CMD_RES); isac->write_isac(isac, ISAC_MASK, 0xff); isac->mocr = 0xaa; if (test_bit(ISAC_IOM1, &isac->flags)) { /* IOM 1 Mode */ isac->write_isac(isac, ISAC_ADF2, 0x0); isac->write_isac(isac, ISAC_SPCR, 0xa); isac->write_isac(isac, ISAC_ADF1, 0x2); isac->write_isac(isac, ISAC_STCR, 0x70); isac->write_isac(isac, ISAC_MODE, 0xc9); } else { /* IOM 2 Mode */ if (!isac->adf2) isac->adf2 = 0x80; isac->write_isac(isac, ISAC_ADF2, isac->adf2); isac->write_isac(isac, ISAC_SQXR, 0x2f); isac->write_isac(isac, ISAC_SPCR, 0x00); isac->write_isac(isac, ISAC_STCR, 0x70); isac->write_isac(isac, ISAC_MODE, 0xc9); isac->write_isac(isac, ISAC_TIMR, 0x00); isac->write_isac(isac, ISAC_ADF1, 0x00); } val = isac->read_isac(isac, ISAC_STAR); DBG(2, "ISAC STAR %x", val); val = isac->read_isac(isac, ISAC_MODE); DBG(2, "ISAC MODE %x", val); val = isac->read_isac(isac, ISAC_ADF2); DBG(2, "ISAC ADF2 %x", val); val = isac->read_isac(isac, ISAC_ISTA); DBG(2, "ISAC ISTA %x", val); if (val & 0x01) { eval = isac->read_isac(isac, ISAC_EXIR); DBG(2, "ISAC EXIR %x", eval); } val = isac->read_isac(isac, ISAC_CIR0); DBG(2, "ISAC CIR0 %x", val); FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL); isac->write_isac(isac, ISAC_MASK, 0x0); // RESET Receiver and Transmitter isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_XRES | ISAC_CMDR_RRES); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds38699.74%150.00%
Andrew Morton10.26%150.00%
Total387100.00%2100.00%


void isacsx_setup(struct isac *isac) { isac->type = TYPE_ISACSX; // clear LDD isac->write_isac(isac, ISACSX_TR_CONF0, 0x00); // enable transmitter isac->write_isac(isac, ISACSX_TR_CONF2, 0x00); // transparent mode 0, RAC, stop/go isac->write_isac(isac, ISACSX_MODED, 0xc9); // all HDLC IRQ unmasked isac->write_isac(isac, ISACSX_MASKD, 0x03); // unmask ICD, CID IRQs isac->write_isac(isac, ISACSX_MASK, ~(ISACSX_ISTA_ICD | ISACSX_ISTA_CIC)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds81100.00%1100.00%
Total81100.00%1100.00%


void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) { struct isac *isac = hisax_d_if->priv; struct sk_buff *skb = arg; DBG(DBG_PR, "pr %#x", pr); switch (pr) { case PH_ACTIVATE | REQUEST: FsmEvent(&isac->l1m, EV_PH_ACTIVATE_REQ, NULL); break; case PH_DEACTIVATE | REQUEST: FsmEvent(&isac->l1m, EV_PH_DEACTIVATE_REQ, NULL); break; case PH_DATA | REQUEST: DBG(DBG_PR, "PH_DATA REQUEST len %d", skb->len); DBG_SKB(DBG_XPACKET, skb); if (isac->l1m.state != ST_L1_F7) { DBG(1, "L1 wrong state %d\n", isac->l1m.state); dev_kfree_skb(skb); break; } BUG_ON(isac->tx_skb); isac->tx_skb = skb; isac_fill_fifo(isac); break; } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds15498.09%150.00%
Eric Sesterhenn / Snakebyte31.91%150.00%
Total157100.00%2100.00%


static int __init hisax_isac_init(void) { printk(KERN_INFO "hisax_isac: ISAC-S/ISAC-SX ISDN driver v0.1.0\n"); l1fsm.state_count = L1_STATE_COUNT; l1fsm.event_count = L1_EVENT_COUNT; l1fsm.strState = strL1State; l1fsm.strEvent = strL1Event; return FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds53100.00%1100.00%
Total53100.00%1100.00%


static void __exit hisax_isac_exit(void) { FsmFree(&l1fsm); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds15100.00%1100.00%
Total15100.00%1100.00%

EXPORT_SYMBOL(isac_init); EXPORT_SYMBOL(isac_d_l2l1); EXPORT_SYMBOL(isacsx_setup); EXPORT_SYMBOL(isacsx_irq); EXPORT_SYMBOL(isac_setup); EXPORT_SYMBOL(isac_irq); module_init(hisax_isac_init); module_exit(hisax_isac_exit);

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds417899.17%220.00%
Eric Sesterhenn / Snakebyte90.21%110.00%
Andrew Morton80.19%220.00%
Alexey Dobriyan60.14%110.00%
Dave Jones50.12%110.00%
Tejun Heo30.07%110.00%
Johannes Berg20.05%110.00%
Joe Perches20.05%110.00%
Total4213100.00%10100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.