Commit 3b1022c5 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-isdn.bkbits.net/linux-2.5.isdn

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 798c67c3 c2ee3a2d
......@@ -503,11 +503,14 @@ isdn_status_callback(isdn_ctrl * c)
retval = 2;
}
break;
case 1:
case 1: /* incoming call accepted by net interface */
list_for_each(l, &isdn_net_devs) {
isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
if (p->isdn_slot == i) {
strcpy(cmd.parm.setup.eazmsn, p->mlp->msn);
isdn_slot_set_usage(i, (isdn_slot_usage(i) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET);
strcpy(isdn_slot_num(i), c->parm.setup.phone);
isdn_slot_command(i, ISDN_CMD_ACCEPTD, &cmd);
retval = 1;
break;
......@@ -1535,26 +1538,20 @@ isdn_get_free_slot(int usage, int l2_proto, int l3_proto,
if (USG_NONE(slot[i].usage) &&
(slot[i].di != -1)) {
int d = slot[i].di;
if ((slot[i].usage & ISDN_USAGE_EXCLUSIVE) &&
((pre_dev != d) || (pre_chan != slot[i].ch)))
continue;
if (!strcmp(isdn_map_eaz2msn(msn, d), "-"))
continue;
if (slot[i].usage & ISDN_USAGE_DISABLED)
continue; /* usage not allowed */
if (dev->drv[d]->flags & DRV_FLAG_RUNNING) {
if (!dev->drv[d]->flags & DRV_FLAG_RUNNING)
continue;
if (((dev->drv[d]->interface->features & features) == features) ||
(((dev->drv[d]->interface->features & vfeatures) == vfeatures) &&
(dev->drv[d]->interface->features & ISDN_FEATURE_L2_TRANS))) {
if ((pre_dev < 0) || (pre_chan < 0)) {
isdn_slot_set_usage(i, (isdn_slot_usage(i) & ISDN_USAGE_EXCLUSIVE) | usage);
if (pre_dev < 0 || pre_chan < 0 ||
(pre_dev == d && pre_chan == slot[i].ch)) {
isdn_slot_set_usage(i, usage);
restore_flags(flags);
return i;
} else if ((pre_dev == d) && (pre_chan == slot[i].ch)) {
isdn_slot_set_usage(i, (isdn_slot_usage(i) & ISDN_USAGE_EXCLUSIVE) | usage);
restore_flags(flags);
return i;
}
}
}
}
......@@ -1571,17 +1568,16 @@ isdn_free_channel(int di, int ch, int usage)
int sl;
sl = isdn_dc2minor(di, ch);
isdn_slot_free(sl, usage);
isdn_slot_free(sl);
}
void
isdn_slot_free(int sl, int usage)
isdn_slot_free(int sl)
{
unsigned long flags;
save_flags(flags);
cli();
if (!usage || (slot[sl].usage & ISDN_USAGE_MASK) == usage) {
strcpy(isdn_slot_num(sl), "???");
slot[sl].ibytes = 0;
slot[sl].obytes = 0;
......@@ -1591,30 +1587,8 @@ isdn_slot_free(int sl, int usage)
isdn_v110_close(slot[sl].iv110.v110);
slot[sl].iv110.v110 = NULL;
// 20.10.99 JIM, try to reinitialize v110 !
isdn_slot_set_usage(sl, isdn_slot_usage(sl) & (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE));
isdn_slot_set_usage(sl, ISDN_USAGE_NONE);
skb_queue_purge(&dev->drv[isdn_slot_driver(sl)]->rpqueue[isdn_slot_channel(sl)]);
}
restore_flags(flags);
}
/*
* Cancel Exclusive-Flag for ISDN-channel
*/
void
isdn_unexclusive_channel(int di, int ch)
{
int i;
ulong flags;
save_flags(flags);
cli();
for (i = 0; i < ISDN_MAX_CHANNELS; i++)
if ((slot[i].di == di) &&
(slot[i].ch == ch)) {
isdn_slot_set_usage(i, isdn_slot_usage(i) & ~ISDN_USAGE_EXCLUSIVE);
restore_flags(flags);
return;
}
restore_flags(flags);
}
......@@ -1959,6 +1933,7 @@ isdn_slot_command(int sl, int cmd, isdn_ctrl *ctrl)
case ISDN_CMD_DIAL:
if (dev->global_flags & ISDN_GLOBAL_STOPPED)
return -EBUSY;
/* fall through */
default:
ctrl->arg = isdn_slot_channel(sl);
......
......@@ -64,7 +64,6 @@ extern int isdn_dc2minor(int di, int ch);
extern void isdn_info_update(void);
extern char *isdn_map_eaz2msn(char *msn, int di);
extern void isdn_timer_ctrl(int tf, int onoff);
extern void isdn_unexclusive_channel(int di, int ch);
extern int isdn_getnum(char **);
extern int isdn_msncmp( const char *, const char *);
extern int isdn_add_channels(driver *, int, int, int);
......@@ -85,7 +84,7 @@ struct dial_info {
};
extern int isdn_get_free_slot(int, int, int, int, int, char *);
extern void isdn_slot_free(int slot, int usage);
extern void isdn_slot_free(int slot);
extern void isdn_slot_all_eaz(int slot);
extern int isdn_slot_command(int slot, int cmd, isdn_ctrl *);
extern int isdn_slot_dial(int slot, struct dial_info *dial);
......
......@@ -21,8 +21,6 @@
#include "isdn_concap.h"
#include <linux/if_arp.h>
#ifdef CONFIG_ISDN_X25
/* The following set of device service operations are for encapsulation
protocols that require for reliable datalink semantics. That means:
......@@ -255,5 +253,3 @@ struct isdn_netif_ops isdn_x25_ops = {
.open = isdn_x25_open,
.close = isdn_x25_close,
};
#endif /* CONFIG_ISDN_X25 */
......@@ -423,163 +423,6 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb)
return 0;
}
/*
* An incoming call-request has arrived.
* Search the interface-chain for an appropriate interface.
* If found, connect the interface to the ISDN-channel and initiate
* D- and B-Channel-setup. If secure-flag is set, accept only
* configured phone-numbers. If callback-flag is set, initiate
* callback-dialing.
*
* Return-Value: 0 = No appropriate interface for this call.
* 1 = Call accepted
* 2 = Reject call, wait cbdelay, then call back
* 3 = Reject call
* 4 = Wait cbdelay, then call back
* 5 = No appropriate interface for this call,
* would eventually match if CID was longer.
*/
int
isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
{
char *eaz;
unsigned char si1, si2;
int match_more = 0;
int retval;
struct list_head *l;
struct isdn_net_phone *n;
ulong flags;
char nr[32];
char *my_eaz;
int slot = isdn_dc2minor(di, ch);
/* Search name in netdev-chain */
save_flags(flags);
cli();
if (!setup->phone[0]) {
nr[0] = '0';
nr[1] = '\0';
printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
} else {
strcpy(nr, setup->phone);
}
si1 = setup->si1;
si2 = setup->si2;
if (!setup->eazmsn[0]) {
printk(KERN_WARNING "isdn_net: Incoming call without CPN, assuming '0'\n");
eaz = "0";
} else {
eaz = setup->eazmsn;
}
if (dev->net_verbose > 1)
printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n", nr, si1, si2, eaz);
/* Accept DATA and VOICE calls at this stage
local eaz is checked later for allowed call types */
if ((si1 != 7) && (si1 != 1)) {
restore_flags(flags);
if (dev->net_verbose > 1)
printk(KERN_INFO "isdn_net: Service-Indicator not 1 or 7, ignored\n");
return 0;
}
n = NULL;
dbg_net_icall("n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
isdn_slot_usage(idx));
list_for_each(l, &isdn_net_devs) {
isdn_net_dev *idev = list_entry(l, isdn_net_dev, global_list);
isdn_net_local *mlp = idev->mlp;
/* check acceptable call types for DOV */
dbg_net_icall("n_fi: if='%s', l.msn=%s, l.flags=%#x, l.dstate=%d\n",
idev->name, mlp->msn, mlp->flags, idev->fi.state);
my_eaz = isdn_slot_map_eaz2msn(slot, mlp->msn);
if (si1 == 1) { /* it's a DOV call, check if we allow it */
if (*my_eaz == 'v' || *my_eaz == 'V' ||
*my_eaz == 'b' || *my_eaz == 'B')
my_eaz++; /* skip to allow a match */
else
continue; /* force non match */
} else { /* it's a DATA call, check if we allow it */
if (*my_eaz == 'b' || *my_eaz == 'B')
my_eaz++; /* skip to allow a match */
}
switch (isdn_msncmp(eaz, my_eaz)) {
case 1:
continue;
case 2:
match_more = 1;
continue;
}
if (isdn_net_bound(idev))
continue;
if (!USG_NONE(isdn_slot_usage(idx)))
continue;
dbg_net_icall("n_fi: match1, pdev=%d pch=%d\n",
idev->pre_device, idev->pre_channel);
if (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE &&
(idev->pre_channel != ch || idev->pre_device != di)) {
dbg_net_icall("n_fi: excl check failed\n");
continue;
}
dbg_net_icall("n_fi: match2\n");
if (mlp->flags & ISDN_NET_SECURE) {
list_for_each_entry(n, &mlp->phone[0], list) {
if (!isdn_msncmp(nr, n->num)) {
goto found;
}
}
continue;
}
found:
dbg_net_icall("n_fi: match3\n");
/* matching interface found */
/*
* Is the state STOPPED?
* If so, no dialin is allowed,
* so reject actively.
* */
if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_OFF) {
restore_flags(flags);
printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
idev->name);
return 3;
}
/*
* Is the interface up?
* If not, reject the call actively.
*/
if (!isdn_net_device_started(idev)) {
restore_flags(flags);
printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
idev->name);
return 3;
}
if (mlp->flags & ISDN_NET_CALLBACK) {
retval = isdn_net_do_callback(idev);
restore_flags(flags);
return retval;
}
printk(KERN_DEBUG "%s: call from %s -> %s accepted\n",
idev->name, nr, eaz);
isdn_net_accept(idev, idx, nr);
restore_flags(flags);
return 1;
}
if (dev->net_verbose)
printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, slot, eaz);
restore_flags(flags);
return (match_more == 2) ? 5:0;
}
/*
* This is called from certain upper protocol layers (multilink ppp
* and x25iface encapsulation module) that want to initiate dialing
......
......@@ -43,11 +43,7 @@ extern int register_isdn_netif(int encap, struct isdn_netif_ops *ops);
extern int isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev);
extern int isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev);
extern int isdn_net_bind_channel(isdn_net_dev *idev, int slot);
extern void isdn_net_unbind_channel(isdn_net_dev *idev);
extern int isdn_net_dial(isdn_net_dev *idev);
extern void isdn_net_accept(isdn_net_dev *idev, int slot, char *nr);
extern int isdn_net_do_callback(isdn_net_dev *idev);
extern int isdn_net_bsent(isdn_net_dev *idev, isdn_ctrl *c);
......
This diff is collapsed.
......@@ -745,7 +745,7 @@ isdn_tty_modem_hup(modem_info * info, int local)
isdn_slot_all_eaz(slot);
info->emu.mdmreg[REG_RINGCNT] = 0;
isdn_slot_free(slot, 0);
isdn_slot_free(slot);
isdn_slot_set_m_idx(slot, -1);
info->isdn_slot = -1;
}
......
......@@ -382,7 +382,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
info->isdn_slot = i;
isdn_slot_set_m_idx(i, info->line);
isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &c);
isdn_slot_free(info->isdn_slot, ISDN_USAGE_FAX);
isdn_slot_free(info->isdn_slot);
isdn_slot_set_m_idx(i, -1);
info->isdn_slot = -1;
restore_flags(flags);
......
......@@ -339,10 +339,11 @@ typedef struct isdn_net_local_s {
/* phone[1] = Outgoing Numbers */
struct list_head slaves; /* list of all bundled channels */
struct list_head online; /* circular list of all bundled
channels, which are currently
online */
spinlock_t online_lock; /* lock to protect queue */
struct list_head online; /* list of all bundled channels,
which are currently online */
spinlock_t online_lock; /* lock to protect online list */
struct list_head running_devs; /* member of global running_devs */
atomic_t refcnt; /* references held by ISDN code */
#ifdef CONFIG_ISDN_X25
struct concap_device_ops *dops; /* callbacks used by encapsulator */
......@@ -403,8 +404,8 @@ typedef struct isdn_net_dev_s {
isdn_net_local *mlp; /* Ptr to master device for all devs*/
struct list_head slaves; /* Members of local->slaves */
struct list_head online; /* Members of local->online */
struct list_head slaves; /* member of local->slaves */
struct list_head online; /* member of local->online */
char name[10]; /* Name of device */
struct list_head global_list; /* global list of all isdn_net_devs */
......
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