implement PCM mode
This commit is contained in:
parent
fe89662fca
commit
845651c9ec
|
@ -19,6 +19,7 @@ Rules.make: $(KDIR)/Rules.make Rules.make.ext
|
|||
|
||||
.config: $(KDIR)/.config
|
||||
cp -pf $(KDIR)/.config .
|
||||
cat add.config >> .config
|
||||
|
||||
arch: $(KDIR)/arch
|
||||
rm -f arch
|
||||
|
|
|
@ -44,16 +44,16 @@ endif
|
|||
# endif
|
||||
#endif
|
||||
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) :=
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += hisaxcore.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) :=
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += hisaxcore.o
|
||||
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += fritzpci.o
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += sedlfax.o
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += hfcpci.o
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += hisaxl1.o
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += hisaxl2.o
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += l3udss1.o
|
||||
obj-$(CONFIG_ISDN_DRV_HISAX) += hisaxcapi.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += fritzpci.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += sedlfax.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += hfcpci.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += hisaxl1.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += hisaxl2.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += l3udss1.o
|
||||
obj-$(CONFIG_ISDN_DRV_NEWHISAX) += hisaxcapi.o
|
||||
|
||||
M_OBJS := $(obj-m)
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ DummyProcess_t *contrNewDummyPc(Contr_t *contr);
|
|||
DummyProcess_t *contrId2DummyPc(Contr_t *contr, __u16 invokeId);
|
||||
int contrL4L3(Contr_t *, u_int, int, struct sk_buff *);
|
||||
int contrL3L4(hisaxif_t *, struct sk_buff *);
|
||||
BInst_t *contrSelChannel(Contr_t *, int);
|
||||
BInst_t *contrSelChannel(Contr_t *, u_int);
|
||||
// ---------------------------------------------------------------------------
|
||||
// struct Listen
|
||||
|
||||
|
@ -295,7 +295,7 @@ typedef struct _Cplci {
|
|||
u_char cause[4]; // we may get a cause from l3 DISCONNECT message
|
||||
// which we'll need send in DISCONNECT_IND caused by
|
||||
// l3 RELEASE message
|
||||
int bchannel;
|
||||
u_int bchannel;
|
||||
struct Bprotocol Bprotocol;
|
||||
} Cplci_t;
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
int contrConstr(Contr_t *contr, hisaxstack_t *st, hisax_pid_t *pid, hisaxobject_t *ocapi)
|
||||
{
|
||||
char tmp[10];
|
||||
hisaxstack_t *cst = st->child;
|
||||
BInst_t *binst;
|
||||
char tmp[10];
|
||||
hisaxstack_t *cst = st->child;
|
||||
BInst_t *binst;
|
||||
|
||||
memset(contr, 0, sizeof(Contr_t));
|
||||
memcpy(&contr->inst.pid, pid, sizeof(hisax_pid_t));
|
||||
|
@ -99,9 +99,16 @@ void contrDestr(Contr_t *contr)
|
|||
|
||||
void contrRun(Contr_t *contr)
|
||||
{
|
||||
struct capi_ctr *ctrl = contr->ctrl;
|
||||
|
||||
struct capi_ctr *ctrl = contr->ctrl;
|
||||
BInst_t *binst;
|
||||
int nb;
|
||||
|
||||
nb = 0;
|
||||
binst = contr->binst;
|
||||
while(binst) {
|
||||
nb++;
|
||||
binst = binst->next;
|
||||
}
|
||||
strncpy(ctrl->manu, "ISDN4Linux, (C) Kai Germaschewski", CAPI_MANUFACTURER_LEN);
|
||||
strncpy(ctrl->serial, "0002", CAPI_SERIAL_LEN);
|
||||
ctrl->version.majorversion = 2;
|
||||
|
@ -110,7 +117,7 @@ void contrRun(Contr_t *contr)
|
|||
ctrl->version.minormanuversion = 1;
|
||||
memset(&ctrl->profile, 0, sizeof(struct capi_profile));
|
||||
ctrl->profile.ncontroller = 1;
|
||||
ctrl->profile.nbchannel = 2;
|
||||
ctrl->profile.nbchannel = nb;
|
||||
ctrl->profile.goptions = 0x11; // internal controller, supplementary services
|
||||
ctrl->profile.support1 = 3; // HDLC, TRANS
|
||||
ctrl->profile.support2 = 3; // X75SLP, TRANS
|
||||
|
@ -384,10 +391,12 @@ Contr_t *newContr(hisaxobject_t *ocapi, hisaxstack_t *st, hisax_pid_t *pid)
|
|||
return contr;
|
||||
}
|
||||
|
||||
BInst_t *contrSelChannel(Contr_t *contr, int channr)
|
||||
BInst_t *contrSelChannel(Contr_t *contr, u_int channel)
|
||||
{
|
||||
hisaxstack_t *cst;
|
||||
BInst_t *binst;
|
||||
hisaxstack_t *cst;
|
||||
BInst_t *binst;
|
||||
channel_info_t ci;
|
||||
int ret;
|
||||
|
||||
if (!contr->binst) {
|
||||
cst = contr->inst.st->child;
|
||||
|
@ -410,11 +419,21 @@ BInst_t *contrSelChannel(Contr_t *contr, int channr)
|
|||
cst = cst->next;
|
||||
}
|
||||
}
|
||||
binst = NULL;
|
||||
if (channr == 1)
|
||||
binst = contr->binst;
|
||||
else if (channr == 2)
|
||||
binst = contr->binst->next;
|
||||
ci.channel = channel;
|
||||
ci.st.p = NULL;
|
||||
ret = contr->inst.obj->ctrl(contr->inst.st, MGR_SELCHANNEL | REQUEST,
|
||||
&ci);
|
||||
if (ret) {
|
||||
int_errtxt("ret(%d)", ret);
|
||||
return(NULL);
|
||||
}
|
||||
cst = ci.st.p;
|
||||
binst = contr->binst;
|
||||
while(binst) {
|
||||
if (cst == binst->bst)
|
||||
break;
|
||||
binst = binst->next;
|
||||
}
|
||||
return(binst);
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,47 @@ get_next_instance(hisaxstack_t *st, hisax_pid_t *pid)
|
|||
return(next);
|
||||
}
|
||||
|
||||
static int
|
||||
sel_channel(hisaxstack_t *st, channel_info_t *ci)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (!ci)
|
||||
return(err);
|
||||
printk(KERN_DEBUG __FUNCTION__": st(%p) st->mgr(%p)\n",
|
||||
st, st->mgr);
|
||||
if (st->mgr) {
|
||||
if (st->mgr->obj && st->mgr->obj->own_ctrl) {
|
||||
err = st->mgr->obj->own_ctrl(st->mgr,
|
||||
MGR_SELCHANNEL | REQUEST, ci);
|
||||
printk(KERN_DEBUG __FUNCTION__": MGR_SELCHANNEL(%d)\n",
|
||||
err);
|
||||
} else
|
||||
int_error();
|
||||
} else {
|
||||
printk(KERN_WARNING __FUNCTION__": no mgr st(%p)\n", st);
|
||||
}
|
||||
if (err) {
|
||||
hisaxstack_t *cst = st->child;
|
||||
int nr = 0;
|
||||
|
||||
ci->st.p = NULL;
|
||||
if (!(ci->channel & (~CHANNEL_NUMBER))) {
|
||||
/* only number is set */
|
||||
while(cst) {
|
||||
nr++;
|
||||
if (nr == (ci->channel & 3)) {
|
||||
ci->st.p = cst;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
cst = cst->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
static int
|
||||
disconnect_if(hisaxinstance_t *inst, u_int prim, hisaxif_t *hif) {
|
||||
int err = 0;
|
||||
|
@ -264,6 +305,8 @@ static int central_manager(void *data, u_int prim, void *arg) {
|
|||
return(clear_stack(st));
|
||||
case MGR_DELSTACK | REQUEST:
|
||||
return(release_stack(st));
|
||||
case MGR_SELCHANNEL | REQUEST:
|
||||
return(sel_channel(st, arg));
|
||||
case MGR_ADDIF | REQUEST:
|
||||
return(add_if(data, prim, arg));
|
||||
case MGR_CONNECT | REQUEST:
|
||||
|
|
|
@ -55,6 +55,25 @@ __u16 q931CIPValue(SETUP_t *setup)
|
|||
return CIPValue;
|
||||
}
|
||||
|
||||
u_int plci_parse_channel_id(u_char *p)
|
||||
{
|
||||
u_int cid = -1;
|
||||
int l;
|
||||
|
||||
if (p) {
|
||||
printk(KERN_DEBUG __FUNCTION__": l(%d) %x\n",p[0],p[1]);
|
||||
l = *p++;
|
||||
if (l == 1) {
|
||||
cid = *p;
|
||||
} else if (l == 3) {
|
||||
cid = *p++ << 16;
|
||||
cid |= *p++ << 8;
|
||||
cid |= *p;
|
||||
}
|
||||
}
|
||||
return(cid);
|
||||
}
|
||||
|
||||
__u16 CIPValue2setup(__u16 CIPValue, SETUP_t *setup)
|
||||
{
|
||||
switch (CIPValue) {
|
||||
|
@ -195,6 +214,7 @@ enum {
|
|||
EV_PLCI_SUSPEND_CONF,
|
||||
EV_PLCI_RESUME_REQ,
|
||||
EV_PLCI_RESUME_CONF,
|
||||
EV_PLCI_CHANNEL_ERR,
|
||||
EV_PLCI_CC_SETUP_IND,
|
||||
EV_PLCI_CC_SETUP_CONF_ERR,
|
||||
EV_PLCI_CC_SETUP_CONF,
|
||||
|
@ -231,6 +251,7 @@ static char* str_ev_plci[] = {
|
|||
"EV_PLCI_SUSPEND_CONF",
|
||||
"EV_PLCI_RESUME_REQ",
|
||||
"EV_PLCI_RESUME_CONF",
|
||||
"EV_PLCI_CHANNEL_ERR",
|
||||
"EV_PLCI_CC_SETUP_IND",
|
||||
"EV_PLCI_CC_SETUP_CONF_ERR",
|
||||
"EV_PLCI_CC_SETUP_CONF",
|
||||
|
@ -511,7 +532,10 @@ static void plci_cc_setup_conf(struct FsmInst *fi, int event, void *arg)
|
|||
_cmsg cmsg;
|
||||
CONNECT_t *conn = arg;
|
||||
|
||||
memset(&cmsg, 0, sizeof(_cmsg));
|
||||
if (cplci->bchannel == -1) {/* no valid channel set */
|
||||
FsmEvent(fi, EV_PLCI_CHANNEL_ERR, NULL);
|
||||
return;
|
||||
}
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_CONNECT_ACTIVE, CAPI_IND);
|
||||
if (arg) {
|
||||
cmsg.ConnectedNumber = conn->CONNECT_PN;
|
||||
|
@ -533,13 +557,37 @@ static void plci_cc_setup_conf_err(struct FsmInst *fi, int event, void *arg)
|
|||
cplciRecvCmsg(cplci, &cmsg);
|
||||
}
|
||||
|
||||
static void plci_channel_err(struct FsmInst *fi, int event, void *arg)
|
||||
{
|
||||
Cplci_t *cplci = fi->userdata;
|
||||
Plci_t *plci = cplci->plci;
|
||||
_cmsg cmsg;
|
||||
RELEASE_COMPLETE_t relc;
|
||||
unsigned char cause[4];
|
||||
|
||||
if (!plci) {
|
||||
int_error();
|
||||
return;
|
||||
}
|
||||
memset(&relc, 0, sizeof(RELEASE_COMPLETE_t));
|
||||
cause[0] = 2;
|
||||
cause[1] = 0x80;
|
||||
cause[2] = 0x86; /* channel unacceptable */
|
||||
relc.CAUSE = cause;
|
||||
plciL4L3(plci, CC_RELEASE_COMPLETE | REQUEST, sizeof(RELEASE_COMPLETE_t),
|
||||
&relc);
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_DISCONNECT, CAPI_IND);
|
||||
cmsg.Reason = CapiProtocolErrorLayer3;
|
||||
FsmEvent(&cplci->plci_m, EV_PLCI_DISCONNECT_IND, &cmsg);
|
||||
cplciRecvCmsg(cplci, &cmsg);
|
||||
}
|
||||
|
||||
static void plci_cc_setup_ind(struct FsmInst *fi, int event, void *arg)
|
||||
{
|
||||
Cplci_t *cplci = fi->userdata;
|
||||
SETUP_t *setup = arg;
|
||||
_cmsg cmsg;
|
||||
|
||||
memset(&cmsg, 0, sizeof(_cmsg));
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_CONNECT, CAPI_IND);
|
||||
|
||||
// FIXME: CW
|
||||
|
@ -590,7 +638,6 @@ static void plci_cc_release_ind(struct FsmInst *fi, int event, void *arg)
|
|||
plciDetachCplci(cplci->plci, cplci);
|
||||
|
||||
cplciLinkDown(cplci);
|
||||
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_DISCONNECT, CAPI_IND);
|
||||
if (rel) {
|
||||
if (rel->CAUSE) {
|
||||
|
@ -682,7 +729,6 @@ static void plci_cc_suspend_conf(struct FsmInst *fi, int event, void *arg)
|
|||
plci_suspend_reply(cplci, CapiSuccess);
|
||||
|
||||
plciDetachCplci(cplci->plci, cplci);
|
||||
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_DISCONNECT, CAPI_IND);
|
||||
FsmEvent(&cplci->plci_m, EV_PLCI_DISCONNECT_IND, &cmsg);
|
||||
cplciRecvCmsg(cplci, &cmsg);
|
||||
|
@ -719,7 +765,7 @@ static void plci_cc_resume_conf(struct FsmInst *fi, int event, void *arg)
|
|||
int_error();
|
||||
return;
|
||||
}
|
||||
cplci->bchannel = ack->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(ack->CHANNEL_ID);
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_FACILITY, CAPI_IND);
|
||||
p = &tmp[1];
|
||||
p += capiEncodeWord(p, 0x0005); // Suspend
|
||||
|
@ -778,60 +824,62 @@ static void plci_info_req(struct FsmInst *fi, int event, void *arg)
|
|||
|
||||
static struct FsmNode fn_plci_list[] =
|
||||
{
|
||||
{ST_PLCI_P_0, EV_PLCI_CONNECT_REQ, plci_connect_req},
|
||||
{ST_PLCI_P_0, EV_PLCI_CONNECT_IND, plci_connect_ind},
|
||||
{ST_PLCI_P_0, EV_PLCI_RESUME_REQ, plci_resume_req},
|
||||
{ST_PLCI_P_0, EV_PLCI_CC_SETUP_IND, plci_cc_setup_ind},
|
||||
{ST_PLCI_P_0, EV_PLCI_CONNECT_REQ, plci_connect_req},
|
||||
{ST_PLCI_P_0, EV_PLCI_CONNECT_IND, plci_connect_ind},
|
||||
{ST_PLCI_P_0, EV_PLCI_RESUME_REQ, plci_resume_req},
|
||||
{ST_PLCI_P_0, EV_PLCI_CC_SETUP_IND, plci_cc_setup_ind},
|
||||
|
||||
{ST_PLCI_P_0_1, EV_PLCI_CONNECT_CONF, plci_connect_conf},
|
||||
{ST_PLCI_P_0_1, EV_PLCI_CONNECT_CONF, plci_connect_conf},
|
||||
|
||||
{ST_PLCI_P_1, EV_PLCI_CONNECT_ACTIVE_IND, plci_connect_active_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_1, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_INFO_REQ, plci_info_req_overlap},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_SETUP_CONF, plci_cc_setup_conf},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_SETUP_CONF_ERR, plci_cc_setup_conf_err},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_DISCONNECT_IND, plci_cc_disconnect_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_RELEASE_PROC_IND, plci_cc_setup_conf_err},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_REJECT_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_CONNECT_ACTIVE_IND, plci_connect_active_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_1, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_INFO_REQ, plci_info_req_overlap},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_SETUP_CONF, plci_cc_setup_conf},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_SETUP_CONF_ERR, plci_cc_setup_conf_err},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_DISCONNECT_IND, plci_cc_disconnect_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_RELEASE_PROC_IND, plci_cc_setup_conf_err},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_CC_REJECT_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_1, EV_PLCI_CHANNEL_ERR, plci_channel_err},
|
||||
|
||||
{ST_PLCI_P_2, EV_PLCI_ALERT_REQ, plci_alert_req},
|
||||
{ST_PLCI_P_2, EV_PLCI_CONNECT_RESP, plci_connect_resp},
|
||||
{ST_PLCI_P_2, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_2, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_2, EV_PLCI_INFO_REQ, plci_info_req},
|
||||
{ST_PLCI_P_2, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_2, EV_PLCI_ALERT_REQ, plci_alert_req},
|
||||
{ST_PLCI_P_2, EV_PLCI_CONNECT_RESP, plci_connect_resp},
|
||||
{ST_PLCI_P_2, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_2, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_2, EV_PLCI_INFO_REQ, plci_info_req},
|
||||
{ST_PLCI_P_2, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
|
||||
{ST_PLCI_P_4, EV_PLCI_CONNECT_ACTIVE_IND, plci_connect_active_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_4, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_INFO_REQ, plci_info_req},
|
||||
{ST_PLCI_P_4, EV_PLCI_CC_SETUP_COMPL_IND, plci_cc_setup_compl_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_CONNECT_ACTIVE_IND, plci_connect_active_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_4, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_INFO_REQ, plci_info_req},
|
||||
{ST_PLCI_P_4, EV_PLCI_CC_SETUP_COMPL_IND, plci_cc_setup_compl_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_4, EV_PLCI_CHANNEL_ERR, plci_channel_err},
|
||||
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CONNECT_ACTIVE_RESP, plci_connect_active_resp},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_INFO_REQ, plci_info_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_SELECT_B_PROTOCOL_REQ, plci_select_b_protocol_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_SUSPEND_REQ, plci_suspend_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_SUSPEND_CONF, plci_suspend_conf},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_DISCONNECT_IND, plci_cc_disconnect_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_NOTIFY_IND, plci_cc_notify_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_SUSPEND_ERR, plci_cc_suspend_err},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_SUSPEND_CONF, plci_cc_suspend_conf},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CONNECT_ACTIVE_RESP, plci_connect_active_resp},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_DISCONNECT_REQ, plci_disconnect_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_INFO_REQ, plci_info_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_SELECT_B_PROTOCOL_REQ, plci_select_b_protocol_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_SUSPEND_REQ, plci_suspend_req},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_SUSPEND_CONF, plci_suspend_conf},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_DISCONNECT_IND, plci_cc_disconnect_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_NOTIFY_IND, plci_cc_notify_ind},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_SUSPEND_ERR, plci_cc_suspend_err},
|
||||
{ST_PLCI_P_ACT, EV_PLCI_CC_SUSPEND_CONF, plci_cc_suspend_conf},
|
||||
|
||||
{ST_PLCI_P_5, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_5, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
{ST_PLCI_P_5, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_5, EV_PLCI_CC_RELEASE_IND, plci_cc_release_ind},
|
||||
|
||||
{ST_PLCI_P_6, EV_PLCI_DISCONNECT_RESP, plci_disconnect_resp},
|
||||
{ST_PLCI_P_6, EV_PLCI_DISCONNECT_RESP, plci_disconnect_resp},
|
||||
|
||||
{ST_PLCI_P_RES, EV_PLCI_RESUME_CONF, plci_resume_conf},
|
||||
{ST_PLCI_P_RES, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_RES, EV_PLCI_CC_RESUME_ERR, plci_cc_resume_err},
|
||||
{ST_PLCI_P_RES, EV_PLCI_CC_RESUME_CONF, plci_cc_resume_conf},
|
||||
{ST_PLCI_P_RES, EV_PLCI_RESUME_CONF, plci_resume_conf},
|
||||
{ST_PLCI_P_RES, EV_PLCI_DISCONNECT_IND, plci_disconnect_ind},
|
||||
{ST_PLCI_P_RES, EV_PLCI_CC_RESUME_ERR, plci_cc_resume_err},
|
||||
{ST_PLCI_P_RES, EV_PLCI_CC_RESUME_CONF, plci_cc_resume_conf},
|
||||
|
||||
#if 0
|
||||
{ST_PLCI_P_0, EV_PLCI_FACILITY_IND, plci_facility_ind_p_0_off_hook},
|
||||
|
@ -917,7 +965,7 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
|
|||
cplciInfoIndIE(cplci, IE_CHANNEL_ID, CAPI_INFOMASK_CHANNELID,
|
||||
p.setup->CHANNEL_ID);
|
||||
if (p.setup->CHANNEL_ID)
|
||||
cplci->bchannel = p.setup->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(p.setup->CHANNEL_ID);
|
||||
FsmEvent(&cplci->plci_m, EV_PLCI_CC_SETUP_IND, arg);
|
||||
break;
|
||||
case CC_TIMEOUT | INDICATION:
|
||||
|
@ -938,7 +986,7 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
|
|||
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
|
||||
CAPI_INFOMASK_CHANNELID, p.conn->CHANNEL_ID);
|
||||
if (p.conn->CHANNEL_ID)
|
||||
cplci->bchannel = p.conn->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(p.conn->CHANNEL_ID);
|
||||
}
|
||||
FsmEvent(&cplci->plci_m, EV_PLCI_CC_SETUP_CONF, arg);
|
||||
break;
|
||||
|
@ -949,7 +997,7 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
|
|||
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
|
||||
CAPI_INFOMASK_CHANNELID, p.c_ack->CHANNEL_ID);
|
||||
if (p.c_ack->CHANNEL_ID)
|
||||
cplci->bchannel = p.c_ack->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(p.c_ack->CHANNEL_ID);
|
||||
}
|
||||
FsmEvent(&cplci->plci_m, EV_PLCI_CC_SETUP_COMPL_IND, arg);
|
||||
break;
|
||||
|
@ -1010,7 +1058,7 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
|
|||
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
|
||||
CAPI_INFOMASK_CHANNELID, p.s_ack->CHANNEL_ID);
|
||||
if (p.s_ack->CHANNEL_ID)
|
||||
cplci->bchannel = p.s_ack->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(p.s_ack->CHANNEL_ID);
|
||||
}
|
||||
break;
|
||||
case CC_PROCEEDING | INDICATION:
|
||||
|
@ -1025,7 +1073,7 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
|
|||
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
|
||||
CAPI_INFOMASK_CHANNELID, p.proc->CHANNEL_ID);
|
||||
if (p.proc->CHANNEL_ID)
|
||||
cplci->bchannel = p.proc->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(p.proc->CHANNEL_ID);
|
||||
}
|
||||
break;
|
||||
case CC_ALERTING | INDICATION:
|
||||
|
@ -1044,7 +1092,7 @@ void cplci_l3l4(Cplci_t *cplci, int pr, void *arg)
|
|||
cplciInfoIndIE(cplci, IE_CHANNEL_ID,
|
||||
CAPI_INFOMASK_CHANNELID, p.alert->CHANNEL_ID);
|
||||
if (p.alert->CHANNEL_ID)
|
||||
cplci->bchannel = p.alert->CHANNEL_ID[1];
|
||||
cplci->bchannel = plci_parse_channel_id(p.alert->CHANNEL_ID);
|
||||
}
|
||||
break;
|
||||
case CC_PROGRESS | INDICATION:
|
||||
|
@ -1137,12 +1185,6 @@ void cplciLinkUp(Cplci_t *cplci)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(cplci->bchannel & 3) || ((cplci->bchannel & 3) == 3)) {
|
||||
// at the moment only B-channel 1 or B-channel 2 allowed
|
||||
int_error();
|
||||
return;
|
||||
}
|
||||
|
||||
cplci->ncci = kmalloc(sizeof(Ncci_t), GFP_ATOMIC);
|
||||
if (!cplci->ncci) {
|
||||
int_error();
|
||||
|
@ -1214,7 +1256,6 @@ void cplciClearOtherApps(Cplci_t *cplci)
|
|||
cp = plci->cplcis[applId - 1];
|
||||
if (cp && (cp != cplci)) {
|
||||
plciDetachCplci(plci, cp);
|
||||
|
||||
cplciCmsgHeader(cp, &cm, CAPI_DISCONNECT, CAPI_IND);
|
||||
cm.Reason = 0x3304; // other application got the call
|
||||
FsmEvent(&cp->plci_m, EV_PLCI_DISCONNECT_IND, &cm);
|
||||
|
@ -1248,7 +1289,6 @@ void cplciInfoIndIE(Cplci_t *cplci, unsigned char ie, __u32 mask, u_char *iep)
|
|||
cplciLinkUp(cplci);
|
||||
}
|
||||
}
|
||||
|
||||
cplciCmsgHeader(cplci, &cmsg, CAPI_INFO, CAPI_IND);
|
||||
cmsg.InfoNumber = ie;
|
||||
cmsg.InfoElement = iep;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/* $Id$
|
||||
|
||||
* hfc_pci.c low level driver for CCD´s hfc-pci based cards
|
||||
* hfc_pci.c low level driver for CCD's hfc-pci based cards
|
||||
*
|
||||
* Author Werner Cornelius (werner@isdn4linux.de)
|
||||
* based on existing driver for CCD hfc ISA cards
|
||||
* type approval valid for HFC-S PCI A based card
|
||||
*
|
||||
* Copyright 1999 by Werner Cornelius (werner@isdn-development.de)
|
||||
* Copyright 1999 by Karsten Keil (keil@isdn4linux.de)
|
||||
* Copyright 2001 by Karsten Keil (keil@isdn4linux.de)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -115,51 +115,59 @@ static const PCI_ENTRY id_list[] =
|
|||
|
||||
|
||||
struct hfcPCI_hw {
|
||||
unsigned char cirm;
|
||||
unsigned char ctmt;
|
||||
unsigned char clkdel;
|
||||
unsigned char states;
|
||||
unsigned char conn;
|
||||
unsigned char mst_m;
|
||||
unsigned char int_m1;
|
||||
unsigned char int_m2;
|
||||
unsigned char int_s1;
|
||||
unsigned char sctrl;
|
||||
unsigned char sctrl_r;
|
||||
unsigned char sctrl_e;
|
||||
unsigned char trm;
|
||||
unsigned char stat;
|
||||
unsigned char fifo;
|
||||
unsigned char fifo_en;
|
||||
unsigned char bswapped;
|
||||
unsigned char nt_mode;
|
||||
int nt_timer;
|
||||
unsigned char pci_bus;
|
||||
unsigned char pci_device_fn;
|
||||
unsigned char *pci_io; /* start of PCI IO memory */
|
||||
void *share_start; /* shared memory for Fifos start */
|
||||
void *fifos; /* FIFO memory */
|
||||
int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
|
||||
struct timer_list timer;
|
||||
unsigned char cirm;
|
||||
unsigned char ctmt;
|
||||
unsigned char clkdel;
|
||||
unsigned char states;
|
||||
unsigned char conn;
|
||||
unsigned char mst_m;
|
||||
unsigned char int_m1;
|
||||
unsigned char int_m2;
|
||||
unsigned char int_s1;
|
||||
unsigned char sctrl;
|
||||
unsigned char sctrl_r;
|
||||
unsigned char sctrl_e;
|
||||
unsigned char trm;
|
||||
unsigned char stat;
|
||||
unsigned char fifo;
|
||||
unsigned char fifo_en;
|
||||
unsigned char bswapped;
|
||||
unsigned char nt_mode;
|
||||
int nt_timer;
|
||||
unsigned char pci_bus;
|
||||
unsigned char pci_device_fn;
|
||||
unsigned char *pci_io; /* start of PCI IO memory */
|
||||
void *share_start; /* shared memory for Fifos start */
|
||||
void *fifos; /* FIFO memory */
|
||||
int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
|
||||
timer_t timer;
|
||||
};
|
||||
|
||||
typedef struct hfcPCI_hw hfcPCI_hw_t;
|
||||
|
||||
#define SPIN_DEBUG
|
||||
#define HFC_CFG_MASTER 1
|
||||
#define HFC_CFG_SLAVE 2
|
||||
#define HFC_CFG_PCM 3
|
||||
#define HFC_CFG_2HFC 4
|
||||
#define HFC_CFG_SLAVEHFC 5
|
||||
|
||||
typedef struct _hfc_pci {
|
||||
struct _hfc_pci *prev;
|
||||
struct _hfc_pci *next;
|
||||
u_char subtyp;
|
||||
u_char chanlimit;
|
||||
u_int irq;
|
||||
u_int addr;
|
||||
struct hfcPCI_hw hw;
|
||||
spinlock_t devlock;
|
||||
u_long flags;
|
||||
struct _hfc_pci *prev;
|
||||
struct _hfc_pci *next;
|
||||
u_char subtyp;
|
||||
u_char chanlimit;
|
||||
u_int cfg;
|
||||
u_int irq;
|
||||
u_int addr;
|
||||
hfcPCI_hw_t hw;
|
||||
spinlock_t devlock;
|
||||
u_long flags;
|
||||
#ifdef SPIN_DEBUG
|
||||
void *lock_adr;
|
||||
void *lock_adr;
|
||||
#endif
|
||||
dchannel_t dch;
|
||||
bchannel_t bch[2];
|
||||
dchannel_t dch;
|
||||
bchannel_t bch[2];
|
||||
} hfc_pci_t;
|
||||
|
||||
|
||||
|
@ -255,7 +263,8 @@ reset_hfcpci(hfc_pci_t *hc)
|
|||
hc->hw.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */
|
||||
hc->hw.sctrl_r = 0;
|
||||
hc->hw.sctrl_e = HFCPCI_AUTO_AWAKE; /* S/T Auto awake */
|
||||
hc->hw.mst_m = HFCPCI_MASTER; /* HFC Master Mode */
|
||||
if (test_bit(HFC_CFG_MASTER, &hc->cfg))
|
||||
hc->hw.mst_m = HFCPCI_MASTER; /* HFC Master Mode */
|
||||
if (hc->hw.nt_mode) {
|
||||
hc->hw.clkdel = CLKDEL_NT; /* ST-Bit delay for NT-Mode */
|
||||
hc->hw.sctrl |= SCTRL_MODE_NT; /* NT-MODE */
|
||||
|
@ -349,9 +358,9 @@ static
|
|||
bchannel_t *
|
||||
Sel_BCS(hfc_pci_t *hc, int channel)
|
||||
{
|
||||
if (hc->bch[0].protocol && (hc->bch[0].channel == channel))
|
||||
if (hc->bch[0].protocol && (hc->bch[0].channel & channel))
|
||||
return (&hc->bch[0]);
|
||||
else if (hc->bch[1].protocol && (hc->bch[1].channel == channel))
|
||||
else if (hc->bch[1].protocol && (hc->bch[1].channel & channel))
|
||||
return (&hc->bch[1]);
|
||||
else
|
||||
return (NULL);
|
||||
|
@ -621,7 +630,7 @@ main_rec_hfcpci(bchannel_t *bch)
|
|||
z_type *zp;
|
||||
|
||||
|
||||
if ((bch->channel) && (!hc->hw.bswapped)) {
|
||||
if ((bch->channel & 2) && (!hc->hw.bswapped)) {
|
||||
bz = &((fifo_area *) (hc->hw.fifos))->b_chans.rxbz_b2;
|
||||
bdata = ((fifo_area *) (hc->hw.fifos))->b_chans.rxdat_b2;
|
||||
real_fifo = 1;
|
||||
|
@ -636,13 +645,13 @@ main_rec_hfcpci(bchannel_t *bch)
|
|||
cli();
|
||||
if (test_and_set_bit(FLG_LOCK_ATOMIC, &hc->dch.DFlags)) {
|
||||
restore_flags(flags);
|
||||
debugprint(&bch->inst, "rec_data %d blocked", bch->channel);
|
||||
debugprint(&bch->inst, "rec_data ch(%x) blocked", bch->channel);
|
||||
return;
|
||||
}
|
||||
restore_flags(flags);
|
||||
if (bz->f1 != bz->f2) {
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, "hfcpci rec %d f1(%d) f2(%d)",
|
||||
debugprint(&bch->inst, "hfcpci rec ch(%x) f1(%d) f2(%d)",
|
||||
bch->channel, bz->f1, bz->f2);
|
||||
zp = &bz->za[bz->f2];
|
||||
|
||||
|
@ -651,7 +660,7 @@ main_rec_hfcpci(bchannel_t *bch)
|
|||
rcnt += B_FIFO_SIZE;
|
||||
rcnt++;
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, "hfcpci rec %d z1(%x) z2(%x) cnt(%d)",
|
||||
debugprint(&bch->inst, "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)",
|
||||
bch->channel, zp->z1, zp->z2, rcnt);
|
||||
if ((skb = hfcpci_empty_fifo(bch, bz, bdata, rcnt))) {
|
||||
skb_queue_tail(&bch->rqueue, skb);
|
||||
|
@ -796,7 +805,7 @@ hfcpci_fill_fifo(bchannel_t *bch)
|
|||
if (bch->tx_len <= 0)
|
||||
return;
|
||||
|
||||
if ((bch->channel) && (!hc->hw.bswapped)) {
|
||||
if ((bch->channel & 2) && (!hc->hw.bswapped)) {
|
||||
bz = &((fifo_area *) (hc->hw.fifos))->b_chans.txbz_b2;
|
||||
bdata = ((fifo_area *) (hc->hw.fifos))->b_chans.txdat_b2;
|
||||
} else {
|
||||
|
@ -808,7 +817,7 @@ hfcpci_fill_fifo(bchannel_t *bch)
|
|||
z1t = &bz->za[MAX_B_FRAMES].z1;
|
||||
z2t = z1t + 1;
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, "hfcpci_fill_fifo_trans%d cnt(%d) z1(%x) z2(%x)",
|
||||
debugprint(&bch->inst, "hfcpci_fill_fifo_trans ch(%x) cnt(%d) z1(%x) z2(%x)",
|
||||
bch->channel, count, *z1t, *z2t);
|
||||
fcnt = *z2t - *z1t;
|
||||
if (fcnt <= 0)
|
||||
|
@ -841,7 +850,7 @@ next_t_frame:
|
|||
fcnt += bch->tx_len;
|
||||
*z1t = new_z1; /* now send data */
|
||||
} else if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, "hfcpci_fill_fifo_trans %d frame length %d discarded",
|
||||
debugprint(&bch->inst, "hfcpci_fill_fifo_trans ch(%x) frame length %d discarded",
|
||||
bch->channel, bch->tx_len);
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flag)) {
|
||||
if (bch->next_skb) {
|
||||
|
@ -861,7 +870,7 @@ next_t_frame:
|
|||
return;
|
||||
}
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, __FUNCTION__": %d f1(%d) f2(%d) z1(f1)(%x)",
|
||||
debugprint(&bch->inst, __FUNCTION__": ch(%x) f1(%d) f2(%d) z1(f1)(%x)",
|
||||
bch->channel, bz->f1, bz->f2, bz->za[bz->f1].z1);
|
||||
fcnt = bz->f1 - bz->f2; /* frame count actually buffered */
|
||||
if (fcnt < 0)
|
||||
|
@ -877,7 +886,7 @@ next_t_frame:
|
|||
maxlen += B_FIFO_SIZE; /* count now contains available bytes */
|
||||
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, "hfcpci_fill_fifo %d count(%ld/%d),%lx",
|
||||
debugprint(&bch->inst, "hfcpci_fill_fifo ch(%x) count(%ld/%d),%lx",
|
||||
bch->channel, count,
|
||||
maxlen, current->state);
|
||||
|
||||
|
@ -926,7 +935,7 @@ hfcpci_send_data(bchannel_t *bch)
|
|||
hfcpci_fill_fifo(bch);
|
||||
test_and_clear_bit(FLG_LOCK_ATOMIC, &hc->dch.DFlags);
|
||||
} else {
|
||||
debugprint(&bch->inst, "send_data %d blocked", bch->channel);
|
||||
debugprint(&bch->inst, "send_data ch(%x) blocked", bch->channel);
|
||||
hfcpci_sched_event(bch, B_BLOCKEDATOMIC);
|
||||
}
|
||||
}
|
||||
|
@ -1201,7 +1210,7 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
hc->hw.int_s1 = exval;
|
||||
}
|
||||
if (val & 0x08) {
|
||||
if (!(bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 0))) {
|
||||
if (!(bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1))) {
|
||||
if (hc->dch.debug)
|
||||
debugprint(&hc->dch.inst, "hfcpci spurious 0x08 IRQ");
|
||||
} else
|
||||
|
@ -1211,14 +1220,14 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
// if (hc->logecho)
|
||||
// receive_emsg(hc);
|
||||
// else
|
||||
if (!(bch = Sel_BCS(hc, 1))) {
|
||||
if (!(bch = Sel_BCS(hc, 2))) {
|
||||
if (hc->dch.debug)
|
||||
debugprint(&hc->dch.inst, "hfcpci spurious 0x10 IRQ");
|
||||
} else
|
||||
main_rec_hfcpci(bch);
|
||||
}
|
||||
if (val & 0x01) {
|
||||
if (!(bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 0))) {
|
||||
if (!(bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1))) {
|
||||
if (hc->dch.debug)
|
||||
debugprint(&hc->dch.inst, "hfcpci spurious 0x01 IRQ");
|
||||
} else {
|
||||
|
@ -1248,7 +1257,7 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
}
|
||||
}
|
||||
if (val & 0x02) {
|
||||
if (!(bch = Sel_BCS(hc, 1))) {
|
||||
if (!(bch = Sel_BCS(hc, 2))) {
|
||||
if (hc->dch.debug)
|
||||
debugprint(&hc->dch.inst, "hfcpci spurious 0x02 IRQ");
|
||||
} else {
|
||||
|
@ -1368,7 +1377,8 @@ HFCD_l1hw(hisaxif_t *hif, struct sk_buff *skb)
|
|||
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
|
||||
dch->inst.lock(dch->inst.data);
|
||||
if ((hh->dinfo == INFO3_P8) || (hh->dinfo == INFO3_P10)) {
|
||||
hc->hw.mst_m |= HFCPCI_MASTER;
|
||||
if (test_bit(HFC_CFG_MASTER, &hc->cfg))
|
||||
hc->hw.mst_m |= HFCPCI_MASTER;
|
||||
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
|
||||
} else
|
||||
ret = -EINVAL;
|
||||
|
@ -1379,7 +1389,8 @@ HFCD_l1hw(hisaxif_t *hif, struct sk_buff *skb)
|
|||
Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); /* HFC ST 3 */
|
||||
udelay(6);
|
||||
Write_hfc(hc, HFCPCI_STATES, 3); /* HFC ST 2 */
|
||||
hc->hw.mst_m |= HFCPCI_MASTER;
|
||||
if (test_bit(HFC_CFG_MASTER, &hc->cfg))
|
||||
hc->hw.mst_m |= HFCPCI_MASTER;
|
||||
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
|
||||
Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION);
|
||||
// l1_msg(hc, HW_POWERUP | CONFIRM, NULL);
|
||||
|
@ -1440,7 +1451,8 @@ HFCD_l1hw(hisaxif_t *hif, struct sk_buff *skb)
|
|||
udelay(6);
|
||||
Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 1); /* G1 */
|
||||
udelay(6);
|
||||
hc->hw.mst_m |= HFCPCI_MASTER;
|
||||
if (test_bit(HFC_CFG_MASTER, &hc->cfg))
|
||||
hc->hw.mst_m |= HFCPCI_MASTER;
|
||||
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
|
||||
udelay(6);
|
||||
Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION | 1);
|
||||
|
@ -1492,19 +1504,26 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
hfc_pci_t *hc = bch->inst.data;
|
||||
long flags;
|
||||
int fifo2;
|
||||
u_char rx_slot = 0, tx_slot = 0, pcm_mode;
|
||||
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
debugprint(&bch->inst, "HFCPCI bchannel%d protocol %x-->%x ch %d-->%d",
|
||||
bch->channel, bch->protocol, protocol, bch->channel, bc);
|
||||
debugprint(&bch->inst, "HFCPCI bchannel protocol %x-->%x ch %x-->%x",
|
||||
bch->protocol, protocol, bch->channel, bc);
|
||||
|
||||
fifo2 = bc;
|
||||
pcm_mode = (bc>>24) & 0xff;
|
||||
if (pcm_mode) { /* PCM SLOT USE */
|
||||
rx_slot = (bc>>8) & 0xff;
|
||||
tx_slot = (bc>>16) & 0xff;
|
||||
bc = bc & 0xff;
|
||||
}
|
||||
save_flags(flags);
|
||||
cli();
|
||||
if (hc->chanlimit > 1) {
|
||||
hc->hw.bswapped = 0; /* B1 and B2 normal mode */
|
||||
hc->hw.sctrl_e &= ~0x80;
|
||||
} else {
|
||||
if (bc) {
|
||||
if (bc & 2) {
|
||||
if (protocol != ISDN_PID_NONE) {
|
||||
hc->hw.bswapped = 1; /* B1 and B2 exchanged */
|
||||
hc->hw.sctrl_e |= 0x80;
|
||||
|
@ -1512,7 +1531,7 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
hc->hw.bswapped = 0; /* B1 and B2 normal mode */
|
||||
hc->hw.sctrl_e &= ~0x80;
|
||||
}
|
||||
fifo2 = 0;
|
||||
fifo2 = 1;
|
||||
} else {
|
||||
hc->hw.bswapped = 0; /* B1 and B2 normal mode */
|
||||
hc->hw.sctrl_e &= ~0x80;
|
||||
|
@ -1527,21 +1546,21 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
restore_flags(flags);
|
||||
return(0);
|
||||
}
|
||||
if (bc) {
|
||||
if (bc & 2) {
|
||||
hc->hw.sctrl &= ~SCTRL_B2_ENA;
|
||||
hc->hw.sctrl_r &= ~SCTRL_B2_ENA;
|
||||
} else {
|
||||
hc->hw.sctrl &= ~SCTRL_B1_ENA;
|
||||
hc->hw.sctrl_r &= ~SCTRL_B1_ENA;
|
||||
}
|
||||
if (fifo2) {
|
||||
if (fifo2 & 2) {
|
||||
hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2;
|
||||
hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
|
||||
} else {
|
||||
hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1;
|
||||
hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
|
||||
}
|
||||
if (bch->channel)
|
||||
if (bch->channel & 2)
|
||||
hc->hw.cirm &= 0x7f;
|
||||
else
|
||||
hc->hw.cirm &= 0xbf;
|
||||
|
@ -1553,7 +1572,7 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
bch->channel = bc;
|
||||
hfcpci_clear_fifo_rx(hc, fifo2);
|
||||
hfcpci_clear_fifo_tx(hc, fifo2);
|
||||
if (bc) {
|
||||
if (bc & 2) {
|
||||
hc->hw.sctrl |= SCTRL_B2_ENA;
|
||||
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
||||
hc->hw.cirm |= 0x80;
|
||||
|
@ -1562,7 +1581,7 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
hc->hw.sctrl_r |= SCTRL_B1_ENA;
|
||||
hc->hw.cirm |= 0x40;
|
||||
}
|
||||
if (fifo2) {
|
||||
if (fifo2 & 2) {
|
||||
hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
|
||||
hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
|
||||
hc->hw.ctmt |= 2;
|
||||
|
@ -1579,14 +1598,14 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
bch->channel = bc;
|
||||
hfcpci_clear_fifo_rx(hc, fifo2);
|
||||
hfcpci_clear_fifo_tx(hc, fifo2);
|
||||
if (bc) {
|
||||
if (bc & 2) {
|
||||
hc->hw.sctrl |= SCTRL_B2_ENA;
|
||||
hc->hw.sctrl_r |= SCTRL_B2_ENA;
|
||||
} else {
|
||||
hc->hw.sctrl |= SCTRL_B1_ENA;
|
||||
hc->hw.sctrl_r |= SCTRL_B1_ENA;
|
||||
}
|
||||
if (fifo2) {
|
||||
if (fifo2 & 2) {
|
||||
hc->hw.last_bfifo_cnt[1] = 0;
|
||||
hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
|
||||
hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
|
||||
|
@ -1622,6 +1641,26 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
|
|||
restore_flags(flags);
|
||||
return(-ENOPROTOOPT);
|
||||
}
|
||||
if (pcm_mode) {
|
||||
if (protocol == ISDN_PID_NONE) {
|
||||
rx_slot = 0;
|
||||
tx_slot = 0;
|
||||
} else {
|
||||
rx_slot |= 0x80;
|
||||
tx_slot |= 0x80;
|
||||
}
|
||||
if (bc & 2) {
|
||||
hc->hw.conn &= 0xc7;
|
||||
hc->hw.conn |= 0x08;
|
||||
Write_hfc(hc, HFCPCI_B2_SSL, tx_slot);
|
||||
Write_hfc(hc, HFCPCI_B2_RSL, rx_slot);
|
||||
} else {
|
||||
hc->hw.conn &= 0xf8;
|
||||
hc->hw.conn |= 0x01;
|
||||
Write_hfc(hc, HFCPCI_B1_SSL, tx_slot);
|
||||
Write_hfc(hc, HFCPCI_B1_RSL, rx_slot);
|
||||
}
|
||||
}
|
||||
Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
|
||||
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
|
||||
Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
|
||||
|
@ -1942,8 +1981,8 @@ inithfcpci(hfc_pci_t *hc)
|
|||
hc->dch.dbusytimer.data = (long) &hc->dch;
|
||||
init_timer(&hc->dch.dbusytimer);
|
||||
hc->chanlimit = 2;
|
||||
mode_hfcpci(&hc->bch[0], 0, -1);
|
||||
mode_hfcpci(&hc->bch[1], 1, -1);
|
||||
mode_hfcpci(&hc->bch[0], 1, -1);
|
||||
mode_hfcpci(&hc->bch[1], 2, -1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -2030,8 +2069,58 @@ static int init_card(hfc_pci_t *hc)
|
|||
return(-EIO);
|
||||
}
|
||||
|
||||
#define MAX_CARDS 4
|
||||
#define MODULE_PARM_T "1-4i"
|
||||
static int
|
||||
SelFreeBChannel(hfc_pci_t *hc, channel_info_t *ci)
|
||||
{
|
||||
bchannel_t *bch;
|
||||
hfc_pci_t *hfc;
|
||||
hisaxstack_t *bst;
|
||||
int cnr;
|
||||
|
||||
if (!ci)
|
||||
return(-EINVAL);
|
||||
ci->st.p = NULL;
|
||||
bst = hc->dch.inst.st->child;
|
||||
cnr=0;
|
||||
while(bst) {
|
||||
if(!bst->mgr) {
|
||||
int_errtxt("no mgr st(%p)", bst);
|
||||
return(-EINVAL);
|
||||
}
|
||||
hfc = bst->mgr->data;
|
||||
if (!hfc) {
|
||||
int_errtxt("no mgr->data st(%p)", bst);
|
||||
return(-EINVAL);
|
||||
}
|
||||
bch = &hfc->bch[cnr & 1];
|
||||
if (!(ci->channel & (~CHANNEL_NUMBER))) {
|
||||
/* only number is set */
|
||||
if ((ci->channel & CHANNEL_NUMBER) == (cnr + 1)) {
|
||||
if (bch->protocol != ISDN_PID_NONE)
|
||||
return(-EBUSY);
|
||||
bch->channel = (cnr & 1) ? 2 : 1;
|
||||
ci->st.p = bst;
|
||||
return(0);
|
||||
}
|
||||
} else if ((ci->channel & (~CHANNEL_NUMBER)) == 0x00a18300) {
|
||||
if (bch->protocol == ISDN_PID_NONE) {
|
||||
ci->st.p = bst;
|
||||
bch->channel = (cnr & 1) ? 2 : 1;
|
||||
bch->channel |= CHANNEL_EXT_PCM;
|
||||
bch->channel |= (ci->channel & 0x1f) << 16;
|
||||
bch->channel |= (ci->channel & 0x1f) << 8;
|
||||
ci->st.p = bst;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
cnr++;
|
||||
bst = bst->next;
|
||||
}
|
||||
return(-EBUSY);
|
||||
}
|
||||
|
||||
#define MAX_CARDS 8
|
||||
#define MODULE_PARM_T "1-8i"
|
||||
static int HFC_cnt;
|
||||
static u_int protocol[MAX_CARDS];
|
||||
static int layermask[MAX_CARDS];
|
||||
|
@ -2142,8 +2231,8 @@ release_card(hfc_pci_t *hc) {
|
|||
|
||||
lock_dev(hc);
|
||||
free_irq(hc->irq, hc);
|
||||
mode_hfcpci(&hc->bch[0], 0, ISDN_PID_NONE);
|
||||
mode_hfcpci(&hc->bch[1], 1, ISDN_PID_NONE);
|
||||
mode_hfcpci(&hc->bch[0], 1, ISDN_PID_NONE);
|
||||
mode_hfcpci(&hc->bch[1], 2, ISDN_PID_NONE);
|
||||
if (hc->dch.dbusytimer.function != NULL) {
|
||||
del_timer(&hc->dch.dbusytimer);
|
||||
hc->dch.dbusytimer.function = NULL;
|
||||
|
@ -2264,11 +2353,19 @@ HFC_manager(void *data, u_int prim, void *arg) {
|
|||
}
|
||||
return(DisConnectIF(inst, arg));
|
||||
break;
|
||||
case MGR_SELCHANNEL | REQUEST:
|
||||
if (channel != 2) {
|
||||
printk(KERN_WARNING __FUNCTION__": selchannel not dinst\n");
|
||||
return(-EINVAL);
|
||||
}
|
||||
return(SelFreeBChannel(card, arg));
|
||||
break;
|
||||
case MGR_SETSTACK | CONFIRM:
|
||||
if (!card) {
|
||||
printk(KERN_WARNING __FUNCTION__": setstack failed\n");
|
||||
return(-ENODEV);
|
||||
}
|
||||
|
||||
if ((channel!=2) && (inst->pid.global == 2)) {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||
|
@ -2294,9 +2391,10 @@ HFC_manager(void *data, u_int prim, void *arg) {
|
|||
int
|
||||
HFC_init(void)
|
||||
{
|
||||
int err,i;
|
||||
hfc_pci_t *card;
|
||||
hisax_pid_t pid;
|
||||
int err,i;
|
||||
hfc_pci_t *card, *prev;
|
||||
hisax_pid_t pid;
|
||||
hisaxstack_t *dst;
|
||||
|
||||
HFC_obj.name = HFCName;
|
||||
HFC_obj.own_ctrl = HFC_manager;
|
||||
|
@ -2328,22 +2426,6 @@ HFC_init(void)
|
|||
card->dch.inst.unlock = unlock_dev;
|
||||
card->dch.inst.data = card;
|
||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||
set_dchannel_pid(&pid, protocol[HFC_cnt] &0xf,
|
||||
layermask[HFC_cnt]);
|
||||
if (protocol[HFC_cnt] & 0x10) {
|
||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_NT_S0;
|
||||
card->dch.inst.pid.protocol[1] = ISDN_PID_L1_NT_S0;
|
||||
pid.protocol[0] = ISDN_PID_L0_NT_S0;
|
||||
pid.protocol[1] = ISDN_PID_L1_NT_S0;
|
||||
card->dch.inst.pid.layermask |= ISDN_LAYER(1);
|
||||
pid.layermask |= ISDN_LAYER(1);
|
||||
if (layermask[HFC_cnt] & ISDN_LAYER(2))
|
||||
pid.protocol[2] = ISDN_PID_L2_LAPD_NET;
|
||||
card->hw.nt_mode = 1;
|
||||
} else {
|
||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||
card->hw.nt_mode = 0;
|
||||
}
|
||||
card->dch.inst.up.owner = &card->dch.inst;
|
||||
card->dch.inst.down.owner = &card->dch.inst;
|
||||
HFC_obj.ctrl(NULL, MGR_DISCONNECT | REQUEST,
|
||||
|
@ -2353,7 +2435,7 @@ HFC_init(void)
|
|||
sprintf(card->dch.inst.name, "HFC%d", HFC_cnt+1);
|
||||
init_dchannel(&card->dch);
|
||||
for (i=0; i<2; i++) {
|
||||
card->bch[i].channel = i;
|
||||
card->bch[i].channel = i + 1;
|
||||
card->bch[i].inst.obj = &HFC_obj;
|
||||
card->bch[i].inst.data = card;
|
||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||
|
@ -2374,6 +2456,56 @@ HFC_init(void)
|
|||
&card->bch[i];
|
||||
}
|
||||
}
|
||||
if (protocol[HFC_cnt] == 0x100) {
|
||||
prev = card->prev;
|
||||
|
||||
if (!prev) {
|
||||
int_errtxt("card(%d) no previous HFC",
|
||||
HFC_cnt);
|
||||
if (!HFC_cnt)
|
||||
HiSax_unregister(&HFC_obj);
|
||||
else
|
||||
err = 0;
|
||||
return(err);
|
||||
}
|
||||
i = HFC_cnt - 1;
|
||||
test_and_set_bit(HFC_CFG_2HFC, &prev->cfg);
|
||||
test_and_set_bit(HFC_CFG_2HFC, &card->cfg);
|
||||
test_and_set_bit(HFC_CFG_SLAVEHFC, &card->cfg);
|
||||
} else {
|
||||
prev = NULL;
|
||||
i = HFC_cnt;
|
||||
}
|
||||
set_dchannel_pid(&pid, protocol[i] & 0xf,
|
||||
layermask[i]);
|
||||
test_and_set_bit(HFC_CFG_MASTER, &card->cfg);
|
||||
if (protocol[i] & 0x10) {
|
||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_NT_S0;
|
||||
card->dch.inst.pid.protocol[1] = ISDN_PID_L1_NT_S0;
|
||||
pid.protocol[0] = ISDN_PID_L0_NT_S0;
|
||||
pid.protocol[1] = ISDN_PID_L1_NT_S0;
|
||||
card->dch.inst.pid.layermask |= ISDN_LAYER(1);
|
||||
pid.layermask |= ISDN_LAYER(1);
|
||||
if (layermask[i] & ISDN_LAYER(2))
|
||||
pid.protocol[2] = ISDN_PID_L2_LAPD_NET;
|
||||
card->hw.nt_mode = 1;
|
||||
} else {
|
||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||
card->hw.nt_mode = 0;
|
||||
}
|
||||
if (protocol[i] & 0x20) {
|
||||
if (pid.layermask & ISDN_LAYER(2))
|
||||
pid.protocol[2] |= ISDN_PID_L2_DF_PTP;
|
||||
if (pid.layermask & ISDN_LAYER(3))
|
||||
pid.protocol[3] |= ISDN_PID_L3_DF_PTP;
|
||||
}
|
||||
if (protocol[i] & 0x40) {
|
||||
if (pid.layermask & ISDN_LAYER(3))
|
||||
pid.protocol[3] |= ISDN_PID_L3_DF_EXTCID;
|
||||
test_and_set_bit(HFC_CFG_PCM, &card->cfg);
|
||||
test_and_set_bit(HFC_CFG_SLAVE, &card->cfg);
|
||||
test_and_clear_bit(HFC_CFG_MASTER, &card->cfg);
|
||||
}
|
||||
printk(KERN_DEBUG "HFC card %p dch %p bch1 %p bch2 %p\n",
|
||||
card, &card->dch, &card->bch[0], &card->bch[1]);
|
||||
if (setup_hfcpci(card)) {
|
||||
|
@ -2392,27 +2524,24 @@ HFC_init(void)
|
|||
return(err);
|
||||
}
|
||||
HFC_cnt++;
|
||||
if ((err = HFC_obj.ctrl(NULL, MGR_NEWSTACK | REQUEST, &card->dch.inst))) {
|
||||
printk(KERN_ERR "MGR_ADDSTACK REQUEST dch err(%d)\n", err);
|
||||
release_card(card);
|
||||
if (!HFC_cnt)
|
||||
HiSax_unregister(&HFC_obj);
|
||||
else
|
||||
err = 0;
|
||||
return(err);
|
||||
if (prev) {
|
||||
dst = prev->dch.inst.st;
|
||||
} else {
|
||||
if ((err = HFC_obj.ctrl(NULL, MGR_NEWSTACK | REQUEST,
|
||||
&card->dch.inst))) {
|
||||
printk(KERN_ERR "MGR_ADDSTACK REQUEST dch err(%d)\n", err);
|
||||
release_card(card);
|
||||
if (!HFC_cnt)
|
||||
HiSax_unregister(&HFC_obj);
|
||||
else
|
||||
err = 0;
|
||||
return(err);
|
||||
}
|
||||
dst = card->dch.inst.st;
|
||||
}
|
||||
if ((err = HFC_obj.ctrl(card->dch.inst.st, MGR_SETSTACK | REQUEST, &pid))) {
|
||||
printk(KERN_ERR "MGR_SETSTACK REQUEST dch err(%d)\n", err);
|
||||
HFC_obj.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
|
||||
if (!HFC_cnt)
|
||||
HiSax_unregister(&HFC_obj);
|
||||
else
|
||||
err = 0;
|
||||
return(err);
|
||||
}
|
||||
for (i=0; i<2; i++) {
|
||||
if ((err = HFC_obj.ctrl(card->dch.inst.st, MGR_NEWSTACK | REQUEST,
|
||||
&card->bch[i].inst))) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
if ((err = HFC_obj.ctrl(dst,
|
||||
MGR_NEWSTACK | REQUEST, &card->bch[i].inst))) {
|
||||
printk(KERN_ERR "MGR_ADDSTACK bchan error %d\n", err);
|
||||
HFC_obj.ctrl(card->dch.inst.st,
|
||||
MGR_DELSTACK | REQUEST, NULL);
|
||||
|
@ -2422,9 +2551,23 @@ HFC_init(void)
|
|||
err = 0;
|
||||
return(err);
|
||||
}
|
||||
card->bch[i].st = card->bch[i].inst.st;
|
||||
}
|
||||
if (protocol[HFC_cnt] != 0x100) { /* next not second HFC */
|
||||
if ((err = HFC_obj.ctrl(dst, MGR_SETSTACK | REQUEST,
|
||||
&pid))) {
|
||||
printk(KERN_ERR "MGR_SETSTACK REQUEST dch err(%d)\n",
|
||||
err);
|
||||
HFC_obj.ctrl(dst, MGR_DELSTACK | REQUEST, NULL);
|
||||
if (!HFC_cnt)
|
||||
HiSax_unregister(&HFC_obj);
|
||||
else
|
||||
err = 0;
|
||||
return(err);
|
||||
}
|
||||
}
|
||||
if ((err = init_card(card))) {
|
||||
HFC_obj.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
|
||||
HFC_obj.ctrl(dst, MGR_DELSTACK | REQUEST, NULL);
|
||||
if (!HFC_cnt)
|
||||
HiSax_unregister(&HFC_obj);
|
||||
else
|
||||
|
|
|
@ -93,78 +93,79 @@ struct hfcB_hw {
|
|||
#define BC_FLG_LL_CONN 15
|
||||
|
||||
typedef struct _bchannel_t {
|
||||
int channel;
|
||||
int protocol;
|
||||
int Flag;
|
||||
int debug;
|
||||
hisaxinstance_t inst;
|
||||
hisaxdevice_t *dev;
|
||||
u_char (*BC_Read_Reg)(void *, int, u_char);
|
||||
void (*BC_Write_Reg)(void *, int, u_char, u_char);
|
||||
struct sk_buff *next_skb;
|
||||
u_char *tx_buf;
|
||||
int tx_idx;
|
||||
int tx_len;
|
||||
u_char *rx_buf;
|
||||
int rx_idx;
|
||||
struct sk_buff_head rqueue; /* B-Channel receive Queue */
|
||||
u_char *blog;
|
||||
u_char *conmsg;
|
||||
struct timer_list transbusy;
|
||||
struct tq_struct tqueue;
|
||||
int event;
|
||||
int err_crc;
|
||||
int err_tx;
|
||||
int err_rdo;
|
||||
int err_inv;
|
||||
int channel;
|
||||
int protocol;
|
||||
int Flag;
|
||||
int debug;
|
||||
hisaxstack_t *st;
|
||||
hisaxinstance_t inst;
|
||||
hisaxdevice_t *dev;
|
||||
u_char (*BC_Read_Reg)(void *, int, u_char);
|
||||
void (*BC_Write_Reg)(void *, int, u_char, u_char);
|
||||
struct sk_buff *next_skb;
|
||||
u_char *tx_buf;
|
||||
int tx_idx;
|
||||
int tx_len;
|
||||
u_char *rx_buf;
|
||||
int rx_idx;
|
||||
struct sk_buff_head rqueue; /* B-Channel receive Queue */
|
||||
u_char *blog;
|
||||
u_char *conmsg;
|
||||
struct timer_list transbusy;
|
||||
struct tq_struct tqueue;
|
||||
int event;
|
||||
int err_crc;
|
||||
int err_tx;
|
||||
int err_rdo;
|
||||
int err_inv;
|
||||
union {
|
||||
struct hdlc_hw hdlc;
|
||||
struct isar_hw isar;
|
||||
} hw;
|
||||
struct hdlc_hw hdlc;
|
||||
struct isar_hw isar;
|
||||
} hw;
|
||||
} bchannel_t;
|
||||
|
||||
struct avm_hw {
|
||||
unsigned int cfg_reg;
|
||||
unsigned int isac;
|
||||
unsigned int hscx[2];
|
||||
unsigned int isacfifo;
|
||||
unsigned int hscxfifo[2];
|
||||
unsigned int counter;
|
||||
unsigned int cfg_reg;
|
||||
unsigned int isac;
|
||||
unsigned int hscx[2];
|
||||
unsigned int isacfifo;
|
||||
unsigned int hscxfifo[2];
|
||||
unsigned int counter;
|
||||
};
|
||||
|
||||
struct sedl_hw {
|
||||
unsigned int cfg_reg;
|
||||
unsigned int adr;
|
||||
unsigned int isac;
|
||||
unsigned int hscx;
|
||||
unsigned int reset_on;
|
||||
unsigned int reset_off;
|
||||
struct isar_reg isar;
|
||||
unsigned int chip;
|
||||
unsigned int bus;
|
||||
unsigned intcfg_reg;
|
||||
unsigned int adr;
|
||||
unsigned int isac;
|
||||
unsigned int hscx;
|
||||
unsigned int reset_on;
|
||||
unsigned int reset_off;
|
||||
struct isar_reg isar;
|
||||
unsigned int chip;
|
||||
unsigned int bus;
|
||||
};
|
||||
|
||||
struct arcofi_msg {
|
||||
struct arcofi_msg *next;
|
||||
u_char receive;
|
||||
u_char len;
|
||||
u_char msg[10];
|
||||
struct arcofi_msg *next;
|
||||
u_char receive;
|
||||
u_char len;
|
||||
u_char msg[10];
|
||||
};
|
||||
|
||||
struct isac_chip {
|
||||
int ph_state;
|
||||
u_char *mon_tx;
|
||||
u_char *mon_rx;
|
||||
int mon_txp;
|
||||
int mon_txc;
|
||||
int mon_rxp;
|
||||
struct arcofi_msg *arcofi_list;
|
||||
struct timer_list arcofitimer;
|
||||
wait_queue_head_t arcofi_wait;
|
||||
u_char arcofi_bc;
|
||||
u_char arcofi_state;
|
||||
u_char mocr;
|
||||
u_char adf2;
|
||||
int ph_state;
|
||||
u_char *mon_tx;
|
||||
u_char *mon_rx;
|
||||
int mon_txp;
|
||||
int mon_txc;
|
||||
int mon_rxp;
|
||||
struct arcofi_msg *arcofi_list;
|
||||
struct timer_list arcofitimer;
|
||||
wait_queue_head_t arcofi_wait;
|
||||
u_char arcofi_bc;
|
||||
u_char arcofi_state;
|
||||
u_char mocr;
|
||||
u_char adf2;
|
||||
};
|
||||
|
||||
struct hfcpci_chip {
|
||||
|
@ -187,31 +188,31 @@ struct hfcpci_chip {
|
|||
#define FLG_HW_INIT 13
|
||||
|
||||
typedef struct _dchannel_t {
|
||||
hisaxinstance_t inst;
|
||||
u_int DFlags;
|
||||
u_char (*readisac) (void *, u_char);
|
||||
void (*writeisac) (void *, u_char, u_char);
|
||||
void (*readisacfifo) (void *, u_char *, int);
|
||||
void (*writeisacfifo) (void *, u_char *, int);
|
||||
char *dlog;
|
||||
int debug;
|
||||
u_char *rx_buf;
|
||||
int rx_idx;
|
||||
struct sk_buff *next_skb;
|
||||
u_char *tx_buf;
|
||||
int tx_idx;
|
||||
int tx_len;
|
||||
int event;
|
||||
int err_crc;
|
||||
int err_tx;
|
||||
int err_rx;
|
||||
hisaxinstance_t inst;
|
||||
u_int DFlags;
|
||||
u_char (*readisac) (void *, u_char);
|
||||
void (*writeisac) (void *, u_char, u_char);
|
||||
void (*readisacfifo) (void *, u_char *, int);
|
||||
void (*writeisacfifo) (void *, u_char *, int);
|
||||
char *dlog;
|
||||
int debug;
|
||||
u_char *rx_buf;
|
||||
int rx_idx;
|
||||
struct sk_buff *next_skb;
|
||||
u_char *tx_buf;
|
||||
int tx_idx;
|
||||
int tx_len;
|
||||
int event;
|
||||
int err_crc;
|
||||
int err_tx;
|
||||
int err_rx;
|
||||
union {
|
||||
struct isac_chip isac;
|
||||
struct hfcpci_chip hfcpci;
|
||||
} hw;
|
||||
struct sk_buff_head rqueue; /* D-channel receive queue */
|
||||
struct tq_struct tqueue;
|
||||
struct timer_list dbusytimer;
|
||||
struct isac_chip isac;
|
||||
struct hfcpci_chip hfcpci;
|
||||
} hw;
|
||||
struct sk_buff_head rqueue; /* D-channel receive queue */
|
||||
struct tq_struct tqueue;
|
||||
struct timer_list dbusytimer;
|
||||
} dchannel_t;
|
||||
|
||||
#define MON0_RX 1
|
||||
|
|
|
@ -403,6 +403,12 @@ l3dss1_get_channel_id(l3_process_t *pc, struct sk_buff *skb) {
|
|||
u_char *sp, *p;
|
||||
|
||||
if ((sp = p = findie(skb->data, skb->len, IE_CHANNEL_ID, 0))) {
|
||||
if (test_bit(FLG_EXTCID, &pc->l3->Flag)) {
|
||||
if (*p != 1) {
|
||||
pc->bc = 1;
|
||||
return (sp);
|
||||
}
|
||||
}
|
||||
if (*p != 1) { /* len for BRI = 1 */
|
||||
if (pc->l3->debug & L3_DEB_WARN)
|
||||
l3_debug(pc->l3, "wrong chid len %d", *p);
|
||||
|
@ -768,6 +774,8 @@ l3dss1_alerting(l3_process_t *pc, u_char pr, void *arg)
|
|||
}
|
||||
L3DelTimer(&pc->timer); /* T304 */
|
||||
newl3state(pc, 4);
|
||||
pc->para.ALERTING.CHANNEL_ID =
|
||||
l3dss1_get_channel_id(pc, skb);
|
||||
pc->para.ALERTING.BEARER =
|
||||
findie(skb->data, skb->len, IE_BEARER, 0);
|
||||
pc->para.ALERTING.FACILITY =
|
||||
|
@ -851,6 +859,8 @@ l3dss1_connect(l3_process_t *pc, u_char pr, void *arg)
|
|||
}
|
||||
L3DelTimer(&pc->timer); /* T310 */
|
||||
newl3state(pc, 10);
|
||||
pc->para.CONNECT.CHANNEL_ID =
|
||||
l3dss1_get_channel_id(pc, skb);
|
||||
pc->para.CONNECT.BEARER =
|
||||
findie(skb->data, skb->len, IE_BEARER, 0);
|
||||
pc->para.CONNECT.FACILITY =
|
||||
|
@ -2243,13 +2253,17 @@ new_udss1(hisaxstack_t *st, hisax_pid_t *pid)
|
|||
int_error();
|
||||
return(-ENOPROTOOPT);
|
||||
}
|
||||
if (pid->protocol[3] != ISDN_PID_L3_DSS1USER) {
|
||||
if ((pid->protocol[3] & ~ISDN_PID_FEATURE_MASK) != ISDN_PID_L3_DSS1USER) {
|
||||
printk(KERN_ERR "udss1 create failed prt %x\n",
|
||||
pid->protocol[3]);
|
||||
kfree(nl3);
|
||||
return(-ENOPROTOOPT);
|
||||
}
|
||||
init_l3(nl3);
|
||||
if (pid->protocol[3] & ISDN_PID_L3_DF_PTP)
|
||||
test_and_set_bit(FLG_PTP, &nl3->Flag);
|
||||
if (pid->protocol[3] & ISDN_PID_L3_DF_EXTCID)
|
||||
test_and_set_bit(FLG_EXTCID, &nl3->Flag);
|
||||
if (!(nl3->global = kmalloc(sizeof(l3_process_t), GFP_ATOMIC))) {
|
||||
printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");
|
||||
release_l3(nl3);
|
||||
|
@ -2360,7 +2374,9 @@ int UDSS1Init(void)
|
|||
strcpy(tmp, dss1_revision);
|
||||
printk(KERN_INFO "HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp));
|
||||
u_dss1.name = MName;
|
||||
u_dss1.DPROTO.protocol[3] = ISDN_PID_L3_DSS1USER;
|
||||
u_dss1.DPROTO.protocol[3] = ISDN_PID_L3_DSS1USER |
|
||||
ISDN_PID_L3_DF_PTP |
|
||||
ISDN_PID_L3_DF_EXTCID;
|
||||
u_dss1.own_ctrl = udss1_manager;
|
||||
u_dss1.prev = NULL;
|
||||
u_dss1.next = NULL;
|
||||
|
|
|
@ -2096,7 +2096,7 @@ new_l2(hisaxstack_t *st, hisax_pid_t *pid, layer2_t **newl2) {
|
|||
int_error();
|
||||
return(-ENOPROTOOPT);
|
||||
}
|
||||
switch(pid->protocol[2]) {
|
||||
switch(pid->protocol[2] & ~ISDN_PID_FEATURE_MASK) {
|
||||
case ISDN_PID_L2_LAPD_NET:
|
||||
sprintf(nl2->inst.name, "lapdn %x", st->id);
|
||||
test_and_set_bit(FLG_LAPD, &nl2->flag);
|
||||
|
@ -2122,6 +2122,11 @@ new_l2(hisaxstack_t *st, hisax_pid_t *pid, layer2_t **newl2) {
|
|||
test_and_set_bit(FLG_ORIG, &nl2->flag);
|
||||
nl2->sapi = 0;
|
||||
nl2->tei = -1;
|
||||
if (pid->protocol[2] & ISDN_PID_L2_DF_PTP) {
|
||||
test_and_set_bit(FLG_PTP, &nl2->flag);
|
||||
test_and_set_bit(FLG_FIXED_TEI, &nl2->flag);
|
||||
nl2->tei = 0;
|
||||
}
|
||||
nl2->maxlen = MAX_DFRAME_LEN;
|
||||
nl2->window = 1;
|
||||
nl2->T200 = 1000;
|
||||
|
@ -2367,7 +2372,9 @@ int Isdnl2Init(void)
|
|||
int err;
|
||||
|
||||
isdnl2.name = MName;
|
||||
isdnl2.DPROTO.protocol[2] = ISDN_PID_L2_LAPD | ISDN_PID_L2_LAPD_NET;
|
||||
isdnl2.DPROTO.protocol[2] = ISDN_PID_L2_LAPD |
|
||||
ISDN_PID_L2_LAPD_NET |
|
||||
ISDN_PID_L2_DF_PTP;
|
||||
isdnl2.BPROTO.protocol[2] = ISDN_PID_L2_B_X75SLP;
|
||||
isdnl2.own_ctrl = l2_manager;
|
||||
isdnl2.prev = NULL;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#define FLG_L2BLOCK 1
|
||||
#define FLG_PTP 2
|
||||
#define FLG_EXTCID 3
|
||||
|
||||
typedef struct _L3Timer {
|
||||
struct _l3_process *pc;
|
||||
|
|
|
@ -367,16 +367,12 @@ void ncciInitSt(Ncci_t *ncci)
|
|||
printk(KERN_DEBUG "ncciInitSt ch(%d) cplci->contr->binst(%p)\n",
|
||||
cplci->bchannel & 3, cplci->contr->binst);
|
||||
pid.protocol[4] = ISDN_PID_L4_B_CAPI20;
|
||||
if ((cplci->bchannel & 0xf4) == 0x80) {
|
||||
ncci->binst = contrSelChannel(cplci->contr, cplci->bchannel & 3);
|
||||
} else {
|
||||
printk(KERN_WARNING "ncciInitSt channel %x not supported\n",
|
||||
cplci->bchannel);
|
||||
}
|
||||
ncci->binst = contrSelChannel(cplci->contr, cplci->bchannel);
|
||||
if (!ncci->binst) {
|
||||
int_error();
|
||||
return;
|
||||
}
|
||||
}
|
||||
printk(KERN_DEBUG "ncciInitSt ncci->binst(%p)\n", ncci->binst);
|
||||
memset(&ncci->binst->inst.pid, 0, sizeof(hisax_pid_t));
|
||||
ncci->binst->inst.data = ncci;
|
||||
ncci->binst->inst.pid.layermask = ISDN_LAYER(4);
|
||||
|
|
|
@ -477,7 +477,8 @@ unregister_instance(hisaxinstance_t *inst) {
|
|||
printk(KERN_WARNING __FUNCTION__": no layer found\n");
|
||||
err = -ENODEV;
|
||||
}
|
||||
inst->st = NULL;
|
||||
if (inst->st && (inst->st->mgr != inst))
|
||||
inst->st = NULL;
|
||||
}
|
||||
REMOVE_FROM_LISTBASE(inst, hisax_instlist);
|
||||
inst->prev = inst->next = NULL;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* $Id$
|
||||
*
|
||||
* Copyright 2000 by Karsten Keil <kkeil@isdn4linux.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
@ -160,8 +161,8 @@ next_frame_len(hisaxport_t *port)
|
|||
} else {
|
||||
len = IFRAME_HEAD_SIZE + *lp;
|
||||
}
|
||||
if (len < port->cnt) {
|
||||
int_errtxt("size mismatch %d/%d", len, port->cnt);
|
||||
if (len > port->cnt) {
|
||||
int_errtxt("size mismatch %d/%d/%d", *lp, len, port->cnt);
|
||||
return(0);
|
||||
}
|
||||
return(len);
|
||||
|
@ -360,6 +361,22 @@ new_devstack(hisaxdevice_t *dev, stack_info_t *si)
|
|||
return(inst.st->id);
|
||||
}
|
||||
|
||||
static hisaxstack_t *
|
||||
sel_channel(u_int addr, u_int channel)
|
||||
{
|
||||
hisaxstack_t *st;
|
||||
channel_info_t ci;
|
||||
|
||||
st = get_stack4id(addr);
|
||||
if (!st)
|
||||
return(NULL);
|
||||
ci.channel = channel;
|
||||
ci.st.p = NULL;
|
||||
if (udev_obj.ctrl(st, MGR_SELCHANNEL | REQUEST, &ci))
|
||||
return(NULL);
|
||||
return(ci.st.p);
|
||||
}
|
||||
|
||||
static int
|
||||
create_layer(hisaxdevice_t *dev, layer_info_t *linfo, int *adr)
|
||||
{
|
||||
|
@ -1099,6 +1116,20 @@ hisax_wdata_if(hisaxdevice_t *dev, iframe_t *iff, int len) {
|
|||
off.len = -ENODEV;
|
||||
hisax_rdata(dev, &off, 1);
|
||||
break;
|
||||
case (MGR_SELCHANNEL | REQUEST):
|
||||
used = head;
|
||||
off.addr = iff->addr;
|
||||
off.prim = MGR_SELCHANNEL | CONFIRM;
|
||||
st = sel_channel(iff->addr, iff->dinfo);
|
||||
if (st) {
|
||||
off.len = 0;
|
||||
off.dinfo = st->id;
|
||||
} else {
|
||||
off.dinfo = 0;
|
||||
off.len = -ENODEV;
|
||||
}
|
||||
hisax_rdata(dev, &off, 1);
|
||||
break;
|
||||
case (MGR_GETLAYERID | REQUEST):
|
||||
used = head;
|
||||
off.addr = iff->addr;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define MGR_CLEARSTACK 0x0f1500
|
||||
#define MGR_REGLAYER 0x0f1600
|
||||
#define MGR_UNREGLAYER 0x0f1700
|
||||
#define MGR_SELCHANNEL 0x0f1800
|
||||
#define MGR_GETLAYER 0x0f2100
|
||||
#define MGR_GETLAYERID 0x0f2200
|
||||
#define MGR_NEWLAYER 0x0f2300
|
||||
|
@ -225,6 +226,12 @@
|
|||
#define ISDN_PID_BCHANNEL_BIT 0x40000000
|
||||
#define ISDN_PID_LAYER_MASK 0x0f000000
|
||||
#define ISDN_PID_LAYER(n) (n<<24)
|
||||
#define ISDN_PID_FEATURE_MASK 0x00F00000
|
||||
|
||||
#define ISDN_PID_L2_DF_PTP 0x00100000
|
||||
#define ISDN_PID_L2_DF_MULT_TEI 0x00200000
|
||||
#define ISDN_PID_L3_DF_PTP 0x00100000
|
||||
#define ISDN_PID_L3_DF_EXTCID 0x00200000
|
||||
|
||||
#define HISAX_CORE_DEVICE 0
|
||||
#define HISAX_RAW_DEVICE 128
|
||||
|
@ -269,6 +276,16 @@
|
|||
#define DUMMY_CR_FLAG 0x7FFFFF00
|
||||
#define CONTROLER_MASK 0x000000FF
|
||||
|
||||
/* stack channel values */
|
||||
#define CHANNEL_NUMBER 0x000000FF
|
||||
#define CHANNEL_RXSLOT 0x0000FF00
|
||||
#define CHANNEL_TXSLOT 0x00FF0000
|
||||
#define CHANNEL_EXTINFO 0xFF000000
|
||||
#define CHANNEL_NR_D 0x00000000
|
||||
#define CHANNEL_NR_B1 0x00000001
|
||||
#define CHANNEL_NR_B2 0x00000002
|
||||
#define CHANNEL_EXT_PCM 0x01000000
|
||||
#define CHANNEL_EXT_REV 0x02000000
|
||||
|
||||
/* interface extentions */
|
||||
#define EXT_STACK_CLONE 0x00000001
|
||||
|
@ -365,6 +382,13 @@ typedef struct _interface_info {
|
|||
int stat;
|
||||
} interface_info_t;
|
||||
|
||||
typedef struct _channel_info {
|
||||
u_int channel;
|
||||
union {
|
||||
u_int id;
|
||||
void *p;
|
||||
} st;
|
||||
} channel_info_t;
|
||||
|
||||
/* l3 pointer arrays */
|
||||
|
||||
|
|
Loading…
Reference in New Issue