#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
static isdn_divert_if *divert_if; /* = NULL */
#else
-#define divert_if (0)
+#define divert_if ((isdn_divert_if *) NULL)
#endif
static int
isdn_command(isdn_ctrl *cmd)
{
+ int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
+
if (cmd->driver == -1) {
printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command);
return(1);
}
if (cmd->command == ISDN_CMD_SETL2) {
- int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
unsigned long l2prot = (cmd->arg >> 8) & 255;
unsigned long features = (dev->drv[cmd->driver]->interface->features
>> ISDN_FEATURE_L2_SHIFT) &
slot[idx].iv110.v110emu = 0;
}
}
+#ifdef ISDN_DEBUG_COMMAND
+ switch (cmd->command) {
+ case ISDN_CMD_SETL2:
+ printk(KERN_DEBUG "ISDN_CMD_SETL2 %d\n", idx); break;
+ case ISDN_CMD_SETL3:
+ printk(KERN_DEBUG "ISDN_CMD_SETL3 %d\n", idx); break;
+ case ISDN_CMD_DIAL:
+ printk(KERN_DEBUG "ISDN_CMD_DIAL %d\n", idx); break;
+ case ISDN_CMD_ACCEPTD:
+ printk(KERN_DEBUG "ISDN_CMD_ACCEPTD %d\n", idx); break;
+ case ISDN_CMD_ACCEPTB:
+ printk(KERN_DEBUG "ISDN_CMD_ACCEPTB %d\n", idx); break;
+ case ISDN_CMD_HANGUP:
+ printk(KERN_DEBUG "ISDN_CMD_HANGUP %d\n", idx); break;
+ case ISDN_CMD_CLREAZ:
+ printk(KERN_DEBUG "ISDN_CMD_CLREAZ %d\n", idx); break;
+ case ISDN_CMD_SETEAZ:
+ printk(KERN_DEBUG "ISDN_CMD_SETEAZ %d\n", idx); break;
+ default:
+ printk(KERN_DEBUG "%s: cmd = %d\n", __FUNCTION__, cmd->command);
+ }
+#endif
return dev->drv[cmd->driver]->interface->command(cmd);
}
case ISDN_STAT_ICALL:
if (i < 0)
return -1;
- dbg_statcallb("ICALL: %d %ld %s\n", di, c->arg, c->parm.num);
+ dbg_statcallb("ICALL: %d (%d,%ld) %s\n", i, di, c->arg, c->parm.num);
if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
cmd.driver = di;
cmd.arg = c->arg;
}
break;
case 1:
- /* Schedule connection-setup */
- isdn_net_dial();
list_for_each(l, &isdn_net_devs) {
isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
- if (p->local.isdn_slot == isdn_dc2minor(di, cmd.arg)) {
- strcpy( cmd.parm.setup.eazmsn, p->local.msn );
- isdn_slot_command(p->local.isdn_slot, ISDN_CMD_ACCEPTD, &cmd);
+ if (p->local.isdn_slot == i) {
+ strcpy(cmd.parm.setup.eazmsn, p->local.msn);
+ isdn_slot_command(i, ISDN_CMD_ACCEPTD, &cmd);
retval = 1;
break;
}
/* Fall through */
case 4:
/* ... then start callback. */
- isdn_net_dial();
break;
case 5:
/* Number would eventually match, if longer */
case ISDN_STAT_CINF:
if (i < 0)
return -1;
- dbg_statcallb("CINF: %ld %s\n", c->arg, c->parm.num);
+ dbg_statcallb("CINF: %d %s\n", i, c->parm.num);
if (dev->global_flags & ISDN_GLOBAL_STOPPED)
return 0;
if (strcmp(c->parm.num, "0"))
isdn_tty_stat_callback(i, c);
break;
case ISDN_STAT_CAUSE:
- dbg_statcallb("CAUSE: %ld %s\n", c->arg, c->parm.num);
+ dbg_statcallb("CAUSE: %d %s\n", i, c->parm.num);
printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n",
dev->drvid[di], c->arg, c->parm.num);
isdn_tty_stat_callback(i, c);
divert_if->stat_callback(c);
break;
case ISDN_STAT_DISPLAY:
- dbg_statcallb("DISPLAY: %ld %s\n", c->arg, c->parm.display);
+ dbg_statcallb("DISPLAY: %d %s\n", i, c->parm.display);
isdn_tty_stat_callback(i, c);
if (divert_if)
divert_if->stat_callback(c);
case ISDN_STAT_DCONN:
if (i < 0)
return -1;
- dbg_statcallb("DCONN: %ld\n", c->arg);
+ dbg_statcallb("DCONN: %d\n", i);
if (dev->global_flags & ISDN_GLOBAL_STOPPED)
return 0;
/* Find any net-device, waiting for D-channel setup */
case ISDN_STAT_DHUP:
if (i < 0)
return -1;
- dbg_statcallb("DHUP: %ld\n", c->arg);
+ dbg_statcallb("DHUP: %d\n", i);
if (dev->global_flags & ISDN_GLOBAL_STOPPED)
return 0;
dev->drv[di]->online &= ~(1 << (c->arg));
case ISDN_STAT_BHUP:
if (i < 0)
return -1;
- dbg_statcallb("BHUP: %ld\n", c->arg);
+ dbg_statcallb("BHUP: %d\n", i);
if (dev->global_flags & ISDN_GLOBAL_STOPPED)
return 0;
dev->drv[di]->online &= ~(1 << (c->arg));
{
ctrl->command = cmd;
ctrl->driver = isdn_slot_driver(sl);
- ctrl->arg &= 0xff; ctrl->arg |= isdn_slot_channel(sl);
-
+ switch (cmd) {
+ case ISDN_CMD_SETL2:
+ case ISDN_CMD_SETL3:
+ case ISDN_CMD_PROT_IO:
+ ctrl->arg &= ~0xff; ctrl->arg |= isdn_slot_channel(sl);
+ break;
+ default:
+ ctrl->arg = isdn_slot_channel(sl);
+ break;
+ }
+
return isdn_command(ctrl);
}
isdn_info_update();
}
+int
+isdn_slot_m_idx(int sl)
+{
+ BUG_ON(sl < 0);
+
+ return slot[sl].m_idx;
+}
+
+void
+isdn_slot_set_m_idx(int sl, int midx)
+{
+ BUG_ON(sl < 0);
+
+ slot[sl].m_idx = midx;
+}
+
+char *
+isdn_slot_num(int sl)
+{
+ BUG_ON(sl < 0);
+
+ return slot[sl].num;
+}
+
void
isdn_slot_set_rx_netdev(int sl, isdn_net_dev *nd)
{
{
BUG_ON(sl < 0);
- slot[sl].rx_netdev = nd;
+ slot[sl].st_netdev = nd;
}
isdn_net_dev *
#endif
enum {
- ST_0 = 0,
- ST_OUT_WAIT_DCONN = 4,
- ST_OUT_WAIT_BCONN = 6,
- ST_IN_WAIT_DCONN = 7,
- ST_IN_WAIT_BCONN = 10,
- ST_WAIT_BEFORE_CB = 11,
+ ST_NULL,
+ ST_OUT_WAIT_DCONN,
+ ST_OUT_WAIT_BCONN,
+ ST_IN_WAIT_DCONN,
+ ST_IN_WAIT_BCONN,
+ ST_ACTIVE,
+ ST_WAIT_BEFORE_CB,
};
/* keep clear of ISDN_CMD_* and ISDN_STAT_* */
*/
qdisc_reset(lp->netdev->dev.qdisc);
}
- lp->dialstate = ST_0;
- isdn_slot_set_rx_netdev(lp->isdn_slot, NULL);
- isdn_slot_set_st_netdev(lp->isdn_slot, NULL);
- isdn_slot_free(lp->isdn_slot, ISDN_USAGE_NET);
+ lp->dialstate = ST_NULL;
+ if (lp->isdn_slot >= 0) {
+ isdn_slot_set_rx_netdev(lp->isdn_slot, NULL);
+ isdn_slot_set_st_netdev(lp->isdn_slot, NULL);
+ isdn_slot_free(lp->isdn_slot, ISDN_USAGE_NET);
+ }
lp->flags &= ~ISDN_NET_CONNECTED;
lp->isdn_slot = -1;
l->transcount = 0;
if (dev->net_verbose > 3)
printk(KERN_DEBUG "%s: %d bogocps\n", l->name, l->cps);
- if ((l->flags & ISDN_NET_CONNECTED) && (l->dialstate == ST_0)) {
+ if ((l->flags & ISDN_NET_CONNECTED) && (l->dialstate == ST_ACTIVE)) {
anymore = 1;
l->huptimer++;
+ printk("huptimer %d, onhtime %d, chargetime %d, chargeint %d\n", l->huptimer, l->onhtime, l->chargetime, l->chargeint);
/*
* if there is some dialmode where timeout-hangup
* should _not_ be done, check for that here
while (time_after(jiffies, l->chargetime + l->chargeint))
l->chargetime += l->chargeint;
if (time_after(jiffies, l->chargetime + l->chargeint - 2 * HZ))
- if (l->outgoing || l->hupflags & ISDN_INHUP)
+ if (l->outgoing || l->hupflags & ISDN_INHUP) {
+ HERE;
isdn_net_hangup(&p->dev);
+ }
} else if (l->outgoing) {
if (l->hupflags & ISDN_CHARGEHUP) {
if (l->hupflags & ISDN_WAITCHARGE) {
isdn_net_hangup(&p->dev);
}
}
- } else if (l->hupflags & ISDN_INHUP)
+ } else if (l->hupflags & ISDN_INHUP) {
+ HERE;
isdn_net_hangup(&p->dev);
+ }
}
if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) {
struct concap_proto *cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
#endif
- lp->dialstate = ST_0;
+ lp->dialstate = ST_ACTIVE;
isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
isdn_net_ciscohdlck_connected(lp);
isdn_net_local *lp;
int cmd = c->command;
- if (!p)
+ if (!p) {
+ HERE;
return 0;
-
+ }
lp = &p->local;
return isdn_net_handle_event(lp, cmd, c);
static void
isdn_net_dial_timer(unsigned long data)
{
- isdn_net_local *lp = (isdn_net_local *) lp;
+ isdn_net_local *lp = (isdn_net_local *) data;
+ if (!lp) {
+ isdn_BUG();
+ return;
+ }
+ printk("%s: %s %#x\n", __FUNCTION__, lp->name, lp->dial_event);
isdn_net_handle_event(lp, lp->dial_event, NULL);
}
}
restore_flags(flags);
isdn_slot_dial(lp->isdn_slot, &dial);
- lp->dial_timer.expires = jiffies + 10 * HZ;
- lp->dial_event = EV_NET_TIMER_IN_DCONN;
- add_timer(&lp->dial_timer);
}
lp->huptimer = 0;
lp->outgoing = 1;
lp->hupflags &= ~ISDN_HAVECHARGE;
}
if (lp->cbdelay && (lp->flags & ISDN_NET_CBOUT)) {
- lp->dial_timer.expires = jiffies + lp->cbdelay * HZ;
+ lp->dial_timer.expires = jiffies + lp->cbdelay;
lp->dial_event = EV_NET_TIMER_CB;
} else {
lp->dial_timer.expires = jiffies + 10 * HZ;
isdn_ctrl *c = arg;
isdn_ctrl cmd;
- dbg_net_dial("%s: dialstate=%d\n", lp->name, lp->dialstate);
+ dbg_net_dial("%s: dialstate=%d pr=%#x\n", lp->name, lp->dialstate,pr);
switch (lp->dialstate) {
- case ST_0:
+ case ST_ACTIVE:
switch (pr) {
case ISDN_STAT_BSENT:
/* A packet has successfully been sent out */
lp->dial_event = EV_NET_TIMER_OUT_BCONN;
add_timer(&lp->dial_timer);
return 1;
+ case ISDN_STAT_DHUP:
+ del_timer(&lp->dial_timer);
+ isdn_slot_all_eaz(lp->isdn_slot);
+ printk(KERN_INFO "%s: remote hangup\n", lp->name);
+ isdn_net_unbind_channel(lp);
+ return 1;
}
break;
case ST_OUT_WAIT_BCONN:
isdn_slot_set_usage(lp->isdn_slot, isdn_slot_usage(lp->isdn_slot) | ISDN_USAGE_OUTGOING);
isdn_net_connected(lp);
return 1;
+ case ISDN_STAT_DHUP:
+ del_timer(&lp->dial_timer);
+ isdn_slot_all_eaz(lp->isdn_slot);
+ printk(KERN_INFO "%s: remote hangup\n", lp->name);
+ isdn_net_unbind_channel(lp);
+ return 1;
}
break;
case ST_IN_WAIT_DCONN:
switch (pr) {
case EV_NET_TIMER_IN_DCONN:
isdn_net_hangup(&p->dev);
- break;
+ return 1;
case ISDN_STAT_DCONN:
del_timer(&lp->dial_timer);
lp->dialstate = ST_IN_WAIT_BCONN;
lp->dial_event = EV_NET_TIMER_IN_BCONN;
add_timer(&lp->dial_timer);
return 1;
+ case ISDN_STAT_DHUP:
+ del_timer(&lp->dial_timer);
+ isdn_slot_all_eaz(lp->isdn_slot);
+ printk(KERN_INFO "%s: remote hangup\n", lp->name);
+ isdn_net_unbind_channel(lp);
+ return 1;
}
break;
case ST_IN_WAIT_BCONN:
isdn_slot_set_rx_netdev(lp->isdn_slot, p);
isdn_net_connected(lp);
return 1;
+ case ISDN_STAT_DHUP:
+ del_timer(&lp->dial_timer);
+ isdn_slot_all_eaz(lp->isdn_slot);
+ printk(KERN_INFO "%s: remote hangup\n", lp->name);
+ isdn_net_unbind_channel(lp);
+ return 1;
}
break;
case ST_WAIT_BEFORE_CB:
isdn_BUG();
break;
}
+ printk("NOT HANDLED?\n");
return 0;
}
/* before obtaining the lock the caller should have checked that
the lp isn't busy */
if (isdn_net_lp_busy(lp)) {
- printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+ isdn_BUG();
goto error;
}
if (!(lp->flags & ISDN_NET_CONNECTED)) {
- printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+ isdn_BUG();
goto error;
}
ret = isdn_slot_write(lp->isdn_slot, skb);
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate);
- if (lp->dialstate == ST_0){
+ if (lp->dialstate == ST_ACTIVE){
lp->stats.tx_errors++;
/*
* There is a certain probability that this currently
return 0; /* STN (skb to nirvana) ;) */
}
restore_flags(flags);
- isdn_net_dial(); /* Initiate dialing */
+ init_dialout(lp);
netif_stop_queue(ndev);
return 1; /* let upper layer requeue skb packet */
}
} else {
/* Device is connected to an ISDN channel */
ndev->trans_start = jiffies;
- if (lp->dialstate == ST_0) {
+ if (lp->dialstate == ST_ACTIVE) {
/* ISDN connection is established, try sending */
int ret;
ret = (isdn_net_xmit(ndev, skb));
unsigned long last_cisco_myseq = lp->cisco_myseq;
int myseq_diff = 0;
- if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate != ST_0) {
- printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+ if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate != ST_ACTIVE) {
+ isdn_BUG();
return;
}
lp->cisco_myseq++;
if (p) {
isdn_net_local *lp = &p->local;
if ((lp->flags & ISDN_NET_CONNECTED) &&
- (lp->dialstate == ST_0)) {
+ (lp->dialstate == ST_ACTIVE)) {
isdn_net_receive(&p->dev, skb);
return 1;
}
n = (isdn_net_phone *) 0;
ematch = wret = swapped = 0;
dbg_net_icall("n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
- dev->usage[idx]);
+ isdn_slot_usage(idx));
list_for_each(l, &isdn_net_devs) {
int matchret;
}
}
if (n || (!(lp->flags & ISDN_NET_SECURE))) {
- dbg_net_icall(KERN_DEBUG "n_fi: match3\n");
+ dbg_net_icall("n_fi: match3\n");
/* matching interface found */
/*
int
isdn_net_force_dial_lp(isdn_net_local * lp)
{
- if ((!(lp->flags & ISDN_NET_CONNECTED)) && lp->dialstate == ST_0) {
+ if ((!(lp->flags & ISDN_NET_CONNECTED)) && lp->dialstate == ST_NULL) {
int chi;
if (lp->phone[1]) {
ulong flags;
of those who forget configuring this */
netdev->local.dialmax = 1;
netdev->local.flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL; /* Hangup before Callback, manual dial */
- netdev->local.cbdelay = 25; /* Wait 5 secs before Callback */
+ netdev->local.cbdelay = 5 * HZ; /* Wait 5 secs before Callback */
netdev->local.dialtimeout = -1; /* Infinite Dial-Timeout */
netdev->local.dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
netdev->local.dialstarted = 0; /* Jiffies of last dial-start */
lp->charge = cfg->charge;
lp->l2_proto = cfg->l2_proto;
lp->l3_proto = cfg->l3_proto;
- lp->cbdelay = cfg->cbdelay;
+ lp->cbdelay = cfg->cbdelay * HZ / 5;
lp->dialmax = cfg->dialmax;
lp->triggercps = cfg->triggercps;
lp->slavedelay = cfg->slavedelay * HZ;
cfg->dialmode = lp->flags & ISDN_NET_DIALMODE_MASK;
cfg->chargehup = (lp->hupflags & 4) ? 1 : 0;
cfg->ihup = (lp->hupflags & 8) ? 1 : 0;
- cfg->cbdelay = lp->cbdelay;
+ cfg->cbdelay = lp->cbdelay * 5 / HZ;
cfg->dialmax = lp->dialmax;
cfg->triggercps = lp->triggercps;
cfg->slavedelay = lp->slavedelay / HZ;