⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hisax_isac.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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/init.h>#include <linux/netdevice.h>#include "hisax_isac.h"// debugging cruft#define __debug_variable debug#include "hisax_debug.h"#ifdef CONFIG_HISAX_DEBUGstatic int debug = 1;module_param(debug, int, 0);static char *ISACVer[] = {  "2086/2186 V1.1",   "2085 B1",   "2085 B2",  "2085 V2.3"};#endifMODULE_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   0x32static 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);}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;	}}// ----------------------------------------------------------------------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);}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);}static void l1_go_f3pdown(struct FsmInst *fi, int event, void *arg){	FsmChangeState(fi, ST_L1_F3_PDOWN);}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);}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);}static void l1_go_f4(struct FsmInst *fi, int event, void *arg){	FsmChangeState(fi, ST_L1_F4);}static void l1_go_f5(struct FsmInst *fi, int event, void *arg){	FsmChangeState(fi, ST_L1_F5);}static void l1_go_f6(struct FsmInst *fi, int event, void *arg){	FsmChangeState(fi, ST_L1_F6);}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);}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);}static void l1_go_f8(struct FsmInst *fi, int event, void *arg){	FsmChangeState(fi, ST_L1_F8);}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);}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);}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);}// state machines according to data sheet PSB 2186 / 3186static 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);	vsprintf(buf, fmt, args);	DBG(DBG_L1M, "%s", buf);	va_end(args);}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]);}static void isac_empty_fifo(struct isac *isac, int count)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -