Commit 611cc8a5 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Introduce generic bind/unbind callbacks

PPP wants callbacks at the time a connection between ISDN channel
and network interface is established, i.e. before dialing to
avoid dialing when no ipppd is present, so use generic
bind/unbind callbacks.
parent 1a0eac20
...@@ -255,22 +255,6 @@ isdn_net_open(struct net_device *dev) ...@@ -255,22 +255,6 @@ isdn_net_open(struct net_device *dev)
return 0; return 0;
} }
/*
* Assign an ISDN-channel to a net-interface
*/
static void
isdn_net_bind_channel(isdn_net_local * lp, int idx)
{
ulong flags;
save_flags(flags);
cli();
lp->isdn_slot = idx;
isdn_slot_set_rx_netdev(lp->isdn_slot, lp->netdev);
isdn_slot_set_st_netdev(lp->isdn_slot, lp->netdev);
restore_flags(flags);
}
/* /*
* unbind a net-interface (resets interface after an error) * unbind a net-interface (resets interface after an error)
*/ */
...@@ -281,6 +265,10 @@ isdn_net_unbind_channel(isdn_net_local * lp) ...@@ -281,6 +265,10 @@ isdn_net_unbind_channel(isdn_net_local * lp)
save_flags(flags); save_flags(flags);
cli(); cli();
if (lp->unbind)
lp->unbind(lp);
skb_queue_purge(&lp->super_tx_queue); skb_queue_purge(&lp->super_tx_queue);
if (!lp->master) { /* reset only master device */ if (!lp->master) { /* reset only master device */
...@@ -301,6 +289,32 @@ isdn_net_unbind_channel(isdn_net_local * lp) ...@@ -301,6 +289,32 @@ isdn_net_unbind_channel(isdn_net_local * lp)
restore_flags(flags); restore_flags(flags);
} }
/*
* Assign an ISDN-channel to a net-interface
*/
static int
isdn_net_bind_channel(isdn_net_local *lp, int idx)
{
int retval = 0;
unsigned long flags;
save_flags(flags);
cli();
lp->isdn_slot = idx;
isdn_slot_set_rx_netdev(lp->isdn_slot, lp->netdev);
isdn_slot_set_st_netdev(lp->isdn_slot, lp->netdev);
if (lp->bind)
retval = lp->bind(lp);
if (retval < 0)
isdn_net_unbind_channel(lp);
restore_flags(flags);
return retval;
}
/* /*
* Perform auto-hangup for net-interfaces. * Perform auto-hangup for net-interfaces.
* *
...@@ -1232,7 +1246,7 @@ isdn_net_init(struct net_device *ndev) ...@@ -1232,7 +1246,7 @@ isdn_net_init(struct net_device *ndev)
static int static int
isdn_net_do_callback(isdn_net_local *lp) isdn_net_do_callback(isdn_net_local *lp)
{ {
int chi; int slot;
/* /*
* Is the state MANUAL? * Is the state MANUAL?
* If so, no callback can be made, * If so, no callback can be made,
...@@ -1246,34 +1260,25 @@ isdn_net_do_callback(isdn_net_local *lp) ...@@ -1246,34 +1260,25 @@ isdn_net_do_callback(isdn_net_local *lp)
printk(KERN_DEBUG "%s: start callback\n", lp->name); printk(KERN_DEBUG "%s: start callback\n", lp->name);
/* Grab a free ISDN-Channel */ /* Grab a free ISDN-Channel */
if ((chi = isdn_get_free_slot( slot = isdn_get_free_slot(ISDN_USAGE_NET, lp->l2_proto, lp->l3_proto,
ISDN_USAGE_NET, lp->pre_device, lp->pre_channel, lp->msn);
lp->l2_proto, if (slot < 0)
lp->l3_proto, goto err;
lp->pre_device,
lp->pre_channel, if (isdn_net_bind_channel(lp, slot) < 0)
lp->msn) goto err;
) < 0) {
printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
return 0;
}
/* Setup dialstate. */ /* Setup dialstate. */
lp->dial_timer.expires = jiffies + lp->cbdelay; lp->dial_timer.expires = jiffies + lp->cbdelay;
lp->dial_event = EV_NET_TIMER_CB; lp->dial_event = EV_NET_TIMER_CB;
add_timer(&lp->dial_timer); add_timer(&lp->dial_timer);
lp->dialstate = ST_WAIT_BEFORE_CB; lp->dialstate = ST_WAIT_BEFORE_CB;
/* Connect interface with channel */
isdn_net_bind_channel(lp, chi);
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
if (isdn_ppp_bind(lp) < 0) {
isdn_net_unbind_channel(lp);
return 0;
}
/* Initiate dialing by returning 2 or 4 */ /* Initiate dialing by returning 2 or 4 */
return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4; return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
err:
return 0;
} }
/* /*
...@@ -1452,9 +1457,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) ...@@ -1452,9 +1457,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
strcpy(isdn_slot_num(idx), nr); strcpy(isdn_slot_num(idx), nr);
isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET); isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET);
isdn_slot_set_st_netdev(idx, lp->netdev);
lp->isdn_slot = slot; isdn_net_bind_channel(lp, idx);
lp->ppp_slot = -1;
lp->outgoing = 0; lp->outgoing = 0;
lp->huptimer = 0; lp->huptimer = 0;
...@@ -1472,12 +1476,6 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) ...@@ -1472,12 +1476,6 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
add_timer(&lp->dial_timer); add_timer(&lp->dial_timer);
lp->dialstate = ST_IN_WAIT_DCONN; lp->dialstate = ST_IN_WAIT_DCONN;
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
if (isdn_ppp_bind(lp) < 0) {
isdn_net_unbind_channel(lp);
restore_flags(flags);
return 0;
}
restore_flags(flags); restore_flags(flags);
return 1; return 1;
} }
...@@ -1509,7 +1507,7 @@ isdn_net_findif(char *name) ...@@ -1509,7 +1507,7 @@ isdn_net_findif(char *name)
* from isdn_net_start_xmit(). * from isdn_net_start_xmit().
*/ */
int int
isdn_net_force_dial_lp(isdn_net_local * lp) isdn_net_force_dial_lp(isdn_net_local *lp)
{ {
int slot; int slot;
unsigned long flags; unsigned long flags;
...@@ -1529,12 +1527,9 @@ isdn_net_force_dial_lp(isdn_net_local * lp) ...@@ -1529,12 +1527,9 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
if (slot < 0) if (slot < 0)
goto err; goto err;
isdn_net_bind_channel(lp, slot); if (isdn_net_bind_channel(lp, slot) < 0)
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) goto err;;
if (isdn_ppp_bind(lp) < 0) {
isdn_net_unbind_channel(lp);
goto err;
}
/* Initiate dialing */ /* Initiate dialing */
restore_flags(flags); restore_flags(flags);
init_dialout(lp); init_dialout(lp);
......
...@@ -2927,7 +2927,8 @@ isdn_ppp_setup(isdn_net_dev *p) ...@@ -2927,7 +2927,8 @@ isdn_ppp_setup(isdn_net_dev *p)
p->dev.do_ioctl = isdn_ppp_dev_ioctl; p->dev.do_ioctl = isdn_ppp_dev_ioctl;
p->local.receive = isdn_ppp_receive; p->local.receive = isdn_ppp_receive;
p->local.connected = isdn_ppp_wakeup_daemon; p->local.connected = isdn_ppp_wakeup_daemon;
p->local.disconnected = isdn_ppp_free; p->local.bind = isdn_ppp_bind;
p->local.unbind = isdn_ppp_free;
return 0; return 0;
} }
...@@ -375,6 +375,8 @@ typedef struct isdn_net_local_s { ...@@ -375,6 +375,8 @@ typedef struct isdn_net_local_s {
struct sk_buff *skb); struct sk_buff *skb);
void (*connected)(struct isdn_net_local_s *lp); void (*connected)(struct isdn_net_local_s *lp);
void (*disconnected)(struct isdn_net_local_s *lp); void (*disconnected)(struct isdn_net_local_s *lp);
int (*bind)(struct isdn_net_local_s *lp);
void (*unbind)(struct isdn_net_local_s *lp);
} isdn_net_local; } isdn_net_local;
/* the interface itself */ /* the interface itself */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment