Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ab50636c
Commit
ab50636c
authored
Aug 07, 2002
by
Anton Altaparmakov
Browse files
Options
Browse Files
Download
Plain Diff
Merge cantab.net:/usr/src/bklinux-2.5 into cantab.net:/usr/src/tng
parents
0907f58e
6865a163
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1383 additions
and
1353 deletions
+1383
-1353
drivers/isdn/act2000/capi.h
drivers/isdn/act2000/capi.h
+1
-1
drivers/isdn/i4l/isdn_audio.c
drivers/isdn/i4l/isdn_audio.c
+4
-4
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_common.c
+416
-314
drivers/isdn/i4l/isdn_common.h
drivers/isdn/i4l/isdn_common.h
+62
-6
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_net.c
+631
-715
drivers/isdn/i4l/isdn_net.h
drivers/isdn/i4l/isdn_net.h
+3
-4
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/i4l/isdn_ppp.c
+20
-19
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/i4l/isdn_tty.c
+134
-186
drivers/isdn/i4l/isdn_tty.h
drivers/isdn/i4l/isdn_tty.h
+4
-1
drivers/isdn/i4l/isdn_ttyfax.c
drivers/isdn/i4l/isdn_ttyfax.c
+14
-35
drivers/isdn/i4l/isdn_v110.c
drivers/isdn/i4l/isdn_v110.c
+17
-19
drivers/isdn/i4l/isdn_v110.h
drivers/isdn/i4l/isdn_v110.h
+9
-3
drivers/isdn/isdnloop/isdnloop.c
drivers/isdn/isdnloop/isdnloop.c
+6
-2
include/linux/isdn.h
include/linux/isdn.h
+7
-29
include/linux/isdnif.h
include/linux/isdnif.h
+0
-2
mm/mmap.c
mm/mmap.c
+55
-13
No files found.
drivers/isdn/act2000/capi.h
View file @
ab50636c
...
...
@@ -138,7 +138,7 @@ typedef struct actcapi_ncpd {
typedef
struct
actcapi_msg
{
actcapi_msghdr
hdr
;
union
msg
{
union
{
__u16
manuf_msg
;
struct
manufacturer_req_net
{
__u16
manuf_msg
;
...
...
drivers/isdn/i4l/isdn_audio.c
View file @
ab50636c
...
...
@@ -564,8 +564,8 @@ isdn_audio_eval_dtmf(modem_info * info)
ISDN_AUDIO_SKB_LOCK
(
skb
)
=
0
;
save_flags
(
flags
);
cli
();
di
=
i
nfo
->
isdn_driver
;
ch
=
i
nfo
->
isdn_channel
;
di
=
i
sdn_slot_driver
(
info
->
isdn_slot
)
;
ch
=
i
sdn_slot_channel
(
info
->
isdn_slot
)
;
__skb_queue_tail
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
],
skb
);
dev
->
drv
[
di
]
->
rcvcount
[
ch
]
+=
2
;
restore_flags
(
flags
);
...
...
@@ -685,8 +685,8 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
ISDN_AUDIO_SKB_LOCK
(
skb
)
=
0
;
save_flags
(
flags
);
cli
();
di
=
i
nfo
->
isdn_driver
;
ch
=
i
nfo
->
isdn_channel
;
di
=
i
sdn_slot_driver
(
info
->
isdn_slot
)
;
ch
=
i
sdn_slot_channel
(
info
->
isdn_slot
)
;
__skb_queue_tail
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
],
skb
);
dev
->
drv
[
di
]
->
rcvcount
[
ch
]
+=
2
;
restore_flags
(
flags
);
...
...
drivers/isdn/i4l/isdn_common.c
View file @
ab50636c
...
...
@@ -19,6 +19,7 @@
#include <linux/vmalloc.h>
#include <linux/isdn.h>
#include <linux/smp_lock.h>
#include <linux/ctype.h>
#include "isdn_common.h"
#include "isdn_tty.h"
#include "isdn_net.h"
...
...
@@ -26,24 +27,31 @@
#ifdef CONFIG_ISDN_AUDIO
#include "isdn_audio.h"
#endif
#ifdef CONFIG_ISDN_DIVERSION_MODULE
#define CONFIG_ISDN_DIVERSION
#endif
#ifdef CONFIG_ISDN_DIVERSION
#include <linux/isdn_divertif.h>
#endif
/* CONFIG_ISDN_DIVERSION */
#include "isdn_v110.h"
#include <linux/devfs_fs_kernel.h>
/* Debugflags */
#undef ISDN_DEBUG_STATCALLB
MODULE_DESCRIPTION
(
"ISDN4Linux: link layer"
);
MODULE_AUTHOR
(
"Fritz Elfert"
);
MODULE_LICENSE
(
"GPL"
);
isdn_dev
*
dev
;
struct
isdn_slot
{
int
di
;
/* driver index */
int
ch
;
/* channel index (per driver) */
int
usage
;
/* how is it used */
char
num
[
ISDN_MSNLEN
];
/* the current phone number */
unsigned
long
ibytes
;
/* Statistics incoming bytes */
unsigned
long
obytes
;
/* Statistics outgoing bytes */
struct
isdn_v110
iv110
;
/* For V.110 */
int
m_idx
;
/* Index for mdm.... */
isdn_net_dev
*
rx_netdev
;
/* rx netdev-pointers */
isdn_net_dev
*
st_netdev
;
/* stat netdev-pointers */
};
static
struct
isdn_slot
slot
[
ISDN_MAX_CHANNELS
];
static
char
*
isdn_revision
=
"$Revision: 1.114.6.16 $"
;
extern
char
*
isdn_net_revision
;
...
...
@@ -60,15 +68,18 @@ static char *isdn_audio_revision = ": none $";
#endif
extern
char
*
isdn_v110_revision
;
#if
def CONFIG_ISDN_DIVERSION
#if
defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
static
isdn_divert_if
*
divert_if
;
/* = NULL */
#endif
/* CONFIG_ISDN_DIVERSION */
#else
#define divert_if ((isdn_divert_if *) NULL)
#endif
static
void
set_global_features
(
void
);
static
void
isdn_register_devfs
(
int
);
static
void
isdn_unregister_devfs
(
int
);
static
int
isdn_wildmat
(
char
*
s
,
char
*
p
);
static
int
isdn_command
(
isdn_ctrl
*
cmd
);
void
isdn_lock_drivers
(
void
)
...
...
@@ -230,12 +241,11 @@ isdn_dc2minor(int di, int ch)
{
int
i
;
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
(
dev
->
chanmap
[
i
]
==
ch
&&
dev
->
drvmap
[
i
]
==
di
)
if
(
slot
[
i
].
ch
==
ch
&&
slot
[
i
].
di
==
di
)
return
i
;
return
-
1
;
}
static
int
isdn_timer_cnt1
=
0
;
static
int
isdn_timer_cnt2
=
0
;
static
int
isdn_timer_cnt3
=
0
;
...
...
@@ -252,11 +262,6 @@ isdn_timer_funct(ulong dummy)
isdn_tty_modem_xmit
();
}
if
(
tf
&
ISDN_TIMER_SLOW
)
{
if
(
++
isdn_timer_cnt1
>=
ISDN_TIMER_02SEC
)
{
isdn_timer_cnt1
=
0
;
if
(
tf
&
ISDN_TIMER_NETDIAL
)
isdn_net_dial
();
}
if
(
++
isdn_timer_cnt2
>=
ISDN_TIMER_1SEC
)
{
isdn_timer_cnt2
=
0
;
if
(
tf
&
ISDN_TIMER_NETHANGUP
)
...
...
@@ -291,7 +296,6 @@ isdn_timer_ctrl(int tf, int onoff)
cli
();
if
((
tf
&
ISDN_TIMER_SLOW
)
&&
(
!
(
dev
->
tflags
&
ISDN_TIMER_SLOW
)))
{
/* If the slow-timer wasn't activated until now */
isdn_timer_cnt1
=
0
;
isdn_timer_cnt2
=
0
;
}
old_tflags
=
dev
->
tflags
;
...
...
@@ -317,7 +321,7 @@ isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb)
return
;
}
/* Update statistics */
dev
->
ibytes
[
i
]
+=
skb
->
len
;
slot
[
i
].
ibytes
+=
skb
->
len
;
/* First, try to deliver data to network-device */
if
(
isdn_net_rcv_skb
(
i
,
skb
))
...
...
@@ -327,10 +331,10 @@ isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb)
* makes sense for async streams only, so it is
* called after possible net-device delivery.
*/
if
(
dev
->
v110
[
i
]
)
{
atomic_inc
(
&
dev
->
v110use
[
i
]
);
skb
=
isdn_v110_decode
(
dev
->
v110
[
i
]
,
skb
);
atomic_dec
(
&
dev
->
v110use
[
i
]
);
if
(
slot
[
i
].
iv110
.
v110
)
{
atomic_inc
(
&
slot
[
i
].
iv110
.
v110use
);
skb
=
isdn_v110_decode
(
slot
[
i
].
iv110
.
v110
,
skb
);
atomic_dec
(
&
slot
[
i
].
iv110
.
v110use
);
if
(
!
skb
)
return
;
}
...
...
@@ -350,15 +354,16 @@ isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb)
* lowlevel-driver, use driver's transparent mode and handle V.110 in
* linklevel instead.
*/
int
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
)
&
...
...
@@ -374,30 +379,38 @@ isdn_command(isdn_ctrl *cmd)
* Layer-2 to transparent
*/
if
(
!
(
features
&
l2_feature
))
{
dev
->
v110emu
[
idx
]
=
l2prot
;
slot
[
idx
].
iv110
.
v110emu
=
l2prot
;
cmd
->
arg
=
(
cmd
->
arg
&
255
)
|
(
ISDN_PROTO_L2_TRANS
<<
8
);
}
else
dev
->
v110emu
[
idx
]
=
0
;
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
);
}
void
isdn_all_eaz
(
int
di
,
int
ch
)
{
isdn_ctrl
cmd
;
if
(
di
<
0
)
return
;
cmd
.
driver
=
di
;
cmd
.
arg
=
ch
;
cmd
.
command
=
ISDN_CMD_SETEAZ
;
cmd
.
parm
.
num
[
0
]
=
'\0'
;
isdn_command
(
&
cmd
);
}
/*
* Begin of a CAPI like LL<->HL interface, currently used only for
* supplementary service (CAPI 2.0 part III)
...
...
@@ -430,7 +443,7 @@ isdn_status_callback(isdn_ctrl * c)
int
r
;
int
retval
=
0
;
isdn_ctrl
cmd
;
isdn_net_dev
*
p
;
struct
list_head
*
l
;
di
=
c
->
driver
;
i
=
isdn_dc2minor
(
di
,
c
->
arg
);
...
...
@@ -442,7 +455,7 @@ isdn_status_callback(isdn_ctrl * c)
return
0
;
if
(
isdn_net_stat_callback
(
i
,
c
))
return
0
;
if
(
isdn_v110_stat_callback
(
i
,
c
))
if
(
isdn_v110_stat_callback
(
&
slot
[
i
].
iv110
,
c
))
return
0
;
if
(
isdn_tty_stat_callback
(
i
,
c
))
return
0
;
...
...
@@ -458,8 +471,8 @@ isdn_status_callback(isdn_ctrl * c)
case
ISDN_STAT_RUN
:
dev
->
drv
[
di
]
->
flags
|=
DRV_FLAG_RUNNING
;
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
(
dev
->
drvmap
[
i
]
==
di
)
isdn_
all_eaz
(
di
,
dev
->
chanmap
[
i
]
);
if
(
slot
[
i
].
di
==
di
)
isdn_
slot_all_eaz
(
i
);
set_global_features
();
break
;
case
ISDN_STAT_STOP
:
...
...
@@ -468,9 +481,7 @@ isdn_status_callback(isdn_ctrl * c)
case
ISDN_STAT_ICALL
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"ICALL (net): %d %ld %s
\n
"
,
di
,
c
->
arg
,
c
->
parm
.
num
);
#endif
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
;
...
...
@@ -488,12 +499,10 @@ isdn_status_callback(isdn_ctrl * c)
* 3 on eventually match, if CID is longer.
*/
if
(
c
->
command
==
ISDN_STAT_ICALL
)
if
((
retval
=
isdn_tty_find_icall
(
di
,
c
->
arg
,
&
c
->
parm
.
setup
)))
return
(
retval
);
#ifdef CONFIG_ISDN_DIVERSION
if
((
retval
=
isdn_tty_find_icall
(
di
,
c
->
arg
,
&
c
->
parm
.
setup
)))
return
(
retval
);
if
(
divert_if
)
if
((
retval
=
divert_if
->
stat_callback
(
c
)))
return
(
retval
);
/* processed */
#endif
/* CONFIG_ISDN_DIVERSION */
if
((
retval
=
divert_if
->
stat_callback
(
c
)))
return
(
retval
);
/* processed */
if
((
!
retval
)
&&
(
dev
->
drv
[
di
]
->
flags
&
DRV_FLAG_REJBUS
))
{
/* No tty responding */
cmd
.
driver
=
di
;
...
...
@@ -504,19 +513,15 @@ isdn_status_callback(isdn_ctrl * c)
}
break
;
case
1
:
/* Schedule connection-setup */
isdn_net_dial
();
cmd
.
driver
=
di
;
cmd
.
arg
=
c
->
arg
;
cmd
.
command
=
ISDN_CMD_ACCEPTD
;
for
(
p
=
dev
->
netdev
;
p
;
p
=
p
->
next
)
if
(
p
->
local
->
isdn_channel
==
cmd
.
arg
)
{
strcpy
(
cmd
.
parm
.
setup
.
eazmsn
,
p
->
local
->
msn
);
isdn_command
(
&
cmd
);
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
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
;
}
}
break
;
case
2
:
/* For calling back, first reject incoming call ... */
...
...
@@ -532,24 +537,19 @@ isdn_status_callback(isdn_ctrl * c)
/* Fall through */
case
4
:
/* ... then start callback. */
isdn_net_dial
();
break
;
case
5
:
/* Number would eventually match, if longer */
retval
=
3
;
break
;
}
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"ICALL: ret=%d
\n
"
,
retval
);
#endif
dbg_statcallb
(
"ICALL: ret=%d
\n
"
,
retval
);
return
retval
;
break
;
case
ISDN_STAT_CINF
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"CINF: %ld %s
\n
"
,
c
->
arg
,
c
->
parm
.
num
);
#endif
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"
))
...
...
@@ -557,39 +557,29 @@ isdn_status_callback(isdn_ctrl * c)
isdn_tty_stat_callback
(
i
,
c
);
break
;
case
ISDN_STAT_CAUSE
:
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"CAUSE: %ld %s
\n
"
,
c
->
arg
,
c
->
parm
.
num
);
#endif
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
);
#ifdef CONFIG_ISDN_DIVERSION
if
(
divert_if
)
divert_if
->
stat_callback
(
c
);
#endif
/* CONFIG_ISDN_DIVERSION */
divert_if
->
stat_callback
(
c
);
break
;
case
ISDN_STAT_DISPLAY
:
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"DISPLAY: %ld %s
\n
"
,
c
->
arg
,
c
->
parm
.
display
);
#endif
dbg_statcallb
(
"DISPLAY: %d %s
\n
"
,
i
,
c
->
parm
.
display
);
isdn_tty_stat_callback
(
i
,
c
);
#ifdef CONFIG_ISDN_DIVERSION
if
(
divert_if
)
divert_if
->
stat_callback
(
c
);
#endif
/* CONFIG_ISDN_DIVERSION */
divert_if
->
stat_callback
(
c
);
break
;
case
ISDN_STAT_DCONN
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"DCONN: %ld
\n
"
,
c
->
arg
);
#endif
dbg_statcallb
(
"DCONN: %d
\n
"
,
i
);
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
return
0
;
/* Find any net-device, waiting for D-channel setup */
if
(
isdn_net_stat_callback
(
i
,
c
))
break
;
isdn_v110_stat_callback
(
i
,
c
);
isdn_v110_stat_callback
(
&
slot
[
i
].
iv110
,
c
);
/* Find any ttyI, waiting for D-channel setup */
if
(
isdn_tty_stat_callback
(
i
,
c
))
{
cmd
.
driver
=
di
;
...
...
@@ -602,9 +592,7 @@ isdn_status_callback(isdn_ctrl * c)
case
ISDN_STAT_DHUP
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"DHUP: %ld
\n
"
,
c
->
arg
);
#endif
dbg_statcallb
(
"DHUP: %d
\n
"
,
i
);
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
return
0
;
dev
->
drv
[
di
]
->
online
&=
~
(
1
<<
(
c
->
arg
));
...
...
@@ -612,21 +600,16 @@ isdn_status_callback(isdn_ctrl * c)
/* Signal hangup to network-devices */
if
(
isdn_net_stat_callback
(
i
,
c
))
break
;
isdn_v110_stat_callback
(
i
,
c
);
isdn_v110_stat_callback
(
&
slot
[
i
].
iv110
,
c
);
if
(
isdn_tty_stat_callback
(
i
,
c
))
break
;
#ifdef CONFIG_ISDN_DIVERSION
if
(
divert_if
)
divert_if
->
stat_callback
(
c
);
#endif
/* CONFIG_ISDN_DIVERSION */
break
;
divert_if
->
stat_callback
(
c
);
break
;
case
ISDN_STAT_BCONN
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"BCONN: %ld
\n
"
,
c
->
arg
);
#endif
dbg_statcallb
(
"BCONN: %ld
\n
"
,
c
->
arg
);
/* Signal B-channel-connect to network-devices */
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
return
0
;
...
...
@@ -634,16 +617,14 @@ isdn_status_callback(isdn_ctrl * c)
isdn_info_update
();
if
(
isdn_net_stat_callback
(
i
,
c
))
break
;
isdn_v110_stat_callback
(
i
,
c
);
isdn_v110_stat_callback
(
&
slot
[
i
].
iv110
,
c
);
if
(
isdn_tty_stat_callback
(
i
,
c
))
break
;
break
;
case
ISDN_STAT_BHUP
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"BHUP: %ld
\n
"
,
c
->
arg
);
#endif
dbg_statcallb
(
"BHUP: %d
\n
"
,
i
);
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
return
0
;
dev
->
drv
[
di
]
->
online
&=
~
(
1
<<
(
c
->
arg
));
...
...
@@ -653,16 +634,14 @@ isdn_status_callback(isdn_ctrl * c)
if
(
isdn_net_stat_callback
(
i
,
c
))
break
;
#endif
isdn_v110_stat_callback
(
i
,
c
);
isdn_v110_stat_callback
(
&
slot
[
i
].
iv110
,
c
);
if
(
isdn_tty_stat_callback
(
i
,
c
))
break
;
break
;
case
ISDN_STAT_NODCH
:
if
(
i
<
0
)
return
-
1
;
#ifdef ISDN_DEBUG_STATCALLB
printk
(
KERN_DEBUG
"NODCH: %ld
\n
"
,
c
->
arg
);
#endif
dbg_statcallb
(
"NODCH: %ld
\n
"
,
c
->
arg
);
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
return
0
;
if
(
isdn_net_stat_callback
(
i
,
c
))
...
...
@@ -679,20 +658,17 @@ isdn_status_callback(isdn_ctrl * c)
save_flags
(
flags
);
cli
();
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
((
dev
->
drvmap
[
i
]
==
di
)
&&
(
dev
->
chanmap
[
i
]
==
c
->
arg
))
{
if
(
c
->
parm
.
num
[
0
])
dev
->
usage
[
i
]
&=
~
ISDN_USAGE_DISABLED
;
else
if
(
USG_NONE
(
dev
->
usage
[
i
]))
{
dev
->
usage
[
i
]
|=
ISDN_USAGE_DISABLED
;
}
else
retval
=
-
1
;
break
;
if
((
slot
[
i
].
di
==
di
)
&&
(
slot
[
i
].
ch
==
c
->
arg
))
{
if
(
c
->
parm
.
num
[
0
])
isdn_slot_set_usage
(
i
,
isdn_slot_usage
(
i
)
&
~
ISDN_USAGE_DISABLED
);
else
if
(
USG_NONE
(
isdn_slot_usage
(
i
)))
isdn_slot_set_usage
(
i
,
isdn_slot_usage
(
i
)
|
ISDN_USAGE_DISABLED
);
else
retval
=
-
1
;
break
;
}
restore_flags
(
flags
);
isdn_info_update
();
break
;
case
ISDN_STAT_UNLOAD
:
while
(
dev
->
drv
[
di
]
->
locks
>
0
)
{
...
...
@@ -707,10 +683,10 @@ isdn_status_callback(isdn_ctrl * c)
cli
();
isdn_tty_stat_callback
(
i
,
c
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
(
dev
->
drvmap
[
i
]
==
di
)
{
dev
->
drvmap
[
i
]
=
-
1
;
dev
->
chanmap
[
i
]
=
-
1
;
dev
->
usage
[
i
]
&=
~
ISDN_USAGE_DISABLED
;
if
(
slot
[
i
].
di
==
di
)
{
slot
[
i
].
di
=
-
1
;
slot
[
i
].
ch
=
-
1
;
slot
[
i
].
usage
&=
~
ISDN_USAGE_DISABLED
;
isdn_unregister_devfs
(
i
);
}
dev
->
drivers
--
;
...
...
@@ -742,12 +718,10 @@ isdn_status_callback(isdn_ctrl * c)
isdn_tty_stat_callback
(
i
,
c
);
break
;
#endif
#ifdef CONFIG_ISDN_DIVERSION
case
ISDN_STAT_PROT
:
case
ISDN_STAT_REDIR
:
if
(
divert_if
)
return
(
divert_if
->
stat_callback
(
c
));
#endif
/* CONFIG_ISDN_DIVERSION */
return
(
divert_if
->
stat_callback
(
c
));
default:
return
-
1
;
}
...
...
@@ -770,50 +744,40 @@ isdn_getnum(char **p)
#define DLE 0x10
/*
* isdn_readbchan() tries to get data from the read-queue.
* isdn_
slot_
readbchan() tries to get data from the read-queue.
* It MUST be called with interrupts off.
*
* Be aware that this is not an atomic operation when sleep != 0, even though
* interrupts are turned off! Well, like that we are currently only called
* on behalf of a read system call on raw device files (which are documented
* to be dangerous and for for debugging purpose only). The inode semaphore
* takes care that this is not called for the same minor device number while
* we are sleeping, but access is not serialized against simultaneous read()
* from the corresponding ttyI device. Can other ugly events, like changes
* of the mapping (di,ch)<->minor, happen during the sleep? --he
*/
int
isdn_
readbchan
(
int
di
,
int
channel
,
u_char
*
buf
,
u_char
*
fp
,
int
len
,
wait_queue_head_t
*
sleep
)
isdn_
slot_readbchan
(
int
sl
,
u_char
*
buf
,
u_char
*
fp
,
int
len
)
{
int
count
;
int
count_pull
;
int
count_put
;
int
dflag
;
int
di
=
isdn_slot_driver
(
sl
);
int
ch
=
isdn_slot_channel
(
sl
);
struct
sk_buff
*
skb
;
u_char
*
cp
;
if
(
!
dev
->
drv
[
di
])
return
0
;
if
(
skb_queue_empty
(
&
dev
->
drv
[
di
]
->
rpqueue
[
channel
]))
{
if
(
sleep
)
interruptible_sleep_on
(
sleep
);
else
return
0
;
}
if
(
len
>
dev
->
drv
[
di
]
->
rcvcount
[
channel
])
len
=
dev
->
drv
[
di
]
->
rcvcount
[
channel
];
if
(
skb_queue_empty
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
]))
return
0
;
if
(
len
>
dev
->
drv
[
di
]
->
rcvcount
[
ch
])
len
=
dev
->
drv
[
di
]
->
rcvcount
[
ch
];
cp
=
buf
;
count
=
0
;
while
(
len
)
{
if
(
!
(
skb
=
skb_peek
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
annel
])))
if
(
!
(
skb
=
skb_peek
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
])))
break
;
#ifdef CONFIG_ISDN_AUDIO
if
(
ISDN_AUDIO_SKB_LOCK
(
skb
))
break
;
ISDN_AUDIO_SKB_LOCK
(
skb
)
=
1
;
if
((
ISDN_AUDIO_SKB_DLECOUNT
(
skb
))
||
(
dev
->
drv
[
di
]
->
DLEflag
&
(
1
<<
ch
annel
)))
{
if
((
ISDN_AUDIO_SKB_DLECOUNT
(
skb
))
||
(
dev
->
drv
[
di
]
->
DLEflag
&
(
1
<<
ch
)))
{
char
*
p
=
skb
->
data
;
unsigned
long
DLEmask
=
(
1
<<
ch
annel
);
unsigned
long
DLEmask
=
(
1
<<
ch
);
dflag
=
0
;
count_pull
=
count_put
=
0
;
...
...
@@ -864,7 +828,7 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que
#ifdef CONFIG_ISDN_AUDIO
ISDN_AUDIO_SKB_LOCK
(
skb
)
=
0
;
#endif
skb
=
skb_dequeue
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
annel
]);
skb
=
skb_dequeue
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
]);
dev_kfree_skb
(
skb
);
}
else
{
/* Not yet emptied this buff, so it
...
...
@@ -876,7 +840,7 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que
ISDN_AUDIO_SKB_LOCK
(
skb
)
=
0
;
#endif
}
dev
->
drv
[
di
]
->
rcvcount
[
ch
annel
]
-=
count_put
;
dev
->
drv
[
di
]
->
rcvcount
[
ch
]
-=
count_put
;
}
return
count
;
}
...
...
@@ -884,13 +848,13 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que
static
__inline
int
isdn_minor2drv
(
int
minor
)
{
return
(
dev
->
drvmap
[
minor
])
;
return
slot
[
minor
].
di
;
}
static
__inline
int
isdn_minor2chan
(
int
minor
)
{
return
(
dev
->
chanmap
[
minor
])
;
return
slot
[
minor
].
ch
;
}
static
char
*
...
...
@@ -903,25 +867,25 @@ isdn_statstr(void)
sprintf
(
istatbuf
,
"idmap:
\t
"
);
p
=
istatbuf
+
strlen
(
istatbuf
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
sprintf
(
p
,
"%s "
,
(
dev
->
drvmap
[
i
]
<
0
)
?
"-"
:
dev
->
drvid
[
dev
->
drvmap
[
i
]
]);
sprintf
(
p
,
"%s "
,
(
slot
[
i
].
di
<
0
)
?
"-"
:
dev
->
drvid
[
slot
[
i
].
di
]);
p
=
istatbuf
+
strlen
(
istatbuf
);
}
sprintf
(
p
,
"
\n
chmap:
\t
"
);
p
=
istatbuf
+
strlen
(
istatbuf
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
sprintf
(
p
,
"%d "
,
dev
->
chanmap
[
i
]
);
sprintf
(
p
,
"%d "
,
slot
[
i
].
ch
);
p
=
istatbuf
+
strlen
(
istatbuf
);
}
sprintf
(
p
,
"
\n
drmap:
\t
"
);
p
=
istatbuf
+
strlen
(
istatbuf
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
sprintf
(
p
,
"%d "
,
dev
->
drvmap
[
i
]
);
sprintf
(
p
,
"%d "
,
slot
[
i
].
di
);
p
=
istatbuf
+
strlen
(
istatbuf
);
}
sprintf
(
p
,
"
\n
usage:
\t
"
);
p
=
istatbuf
+
strlen
(
istatbuf
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
sprintf
(
p
,
"%d "
,
dev
->
usage
[
i
]
);
sprintf
(
p
,
"%d "
,
slot
[
i
].
usage
);
p
=
istatbuf
+
strlen
(
istatbuf
);
}
sprintf
(
p
,
"
\n
flags:
\t
"
);
...
...
@@ -938,7 +902,7 @@ isdn_statstr(void)
sprintf
(
p
,
"
\n
phone:
\t
"
);
p
=
istatbuf
+
strlen
(
istatbuf
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
sprintf
(
p
,
"%s "
,
dev
->
num
[
i
]
);
sprintf
(
p
,
"%s "
,
isdn_slot_num
(
i
)
);
p
=
istatbuf
+
strlen
(
istatbuf
);
}
sprintf
(
p
,
"
\n
"
);
...
...
@@ -1095,8 +1059,8 @@ isdn_status_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
sizeof
(
ulong
)
*
ISDN_MAX_CHANNELS
*
2
)))
return
ret
;
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
put_user
(
dev
->
ibytes
[
i
]
,
p
++
);
put_user
(
dev
->
obytes
[
i
]
,
p
++
);
put_user
(
slot
[
i
].
ibytes
,
p
++
);
put_user
(
slot
[
i
].
obytes
,
p
++
);
}
return
0
;
}
else
...
...
@@ -1279,10 +1243,9 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
int
ret
;
int
i
;
char
*
p
;
char
*
s
;
union
iocpar
{
char
name
[
10
];
char
bname
[
2
2
];
char
bname
[
2
0
];
isdn_ioctl_struct
iocts
;
isdn_net_ioctl_phone
phone
;
isdn_net_ioctl_cfg
cfg
;
...
...
@@ -1310,42 +1273,24 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
#ifdef CONFIG_NETDEVICES
case
IIOCNETAIF
:
/* Add a network-interface */
if
(
arg
)
{
if
(
copy_from_user
(
name
,
(
char
*
)
arg
,
sizeof
(
name
)))
return
-
EFAULT
;
s
=
name
;
}
else
{
s
=
NULL
;
}
if
(
copy_from_user
(
name
,
(
char
*
)
arg
,
sizeof
(
name
)
-
1
))
return
-
EFAULT
;
name
[
sizeof
(
name
)
-
1
]
=
0
;
ret
=
down_interruptible
(
&
dev
->
sem
);
if
(
ret
)
return
ret
;
if
((
s
=
isdn_net_new
(
s
,
NULL
)))
{
if
(
copy_to_user
((
char
*
)
arg
,
s
,
strlen
(
s
)
+
1
)){
ret
=
-
EFAULT
;
}
else
{
ret
=
0
;
}
}
else
ret
=
-
ENODEV
;
if
(
ret
)
return
ret
;
ret
=
isdn_net_new
(
name
,
NULL
);
up
(
&
dev
->
sem
);
return
ret
;
case
IIOCNETASL
:
/* Add a slave to a network-interface */
if
(
arg
)
{
if
(
copy_from_user
(
bname
,
(
char
*
)
arg
,
sizeof
(
bname
)
-
1
))
return
-
EFAULT
;
}
else
return
-
EINVAL
;
if
(
copy_from_user
(
bname
,
(
char
*
)
arg
,
sizeof
(
bname
)
-
1
))
return
-
EFAULT
;
bname
[
sizeof
(
bname
)
-
1
]
=
0
;
ret
=
down_interruptible
(
&
dev
->
sem
);
if
(
ret
)
return
ret
;
if
((
s
=
isdn_net_newslave
(
bname
)))
{
if
(
copy_to_user
((
char
*
)
arg
,
s
,
strlen
(
s
)
+
1
)){
ret
=
-
EFAULT
;
}
else
{
ret
=
0
;
}
}
else
ret
=
-
ENODEV
;
if
(
ret
)
return
ret
;
ret
=
isdn_net_newslave
(
bname
);
up
(
&
dev
->
sem
);
return
ret
;
case
IIOCNETDIF
:
...
...
@@ -1742,8 +1687,8 @@ isdn_map_eaz2msn(char *msn, int di)
#define L2V (~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038))
int
isdn_get_free_
channel
(
int
usage
,
int
l2_proto
,
int
l3_proto
,
int
pre_dev
,
int
pre_chan
,
char
*
msn
)
isdn_get_free_
slot
(
int
usage
,
int
l2_proto
,
int
l3_proto
,
int
pre_dev
,
int
pre_chan
,
char
*
msn
)
{
int
i
;
ulong
flags
;
...
...
@@ -1760,34 +1705,28 @@ isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
* because we can emulate this in linklevel.
*/
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
(
USG_NONE
(
dev
->
usage
[
i
]
)
&&
(
dev
->
drvmap
[
i
]
!=
-
1
))
{
int
d
=
dev
->
drvmap
[
i
]
;
if
((
dev
->
usage
[
i
]
&
ISDN_USAGE_EXCLUSIVE
)
&&
((
pre_dev
!=
d
)
||
(
pre_chan
!=
dev
->
chanmap
[
i
]
)))
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
(
dev
->
usage
[
i
]
&
ISDN_USAGE_DISABLED
)
if
(
slot
[
i
].
usage
&
ISDN_USAGE_DISABLED
)
continue
;
/* usage not allowed */
if
(
dev
->
drv
[
d
]
->
flags
&
DRV_FLAG_RUNNING
)
{
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
))
{
dev
->
usage
[
i
]
&=
ISDN_USAGE_EXCLUSIVE
;
dev
->
usage
[
i
]
|=
usage
;
isdn_info_update
();
isdn_slot_set_usage
(
i
,
(
isdn_slot_usage
(
i
)
&
ISDN_USAGE_EXCLUSIVE
)
|
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
;
}
else
{
if
((
pre_dev
==
d
)
&&
(
pre_chan
==
dev
->
chanmap
[
i
]))
{
dev
->
usage
[
i
]
&=
ISDN_USAGE_EXCLUSIVE
;
dev
->
usage
[
i
]
|=
usage
;
isdn_info_update
();
restore_flags
(
flags
);
return
i
;
}
}
}
}
...
...
@@ -1802,28 +1741,32 @@ isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
void
isdn_free_channel
(
int
di
,
int
ch
,
int
usage
)
{
int
i
;
ulong
flags
;
int
sl
;
sl
=
isdn_dc2minor
(
di
,
ch
);
isdn_slot_free
(
sl
,
usage
);
}
void
isdn_slot_free
(
int
sl
,
int
usage
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
(((
!
usage
)
||
((
dev
->
usage
[
i
]
&
ISDN_USAGE_MASK
)
==
usage
))
&&
(
dev
->
drvmap
[
i
]
==
di
)
&&
(
dev
->
chanmap
[
i
]
==
ch
))
{
dev
->
usage
[
i
]
&=
(
ISDN_USAGE_NONE
|
ISDN_USAGE_EXCLUSIVE
);
strcpy
(
dev
->
num
[
i
],
"???"
);
dev
->
ibytes
[
i
]
=
0
;
dev
->
obytes
[
i
]
=
0
;
if
(
!
usage
||
(
slot
[
sl
].
usage
&
ISDN_USAGE_MASK
)
==
usage
)
{
strcpy
(
isdn_slot_num
(
sl
),
"???"
);
slot
[
sl
].
ibytes
=
0
;
slot
[
sl
].
obytes
=
0
;
// 20.10.99 JIM, try to reinitialize v110 !
dev
->
v110emu
[
i
]
=
0
;
atomic_set
(
&
(
dev
->
v110use
[
i
])
,
0
);
isdn_v110_close
(
dev
->
v110
[
i
]
);
dev
->
v110
[
i
]
=
NULL
;
slot
[
sl
].
iv110
.
v110emu
=
0
;
atomic_set
(
&
slot
[
sl
].
iv110
.
v110use
,
0
);
isdn_v110_close
(
slot
[
sl
].
iv110
.
v110
);
slot
[
sl
].
iv110
.
v110
=
NULL
;
// 20.10.99 JIM, try to reinitialize v110 !
isdn_info_update
(
);
skb_queue_purge
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
]);
}
isdn_slot_set_usage
(
sl
,
isdn_slot_usage
(
sl
)
&
(
ISDN_USAGE_NONE
|
ISDN_USAGE_EXCLUSIVE
)
);
skb_queue_purge
(
&
dev
->
drv
[
isdn_slot_driver
(
sl
)]
->
rpqueue
[
isdn_slot_channel
(
sl
)
]);
}
restore_flags
(
flags
);
}
...
...
@@ -1839,10 +1782,9 @@ isdn_unexclusive_channel(int di, int ch)
save_flags
(
flags
);
cli
();
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
((
dev
->
drvmap
[
i
]
==
di
)
&&
(
dev
->
chanmap
[
i
]
==
ch
))
{
dev
->
usage
[
i
]
&=
~
ISDN_USAGE_EXCLUSIVE
;
isdn_info_update
();
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
;
}
...
...
@@ -1853,17 +1795,20 @@ isdn_unexclusive_channel(int di, int ch)
* Return: length of data on success, -ERRcode on failure.
*/
int
isdn_
writebuf_skb_stub
(
int
drvidx
,
int
chan
,
int
ack
,
struct
sk_buff
*
skb
)
isdn_
slot_write
(
int
sl
,
struct
sk_buff
*
skb
)
{
int
ret
;
struct
sk_buff
*
nskb
=
NULL
;
int
v110_ret
=
skb
->
len
;
int
idx
=
isdn_dc2minor
(
drvidx
,
chan
);
int
di
=
isdn_slot_driver
(
sl
);
int
ch
=
isdn_slot_channel
(
sl
);
BUG_ON
(
sl
<
0
);
if
(
dev
->
v110
[
idx
]
)
{
atomic_inc
(
&
dev
->
v110use
[
idx
]
);
nskb
=
isdn_v110_encode
(
dev
->
v110
[
idx
]
,
skb
);
atomic_dec
(
&
dev
->
v110use
[
idx
]
);
if
(
slot
[
sl
].
iv110
.
v110
)
{
atomic_inc
(
&
slot
[
sl
].
iv110
.
v110use
);
nskb
=
isdn_v110_encode
(
slot
[
sl
].
iv110
.
v110
,
skb
);
atomic_dec
(
&
slot
[
sl
].
iv110
.
v110use
);
if
(
!
nskb
)
return
0
;
v110_ret
=
*
((
int
*
)
nskb
->
data
);
...
...
@@ -1873,10 +1818,9 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
return
v110_ret
;
}
/* V.110 must always be acknowledged */
ack
=
1
;
ret
=
dev
->
drv
[
drvidx
]
->
interface
->
writebuf_skb
(
drvidx
,
chan
,
ack
,
nskb
);
ret
=
dev
->
drv
[
di
]
->
interface
->
writebuf_skb
(
di
,
ch
,
1
,
nskb
);
}
else
{
int
hl
=
dev
->
drv
[
drvidx
]
->
interface
->
hl_hdrlen
;
int
hl
=
isdn_slot_hdrlen
(
sl
)
;
if
(
skb_headroom
(
skb
)
<
hl
){
/*
...
...
@@ -1892,22 +1836,22 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
skb_tmp
=
skb_realloc_headroom
(
skb
,
hl
);
printk
(
KERN_DEBUG
"isdn_writebuf_skb_stub: reallocating headroom%s
\n
"
,
skb_tmp
?
""
:
" failed"
);
if
(
!
skb_tmp
)
return
-
ENOMEM
;
/* 0 better? */
ret
=
dev
->
drv
[
d
rvidx
]
->
interface
->
writebuf_skb
(
drvidx
,
chan
,
ack
,
skb_tmp
);
ret
=
dev
->
drv
[
d
i
]
->
interface
->
writebuf_skb
(
di
,
ch
,
1
,
skb_tmp
);
if
(
ret
>
0
){
dev_kfree_skb
(
skb
);
}
else
{
dev_kfree_skb
(
skb_tmp
);
}
}
else
{
ret
=
dev
->
drv
[
d
rvidx
]
->
interface
->
writebuf_skb
(
drvidx
,
chan
,
ack
,
skb
);
ret
=
dev
->
drv
[
d
i
]
->
interface
->
writebuf_skb
(
di
,
ch
,
1
,
skb
);
}
}
if
(
ret
>
0
)
{
dev
->
obytes
[
idx
]
+=
ret
;
if
(
dev
->
v110
[
idx
]
)
{
atomic_inc
(
&
dev
->
v110use
[
idx
]
);
dev
->
v110
[
idx
]
->
skbuser
++
;
atomic_dec
(
&
dev
->
v110use
[
idx
]
);
slot
[
sl
].
obytes
+=
ret
;
if
(
slot
[
sl
].
iv110
.
v110
)
{
atomic_inc
(
&
slot
[
sl
].
iv110
.
v110use
);
slot
[
sl
].
iv110
.
v110
->
skbuser
++
;
atomic_dec
(
&
slot
[
sl
].
iv110
.
v110use
);
/* For V.110 return unencoded data length */
ret
=
v110_ret
;
/* if the complete frame was send we free the skb;
...
...
@@ -1916,7 +1860,7 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
dev_kfree_skb
(
skb
);
}
}
else
if
(
dev
->
v110
[
idx
]
)
if
(
slot
[
sl
].
iv110
.
v110
)
dev_kfree_skb
(
nskb
);
return
ret
;
}
...
...
@@ -1997,9 +1941,9 @@ isdn_add_channels(driver *d, int drvidx, int n, int adding)
cli
();
for
(
j
=
d
->
channels
;
j
<
m
;
j
++
)
for
(
k
=
0
;
k
<
ISDN_MAX_CHANNELS
;
k
++
)
if
(
dev
->
chanmap
[
k
]
<
0
)
{
dev
->
chanmap
[
k
]
=
j
;
dev
->
drvmap
[
k
]
=
drvidx
;
if
(
slot
[
k
].
ch
<
0
)
{
slot
[
k
].
ch
=
j
;
slot
[
k
].
di
=
drvidx
;
isdn_register_devfs
(
k
);
break
;
}
...
...
@@ -2026,7 +1970,7 @@ set_global_features(void)
}
}
#if
def CONFIG_ISDN_DIVERSION
#if
defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
static
char
*
map_drvname
(
int
di
)
{
...
...
@@ -2075,7 +2019,7 @@ int DIVERT_REG_NAME(isdn_divert_if *i_div)
EXPORT_SYMBOL
(
DIVERT_REG_NAME
);
#endif
/* CONFIG_ISDN_DIVERSION */
#endif
EXPORT_SYMBOL
(
register_isdn
);
...
...
@@ -2140,6 +2084,186 @@ register_isdn(isdn_if * i)
return
1
;
}
int
isdn_slot_driver
(
int
sl
)
{
BUG_ON
(
sl
<
0
);
return
slot
[
sl
].
di
;
}
int
isdn_slot_channel
(
int
sl
)
{
BUG_ON
(
sl
<
0
);
return
slot
[
sl
].
ch
;
}
int
isdn_slot_hdrlen
(
int
sl
)
{
int
di
=
isdn_slot_driver
(
sl
);
return
dev
->
drv
[
di
]
->
interface
->
hl_hdrlen
;
}
char
*
isdn_slot_map_eaz2msn
(
int
sl
,
char
*
msn
)
{
int
di
=
isdn_slot_driver
(
sl
);
return
isdn_map_eaz2msn
(
msn
,
di
);
}
int
isdn_slot_command
(
int
sl
,
int
cmd
,
isdn_ctrl
*
ctrl
)
{
ctrl
->
command
=
cmd
;
ctrl
->
driver
=
isdn_slot_driver
(
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
);
}
int
isdn_slot_dial
(
int
sl
,
struct
dial_info
*
dial
)
{
isdn_ctrl
cmd
;
int
retval
;
char
*
msn
=
isdn_slot_map_eaz2msn
(
sl
,
dial
->
msn
);
/* check for DOV */
if
(
dial
->
si1
==
7
&&
tolower
(
dial
->
phone
[
0
])
==
'v'
)
{
/* DOV call */
dial
->
si1
=
1
;
dial
->
phone
++
;
/* skip v/V */
}
strcpy
(
isdn_slot_num
(
sl
),
dial
->
phone
);
isdn_slot_set_usage
(
sl
,
isdn_slot_usage
(
sl
)
|
ISDN_USAGE_OUTGOING
);
retval
=
isdn_slot_command
(
sl
,
ISDN_CMD_CLREAZ
,
&
cmd
);
if
(
retval
)
return
retval
;
strcpy
(
cmd
.
parm
.
num
,
msn
);
retval
=
isdn_slot_command
(
sl
,
ISDN_CMD_SETEAZ
,
&
cmd
);
cmd
.
arg
=
dial
->
l2_proto
<<
8
;
cmd
.
parm
.
fax
=
dial
->
fax
;
retval
=
isdn_slot_command
(
sl
,
ISDN_CMD_SETL2
,
&
cmd
);
if
(
retval
)
return
retval
;
cmd
.
arg
=
dial
->
l3_proto
<<
8
;
retval
=
isdn_slot_command
(
sl
,
ISDN_CMD_SETL3
,
&
cmd
);
if
(
retval
)
return
retval
;
cmd
.
parm
.
setup
.
si1
=
dial
->
si1
;
cmd
.
parm
.
setup
.
si2
=
dial
->
si2
;
strcpy
(
cmd
.
parm
.
setup
.
eazmsn
,
msn
);
strcpy
(
cmd
.
parm
.
setup
.
phone
,
dial
->
phone
);
printk
(
KERN_INFO
"ISDN: slot %d: Dialing %s -> %s (SI %d/%d) (B %d/%d)
\n
"
,
sl
,
cmd
.
parm
.
setup
.
eazmsn
,
cmd
.
parm
.
setup
.
phone
,
cmd
.
parm
.
setup
.
si1
,
cmd
.
parm
.
setup
.
si2
,
dial
->
l2_proto
,
dial
->
l3_proto
);
return
isdn_slot_command
(
sl
,
ISDN_CMD_DIAL
,
&
cmd
);
}
void
isdn_slot_all_eaz
(
int
sl
)
{
isdn_ctrl
cmd
;
cmd
.
parm
.
num
[
0
]
=
'\0'
;
isdn_slot_command
(
sl
,
ISDN_CMD_SETEAZ
,
&
cmd
);
}
int
isdn_slot_usage
(
int
sl
)
{
BUG_ON
(
sl
<
0
);
return
slot
[
sl
].
usage
;
}
void
isdn_slot_set_usage
(
int
sl
,
int
usage
)
{
BUG_ON
(
sl
<
0
);
slot
[
sl
].
usage
=
usage
;
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
;
}
isdn_net_dev
*
isdn_slot_rx_netdev
(
int
sl
)
{
BUG_ON
(
sl
<
0
);
return
slot
[
sl
].
rx_netdev
;
}
void
isdn_slot_set_st_netdev
(
int
sl
,
isdn_net_dev
*
nd
)
{
BUG_ON
(
sl
<
0
);
slot
[
sl
].
st_netdev
=
nd
;
}
isdn_net_dev
*
isdn_slot_st_netdev
(
int
sl
)
{
BUG_ON
(
sl
<
0
);
return
slot
[
sl
].
st_netdev
;
}
/*
*****************************************************************************
* And now the modules code.
...
...
@@ -2247,53 +2371,43 @@ static void isdn_cleanup_devfs(void)
static
int
__init
isdn_init
(
void
)
{
int
i
;
int
retval
;
char
tmprev
[
50
];
if
(
!
(
dev
=
(
isdn_dev
*
)
vmalloc
(
sizeof
(
isdn_dev
))))
{
printk
(
KERN_WARNING
"isdn: Could not allocate device-struct.
\n
"
);
return
-
EIO
;
dev
=
vmalloc
(
sizeof
(
*
dev
));
if
(
!
dev
)
{
retval
=
-
ENOMEM
;
goto
err
;
}
memset
(
(
char
*
)
dev
,
0
,
sizeof
(
isdn_
dev
));
memset
(
dev
,
0
,
sizeof
(
*
dev
));
init_timer
(
&
dev
->
timer
);
dev
->
timer
.
function
=
isdn_timer_funct
;
init_MUTEX
(
&
dev
->
sem
);
init_waitqueue_head
(
&
dev
->
info_waitq
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
dev
->
drvmap
[
i
]
=
-
1
;
dev
->
chanmap
[
i
]
=
-
1
;
dev
->
m_idx
[
i
]
=
-
1
;
strcpy
(
dev
->
num
[
i
]
,
"???"
);
slot
[
i
].
di
=
-
1
;
slot
[
i
].
ch
=
-
1
;
slot
[
i
].
m_idx
=
-
1
;
strcpy
(
isdn_slot_num
(
i
)
,
"???"
);
init_waitqueue_head
(
&
dev
->
mdm
.
info
[
i
].
open_wait
);
init_waitqueue_head
(
&
dev
->
mdm
.
info
[
i
].
close_wait
);
}
if
(
register_chrdev
(
ISDN_MAJOR
,
"isdn"
,
&
isdn_fops
))
{
retval
=
register_chrdev
(
ISDN_MAJOR
,
"isdn"
,
&
isdn_fops
);
if
(
retval
)
{
printk
(
KERN_WARNING
"isdn: Could not register control devices
\n
"
);
vfree
(
dev
);
return
-
EIO
;
goto
err_vfree
;
}
isdn_init_devfs
();
if
((
i
=
isdn_tty_modem_init
())
<
0
)
{
retval
=
isdn_tty_init
();
if
(
retval
<
0
)
{
printk
(
KERN_WARNING
"isdn: Could not register tty devices
\n
"
);
if
(
i
==
-
3
)
tty_unregister_driver
(
&
dev
->
mdm
.
cua_modem
);
if
(
i
<=
-
2
)
tty_unregister_driver
(
&
dev
->
mdm
.
tty_modem
);
vfree
(
dev
);
isdn_cleanup_devfs
();
unregister_chrdev
(
ISDN_MAJOR
,
"isdn"
);
return
-
EIO
;
goto
err_cleanup_devfs
;
}
#ifdef CONFIG_ISDN_PPP
if
(
isdn_ppp_init
()
<
0
)
{
retval
=
isdn_ppp_init
();
if
(
retval
<
0
)
{
printk
(
KERN_WARNING
"isdn: Could not create PPP-device-structs
\n
"
);
tty_unregister_driver
(
&
dev
->
mdm
.
tty_modem
);
tty_unregister_driver
(
&
dev
->
mdm
.
cua_modem
);
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
kfree
(
dev
->
mdm
.
info
[
i
].
xmit_buf
-
4
);
isdn_cleanup_devfs
();
unregister_chrdev
(
ISDN_MAJOR
,
"isdn"
);
vfree
(
dev
);
return
-
EIO
;
goto
err_tty_modem
;
}
#endif
/* CONFIG_ISDN_PPP */
...
...
@@ -2317,6 +2431,16 @@ static int __init isdn_init(void)
#endif
isdn_info_update
();
return
0
;
err_tty_modem:
isdn_tty_exit
();
err_cleanup_devfs:
isdn_cleanup_devfs
();
unregister_chrdev
(
ISDN_MAJOR
,
"isdn"
);
err_vfree:
vfree
(
dev
);
err:
return
retval
;
}
/*
...
...
@@ -2325,46 +2449,24 @@ static int __init isdn_init(void)
static
void
__exit
isdn_exit
(
void
)
{
unsigned
long
flags
;
int
i
;
#ifdef CONFIG_ISDN_PPP
isdn_ppp_cleanup
();
#endif
save_flags
(
flags
);
cli
();
if
(
isdn_net_rmall
()
<
0
)
{
printk
(
KERN_WARNING
"isdn: net-device busy, remove cancelled
\n
"
);
restore_flags
(
flags
);
return
;
}
if
(
tty_unregister_driver
(
&
dev
->
mdm
.
tty_modem
))
{
printk
(
KERN_WARNING
"isdn: ttyI-device busy, remove cancelled
\n
"
);
restore_flags
(
flags
);
return
;
}
if
(
tty_unregister_driver
(
&
dev
->
mdm
.
cua_modem
))
{
printk
(
KERN_WARNING
"isdn: cui-device busy, remove cancelled
\n
"
);
restore_flags
(
flags
);
return
;
}
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
isdn_tty_cleanup_xmit
(
&
dev
->
mdm
.
info
[
i
]);
kfree
(
dev
->
mdm
.
info
[
i
].
xmit_buf
-
4
);
#ifdef CONFIG_ISDN_TTY_FAX
kfree
(
dev
->
mdm
.
info
[
i
].
fax
);
#endif
}
if
(
unregister_chrdev
(
ISDN_MAJOR
,
"isdn"
)
!=
0
)
{
printk
(
KERN_WARNING
"isdn: controldevice busy, remove cancelled
\n
"
);
restore_flags
(
flags
);
}
else
{
isdn_cleanup_devfs
();
del_timer
(
&
dev
->
timer
);
restore_flags
(
flags
);
/* call vfree with interrupts enabled, else it will hang */
vfree
(
dev
);
printk
(
KERN_NOTICE
"ISDN-subsystem unloaded
\n
"
);
}
if
(
isdn_net_rmall
()
<
0
)
BUG
();
isdn_tty_exit
();
if
(
unregister_chrdev
(
ISDN_MAJOR
,
"isdn"
))
BUG
();
isdn_cleanup_devfs
();
del_timer
(
&
dev
->
timer
);
restore_flags
(
flags
);
/* call vfree with interrupts enabled, else it will hang */
vfree
(
dev
);
}
module_init
(
isdn_init
);
...
...
drivers/isdn/i4l/isdn_common.h
View file @
ab50636c
...
...
@@ -23,6 +23,32 @@
#undef ISDN_DEBUG_NET_DUMP
#undef ISDN_DEBUG_NET_DIAL
#undef ISDN_DEBUG_NET_ICALL
#undef ISDN_DEBUG_STATCALLB
#undef ISDN_DEBUG_COMMAND
#ifdef ISDN_DEBUG_NET_DIAL
#define dbg_net_dial(arg...) printk(KERN_DEBUG arg)
#else
#define dbg_net_dial(arg...) do {} while (0)
#endif
#ifdef ISDN_DEBUG_NET_ICALL
#define dbg_net_icall(arg...) printk(KERN_DEBUG arg)
#else
#define dbg_net_icall(arg...) do {} while (0)
#endif
#ifdef ISDN_DEBUG_STATCALLB
#define dbg_statcallb(arg...) printk(KERN_DEBUG arg)
#else
#define dbg_statcallb(arg...) do {} while (0)
#endif
#define isdn_BUG() \
do { printk(KERN_WARNING "ISDN Bug at %s:%d\n", __FILE__, __LINE__); \
} while(0)
#define HERE printk("%s:%d (%s)\n", __FILE__, __LINE__, __FUNCTION__)
/* Prototypes */
extern
void
isdn_MOD_INC_USE_COUNT
(
void
);
...
...
@@ -30,20 +56,50 @@ extern void isdn_MOD_DEC_USE_COUNT(void);
extern
void
isdn_lock_drivers
(
void
);
extern
void
isdn_unlock_drivers
(
void
);
extern
void
isdn_free_channel
(
int
di
,
int
ch
,
int
usage
);
extern
void
isdn_all_eaz
(
int
di
,
int
ch
);
extern
int
isdn_command
(
isdn_ctrl
*
);
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_readbchan
(
int
,
int
,
u_char
*
,
u_char
*
,
int
,
wait_queue_head_t
*
);
extern
int
isdn_get_free_channel
(
int
,
int
,
int
,
int
,
int
,
char
*
);
extern
int
isdn_writebuf_skb_stub
(
int
,
int
,
int
,
struct
sk_buff
*
);
extern
int
register_isdn
(
isdn_if
*
i
);
extern
int
isdn_msncmp
(
const
char
*
,
const
char
*
);
extern
int
isdn_add_channels
(
driver
*
,
int
,
int
,
int
);
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
extern
void
isdn_dumppkt
(
char
*
,
u_char
*
,
int
,
int
);
#else
static
inline
void
isdn_dumppkt
(
char
*
s
,
u_char
*
d
,
int
l
,
int
m
)
{
}
#endif
struct
dial_info
{
int
l2_proto
;
int
l3_proto
;
struct
T30_s
*
fax
;
unsigned
char
si1
;
unsigned
char
si2
;
unsigned
char
*
msn
;
unsigned
char
*
phone
;
};
extern
struct
list_head
isdn_net_devs
;
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_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
);
extern
char
*
isdn_slot_map_eaz2msn
(
int
slot
,
char
*
msn
);
extern
int
isdn_slot_write
(
int
slot
,
struct
sk_buff
*
);
extern
int
isdn_slot_readbchan
(
int
slot
,
u_char
*
,
u_char
*
,
int
);
extern
int
isdn_slot_hdrlen
(
int
slot
);
extern
int
isdn_slot_driver
(
int
slot
);
extern
int
isdn_slot_channel
(
int
slot
);
extern
int
isdn_slot_usage
(
int
slot
);
extern
void
isdn_slot_set_usage
(
int
slot
,
int
usage
);
extern
char
*
isdn_slot_num
(
int
slot
);
extern
int
isdn_slot_m_idx
(
int
slot
);
extern
void
isdn_slot_set_m_idx
(
int
slot
,
int
midx
);
extern
void
isdn_slot_set_rx_netdev
(
int
sl
,
isdn_net_dev
*
nd
);
extern
void
isdn_slot_set_st_netdev
(
int
sl
,
isdn_net_dev
*
nd
);
extern
isdn_net_dev
*
isdn_slot_rx_netdev
(
int
sl
);
extern
isdn_net_dev
*
isdn_slot_st_netdev
(
int
sl
);
drivers/isdn/i4l/isdn_net.c
View file @
ab50636c
...
...
@@ -38,6 +38,27 @@
#include "isdn_concap.h"
#endif
enum
{
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_* */
enum
{
EV_NET_DIAL
=
0x200
,
EV_NET_TIMER_IN_DCONN
=
0x201
,
EV_NET_TIMER_IN_BCONN
=
0x202
,
EV_NET_TIMER_OUT_DCONN
=
0x203
,
EV_NET_TIMER_OUT_BCONN
=
0x204
,
EV_NET_TIMER_CB
=
0x205
,
};
LIST_HEAD
(
isdn_net_devs
);
/* Linked list of isdn_net_dev's */
/*
* Outline of new tbusy handling:
...
...
@@ -72,7 +93,7 @@
*/
static
__inline__
int
isdn_net_device_started
(
isdn_net_dev
*
n
)
{
isdn_net_local
*
lp
=
n
->
local
;
isdn_net_local
*
lp
=
&
n
->
local
;
struct
net_device
*
dev
;
if
(
lp
->
master
)
...
...
@@ -179,10 +200,13 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
int
isdn_net_force_dial_lp
(
isdn_net_local
*
);
static
int
isdn_net_start_xmit
(
struct
sk_buff
*
,
struct
net_device
*
);
static
int
do_dialout
(
isdn_net_local
*
lp
);
static
void
isdn_net_ciscohdlck_connected
(
isdn_net_local
*
lp
);
static
void
isdn_net_ciscohdlck_disconnected
(
isdn_net_local
*
lp
);
static
int
isdn_net_handle_event
(
isdn_net_local
*
lp
,
int
pr
,
void
*
arg
);
char
*
isdn_net_revision
=
"$Revision: 1.140.6.11 $"
;
/*
...
...
@@ -280,10 +304,9 @@ isdn_net_bind_channel(isdn_net_local * lp, int idx)
save_flags
(
flags
);
cli
();
lp
->
flags
|=
ISDN_NET_CONNECTED
;
lp
->
isdn_device
=
dev
->
drvmap
[
idx
];
lp
->
isdn_channel
=
dev
->
chanmap
[
idx
];
dev
->
rx_netdev
[
idx
]
=
lp
->
netdev
;
dev
->
st_netdev
[
idx
]
=
lp
->
netdev
;
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
);
}
...
...
@@ -306,13 +329,14 @@ isdn_net_unbind_channel(isdn_net_local * lp)
*/
qdisc_reset
(
lp
->
netdev
->
dev
.
qdisc
);
}
lp
->
dialstate
=
0
;
dev
->
rx_netdev
[
isdn_dc2minor
(
lp
->
isdn_device
,
lp
->
isdn_channel
)]
=
NULL
;
dev
->
st_netdev
[
isdn_dc2minor
(
lp
->
isdn_device
,
lp
->
isdn_channel
)]
=
NULL
;
isdn_free_channel
(
lp
->
isdn_device
,
lp
->
isdn_channel
,
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_device
=
-
1
;
lp
->
isdn_channel
=
-
1
;
lp
->
isdn_slot
=
-
1
;
restore_flags
(
flags
);
}
...
...
@@ -335,12 +359,13 @@ unsigned long last_jiffies = -HZ;
void
isdn_net_autohup
()
{
isdn_net_dev
*
p
=
dev
->
netdev
;
struct
list_head
*
l
;
int
anymore
;
anymore
=
0
;
while
(
p
)
{
isdn_net_local
*
l
=
p
->
local
;
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
isdn_net_local
*
l
=
&
p
->
local
;
if
(
jiffies
==
last_jiffies
)
l
->
cps
=
l
->
transcount
;
else
...
...
@@ -348,9 +373,10 @@ isdn_net_autohup()
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
))
{
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
...
...
@@ -363,8 +389,10 @@ isdn_net_autohup()
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
)
{
...
...
@@ -378,8 +406,10 @@ isdn_net_autohup()
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
))
{
...
...
@@ -387,7 +417,6 @@ isdn_net_autohup()
break
;
}
}
p
=
(
isdn_net_dev
*
)
p
->
next
;
}
last_jiffies
=
jiffies
;
isdn_timer_ctrl
(
ISDN_TIMER_NETHANGUP
,
anymore
);
...
...
@@ -398,6 +427,47 @@ static void isdn_net_lp_disconnected(isdn_net_local *lp)
isdn_net_rm_from_bundle
(
lp
);
}
static
void
isdn_net_connected
(
isdn_net_local
*
lp
)
{
#ifdef CONFIG_ISDN_X25
struct
concap_proto
*
cprot
=
lp
->
netdev
->
cprot
;
struct
concap_proto_ops
*
pops
=
cprot
?
cprot
->
pops
:
0
;
#endif
lp
->
dialstate
=
ST_ACTIVE
;
isdn_timer_ctrl
(
ISDN_TIMER_NETHANGUP
,
1
);
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_CISCOHDLCK
)
isdn_net_ciscohdlck_connected
(
lp
);
if
(
lp
->
p_encap
!=
ISDN_NET_ENCAP_SYNCPPP
)
{
if
(
lp
->
master
)
{
/* is lp a slave? */
isdn_net_dev
*
nd
=
((
isdn_net_local
*
)
lp
->
master
->
priv
)
->
netdev
;
isdn_net_add_to_bundle
(
nd
,
lp
);
}
}
printk
(
KERN_INFO
"isdn_net: %s connected
\n
"
,
lp
->
name
);
/* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here.
*/
lp
->
chargetime
=
jiffies
;
/* reset dial-timeout */
lp
->
dialstarted
=
0
;
lp
->
dialwait_timer
=
0
;
#ifdef CONFIG_ISDN_PPP
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
isdn_ppp_wakeup_daemon
(
lp
);
#endif
#ifdef CONFIG_ISDN_X25
/* try if there are generic concap receiver routines */
if
(
pops
)
if
(
pops
->
connect_ind
)
pops
->
connect_ind
(
cprot
);
#endif
/* CONFIG_ISDN_X25 */
/* ppp needs to do negotiations first */
if
(
lp
->
p_encap
!=
ISDN_NET_ENCAP_SYNCPPP
)
isdn_net_device_wake_queue
(
lp
);
}
/*
* Handle status-messages from ISDN-interfacecard.
* This function is called from within the main-status-dispatcher
...
...
@@ -407,443 +477,343 @@ static void isdn_net_lp_disconnected(isdn_net_local *lp)
int
isdn_net_stat_callback
(
int
idx
,
isdn_ctrl
*
c
)
{
isdn_net_dev
*
p
=
dev
->
st_netdev
[
idx
];
isdn_net_dev
*
p
=
isdn_slot_st_netdev
(
idx
);
isdn_net_local
*
lp
;
int
cmd
=
c
->
command
;
if
(
p
)
{
isdn_net_local
*
lp
=
p
->
local
;
#ifdef CONFIG_ISDN_X25
struct
concap_proto
*
cprot
=
lp
->
netdev
->
cprot
;
struct
concap_proto_ops
*
pops
=
cprot
?
cprot
->
pops
:
0
;
#endif
switch
(
cmd
)
{
case
ISDN_STAT_BSENT
:
/* A packet has successfully been sent out */
if
((
lp
->
flags
&
ISDN_NET_CONNECTED
)
&&
(
!
lp
->
dialstate
))
{
isdn_net_dec_frame_cnt
(
lp
);
lp
->
stats
.
tx_packets
++
;
lp
->
stats
.
tx_bytes
+=
c
->
parm
.
length
;
}
return
1
;
case
ISDN_STAT_DCONN
:
/* D-Channel is up */
switch
(
lp
->
dialstate
)
{
case
4
:
case
7
:
case
8
:
lp
->
dialstate
++
;
return
1
;
case
12
:
lp
->
dialstate
=
5
;
return
1
;
}
break
;
case
ISDN_STAT_DHUP
:
/* Either D-Channel-hangup or error during dialout */
#ifdef CONFIG_ISDN_X25
/* If we are not connencted then dialing had
failed. If there are generic encap protocol
receiver routines signal the closure of
the link*/
if
(
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
)
&&
pops
&&
pops
->
disconn_ind
)
pops
->
disconn_ind
(
cprot
);
#endif
/* CONFIG_ISDN_X25 */
if
((
!
lp
->
dialstate
)
&&
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
{
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_CISCOHDLCK
)
isdn_net_ciscohdlck_disconnected
(
lp
);
#ifdef CONFIG_ISDN_PPP
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
isdn_ppp_free
(
lp
);
#endif
isdn_net_lp_disconnected
(
lp
);
isdn_all_eaz
(
lp
->
isdn_device
,
lp
->
isdn_channel
);
printk
(
KERN_INFO
"%s: remote hangup
\n
"
,
lp
->
name
);
printk
(
KERN_INFO
"%s: Chargesum is %d
\n
"
,
lp
->
name
,
lp
->
charge
);
isdn_net_unbind_channel
(
lp
);
return
1
;
}
break
;
#ifdef CONFIG_ISDN_X25
case
ISDN_STAT_BHUP
:
/* B-Channel-hangup */
/* try if there are generic encap protocol
receiver routines and signal the closure of
the link */
if
(
pops
&&
pops
->
disconn_ind
){
pops
->
disconn_ind
(
cprot
);
return
1
;
}
break
;
#endif
/* CONFIG_ISDN_X25 */
case
ISDN_STAT_BCONN
:
/* B-Channel is up */
isdn_net_zero_frame_cnt
(
lp
);
switch
(
lp
->
dialstate
)
{
case
5
:
case
6
:
case
7
:
case
8
:
case
9
:
case
10
:
case
12
:
if
(
lp
->
dialstate
<=
6
)
{
dev
->
usage
[
idx
]
|=
ISDN_USAGE_OUTGOING
;
isdn_info_update
();
}
else
dev
->
rx_netdev
[
idx
]
=
p
;
lp
->
dialstate
=
0
;
isdn_timer_ctrl
(
ISDN_TIMER_NETHANGUP
,
1
);
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_CISCOHDLCK
)
isdn_net_ciscohdlck_connected
(
lp
);
if
(
lp
->
p_encap
!=
ISDN_NET_ENCAP_SYNCPPP
)
{
if
(
lp
->
master
)
{
/* is lp a slave? */
isdn_net_dev
*
nd
=
((
isdn_net_local
*
)
lp
->
master
->
priv
)
->
netdev
;
isdn_net_add_to_bundle
(
nd
,
lp
);
}
}
printk
(
KERN_INFO
"isdn_net: %s connected
\n
"
,
lp
->
name
);
/* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here.
*/
lp
->
chargetime
=
jiffies
;
/* reset dial-timeout */
lp
->
dialstarted
=
0
;
lp
->
dialwait_timer
=
0
;
if
(
!
p
)
{
HERE
;
return
0
;
}
lp
=
&
p
->
local
;
#ifdef CONFIG_ISDN_PPP
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
isdn_ppp_wakeup_daemon
(
lp
);
#endif
#ifdef CONFIG_ISDN_X25
/* try if there are generic concap receiver routines */
if
(
pops
)
if
(
pops
->
connect_ind
)
pops
->
connect_ind
(
cprot
);
#endif
/* CONFIG_ISDN_X25 */
/* ppp needs to do negotiations first */
if
(
lp
->
p_encap
!=
ISDN_NET_ENCAP_SYNCPPP
)
isdn_net_device_wake_queue
(
lp
);
return
1
;
}
break
;
case
ISDN_STAT_NODCH
:
/* No D-Channel avail. */
if
(
lp
->
dialstate
==
4
)
{
lp
->
dialstate
--
;
return
1
;
}
break
;
case
ISDN_STAT_CINF
:
/* Charge-info from TelCo. Calculate interval between
* charge-infos and set timestamp for last info for
* usage by isdn_net_autohup()
*/
lp
->
charge
++
;
if
(
lp
->
hupflags
&
ISDN_HAVECHARGE
)
{
lp
->
hupflags
&=
~
ISDN_WAITCHARGE
;
lp
->
chargeint
=
jiffies
-
lp
->
chargetime
-
(
2
*
HZ
);
}
if
(
lp
->
hupflags
&
ISDN_WAITCHARGE
)
lp
->
hupflags
|=
ISDN_HAVECHARGE
;
lp
->
chargetime
=
jiffies
;
printk
(
KERN_DEBUG
"isdn_net: Got CINF chargetime of %s now %lu
\n
"
,
lp
->
name
,
lp
->
chargetime
);
return
1
;
}
return
isdn_net_handle_event
(
lp
,
cmd
,
c
);
}
static
void
isdn_net_dial_timer
(
unsigned
long
data
)
{
isdn_net_local
*
lp
=
(
isdn_net_local
*
)
data
;
if
(
!
lp
)
{
isdn_BUG
();
return
;
}
return
0
;
printk
(
"%s: %s %#x
\n
"
,
__FUNCTION__
,
lp
->
name
,
lp
->
dial_event
);
isdn_net_handle_event
(
lp
,
lp
->
dial_event
,
NULL
);
}
/*
* Perform dialout for net-interfaces and timeout-handling for
* D-Channel-up and B-Channel-up Messages.
* This function is initially called from within isdn_net_start_xmit() or
* or isdn_net_find_icall() after initializing the dialstate for an
* interface. If further calls are needed, the function schedules itself
* for a timer-callback via isdn_timer_function().
* The dialstate is also affected by incoming status-messages from
* the ISDN-Channel which are handled in isdn_net_stat_callback() above.
/* Initiate dialout. Set phone-number-pointer to first number
* of interface.
*/
void
i
sdn_net_dial
(
void
)
static
int
i
nit_dialout
(
isdn_net_local
*
lp
)
{
isdn_net_dev
*
p
=
dev
->
netdev
;
int
anymore
=
0
;
int
i
;
unsigned
long
flags
;
isdn_ctrl
cmd
;
u_char
*
phone_number
;
while
(
p
)
{
isdn_net_local
*
lp
=
p
->
local
;
#ifdef ISDN_DEBUG_NET_DIAL
if
(
lp
->
dialstate
)
printk
(
KERN_DEBUG
"%s: dialstate=%d
\n
"
,
lp
->
name
,
lp
->
dialstate
);
#endif
switch
(
lp
->
dialstate
)
{
case
0
:
/* Nothing to do for this interface */
break
;
case
1
:
/* Initiate dialout. Set phone-number-pointer to first number
* of interface.
*/
save_flags
(
flags
);
cli
();
lp
->
dial
=
lp
->
phone
[
1
];
restore_flags
(
flags
);
if
(
!
lp
->
dial
)
{
printk
(
KERN_WARNING
"%s: phone number deleted?
\n
"
,
lp
->
name
);
isdn_net_hangup
(
&
p
->
dev
);
break
;
}
anymore
=
1
;
if
(
lp
->
dialtimeout
>
0
)
if
(
lp
->
dialstarted
==
0
||
time_after
(
jiffies
,
lp
->
dialstarted
+
lp
->
dialtimeout
+
lp
->
dialwait
))
{
lp
->
dialstarted
=
jiffies
;
lp
->
dialwait_timer
=
0
;
}
save_flags
(
flags
);
cli
();
lp
->
dial
=
lp
->
phone
[
1
];
restore_flags
(
flags
);
lp
->
dialstate
++
;
/* Fall through */
case
2
:
/* Prepare dialing. Clear EAZ, then set EAZ. */
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
arg
=
lp
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_CLREAZ
;
isdn_command
(
&
cmd
);
sprintf
(
cmd
.
parm
.
num
,
"%s"
,
isdn_map_eaz2msn
(
lp
->
msn
,
cmd
.
driver
));
cmd
.
command
=
ISDN_CMD_SETEAZ
;
isdn_command
(
&
cmd
);
lp
->
dialretry
=
0
;
anymore
=
1
;
lp
->
dialstate
++
;
/* Fall through */
case
3
:
/* Setup interface, dial current phone-number, switch to next number.
* If list of phone-numbers is exhausted, increment
* retry-counter.
*/
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
||
(
ISDN_NET_DIALMODE
(
*
lp
)
==
ISDN_NET_DM_OFF
))
{
char
*
s
;
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
s
=
"dial suppressed: isdn system stopped"
;
else
s
=
"dial suppressed: dialmode `off'"
;
isdn_net_unreachable
(
&
p
->
dev
,
0
,
s
);
isdn_net_hangup
(
&
p
->
dev
);
break
;
}
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_SETL2
;
cmd
.
arg
=
lp
->
isdn_channel
+
(
lp
->
l2_proto
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_SETL3
;
cmd
.
arg
=
lp
->
isdn_channel
+
(
lp
->
l3_proto
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
arg
=
lp
->
isdn_channel
;
save_flags
(
flags
);
cli
();
if
(
!
lp
->
dial
)
{
restore_flags
(
flags
);
printk
(
KERN_WARNING
"%s: phone number deleted?
\n
"
,
lp
->
name
);
isdn_net_hangup
(
&
p
->
dev
);
break
;
}
if
(
!
strncmp
(
lp
->
dial
->
num
,
"LEASED"
,
strlen
(
"LEASED"
)))
{
restore_flags
(
flags
);
lp
->
dialstate
=
4
;
printk
(
KERN_INFO
"%s: Open leased line ...
\n
"
,
lp
->
name
);
}
else
{
if
(
lp
->
dialtimeout
>
0
)
if
(
time_after
(
jiffies
,
lp
->
dialstarted
+
lp
->
dialtimeout
))
{
restore_flags
(
flags
);
lp
->
dialwait_timer
=
jiffies
+
lp
->
dialwait
;
lp
->
dialstarted
=
0
;
isdn_net_unreachable
(
&
p
->
dev
,
0
,
"dial: timed out"
);
isdn_net_hangup
(
&
p
->
dev
);
break
;
}
if
(
!
lp
->
dial
)
{
printk
(
KERN_WARNING
"%s: phone number deleted?
\n
"
,
lp
->
name
);
isdn_net_hangup
(
&
lp
->
netdev
->
dev
);
return
0
;
}
if
(
lp
->
dialtimeout
>
0
&&
(
lp
->
dialstarted
==
0
||
time_after
(
jiffies
,
lp
->
dialstarted
+
lp
->
dialtimeout
+
lp
->
dialwait
)))
{
lp
->
dialstarted
=
jiffies
;
lp
->
dialwait_timer
=
0
;
}
lp
->
dialretry
=
0
;
return
do_dialout
(
lp
);
}
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_DIAL
;
cmd
.
parm
.
setup
.
si2
=
0
;
/* check for DOV */
phone_number
=
lp
->
dial
->
num
;
if
((
*
phone_number
==
'v'
)
||
(
*
phone_number
==
'V'
))
{
/* DOV call */
cmd
.
parm
.
setup
.
si1
=
1
;
}
else
{
/* DATA call */
cmd
.
parm
.
setup
.
si1
=
7
;
}
/* Setup interface, dial current phone-number, switch to next number.
* If list of phone-numbers is exhausted, increment
* retry-counter.
*/
static
int
do_dialout
(
isdn_net_local
*
lp
)
{
unsigned
long
flags
;
strcpy
(
cmd
.
parm
.
setup
.
phone
,
phone_number
);
/*
* Switch to next number or back to start if at end of list.
*/
if
(
!
(
lp
->
dial
=
(
isdn_net_phone
*
)
lp
->
dial
->
next
))
{
lp
->
dial
=
lp
->
phone
[
1
];
lp
->
dialretry
++
;
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
||
(
ISDN_NET_DIALMODE
(
*
lp
)
==
ISDN_NET_DM_OFF
))
{
char
*
s
;
if
(
dev
->
global_flags
&
ISDN_GLOBAL_STOPPED
)
s
=
"dial suppressed: isdn system stopped"
;
else
s
=
"dial suppressed: dialmode `off'"
;
isdn_net_unreachable
(
&
lp
->
netdev
->
dev
,
0
,
s
);
isdn_net_hangup
(
&
lp
->
netdev
->
dev
);
return
0
;
}
if
(
lp
->
dialretry
>
lp
->
dialmax
)
{
restore_flags
(
flags
);
if
(
lp
->
dialtimeout
==
0
)
{
lp
->
dialwait_timer
=
jiffies
+
lp
->
dialwait
;
lp
->
dialstarted
=
0
;
isdn_net_unreachable
(
&
p
->
dev
,
0
,
"dial: tried all numbers dialmax times"
);
}
isdn_net_hangup
(
&
p
->
dev
);
break
;
}
}
restore_flags
(
flags
);
sprintf
(
cmd
.
parm
.
setup
.
eazmsn
,
"%s"
,
isdn_map_eaz2msn
(
lp
->
msn
,
cmd
.
driver
));
i
=
isdn_dc2minor
(
lp
->
isdn_device
,
lp
->
isdn_channel
);
if
(
i
>=
0
)
{
strcpy
(
dev
->
num
[
i
],
cmd
.
parm
.
setup
.
phone
);
dev
->
usage
[
i
]
|=
ISDN_USAGE_OUTGOING
;
isdn_info_update
();
}
printk
(
KERN_INFO
"%s: dialing %d %s... %s
\n
"
,
lp
->
name
,
lp
->
dialretry
,
cmd
.
parm
.
setup
.
phone
,
(
cmd
.
parm
.
setup
.
si1
==
1
)
?
"DOV"
:
""
);
lp
->
dtimer
=
0
;
#ifdef ISDN_DEBUG_NET_DIAL
printk
(
KERN_DEBUG
"dial: d=%d c=%d
\n
"
,
lp
->
isdn_device
,
lp
->
isdn_channel
);
#endif
isdn_command
(
&
cmd
);
}
lp
->
huptimer
=
0
;
lp
->
outgoing
=
1
;
if
(
lp
->
chargeint
)
{
lp
->
hupflags
|=
ISDN_HAVECHARGE
;
lp
->
hupflags
&=
~
ISDN_WAITCHARGE
;
}
else
{
lp
->
hupflags
|=
ISDN_WAITCHARGE
;
lp
->
hupflags
&=
~
ISDN_HAVECHARGE
;
save_flags
(
flags
);
cli
();
if
(
!
lp
->
dial
)
{
restore_flags
(
flags
);
printk
(
KERN_WARNING
"%s: phone number deleted?
\n
"
,
lp
->
name
);
isdn_net_hangup
(
&
lp
->
netdev
->
dev
);
return
0
;
}
if
(
!
strncmp
(
lp
->
dial
->
num
,
"LEASED"
,
strlen
(
"LEASED"
)))
{
restore_flags
(
flags
);
lp
->
dialstate
=
ST_OUT_WAIT_DCONN
;
printk
(
KERN_INFO
"%s: Open leased line ...
\n
"
,
lp
->
name
);
return
1
;
}
else
{
struct
dial_info
dial
=
{
.
l2_proto
=
lp
->
l2_proto
,
.
l3_proto
=
lp
->
l3_proto
,
.
si1
=
7
,
.
si2
=
0
,
.
msn
=
lp
->
msn
,
.
phone
=
lp
->
dial
->
num
,
};
if
(
lp
->
dialtimeout
>
0
)
{
if
(
time_after
(
jiffies
,
lp
->
dialstarted
+
lp
->
dialtimeout
))
{
restore_flags
(
flags
);
lp
->
dialwait_timer
=
jiffies
+
lp
->
dialwait
;
lp
->
dialstarted
=
0
;
isdn_net_unreachable
(
&
lp
->
netdev
->
dev
,
0
,
"dial: timed out"
);
isdn_net_hangup
(
&
lp
->
netdev
->
dev
);
return
0
;
}
}
/*
* Switch to next number or back to start if at end of list.
*/
if
(
!
(
lp
->
dial
=
(
isdn_net_phone
*
)
lp
->
dial
->
next
))
{
lp
->
dial
=
lp
->
phone
[
1
];
lp
->
dialretry
++
;
if
(
lp
->
dialretry
>
lp
->
dialmax
)
{
restore_flags
(
flags
);
if
(
lp
->
dialtimeout
==
0
)
{
lp
->
dialwait_timer
=
jiffies
+
lp
->
dialwait
;
lp
->
dialstarted
=
0
;
isdn_net_unreachable
(
&
lp
->
netdev
->
dev
,
0
,
"dial: tried all numbers dialmax times"
);
}
anymore
=
1
;
lp
->
dialstate
=
(
lp
->
cbdelay
&&
(
lp
->
flags
&
ISDN_NET_CBOUT
))
?
12
:
4
;
break
;
case
4
:
/* Wait for D-Channel-connect.
* If timeout, switch back to state 3.
* Dialmax-handling moved to state 3.
*/
if
(
lp
->
dtimer
++
>
ISDN_TIMER_DTIMEOUT10
)
lp
->
dialstate
=
3
;
anymore
=
1
;
break
;
case
5
:
/* Got D-Channel-Connect, send B-Channel-request */
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
arg
=
lp
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_ACCEPTB
;
anymore
=
1
;
lp
->
dtimer
=
0
;
lp
->
dialstate
++
;
isdn_command
(
&
cmd
);
break
;
case
6
:
/* Wait for B- or D-Channel-connect. If timeout,
* switch back to state 3.
*/
#ifdef ISDN_DEBUG_NET_DIAL
printk
(
KERN_DEBUG
"dialtimer2: %d
\n
"
,
lp
->
dtimer
);
#endif
if
(
lp
->
dtimer
++
>
ISDN_TIMER_DTIMEOUT10
)
lp
->
dialstate
=
3
;
anymore
=
1
;
break
;
case
7
:
/* Got incoming Call, setup L2 and L3 protocols,
* then wait for D-Channel-connect
*/
#ifdef ISDN_DEBUG_NET_DIAL
printk
(
KERN_DEBUG
"dialtimer4: %d
\n
"
,
lp
->
dtimer
);
isdn_net_hangup
(
&
lp
->
netdev
->
dev
);
return
0
;
}
}
restore_flags
(
flags
);
isdn_slot_dial
(
lp
->
isdn_slot
,
&
dial
);
}
lp
->
huptimer
=
0
;
lp
->
outgoing
=
1
;
if
(
lp
->
chargeint
)
{
lp
->
hupflags
|=
ISDN_HAVECHARGE
;
lp
->
hupflags
&=
~
ISDN_WAITCHARGE
;
}
else
{
lp
->
hupflags
|=
ISDN_WAITCHARGE
;
lp
->
hupflags
&=
~
ISDN_HAVECHARGE
;
}
if
(
lp
->
cbdelay
&&
(
lp
->
flags
&
ISDN_NET_CBOUT
))
{
lp
->
dial_timer
.
expires
=
jiffies
+
lp
->
cbdelay
;
lp
->
dial_event
=
EV_NET_TIMER_CB
;
}
else
{
lp
->
dial_timer
.
expires
=
jiffies
+
10
*
HZ
;
lp
->
dial_event
=
EV_NET_TIMER_OUT_DCONN
;
}
lp
->
dialstate
=
ST_OUT_WAIT_DCONN
;
add_timer
(
&
lp
->
dial_timer
);
return
1
;
}
/* For EV_NET_DIAL, returns 1 if timer callback is needed
* For ISDN_STAT_*, returns 1 if event was for us
*/
static
int
isdn_net_handle_event
(
isdn_net_local
*
lp
,
int
pr
,
void
*
arg
)
{
#ifdef CONFIG_ISDN_X25
struct
concap_proto
*
cprot
=
lp
->
netdev
->
cprot
;
struct
concap_proto_ops
*
pops
=
cprot
?
cprot
->
pops
:
0
;
#endif
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_SETL2
;
cmd
.
arg
=
lp
->
isdn_channel
+
(
lp
->
l2_proto
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_SETL3
;
cmd
.
arg
=
lp
->
isdn_channel
+
(
lp
->
l3_proto
<<
8
);
isdn_command
(
&
cmd
);
if
(
lp
->
dtimer
++
>
ISDN_TIMER_DTIMEOUT15
)
isdn_net_hangup
(
&
p
->
dev
);
else
{
anymore
=
1
;
lp
->
dialstate
++
;
}
break
;
case
9
:
/* Got incoming D-Channel-Connect, send B-Channel-request */
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
arg
=
lp
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_ACCEPTB
;
isdn_command
(
&
cmd
);
anymore
=
1
;
lp
->
dtimer
=
0
;
lp
->
dialstate
++
;
break
;
case
8
:
case
10
:
/* Wait for B- or D-channel-connect */
#ifdef ISDN_DEBUG_NET_DIAL
printk
(
KERN_DEBUG
"dialtimer4: %d
\n
"
,
lp
->
dtimer
);
isdn_net_dev
*
p
=
lp
->
netdev
;
isdn_ctrl
*
c
=
arg
;
isdn_ctrl
cmd
;
dbg_net_dial
(
"%s: dialstate=%d pr=%#x
\n
"
,
lp
->
name
,
lp
->
dialstate
,
pr
);
switch
(
lp
->
dialstate
)
{
case
ST_ACTIVE
:
switch
(
pr
)
{
case
ISDN_STAT_BSENT
:
/* A packet has successfully been sent out */
if
(
lp
->
flags
&
ISDN_NET_CONNECTED
)
{
isdn_net_dec_frame_cnt
(
lp
);
lp
->
stats
.
tx_packets
++
;
lp
->
stats
.
tx_bytes
+=
c
->
parm
.
length
;
return
1
;
}
break
;
case
ISDN_STAT_DHUP
:
/* Either D-Channel-hangup or error during dialout */
#ifdef CONFIG_ISDN_X25 // FIXME handle != ST_0?
/* If we are not connencted then dialing had
failed. If there are generic encap protocol
receiver routines signal the closure of
the link*/
if
(
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
)
&&
pops
&&
pops
->
disconn_ind
)
pops
->
disconn_ind
(
cprot
);
#endif
/* CONFIG_ISDN_X25 */
if
(
lp
->
flags
&
ISDN_NET_CONNECTED
)
{
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_CISCOHDLCK
)
isdn_net_ciscohdlck_disconnected
(
lp
);
#ifdef CONFIG_ISDN_PPP
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
isdn_ppp_free
(
lp
);
#endif
if
(
lp
->
dtimer
++
>
ISDN_TIMER_DTIMEOUT10
)
isdn_net_hangup
(
&
p
->
dev
);
else
anymore
=
1
;
break
;
case
11
:
/* Callback Delay */
if
(
lp
->
dtimer
++
>
lp
->
cbdelay
)
lp
->
dialstate
=
1
;
anymore
=
1
;
break
;
case
12
:
/* Remote does callback. Hangup after cbdelay, then wait for incoming
* call (in state 4).
*/
if
(
lp
->
dtimer
++
>
lp
->
cbdelay
)
{
printk
(
KERN_INFO
"%s: hangup waiting for callback ...
\n
"
,
lp
->
name
);
lp
->
dtimer
=
0
;
lp
->
dialstate
=
4
;
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_HANGUP
;
cmd
.
arg
=
lp
->
isdn_channel
;
isdn_command
(
&
cmd
);
isdn_all_eaz
(
lp
->
isdn_device
,
lp
->
isdn_channel
);
}
anymore
=
1
;
break
;
default:
printk
(
KERN_WARNING
"isdn_net: Illegal dialstate %d for device %s
\n
"
,
lp
->
dialstate
,
lp
->
name
);
isdn_net_lp_disconnected
(
lp
);
isdn_slot_all_eaz
(
lp
->
isdn_slot
);
printk
(
KERN_INFO
"%s: remote hangup
\n
"
,
lp
->
name
);
printk
(
KERN_INFO
"%s: Chargesum is %d
\n
"
,
lp
->
name
,
lp
->
charge
);
isdn_net_unbind_channel
(
lp
);
return
1
;
}
break
;
#ifdef CONFIG_ISDN_X25 // FIXME handle != ST_0?
case
ISDN_STAT_BHUP
:
/* B-Channel-hangup */
/* try if there are generic encap protocol
receiver routines and signal the closure of
the link */
if
(
pops
&&
pops
->
disconn_ind
){
pops
->
disconn_ind
(
cprot
);
return
1
;
}
break
;
#endif
/* CONFIG_ISDN_X25 */
case
ISDN_STAT_CINF
:
/* Charge-info from TelCo. Calculate interval between
* charge-infos and set timestamp for last info for
* usage by isdn_net_autohup()
*/
lp
->
charge
++
;
if
(
lp
->
hupflags
&
ISDN_HAVECHARGE
)
{
lp
->
hupflags
&=
~
ISDN_WAITCHARGE
;
lp
->
chargeint
=
jiffies
-
lp
->
chargetime
-
(
2
*
HZ
);
}
if
(
lp
->
hupflags
&
ISDN_WAITCHARGE
)
lp
->
hupflags
|=
ISDN_HAVECHARGE
;
lp
->
chargetime
=
jiffies
;
printk
(
KERN_DEBUG
"isdn_net: Got CINF chargetime of %s now %lu
\n
"
,
lp
->
name
,
lp
->
chargetime
);
return
1
;
}
break
;
case
ST_OUT_WAIT_DCONN
:
switch
(
pr
)
{
case
EV_NET_TIMER_OUT_DCONN
:
/* try again */
do_dialout
(
lp
);
return
1
;
case
EV_NET_TIMER_CB
:
/* Remote does callback. Hangup after cbdelay,
* then wait for incoming call */
printk
(
KERN_INFO
"%s: hangup waiting for callback ...
\n
"
,
lp
->
name
);
isdn_net_hangup
(
&
lp
->
netdev
->
dev
);
return
1
;
case
ISDN_STAT_DCONN
:
/* Got D-Channel-Connect, send B-Channel-request */
del_timer
(
&
lp
->
dial_timer
);
lp
->
dialstate
=
ST_OUT_WAIT_BCONN
;
isdn_slot_command
(
lp
->
isdn_slot
,
ISDN_CMD_ACCEPTB
,
&
cmd
);
lp
->
dial_timer
.
expires
=
jiffies
+
10
*
HZ
;
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
:
switch
(
pr
)
{
case
EV_NET_TIMER_OUT_BCONN
:
/* try again */
do_dialout
(
lp
);
return
1
;
case
ISDN_STAT_BCONN
:
del_timer
(
&
lp
->
dial_timer
);
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
);
return
1
;
case
ISDN_STAT_DCONN
:
del_timer
(
&
lp
->
dial_timer
);
lp
->
dialstate
=
ST_IN_WAIT_BCONN
;
isdn_slot_command
(
lp
->
isdn_slot
,
ISDN_CMD_ACCEPTB
,
&
cmd
);
lp
->
dial_timer
.
expires
=
jiffies
+
10
*
HZ
;
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
:
switch
(
pr
)
{
case
EV_NET_TIMER_IN_BCONN
:
isdn_net_hangup
(
&
p
->
dev
);
break
;
case
ISDN_STAT_BCONN
:
del_timer
(
&
lp
->
dial_timer
);
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
;
}
p
=
(
isdn_net_dev
*
)
p
->
next
;
break
;
case
ST_WAIT_BEFORE_CB
:
switch
(
pr
)
{
case
EV_NET_TIMER_CB
:
/* Callback Delay */
init_dialout
(
lp
);
return
1
;
}
break
;
default:
isdn_BUG
();
break
;
}
isdn_timer_ctrl
(
ISDN_TIMER_NETDIAL
,
anymore
);
printk
(
"NOT HANDLED?
\n
"
);
return
0
;
}
/*
...
...
@@ -883,12 +853,9 @@ isdn_net_hangup(struct net_device *d)
pops
->
disconn_ind
(
cprot
);
#endif
/* CONFIG_ISDN_X25 */
cmd
.
driver
=
lp
->
isdn_device
;
cmd
.
command
=
ISDN_CMD_HANGUP
;
cmd
.
arg
=
lp
->
isdn_channel
;
isdn_command
(
&
cmd
);
isdn_slot_command
(
lp
->
isdn_slot
,
ISDN_CMD_HANGUP
,
&
cmd
);
printk
(
KERN_INFO
"%s: Chargesum is %d
\n
"
,
lp
->
name
,
lp
->
charge
);
isdn_
all_eaz
(
lp
->
isdn_device
,
lp
->
isdn_channel
);
isdn_
slot_all_eaz
(
lp
->
isdn_slot
);
}
isdn_net_unbind_channel
(
lp
);
}
...
...
@@ -1041,15 +1008,15 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
/* 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_
writebuf_skb_stub
(
lp
->
isdn_device
,
lp
->
isdn_channel
,
1
,
skb
);
ret
=
isdn_
slot_write
(
lp
->
isdn_slot
,
skb
);
if
(
ret
!=
len
)
{
/* we should never get here */
printk
(
KERN_WARNING
"%s: HL driver queue full
\n
"
,
lp
->
name
);
...
...
@@ -1137,7 +1104,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
lp
->
sqfull
=
0
;
}
/* this is a hack to allow auto-hangup for slaves on moderate loads */
nd
->
queue
=
nd
->
local
;
nd
->
queue
=
&
nd
->
local
;
}
return
retv
;
...
...
@@ -1165,7 +1132,7 @@ void isdn_net_tx_timeout(struct net_device * ndev)
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
){
if
(
lp
->
dialstate
==
ST_ACTIVE
){
lp
->
stats
.
tx_errors
++
;
/*
* There is a certain probability that this currently
...
...
@@ -1220,14 +1187,8 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
#endif
/* auto-dialing xmit function */
{
#ifdef ISDN_DEBUG_NET_DUMP
u_char
*
buf
;
#endif
isdn_net_adjust_hdr
(
skb
,
ndev
);
#ifdef ISDN_DEBUG_NET_DUMP
buf
=
skb
->
data
;
isdn_dumppkt
(
"S:"
,
buf
,
skb
->
len
,
40
);
#endif
isdn_dumppkt
(
"S:"
,
skb
->
data
,
skb
->
len
,
40
);
if
(
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
{
int
chi
;
...
...
@@ -1257,7 +1218,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
/* Grab a free ISDN-Channel */
if
(((
chi
=
isdn_get_free_
channel
(
isdn_get_free_
slot
(
ISDN_USAGE_NET
,
lp
->
l2_proto
,
lp
->
l3_proto
,
...
...
@@ -1266,7 +1227,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
lp
->
msn
)
)
<
0
)
&&
((
chi
=
isdn_get_free_
channel
(
isdn_get_free_
slot
(
ISDN_USAGE_NET
,
lp
->
l2_proto
,
lp
->
l3_proto
,
...
...
@@ -1283,7 +1244,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
/* Log packet, which triggered dialing */
if
(
dev
->
net_verbose
)
isdn_net_log_skb
(
skb
,
lp
);
lp
->
dialstate
=
1
;
/* Connect interface with channel */
isdn_net_bind_channel
(
lp
,
chi
);
#ifdef CONFIG_ISDN_PPP
...
...
@@ -1296,14 +1256,14 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return
0
;
/* STN (skb to nirvana) ;) */
}
restore_flags
(
flags
);
i
sdn_net_dial
();
/* Initiate dialing */
i
nit_dialout
(
lp
);
netif_stop_queue
(
ndev
);
return
1
;
/* let upper layer requeue skb packet */
}
#endif
/* Initiate dialing */
restore_flags
(
flags
);
i
sdn_net_dial
(
);
i
nit_dialout
(
lp
);
isdn_net_device_stop_queue
(
lp
);
return
1
;
}
else
{
...
...
@@ -1315,7 +1275,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
else
{
/* Device is connected to an ISDN channel */
ndev
->
trans_start
=
jiffies
;
if
(
!
lp
->
dialstate
)
{
if
(
lp
->
dialstate
==
ST_ACTIVE
)
{
/* ISDN connection is established, try sending */
int
ret
;
ret
=
(
isdn_net_xmit
(
ndev
,
skb
));
...
...
@@ -1433,7 +1393,7 @@ isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev)
static
struct
sk_buff
*
isdn_net_ciscohdlck_alloc_skb
(
isdn_net_local
*
lp
,
int
len
)
{
unsigned
short
hl
=
dev
->
drv
[
lp
->
isdn_device
]
->
interface
->
hl_hdrlen
;
unsigned
short
hl
=
isdn_slot_hdrlen
(
lp
->
isdn_slot
)
;
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
hl
+
len
,
GFP_ATOMIC
);
...
...
@@ -1523,8 +1483,8 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
unsigned
long
last_cisco_myseq
=
lp
->
cisco_myseq
;
int
myseq_diff
=
0
;
if
(
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
)
||
lp
->
dialstate
)
{
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
++
;
...
...
@@ -1814,9 +1774,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
skb
->
dev
=
ndev
;
skb
->
pkt_type
=
PACKET_HOST
;
skb
->
mac
.
raw
=
skb
->
data
;
#ifdef ISDN_DEBUG_NET_DUMP
isdn_dumppkt
(
"R:"
,
skb
->
data
,
skb
->
len
,
40
);
#endif
switch
(
lp
->
p_encap
)
{
case
ISDN_NET_ENCAP_ETHER
:
/* Ethernet over ISDN */
...
...
@@ -1893,12 +1851,12 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
int
isdn_net_rcv_skb
(
int
idx
,
struct
sk_buff
*
skb
)
{
isdn_net_dev
*
p
=
dev
->
rx_netdev
[
idx
]
;
isdn_net_dev
*
p
=
isdn_slot_rx_netdev
(
idx
)
;
if
(
p
)
{
isdn_net_local
*
lp
=
p
->
local
;
isdn_net_local
*
lp
=
&
p
->
local
;
if
((
lp
->
flags
&
ISDN_NET_CONNECTED
)
&&
(
!
lp
->
dialstate
))
{
(
lp
->
dialstate
==
ST_ACTIVE
))
{
isdn_net_receive
(
&
p
->
dev
,
skb
);
return
1
;
}
...
...
@@ -2093,40 +2051,34 @@ isdn_net_init(struct net_device *ndev)
static
void
isdn_net_swapbind
(
int
drvidx
)
{
isdn_net_dev
*
p
;
struct
list_head
*
l
;
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: swapping ch of %d
\n
"
,
drvidx
);
#endif
p
=
dev
->
netdev
;
while
(
p
)
{
if
(
p
->
local
->
pre_device
==
drvidx
)
switch
(
p
->
local
->
pre_channel
)
{
case
0
:
p
->
local
->
pre_channel
=
1
;
break
;
case
1
:
p
->
local
->
pre_channel
=
0
;
break
;
}
p
=
(
isdn_net_dev
*
)
p
->
next
;
dbg_net_icall
(
"n_fi: swapping ch of %d
\n
"
,
drvidx
);
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
if
(
p
->
local
.
pre_device
!=
drvidx
)
continue
;
switch
(
p
->
local
.
pre_channel
)
{
case
0
:
p
->
local
.
pre_channel
=
1
;
break
;
case
1
:
p
->
local
.
pre_channel
=
0
;
break
;
}
}
}
static
void
isdn_net_swap_usage
(
int
i1
,
int
i2
)
{
int
u1
=
dev
->
usage
[
i1
]
&
ISDN_USAGE_EXCLUSIVE
;
int
u2
=
dev
->
usage
[
i2
]
&
ISDN_USAGE_EXCLUSIVE
;
int
u1
=
isdn_slot_usage
(
i1
)
;
int
u2
=
isdn_slot_usage
(
i2
)
;
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: usage of %d and %d
\n
"
,
i1
,
i2
);
#endif
dev
->
usage
[
i1
]
&=
~
ISDN_USAGE_EXCLUSIVE
;
dev
->
usage
[
i1
]
|=
u2
;
dev
->
usage
[
i2
]
&=
~
ISDN_USAGE_EXCLUSIVE
;
dev
->
usage
[
i2
]
|=
u1
;
isdn_info_update
();
dbg_net_icall
(
"n_fi: usage of %d and %d
\n
"
,
i1
,
i2
);
isdn_slot_set_usage
(
i1
,
(
u1
&
~
ISDN_USAGE_EXCLUSIVE
)
|
(
u2
&
ISDN_USAGE_EXCLUSIVE
));
isdn_slot_set_usage
(
i2
,
(
u2
&
~
ISDN_USAGE_EXCLUSIVE
)
|
(
u1
&
ISDN_USAGE_EXCLUSIVE
));
}
/*
...
...
@@ -2155,12 +2107,14 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
int
wret
;
int
swapped
;
int
sidx
=
0
;
isdn_net_dev
*
p
;
struct
list_head
*
l
;
isdn_net_phone
*
n
;
ulong
flags
;
char
nr
[
32
];
char
*
my_eaz
;
isdn_ctrl
cmd
;
int
slot
=
isdn_dc2minor
(
di
,
ch
);
/* Search name in netdev-chain */
save_flags
(
flags
);
cli
();
...
...
@@ -2188,16 +2142,15 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
return
0
;
}
n
=
(
isdn_net_phone
*
)
0
;
p
=
dev
->
netdev
;
n
=
(
isdn_net_phone
*
)
0
;
ematch
=
wret
=
swapped
=
0
;
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: di=%d ch=%d idx=%d usg=%d
\n
"
,
di
,
ch
,
idx
,
dev
->
usage
[
idx
]);
#endif
while
(
p
)
{
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
)
{
int
matchret
;
isdn_net_local
*
lp
=
p
->
local
;
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
isdn_net_local
*
lp
=
&
p
->
local
;
/* If last check has triggered as binding-swap, revert it */
switch
(
swapped
)
{
...
...
@@ -2210,7 +2163,7 @@ p = dev->netdev;
}
swapped
=
0
;
/* check acceptable call types for DOV */
my_eaz
=
isdn_
map_eaz2msn
(
lp
->
msn
,
di
);
my_eaz
=
isdn_
slot_map_eaz2msn
(
slot
,
lp
->
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'
)
...
...
@@ -2231,22 +2184,18 @@ p = dev->netdev;
/* Remember if more numbers eventually can match */
if
(
matchret
>
wret
)
wret
=
matchret
;
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d
\n
"
,
dbg_net_icall
(
"n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d
\n
"
,
lp
->
name
,
lp
->
msn
,
lp
->
flags
,
lp
->
dialstate
);
#endif
if
((
!
matchret
)
&&
/* EAZ is matching */
(((
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
&&
/* but not connected */
(
USG_NONE
(
dev
->
usage
[
idx
]
)))
||
/* and ch. unused or */
((((
lp
->
dialstate
==
4
)
||
(
lp
->
dialstate
==
12
))
&&
/* if dialing */
(
USG_NONE
(
isdn_slot_usage
(
idx
)
)))
||
/* and ch. unused or */
((((
lp
->
dialstate
==
ST_OUT_WAIT_DCONN
)
||
(
lp
->
dialstate
==
ST_OUT_WAIT_DCONN
))
&&
/* if dialing */
(
!
(
lp
->
flags
&
ISDN_NET_CALLBACK
)))
/* but no callback */
)))
{
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: match1, pdev=%d pch=%d
\n
"
,
dbg_net_icall
(
"n_fi: match1, pdev=%d pch=%d
\n
"
,
lp
->
pre_device
,
lp
->
pre_channel
);
#endif
if
(
dev
->
usage
[
idx
]
&
ISDN_USAGE_EXCLUSIVE
)
{
if
(
isdn_slot_usage
(
idx
)
&
ISDN_USAGE_EXCLUSIVE
)
{
if
((
lp
->
pre_channel
!=
ch
)
||
(
lp
->
pre_device
!=
di
))
{
/* Here we got a problem:
...
...
@@ -2260,16 +2209,12 @@ p = dev->netdev;
*/
if
(
ch
==
0
)
{
sidx
=
isdn_dc2minor
(
di
,
1
);
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: ch is 0
\n
"
);
#endif
if
(
USG_NONE
(
dev
->
usage
[
sidx
]))
{
dbg_net_icall
(
"n_fi: ch is 0
\n
"
);
if
(
USG_NONE
(
isdn_slot_usage
(
sidx
)))
{
/* Second Channel is free, now see if it is bound
* exclusive too. */
if
(
dev
->
usage
[
sidx
]
&
ISDN_USAGE_EXCLUSIVE
)
{
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: 2nd channel is down and bound
\n
"
);
#endif
if
(
isdn_slot_usage
(
sidx
)
&
ISDN_USAGE_EXCLUSIVE
)
{
dbg_net_icall
(
"n_fi: 2nd channel is down and bound
\n
"
);
/* Yes, swap bindings only, if the original
* binding is bound to channel 1 of this driver */
if
((
lp
->
pre_device
==
di
)
&&
...
...
@@ -2278,43 +2223,31 @@ p = dev->netdev;
swapped
=
1
;
}
else
{
/* ... else iterate next device */
p
=
(
isdn_net_dev
*
)
p
->
next
;
continue
;
}
}
else
{
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: 2nd channel is down and unbound
\n
"
);
#endif
dbg_net_icall
(
"n_fi: 2nd channel is down and unbound
\n
"
);
/* No, swap always and swap excl-usage also */
isdn_net_swap_usage
(
idx
,
sidx
);
isdn_net_swapbind
(
di
);
swapped
=
2
;
}
/* Now check for exclusive binding again */
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: final check
\n
"
);
#endif
if
((
dev
->
usage
[
idx
]
&
ISDN_USAGE_EXCLUSIVE
)
&&
dbg_net_icall
(
"n_fi: final check
\n
"
);
if
((
isdn_slot_usage
(
idx
)
&
ISDN_USAGE_EXCLUSIVE
)
&&
((
lp
->
pre_channel
!=
ch
)
||
(
lp
->
pre_device
!=
di
)))
{
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: final check failed
\n
"
);
#endif
p
=
(
isdn_net_dev
*
)
p
->
next
;
dbg_net_icall
(
"n_fi: final check failed
\n
"
);
continue
;
}
}
}
else
{
/* We are already on the second channel, so nothing to do */
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: already on 2nd channel
\n
"
);
#endif
dbg_net_icall
(
"n_fi: already on 2nd channel
\n
"
);
}
}
}
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: match2
\n
"
);
#endif
dbg_net_icall
(
"n_fi: match2
\n
"
);
n
=
lp
->
phone
[
0
];
if
(
lp
->
flags
&
ISDN_NET_SECURE
)
{
while
(
n
)
{
...
...
@@ -2324,9 +2257,7 @@ p = dev->netdev;
}
}
if
(
n
||
(
!
(
lp
->
flags
&
ISDN_NET_SECURE
)))
{
#ifdef ISDN_DEBUG_NET_ICALL
printk
(
KERN_DEBUG
"n_fi: match3
\n
"
);
#endif
dbg_net_icall
(
"n_fi: match3
\n
"
);
/* matching interface found */
/*
...
...
@@ -2370,7 +2301,6 @@ p = dev->netdev;
/* Found parent, if it's offline iterate next device */
printk
(
KERN_DEBUG
"mlpf: %d
\n
"
,
mlp
->
flags
&
ISDN_NET_CONNECTED
);
if
(
!
(
mlp
->
flags
&
ISDN_NET_CONNECTED
))
{
p
=
(
isdn_net_dev
*
)
p
->
next
;
continue
;
}
}
...
...
@@ -2392,7 +2322,7 @@ p = dev->netdev;
if
(
lp
->
phone
[
1
])
{
/* Grab a free ISDN-Channel */
if
((
chi
=
isdn_get_free_
channel
(
isdn_get_free_
slot
(
ISDN_USAGE_NET
,
lp
->
l2_proto
,
lp
->
l3_proto
,
...
...
@@ -2406,8 +2336,11 @@ p = dev->netdev;
return
0
;
}
/* Setup dialstate. */
lp
->
dtimer
=
0
;
lp
->
dialstate
=
11
;
lp
->
dial_timer
.
expires
=
jiffies
+
lp
->
cbdelay
;
lp
->
dial_event
=
EV_NET_TIMER_CB
;
add_timer
(
&
lp
->
dial_timer
);
lp
->
dialstate
=
ST_WAIT_BEFORE_CB
;
/* Connect interface with channel */
isdn_net_bind_channel
(
lp
,
chi
);
#ifdef CONFIG_ISDN_PPP
...
...
@@ -2430,30 +2363,39 @@ p = dev->netdev;
eaz
);
/* if this interface is dialing, it does it probably on a different
device, so free this device */
if
(
(
lp
->
dialstate
==
4
)
||
(
lp
->
dialstate
==
12
)
)
{
if
(
lp
->
dialstate
==
ST_OUT_WAIT_DCONN
)
{
#ifdef CONFIG_ISDN_PPP
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
isdn_ppp_free
(
lp
);
#endif
isdn_net_lp_disconnected
(
lp
);
isdn_
free_channel
(
lp
->
isdn_device
,
lp
->
isdn_channel
,
isdn_
slot_free
(
lp
->
isdn_slot
,
ISDN_USAGE_NET
);
}
dev
->
usage
[
idx
]
&=
ISDN_USAGE_EXCLUSIVE
;
dev
->
usage
[
idx
]
|=
ISDN_USAGE_NET
;
strcpy
(
dev
->
num
[
idx
],
nr
);
isdn_info_update
();
dev
->
st_netdev
[
idx
]
=
lp
->
netdev
;
lp
->
isdn_device
=
di
;
lp
->
isdn_channel
=
ch
;
strcpy
(
isdn_slot_num
(
idx
),
nr
);
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
;
lp
->
ppp_slot
=
-
1
;
lp
->
flags
|=
ISDN_NET_CONNECTED
;
lp
->
dialstate
=
7
;
lp
->
dtimer
=
0
;
lp
->
outgoing
=
0
;
lp
->
huptimer
=
0
;
lp
->
hupflags
|=
ISDN_WAITCHARGE
;
lp
->
hupflags
&=
~
ISDN_HAVECHARGE
;
/* Got incoming Call, setup L2 and L3 protocols,
* then wait for D-Channel-connect
*/
cmd
.
arg
=
lp
->
l2_proto
<<
8
;
isdn_slot_command
(
lp
->
isdn_slot
,
ISDN_CMD_SETL2
,
&
cmd
);
cmd
.
arg
=
lp
->
l3_proto
<<
8
;
isdn_slot_command
(
lp
->
isdn_slot
,
ISDN_CMD_SETL3
,
&
cmd
);
lp
->
dial_timer
.
expires
=
jiffies
+
15
*
HZ
;
lp
->
dial_event
=
EV_NET_TIMER_IN_DCONN
;
add_timer
(
&
lp
->
dial_timer
);
lp
->
dialstate
=
ST_IN_WAIT_DCONN
;
#ifdef CONFIG_ISDN_PPP
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
if
(
isdn_ppp_bind
(
lp
)
<
0
)
{
...
...
@@ -2467,11 +2409,10 @@ p = dev->netdev;
}
}
}
p
=
(
isdn_net_dev
*
)
p
->
next
;
}
/* If none of configured EAZ/MSN matched and not verbose, be silent */
if
(
!
ematch
||
dev
->
net_verbose
)
printk
(
KERN_INFO
"isdn_net: call from %s -> %d %s ignored
\n
"
,
nr
,
di
,
eaz
);
printk
(
KERN_INFO
"isdn_net: call from %s -> %d %s ignored
\n
"
,
nr
,
slot
,
eaz
);
restore_flags
(
flags
);
return
(
wret
==
2
)
?
5
:
0
;
}
...
...
@@ -2482,14 +2423,14 @@ p = dev->netdev;
isdn_net_dev
*
isdn_net_findif
(
char
*
name
)
{
isdn_net_dev
*
p
=
dev
->
netdev
;
struct
list_head
*
l
;
while
(
p
)
{
if
(
!
strcmp
(
p
->
local
->
name
,
name
))
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
if
(
!
strcmp
(
p
->
local
.
name
,
name
))
return
p
;
p
=
(
isdn_net_dev
*
)
p
->
next
;
}
return
(
isdn_net_dev
*
)
NULL
;
return
NULL
;
}
/*
...
...
@@ -2500,7 +2441,7 @@ isdn_net_findif(char *name)
int
isdn_net_force_dial_lp
(
isdn_net_local
*
lp
)
{
if
((
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
&&
!
lp
->
dialstate
)
{
if
((
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
&&
lp
->
dialstate
==
ST_NULL
)
{
int
chi
;
if
(
lp
->
phone
[
1
])
{
ulong
flags
;
...
...
@@ -2509,7 +2450,7 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
/* Grab a free ISDN-Channel */
if
((
chi
=
isdn_get_free_
channel
(
isdn_get_free_
slot
(
ISDN_USAGE_NET
,
lp
->
l2_proto
,
lp
->
l3_proto
,
...
...
@@ -2521,7 +2462,6 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
restore_flags
(
flags
);
return
-
EAGAIN
;
}
lp
->
dialstate
=
1
;
/* Connect interface with channel */
isdn_net_bind_channel
(
lp
,
chi
);
#ifdef CONFIG_ISDN_PPP
...
...
@@ -2534,7 +2474,7 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
#endif
/* Initiate dialing */
restore_flags
(
flags
);
i
sdn_net_dial
(
);
i
nit_dialout
(
lp
);
return
0
;
}
else
return
-
EINVAL
;
...
...
@@ -2567,47 +2507,39 @@ isdn_net_force_dial(char *name)
if
(
!
p
)
return
-
ENODEV
;
return
(
isdn_net_force_dial_lp
(
p
->
local
));
return
(
isdn_net_force_dial_lp
(
&
p
->
local
));
}
/*
* Allocate a new network-interface and initialize its data structures.
*/
char
*
int
isdn_net_new
(
char
*
name
,
struct
net_device
*
master
)
{
int
retval
;
isdn_net_dev
*
netdev
;
/* Avoid creating an existing interface */
if
(
isdn_net_findif
(
name
))
{
printk
(
KERN_WARNING
"isdn_net: interface %s already exists
\n
"
,
name
);
return
NULL
;
return
-
EEXIST
;
}
if
(
!
(
netdev
=
(
isdn_net_dev
*
)
kmalloc
(
sizeof
(
isdn_net_dev
),
GFP_KERNEL
)))
{
if
(
!
(
netdev
=
kmalloc
(
sizeof
(
isdn_net_dev
),
GFP_KERNEL
)))
{
printk
(
KERN_WARNING
"isdn_net: Could not allocate net-device
\n
"
);
return
NULL
;
return
-
ENOMEM
;
}
memset
(
netdev
,
0
,
sizeof
(
isdn_net_dev
));
if
(
!
(
netdev
->
local
=
(
isdn_net_local
*
)
kmalloc
(
sizeof
(
isdn_net_local
),
GFP_KERNEL
)))
{
printk
(
KERN_WARNING
"isdn_net: Could not allocate device locals
\n
"
);
kfree
(
netdev
);
return
NULL
;
}
memset
(
netdev
->
local
,
0
,
sizeof
(
isdn_net_local
));
if
(
name
==
NULL
)
strcpy
(
netdev
->
local
->
name
,
" "
);
else
strcpy
(
netdev
->
local
->
name
,
name
);
strcpy
(
netdev
->
dev
.
name
,
netdev
->
local
->
name
);
netdev
->
dev
.
priv
=
netdev
->
local
;
strcpy
(
netdev
->
local
.
name
,
name
);
strcpy
(
netdev
->
dev
.
name
,
name
);
netdev
->
dev
.
priv
=
&
netdev
->
local
;
netdev
->
dev
.
init
=
isdn_net_init
;
netdev
->
local
->
p_encap
=
ISDN_NET_ENCAP_RAWIP
;
netdev
->
local
.
p_encap
=
ISDN_NET_ENCAP_RAWIP
;
if
(
master
)
{
/* Device shall be a slave */
struct
net_device
*
p
=
(((
isdn_net_local
*
)
master
->
priv
)
->
slave
);
struct
net_device
*
q
=
master
;
netdev
->
local
->
master
=
master
;
netdev
->
local
.
master
=
master
;
/* Put device at end of slave-chain */
while
(
p
)
{
q
=
p
;
...
...
@@ -2621,81 +2553,80 @@ isdn_net_new(char *name, struct net_device *master)
*/
netdev
->
dev
.
tx_timeout
=
isdn_net_tx_timeout
;
netdev
->
dev
.
watchdog_timeo
=
ISDN_NET_TX_TIMEOUT
;
if
(
register_netdev
(
&
netdev
->
dev
)
!=
0
)
{
retval
=
register_netdev
(
&
netdev
->
dev
);
if
(
retval
)
{
printk
(
KERN_WARNING
"isdn_net: Could not register net-device
\n
"
);
kfree
(
netdev
->
local
);
kfree
(
netdev
);
return
NULL
;
return
retval
;
}
}
netdev
->
local
->
magic
=
ISDN_NET_MAGIC
;
netdev
->
local
.
magic
=
ISDN_NET_MAGIC
;
netdev
->
queue
=
netdev
->
local
;
netdev
->
queue
=
&
netdev
->
local
;
spin_lock_init
(
&
netdev
->
queue_lock
);
netdev
->
local
->
last
=
netdev
->
local
;
netdev
->
local
->
netdev
=
netdev
;
netdev
->
local
->
next
=
netdev
->
local
;
netdev
->
local
->
tqueue
.
sync
=
0
;
netdev
->
local
->
tqueue
.
routine
=
isdn_net_softint
;
netdev
->
local
->
tqueue
.
data
=
netdev
->
local
;
spin_lock_init
(
&
netdev
->
local
->
xmit_lock
);
netdev
->
local
->
isdn_device
=
-
1
;
netdev
->
local
->
isdn_channel
=
-
1
;
netdev
->
local
->
pre_device
=
-
1
;
netdev
->
local
->
pre_channel
=
-
1
;
netdev
->
local
->
exclusive
=
-
1
;
netdev
->
local
->
ppp_slot
=
-
1
;
netdev
->
local
->
pppbind
=
-
1
;
skb_queue_head_init
(
&
netdev
->
local
->
super_tx_queue
);
netdev
->
local
->
l2_proto
=
ISDN_PROTO_L2_X75I
;
netdev
->
local
->
l3_proto
=
ISDN_PROTO_L3_TRANS
;
netdev
->
local
->
triggercps
=
6000
;
netdev
->
local
->
slavedelay
=
10
*
HZ
;
netdev
->
local
->
hupflags
=
ISDN_INHUP
;
/* Do hangup even on incoming calls */
netdev
->
local
->
onhtime
=
10
;
/* Default hangup-time for saving costs
netdev
->
local
.
last
=
&
netdev
->
local
;
netdev
->
local
.
netdev
=
netdev
;
netdev
->
local
.
next
=
&
netdev
->
local
;
netdev
->
local
.
tqueue
.
sync
=
0
;
netdev
->
local
.
tqueue
.
routine
=
isdn_net_softint
;
netdev
->
local
.
tqueue
.
data
=
&
netdev
->
local
;
spin_lock_init
(
&
netdev
->
local
.
xmit_lock
);
netdev
->
local
.
isdn_slot
=
-
1
;
netdev
->
local
.
pre_device
=
-
1
;
netdev
->
local
.
pre_channel
=
-
1
;
netdev
->
local
.
exclusive
=
-
1
;
netdev
->
local
.
ppp_slot
=
-
1
;
netdev
->
local
.
pppbind
=
-
1
;
skb_queue_head_init
(
&
netdev
->
local
.
super_tx_queue
);
netdev
->
local
.
l2_proto
=
ISDN_PROTO_L2_X75I
;
netdev
->
local
.
l3_proto
=
ISDN_PROTO_L3_TRANS
;
netdev
->
local
.
triggercps
=
6000
;
netdev
->
local
.
slavedelay
=
10
*
HZ
;
netdev
->
local
.
hupflags
=
ISDN_INHUP
;
/* Do hangup even on incoming calls */
netdev
->
local
.
onhtime
=
10
;
/* Default hangup-time for saving costs
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
->
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 */
netdev
->
local
->
dialwait_timer
=
0
;
/* Jiffies of earliest next dial-start */
netdev
->
local
.
dialmax
=
1
;
netdev
->
local
.
flags
=
ISDN_NET_CBHUP
|
ISDN_NET_DM_MANUAL
;
/* Hangup before Callback, manual dial */
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 */
netdev
->
local
.
dialwait_timer
=
0
;
/* Jiffies of earliest next dial-start */
init_timer
(
&
netdev
->
local
.
dial_timer
);
netdev
->
local
.
dial_timer
.
data
=
(
unsigned
long
)
&
netdev
->
local
;
netdev
->
local
.
dial_timer
.
function
=
isdn_net_dial_timer
;
/* Put into to netdev-chain */
netdev
->
next
=
(
void
*
)
dev
->
netdev
;
dev
->
netdev
=
netdev
;
return
netdev
->
dev
.
name
;
list_add
(
&
netdev
->
global_list
,
&
isdn_net_devs
);
return
0
;
}
char
*
int
isdn_net_newslave
(
char
*
parm
)
{
char
*
p
=
strchr
(
parm
,
','
);
isdn_net_dev
*
n
;
char
newname
[
10
];
isdn_net_dev
*
m
;
if
(
p
)
{
/* Slave-Name MUST not be empty */
if
(
!
strlen
(
p
+
1
))
return
NULL
;
strcpy
(
newname
,
p
+
1
);
*
p
=
0
;
/* Master must already exist */
if
(
!
(
n
=
isdn_net_findif
(
parm
)))
return
NULL
;
/* Master must be a real interface, not a slave */
if
(
n
->
local
->
master
)
return
NULL
;
/* Master must not be started yet */
if
(
isdn_net_device_started
(
n
))
return
NULL
;
return
(
isdn_net_new
(
newname
,
&
(
n
->
dev
)));
}
return
NULL
;
/* Slave-Name MUST not be empty */
if
(
!
p
||
!
p
[
1
])
return
-
EINVAL
;
*
p
=
0
;
/* Master must already exist */
if
(
!
(
m
=
isdn_net_findif
(
parm
)))
return
-
ESRCH
;
/* Master must be a real interface, not a slave */
if
(
m
->
local
.
master
)
return
-
ENXIO
;
/* Master must not be started yet */
if
(
isdn_net_device_started
(
m
))
return
-
EBUSY
;
return
isdn_net_new
(
p
+
1
,
&
m
->
dev
);
}
/*
...
...
@@ -2717,7 +2648,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
ulong
flags
;
#endif
if
(
p
)
{
isdn_net_local
*
lp
=
p
->
local
;
isdn_net_local
*
lp
=
&
p
->
local
;
/* See if any registered driver supports the features we want */
features
=
((
1
<<
cfg
->
l2_proto
)
<<
ISDN_FEATURE_L2_SHIFT
)
|
...
...
@@ -2777,7 +2708,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
case
ISDN_NET_ENCAP_X25IFACE
:
#ifndef CONFIG_ISDN_X25
printk
(
KERN_WARNING
"%s: isdn-x25 support not configured
\n
"
,
p
->
local
->
name
);
p
->
local
.
name
);
return
-
EINVAL
;
#else
p
->
dev
.
type
=
ARPHRD_X25
;
/* change ARP type */
...
...
@@ -2793,7 +2724,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
break
;
printk
(
KERN_WARNING
"%s: encapsulation protocol %d not supported
\n
"
,
p
->
local
->
name
,
cfg
->
p_encap
);
p
->
local
.
name
,
cfg
->
p_encap
);
return
-
EINVAL
;
}
if
(
strlen
(
cfg
->
drvid
))
{
...
...
@@ -2830,7 +2761,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
/* If binding is exclusive, try to grab the channel */
save_flags
(
flags
);
if
((
i
=
isdn_get_free_
channel
(
ISDN_USAGE_NET
,
if
((
i
=
isdn_get_free_
slot
(
ISDN_USAGE_NET
,
lp
->
l2_proto
,
lp
->
l3_proto
,
drvidx
,
chidx
,
lp
->
msn
))
<
0
)
{
/* Grab failed, because desired channel is in use */
...
...
@@ -2839,8 +2770,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
return
-
EBUSY
;
}
/* All went ok, so update isdninfo */
dev
->
usage
[
i
]
=
ISDN_USAGE_EXCLUSIVE
;
isdn_info_update
();
isdn_slot_set_usage
(
i
,
ISDN_USAGE_EXCLUSIVE
);
restore_flags
(
flags
);
lp
->
exclusive
=
i
;
}
else
{
...
...
@@ -2860,7 +2790,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
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
;
...
...
@@ -2944,7 +2874,7 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
isdn_net_dev
*
p
=
isdn_net_findif
(
cfg
->
name
);
if
(
p
)
{
isdn_net_local
*
lp
=
p
->
local
;
isdn_net_local
*
lp
=
&
p
->
local
;
strcpy
(
cfg
->
eaz
,
lp
->
msn
);
cfg
->
exclusive
=
lp
->
exclusive
;
...
...
@@ -2968,7 +2898,7 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
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
;
...
...
@@ -3003,8 +2933,8 @@ isdn_net_addphone(isdn_net_ioctl_phone * phone)
if
(
!
(
n
=
(
isdn_net_phone
*
)
kmalloc
(
sizeof
(
isdn_net_phone
),
GFP_KERNEL
)))
return
-
ENOMEM
;
strcpy
(
n
->
num
,
phone
->
phone
);
n
->
next
=
p
->
local
->
phone
[
phone
->
outgoing
&
1
];
p
->
local
->
phone
[
phone
->
outgoing
&
1
]
=
n
;
n
->
next
=
p
->
local
.
phone
[
phone
->
outgoing
&
1
];
p
->
local
.
phone
[
phone
->
outgoing
&
1
]
=
n
;
return
0
;
}
return
-
ENODEV
;
...
...
@@ -3026,7 +2956,7 @@ isdn_net_getphones(isdn_net_ioctl_phone * phone, char *phones)
if
(
!
p
)
return
-
ENODEV
;
inout
&=
1
;
for
(
n
=
p
->
local
->
phone
[
inout
];
n
;
n
=
n
->
next
)
{
for
(
n
=
p
->
local
.
phone
[
inout
];
n
;
n
=
n
->
next
)
{
if
(
more
)
{
put_user
(
' '
,
phones
++
);
count
++
;
...
...
@@ -3051,7 +2981,7 @@ int
isdn_net_getpeer
(
isdn_net_ioctl_phone
*
phone
,
isdn_net_ioctl_phone
*
peer
)
{
isdn_net_dev
*
p
=
isdn_net_findif
(
phone
->
name
);
int
ch
,
dv
,
idx
;
int
idx
;
if
(
!
p
)
return
-
ENODEV
;
/*
...
...
@@ -3060,15 +2990,12 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone *peer)
* in (partially) wrong number copied to user. This race
* currently ignored.
*/
ch
=
p
->
local
->
isdn_channel
;
dv
=
p
->
local
->
isdn_device
;
if
(
ch
<
0
&&
dv
<
0
)
return
-
ENOTCONN
;
idx
=
isdn_dc2minor
(
dv
,
ch
);
if
(
idx
<
0
)
return
-
ENODEV
;
idx
=
p
->
local
.
isdn_slot
;
if
(
idx
<
0
)
return
-
ENOTCONN
;
/* for pre-bound channels, we need this extra check */
if
(
strncmp
(
dev
->
num
[
idx
]
,
"???"
,
3
)
==
0
)
return
-
ENOTCONN
;
strncpy
(
phone
->
phone
,
dev
->
num
[
idx
]
,
ISDN_MSNLEN
);
phone
->
outgoing
=
USG_OUTGOING
(
dev
->
usage
[
idx
]
);
if
(
strncmp
(
isdn_slot_num
(
idx
)
,
"???"
,
3
)
==
0
)
return
-
ENOTCONN
;
strncpy
(
phone
->
phone
,
isdn_slot_num
(
idx
)
,
ISDN_MSNLEN
);
phone
->
outgoing
=
USG_OUTGOING
(
isdn_slot_usage
(
idx
)
);
if
(
copy_to_user
(
peer
,
phone
,
sizeof
(
*
peer
))
)
return
-
EFAULT
;
return
0
;
}
...
...
@@ -3087,16 +3014,16 @@ isdn_net_delphone(isdn_net_ioctl_phone * phone)
if
(
p
)
{
save_flags
(
flags
);
cli
();
n
=
p
->
local
->
phone
[
inout
];
n
=
p
->
local
.
phone
[
inout
];
m
=
NULL
;
while
(
n
)
{
if
(
!
strcmp
(
n
->
num
,
phone
->
phone
))
{
if
(
p
->
local
->
dial
==
n
)
p
->
local
->
dial
=
n
->
next
;
if
(
p
->
local
.
dial
==
n
)
p
->
local
.
dial
=
n
->
next
;
if
(
m
)
m
->
next
=
n
->
next
;
else
p
->
local
->
phone
[
inout
]
=
n
->
next
;
p
->
local
.
phone
[
inout
]
=
n
->
next
;
kfree
(
n
);
restore_flags
(
flags
);
return
0
;
...
...
@@ -3124,15 +3051,15 @@ isdn_net_rmallphone(isdn_net_dev * p)
save_flags
(
flags
);
cli
();
for
(
i
=
0
;
i
<
2
;
i
++
)
{
n
=
p
->
local
->
phone
[
i
];
n
=
p
->
local
.
phone
[
i
];
while
(
n
)
{
m
=
n
->
next
;
kfree
(
n
);
n
=
m
;
}
p
->
local
->
phone
[
i
]
=
NULL
;
p
->
local
.
phone
[
i
]
=
NULL
;
}
p
->
local
->
dial
=
NULL
;
p
->
local
.
dial
=
NULL
;
restore_flags
(
flags
);
return
0
;
}
...
...
@@ -3147,9 +3074,9 @@ isdn_net_force_hangup(char *name)
struct
net_device
*
q
;
if
(
p
)
{
if
(
p
->
local
->
isdn_device
<
0
)
if
(
p
->
local
.
isdn_slot
<
0
)
return
1
;
q
=
p
->
local
->
slave
;
q
=
p
->
local
.
slave
;
/* If this interface has slaves, do a hangup for them also. */
while
(
q
)
{
isdn_net_hangup
(
q
);
...
...
@@ -3165,7 +3092,7 @@ isdn_net_force_hangup(char *name)
* Helper-function for isdn_net_rm: Do the real work.
*/
static
int
isdn_net_realrm
(
isdn_net_dev
*
p
,
isdn_net_dev
*
q
)
isdn_net_realrm
(
isdn_net_dev
*
p
)
{
unsigned
long
flags
;
...
...
@@ -3182,42 +3109,37 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
/* Free all phone-entries */
isdn_net_rmallphone
(
p
);
/* If interface is bound exclusive, free channel-usage */
if
(
p
->
local
->
exclusive
!=
-
1
)
isdn_unexclusive_channel
(
p
->
local
->
pre_device
,
p
->
local
->
pre_channel
);
if
(
p
->
local
->
master
)
{
if
(
p
->
local
.
exclusive
!=
-
1
)
isdn_unexclusive_channel
(
p
->
local
.
pre_device
,
p
->
local
.
pre_channel
);
if
(
p
->
local
.
master
)
{
/* It's a slave-device, so update master's slave-pointer if necessary */
if
(((
isdn_net_local
*
)
(
p
->
local
->
master
->
priv
))
->
slave
==
&
p
->
dev
)
((
isdn_net_local
*
)
(
p
->
local
->
master
->
priv
))
->
slave
=
p
->
local
->
slave
;
if
(((
isdn_net_local
*
)
(
p
->
local
.
master
->
priv
))
->
slave
==
&
p
->
dev
)
((
isdn_net_local
*
)
(
p
->
local
.
master
->
priv
))
->
slave
=
p
->
local
.
slave
;
}
else
{
/* Unregister only if it's a master-device */
p
->
dev
.
hard_header_cache
=
p
->
local
->
org_hhc
;
p
->
dev
.
header_cache_update
=
p
->
local
->
org_hcu
;
p
->
dev
.
hard_header_cache
=
p
->
local
.
org_hhc
;
p
->
dev
.
header_cache_update
=
p
->
local
.
org_hcu
;
unregister_netdev
(
&
p
->
dev
);
}
/* Unlink device from chain */
if
(
q
)
q
->
next
=
p
->
next
;
else
dev
->
netdev
=
p
->
next
;
if
(
p
->
local
->
slave
)
{
list_del
(
&
p
->
global_list
);
if
(
p
->
local
.
slave
)
{
/* If this interface has a slave, remove it also */
char
*
slavename
=
((
isdn_net_local
*
)
(
p
->
local
->
slave
->
priv
))
->
name
;
isdn_net_dev
*
n
=
dev
->
netdev
;
q
=
NULL
;
while
(
n
)
{
if
(
!
strcmp
(
n
->
local
->
name
,
slavename
))
{
isdn_net_realrm
(
n
,
q
);
char
*
slavename
=
((
isdn_net_local
*
)
(
p
->
local
.
slave
->
priv
))
->
name
;
struct
list_head
*
l
;
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
n
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
if
(
!
strcmp
(
n
->
local
.
name
,
slavename
))
{
isdn_net_realrm
(
n
);
break
;
}
q
=
n
;
n
=
(
isdn_net_dev
*
)
n
->
next
;
}
}
/* If no more net-devices remain, disable auto-hangup timer */
if
(
dev
->
netdev
==
NULL
)
if
(
list_empty
(
&
isdn_net_devs
)
)
isdn_timer_ctrl
(
ISDN_TIMER_NETHANGUP
,
0
);
restore_flags
(
flags
);
kfree
(
p
->
local
);
kfree
(
p
);
return
0
;
...
...
@@ -3229,21 +3151,14 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
int
isdn_net_rm
(
char
*
name
)
{
isdn_net_dev
*
p
;
isdn_net_dev
*
q
;
struct
list_head
*
l
;
/* Search name in netdev-chain */
p
=
dev
->
netdev
;
q
=
NULL
;
while
(
p
)
{
if
(
!
strcmp
(
p
->
local
->
name
,
name
))
return
(
isdn_net_realrm
(
p
,
q
));
q
=
p
;
p
=
(
isdn_net_dev
*
)
p
->
next
;
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
if
(
!
strcmp
(
p
->
local
.
name
,
name
))
return
isdn_net_realrm
(
p
);
}
/* If no more net-devices remain, disable auto-hangup timer */
if
(
dev
->
netdev
==
NULL
)
isdn_timer_ctrl
(
ISDN_TIMER_NETHANGUP
,
0
);
return
-
ENODEV
;
}
...
...
@@ -3259,16 +3174,17 @@ isdn_net_rmall(void)
/* Walk through netdev-chain */
save_flags
(
flags
);
cli
();
while
(
dev
->
netdev
)
{
if
(
!
dev
->
netdev
->
local
->
master
)
{
/* Remove master-devices only, slaves get removed with their master */
if
((
ret
=
isdn_net_realrm
(
dev
->
netdev
,
NULL
)))
{
while
(
!
list_empty
(
&
isdn_net_devs
))
{
isdn_net_dev
*
p
=
list_entry
(
isdn_net_devs
.
next
,
isdn_net_dev
,
global_list
);
/* Remove master-devices only, slaves get removed with their master */
if
(
!
p
->
local
.
master
)
{
if
((
ret
=
isdn_net_realrm
(
p
)))
{
restore_flags
(
flags
);
return
ret
;
}
}
}
dev
->
netdev
=
NULL
;
restore_flags
(
flags
);
return
0
;
}
drivers/isdn/i4l/isdn_net.h
View file @
ab50636c
...
...
@@ -31,8 +31,8 @@
#define CISCO_SLARP_REPLY 1
#define CISCO_SLARP_KEEPALIVE 2
extern
char
*
isdn_net_new
(
char
*
,
struct
net_device
*
);
extern
char
*
isdn_net_newslave
(
char
*
);
extern
int
isdn_net_new
(
char
*
,
struct
net_device
*
);
extern
int
isdn_net_newslave
(
char
*
);
extern
int
isdn_net_rm
(
char
*
);
extern
int
isdn_net_rmall
(
void
);
extern
int
isdn_net_stat_callback
(
int
,
isdn_ctrl
*
);
...
...
@@ -44,7 +44,6 @@ extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *);
extern
int
isdn_net_delphone
(
isdn_net_ioctl_phone
*
);
extern
int
isdn_net_find_icall
(
int
,
int
,
int
,
setup_parm
*
);
extern
void
isdn_net_hangup
(
struct
net_device
*
);
extern
void
isdn_net_dial
(
void
);
extern
void
isdn_net_autohup
(
void
);
extern
int
isdn_net_force_hangup
(
char
*
);
extern
int
isdn_net_force_dial
(
char
*
);
...
...
@@ -131,7 +130,7 @@ static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp)
if
(
master_lp
->
netdev
->
queue
==
lp
)
{
master_lp
->
netdev
->
queue
=
lp
->
next
;
if
(
lp
->
next
==
lp
)
{
/* last in queue */
master_lp
->
netdev
->
queue
=
master_lp
->
netdev
->
local
;
master_lp
->
netdev
->
queue
=
&
master_lp
->
netdev
->
local
;
}
}
lp
->
next
=
lp
->
last
=
lp
;
/* (re)set own pointers */
...
...
drivers/isdn/i4l/isdn_ppp.c
View file @
ab50636c
...
...
@@ -165,14 +165,15 @@ isdn_ppp_bind(isdn_net_local * lp)
save_flags
(
flags
);
cli
();
if
(
lp
->
pppbind
<
0
)
{
/* device bounded to ippp device ? */
isdn_net_dev
*
net_dev
=
dev
->
netdev
;
struct
list_head
*
l
;
char
exclusive
[
ISDN_MAX_CHANNELS
];
/* exclusive flags */
memset
(
exclusive
,
0
,
ISDN_MAX_CHANNELS
);
while
(
net_dev
)
{
/* step through net devices to find exclusive minors */
isdn_net_local
*
lp
=
net_dev
->
local
;
/* step through net devices to find exclusive minors */
list_for_each
(
l
,
&
isdn_net_devs
)
{
isdn_net_dev
*
p
=
list_entry
(
l
,
isdn_net_dev
,
global_list
);
isdn_net_local
*
lp
=
&
p
->
local
;
if
(
lp
->
pppbind
>=
0
)
exclusive
[
lp
->
pppbind
]
=
1
;
net_dev
=
net_dev
->
next
;
}
/*
* search a free device / slot
...
...
@@ -804,11 +805,11 @@ isdn_ppp_write(struct file *file, const char *buf, size_t count, loff_t *off)
if
(
proto
!=
PPP_LCP
)
lp
->
huptimer
=
0
;
if
(
lp
->
isdn_
device
<
0
||
lp
->
isdn_channel
<
0
)
{
if
(
lp
->
isdn_
slot
<
0
)
{
retval
=
0
;
goto
out
;
}
if
((
dev
->
drv
[
lp
->
isdn_device
]
->
flags
&
DRV_FLAG_RUNNING
)
&&
if
((
dev
->
drv
[
isdn_slot_driver
(
lp
->
isdn_slot
)
]
->
flags
&
DRV_FLAG_RUNNING
)
&&
lp
->
dialstate
==
0
&&
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
{
unsigned
short
hl
;
...
...
@@ -818,7 +819,7 @@ isdn_ppp_write(struct file *file, const char *buf, size_t count, loff_t *off)
* sk_buff. old call to dev_alloc_skb only reserved
* 16 bytes, now we are looking what the driver want
*/
hl
=
dev
->
drv
[
lp
->
isdn_device
]
->
interface
->
hl_hdrlen
;
hl
=
isdn_slot_hdrlen
(
lp
->
isdn_slot
)
;
skb
=
alloc_skb
(
hl
+
count
,
GFP_ATOMIC
);
if
(
!
skb
)
{
printk
(
KERN_WARNING
"isdn_ppp_write: out of memory!
\n
"
);
...
...
@@ -974,7 +975,7 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf
int
slot
;
int
proto
;
if
(
net_dev
->
local
->
master
)
if
(
net_dev
->
local
.
master
)
BUG
();
// we're called with the master device always
slot
=
lp
->
ppp_slot
;
...
...
@@ -1077,12 +1078,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
case
PPP_VJC_UNCOMP
:
if
(
is
->
debug
&
0x20
)
printk
(
KERN_DEBUG
"isdn_ppp: VJC_UNCOMP
\n
"
);
if
(
net_dev
->
local
->
ppp_slot
<
0
)
{
if
(
net_dev
->
local
.
ppp_slot
<
0
)
{
printk
(
KERN_ERR
__FUNCTION__
": net_dev->local->ppp_slot(%d) out of range
\n
"
,
net_dev
->
local
->
ppp_slot
);
net_dev
->
local
.
ppp_slot
);
goto
drop_packet
;
}
if
(
slhc_remember
(
ippp_table
[
net_dev
->
local
->
ppp_slot
]
->
slcomp
,
skb
->
data
,
skb
->
len
)
<=
0
)
{
if
(
slhc_remember
(
ippp_table
[
net_dev
->
local
.
ppp_slot
]
->
slcomp
,
skb
->
data
,
skb
->
len
)
<=
0
)
{
printk
(
KERN_WARNING
"isdn_ppp: received illegal VJC_UNCOMP frame!
\n
"
);
goto
drop_packet
;
}
...
...
@@ -1103,12 +1104,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
}
skb_put
(
skb
,
skb_old
->
len
+
128
);
memcpy
(
skb
->
data
,
skb_old
->
data
,
skb_old
->
len
);
if
(
net_dev
->
local
->
ppp_slot
<
0
)
{
if
(
net_dev
->
local
.
ppp_slot
<
0
)
{
printk
(
KERN_ERR
__FUNCTION__
": net_dev->local->ppp_slot(%d) out of range
\n
"
,
net_dev
->
local
->
ppp_slot
);
net_dev
->
local
.
ppp_slot
);
goto
drop_packet
;
}
pkt_len
=
slhc_uncompress
(
ippp_table
[
net_dev
->
local
->
ppp_slot
]
->
slcomp
,
pkt_len
=
slhc_uncompress
(
ippp_table
[
net_dev
->
local
.
ppp_slot
]
->
slcomp
,
skb
->
data
,
skb_old
->
len
);
kfree_skb
(
skb_old
);
if
(
pkt_len
<
0
)
...
...
@@ -1144,7 +1145,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
return
;
drop_packet:
net_dev
->
local
->
stats
.
rx_dropped
++
;
net_dev
->
local
.
stats
.
rx_dropped
++
;
kfree_skb
(
skb
);
}
...
...
@@ -1263,7 +1264,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
* sk_buff. old call to dev_alloc_skb only reserved
* 16 bytes, now we are looking what the driver want.
*/
hl
=
dev
->
drv
[
lp
->
isdn_device
]
->
interface
->
hl_hdrlen
+
IPPP_MAX_HEADER
;
hl
=
isdn_slot_hdrlen
(
lp
->
isdn_slot
)
+
IPPP_MAX_HEADER
;
;
/*
* Note: hl might still be insufficient because the method
* above does not account for a possibible MPPP slave channel
...
...
@@ -1976,7 +1977,7 @@ isdn_ppp_dial_slave(char *name)
if
(
!
(
ndev
=
isdn_net_findif
(
name
)))
return
1
;
lp
=
ndev
->
local
;
lp
=
&
ndev
->
local
;
if
(
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
return
5
;
...
...
@@ -2007,7 +2008,7 @@ isdn_ppp_hangup_slave(char *name)
if
(
!
(
ndev
=
isdn_net_findif
(
name
)))
return
1
;
lp
=
ndev
->
local
;
lp
=
&
ndev
->
local
;
if
(
!
(
lp
->
flags
&
ISDN_NET_CONNECTED
))
return
5
;
...
...
@@ -2094,7 +2095,7 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
isdn_net_local
*
lp
=
is
->
lp
;
/* Alloc large enough skb */
hl
=
dev
->
drv
[
lp
->
isdn_device
]
->
interface
->
hl_hdrlen
;
hl
=
isdn_slot_hdrlen
(
lp
->
isdn_slot
)
;
skb
=
alloc_skb
(
len
+
hl
+
16
,
GFP_ATOMIC
);
if
(
!
skb
)
{
printk
(
KERN_WARNING
...
...
drivers/isdn/i4l/isdn_tty.c
View file @
ab50636c
...
...
@@ -128,7 +128,7 @@ isdn_tty_readmodem(void)
modem_info
*
info
;
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
if
((
midx
=
dev
->
m_idx
[
i
]
)
>=
0
)
{
if
((
midx
=
isdn_slot_m_idx
(
i
)
)
>=
0
)
{
info
=
&
dev
->
mdm
.
info
[
midx
];
if
(
info
->
online
)
{
r
=
0
;
...
...
@@ -143,9 +143,9 @@ isdn_tty_readmodem(void)
if
(
c
>
0
)
{
save_flags
(
flags
);
cli
();
r
=
isdn_
readbchan
(
info
->
isdn_driver
,
info
->
isdn_channel
,
r
=
isdn_
slot_readbchan
(
info
->
isdn_slot
,
tty
->
flip
.
char_buf_ptr
,
tty
->
flip
.
flag_buf_ptr
,
c
,
0
);
tty
->
flip
.
flag_buf_ptr
,
c
);
/* CISCO AsyncPPP Hack */
if
(
!
(
info
->
emu
.
mdmreg
[
REG_CPPP
]
&
BIT_CPPP
))
memset
(
tty
->
flip
.
flag_buf_ptr
,
0
,
r
);
...
...
@@ -182,7 +182,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
#endif
modem_info
*
info
;
if
((
midx
=
dev
->
m_idx
[
i
]
)
<
0
)
{
if
((
midx
=
isdn_slot_m_idx
(
i
)
)
<
0
)
{
/* if midx is invalid, packet is not for tty */
return
0
;
}
...
...
@@ -315,8 +315,7 @@ isdn_tty_tint(modem_info * info)
if
(
!
skb
)
return
;
len
=
skb
->
len
;
if
((
slen
=
isdn_writebuf_skb_stub
(
info
->
isdn_driver
,
info
->
isdn_channel
,
1
,
skb
))
==
len
)
{
if
((
slen
=
isdn_slot_write
(
info
->
isdn_slot
,
skb
))
==
len
)
{
struct
tty_struct
*
tty
=
info
->
tty
;
info
->
send_outstanding
++
;
info
->
msr
&=
~
UART_MSR_CTS
;
...
...
@@ -479,11 +478,11 @@ isdn_tty_senddown(modem_info * info)
atomic_inc
(
&
info
->
xmit_lock
);
if
(
!
(
atomic_dec_and_test
(
&
info
->
xmit_lock
)))
return
;
if
(
info
->
isdn_
driver
<
0
)
{
if
(
info
->
isdn_
slot
<
0
)
{
info
->
xmit_count
=
0
;
return
;
}
skb_res
=
dev
->
drv
[
info
->
isdn_driver
]
->
interface
->
hl_hdrlen
+
4
;
skb_res
=
isdn_slot_hdrlen
(
info
->
isdn_slot
)
;
#ifdef CONFIG_ISDN_AUDIO
if
(
info
->
vonline
&
2
)
audio_len
=
buflen
*
voice_cf
[
info
->
emu
.
vpar
[
3
]];
...
...
@@ -627,7 +626,6 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m)
int
usg
=
ISDN_USAGE_MODEM
;
int
si
=
7
;
int
l2
=
m
->
mdmreg
[
REG_L2PROT
];
isdn_ctrl
cmd
;
ulong
flags
;
int
i
;
int
j
;
...
...
@@ -652,56 +650,34 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m)
m
->
mdmreg
[
REG_SI1I
]
=
si2bit
[
si
];
save_flags
(
flags
);
cli
();
i
=
isdn_get_free_
channel
(
usg
,
l2
,
m
->
mdmreg
[
REG_L3PROT
],
-
1
,
-
1
,
m
->
msn
);
i
=
isdn_get_free_
slot
(
usg
,
l2
,
m
->
mdmreg
[
REG_L3PROT
],
-
1
,
-
1
,
m
->
msn
);
if
(
i
<
0
)
{
restore_flags
(
flags
);
isdn_tty_modem_result
(
RESULT_NO_DIALTONE
,
info
);
}
else
{
info
->
isdn_driver
=
dev
->
drvmap
[
i
];
info
->
isdn_channel
=
dev
->
chanmap
[
i
];
info
->
drv_index
=
i
;
dev
->
m_idx
[
i
]
=
info
->
line
;
dev
->
usage
[
i
]
|=
ISDN_USAGE_OUTGOING
;
struct
dial_info
dial
=
{
.
l2_proto
=
l2
,
.
l3_proto
=
m
->
mdmreg
[
REG_L3PROT
],
.
si1
=
si
,
.
si2
=
m
->
mdmreg
[
REG_SI2
],
.
msn
=
m
->
msn
,
.
phone
=
n
,
};
info
->
isdn_slot
=
i
;
isdn_slot_set_m_idx
(
i
,
info
->
line
);
info
->
last_dir
=
1
;
info
->
last_l2
=
l2
;
strcpy
(
info
->
last_num
,
n
);
isdn_info_update
();
restore_flags
(
flags
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_CLREAZ
;
isdn_command
(
&
cmd
);
strcpy
(
cmd
.
parm
.
num
,
isdn_map_eaz2msn
(
m
->
msn
,
info
->
isdn_driver
));
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETEAZ
;
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL2
;
info
->
last_l2
=
l2
;
cmd
.
arg
=
info
->
isdn_channel
+
(
l2
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL3
;
cmd
.
arg
=
info
->
isdn_channel
+
(
m
->
mdmreg
[
REG_L3PROT
]
<<
8
);
#ifdef CONFIG_ISDN_TTY_FAX
if
(
l2
==
ISDN_PROTO_L2_FAX
)
{
cmd
.
parm
.
fax
=
info
->
fax
;
dial
.
fax
=
info
->
fax
;
info
->
fax
->
direction
=
ISDN_TTY_FAX_CONN_OUT
;
}
#endif
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
sprintf
(
cmd
.
parm
.
setup
.
phone
,
"%s"
,
n
);
sprintf
(
cmd
.
parm
.
setup
.
eazmsn
,
"%s"
,
isdn_map_eaz2msn
(
m
->
msn
,
info
->
isdn_driver
));
cmd
.
parm
.
setup
.
si1
=
si
;
cmd
.
parm
.
setup
.
si2
=
m
->
mdmreg
[
REG_SI2
];
cmd
.
command
=
ISDN_CMD_DIAL
;
info
->
dialing
=
1
;
info
->
emu
.
carrierwait
=
0
;
strcpy
(
dev
->
num
[
i
],
n
);
isdn_info_update
();
isdn_command
(
&
cmd
);
isdn_slot_dial
(
info
->
isdn_slot
,
&
dial
);
isdn_timer_ctrl
(
ISDN_TIMER_CARRIER
,
1
);
}
}
...
...
@@ -714,19 +690,15 @@ void
isdn_tty_modem_hup
(
modem_info
*
info
,
int
local
)
{
isdn_ctrl
cmd
;
int
di
,
ch
;
int
slot
;
if
(
!
info
)
return
;
di
=
info
->
isdn_driver
;
ch
=
info
->
isdn_channel
;
if
(
di
<
0
||
ch
<
0
)
slot
=
info
->
isdn_slot
;
if
(
slot
<
0
)
return
;
info
->
isdn_driver
=
-
1
;
info
->
isdn_channel
=
-
1
;
#ifdef ISDN_DEBUG_MODEM_HUP
printk
(
KERN_DEBUG
"Mhup ttyI%d
\n
"
,
info
->
line
);
#endif
...
...
@@ -768,21 +740,14 @@ isdn_tty_modem_hup(modem_info * info, int local)
info
->
msr
&=
~
(
UART_MSR_DCD
|
UART_MSR_RI
);
info
->
lsr
|=
UART_LSR_TEMT
;
if
(
local
)
{
cmd
.
driver
=
di
;
cmd
.
command
=
ISDN_CMD_HANGUP
;
cmd
.
arg
=
ch
;
isdn_command
(
&
cmd
);
}
if
(
local
)
isdn_slot_command
(
slot
,
ISDN_CMD_HANGUP
,
&
cmd
);
isdn_
all_eaz
(
di
,
ch
);
isdn_
slot_all_eaz
(
slot
);
info
->
emu
.
mdmreg
[
REG_RINGCNT
]
=
0
;
isdn_free_channel
(
di
,
ch
,
0
);
if
(
info
->
drv_index
>=
0
)
{
dev
->
m_idx
[
info
->
drv_index
]
=
-
1
;
info
->
drv_index
=
-
1
;
}
isdn_slot_free
(
slot
,
0
);
isdn_slot_set_m_idx
(
slot
,
-
1
);
info
->
isdn_slot
=
-
1
;
}
/*
...
...
@@ -812,11 +777,11 @@ isdn_tty_suspend(char *id, modem_info * info, atemu * m)
printk
(
KERN_DEBUG
"Msusp ttyI%d
\n
"
,
info
->
line
);
#endif
l
=
strlen
(
id
);
if
((
info
->
isdn_
driver
>=
0
))
{
if
((
info
->
isdn_
slot
>=
0
))
{
cmd
.
parm
.
cmsg
.
Length
=
l
+
18
;
cmd
.
parm
.
cmsg
.
Command
=
CAPI_FACILITY
;
cmd
.
parm
.
cmsg
.
Subcommand
=
CAPI_REQ
;
cmd
.
parm
.
cmsg
.
adr
.
Controller
=
i
nfo
->
isdn_driver
+
1
;
cmd
.
parm
.
cmsg
.
adr
.
Controller
=
i
sdn_slot_driver
(
info
->
isdn_slot
)
+
1
;
cmd
.
parm
.
cmsg
.
para
[
0
]
=
3
;
/* 16 bit 0x0003 suplementary service */
cmd
.
parm
.
cmsg
.
para
[
1
]
=
0
;
cmd
.
parm
.
cmsg
.
para
[
2
]
=
l
+
3
;
...
...
@@ -824,10 +789,7 @@ isdn_tty_suspend(char *id, modem_info * info, atemu * m)
cmd
.
parm
.
cmsg
.
para
[
4
]
=
0
;
cmd
.
parm
.
cmsg
.
para
[
5
]
=
l
;
strncpy
(
&
cmd
.
parm
.
cmsg
.
para
[
6
],
id
,
l
);
cmd
.
command
=
CAPI_PUT_MESSAGE
;
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
isdn_command
(
&
cmd
);
isdn_slot_command
(
info
->
isdn_slot
,
CAPI_PUT_MESSAGE
,
&
cmd
);
}
}
...
...
@@ -871,43 +833,26 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m)
m
->
mdmreg
[
REG_SI1I
]
=
si2bit
[
si
];
save_flags
(
flags
);
cli
();
i
=
isdn_get_free_
channel
(
usg
,
l2
,
m
->
mdmreg
[
REG_L3PROT
],
-
1
,
-
1
,
m
->
msn
);
i
=
isdn_get_free_
slot
(
usg
,
l2
,
m
->
mdmreg
[
REG_L3PROT
],
-
1
,
-
1
,
m
->
msn
);
if
(
i
<
0
)
{
restore_flags
(
flags
);
isdn_tty_modem_result
(
RESULT_NO_DIALTONE
,
info
);
}
else
{
info
->
isdn_driver
=
dev
->
drvmap
[
i
];
info
->
isdn_channel
=
dev
->
chanmap
[
i
];
info
->
drv_index
=
i
;
dev
->
m_idx
[
i
]
=
info
->
line
;
dev
->
usage
[
i
]
|=
ISDN_USAGE_OUTGOING
;
info
->
isdn_slot
=
i
;
isdn_slot_set_m_idx
(
i
,
info
->
line
);
isdn_slot_set_usage
(
i
,
isdn_slot_usage
(
i
)
|
ISDN_USAGE_OUTGOING
);
info
->
last_dir
=
1
;
// strcpy(info->last_num, n);
isdn_info_update
();
restore_flags
(
flags
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_CLREAZ
;
isdn_command
(
&
cmd
);
strcpy
(
cmd
.
parm
.
num
,
isdn_map_eaz2msn
(
m
->
msn
,
info
->
isdn_driver
));
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETEAZ
;
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL2
;
info
->
last_l2
=
l2
;
cmd
.
arg
=
info
->
isdn_channel
+
(
l2
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL3
;
cmd
.
arg
=
info
->
isdn_channel
+
(
m
->
mdmreg
[
REG_L3PROT
]
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
arg
=
l2
<<
8
;
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_SETL2
,
&
cmd
);
cmd
.
arg
=
m
->
mdmreg
[
REG_L3PROT
]
<<
8
;
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_SETL3
,
&
cmd
);
cmd
.
parm
.
cmsg
.
Length
=
l
+
18
;
cmd
.
parm
.
cmsg
.
Command
=
CAPI_FACILITY
;
cmd
.
parm
.
cmsg
.
Subcommand
=
CAPI_REQ
;
cmd
.
parm
.
cmsg
.
adr
.
Controller
=
i
nfo
->
isdn_driver
+
1
;
cmd
.
parm
.
cmsg
.
adr
.
Controller
=
i
sdn_slot_driver
(
info
->
isdn_slot
)
+
1
;
cmd
.
parm
.
cmsg
.
para
[
0
]
=
3
;
/* 16 bit 0x0003 suplementary service */
cmd
.
parm
.
cmsg
.
para
[
1
]
=
0
;
cmd
.
parm
.
cmsg
.
para
[
2
]
=
l
+
3
;
...
...
@@ -915,11 +860,10 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m)
cmd
.
parm
.
cmsg
.
para
[
4
]
=
0
;
cmd
.
parm
.
cmsg
.
para
[
5
]
=
l
;
strncpy
(
&
cmd
.
parm
.
cmsg
.
para
[
6
],
id
,
l
);
cmd
.
command
=
CAPI_PUT_MESSAGE
;
info
->
dialing
=
1
;
// strcpy(dev->num[i], n);
isdn_info_update
();
isdn_
command
(
&
cmd
);
isdn_
slot_command
(
info
->
isdn_slot
,
CAPI_PUT_MESSAGE
,
&
cmd
);
isdn_timer_ctrl
(
ISDN_TIMER_CARRIER
,
1
);
}
}
...
...
@@ -965,51 +909,33 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
m
->
mdmreg
[
REG_SI1I
]
=
si2bit
[
si
];
save_flags
(
flags
);
cli
();
i
=
isdn_get_free_
channel
(
usg
,
l2
,
m
->
mdmreg
[
REG_L3PROT
],
-
1
,
-
1
,
m
->
msn
);
i
=
isdn_get_free_
slot
(
usg
,
l2
,
m
->
mdmreg
[
REG_L3PROT
],
-
1
,
-
1
,
m
->
msn
);
if
(
i
<
0
)
{
restore_flags
(
flags
);
isdn_tty_modem_result
(
RESULT_NO_DIALTONE
,
info
);
}
else
{
info
->
isdn_driver
=
dev
->
drvmap
[
i
];
info
->
isdn_channel
=
dev
->
chanmap
[
i
];
info
->
drv_index
=
i
;
dev
->
m_idx
[
i
]
=
info
->
line
;
dev
->
usage
[
i
]
|=
ISDN_USAGE_OUTGOING
;
info
->
isdn_slot
=
i
;
isdn_slot_set_m_idx
(
i
,
info
->
line
);
isdn_slot_set_usage
(
i
,
isdn_slot_usage
(
i
)
|
ISDN_USAGE_OUTGOING
);
info
->
last_dir
=
1
;
isdn_info_update
();
restore_flags
(
flags
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_CLREAZ
;
isdn_command
(
&
cmd
);
strcpy
(
cmd
.
parm
.
num
,
isdn_map_eaz2msn
(
m
->
msn
,
info
->
isdn_driver
));
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETEAZ
;
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL2
;
info
->
last_l2
=
l2
;
cmd
.
arg
=
info
->
isdn_channel
+
(
l2
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL3
;
cmd
.
arg
=
info
->
isdn_channel
+
(
m
->
mdmreg
[
REG_L3PROT
]
<<
8
);
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
arg
=
l2
<<
8
;
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_SETL2
,
&
cmd
);
cmd
.
arg
=
m
->
mdmreg
[
REG_L3PROT
]
<<
8
;
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_SETL3
,
&
cmd
);
cmd
.
parm
.
cmsg
.
Length
=
l
+
14
;
cmd
.
parm
.
cmsg
.
Command
=
CAPI_MANUFACTURER
;
cmd
.
parm
.
cmsg
.
Subcommand
=
CAPI_REQ
;
cmd
.
parm
.
cmsg
.
adr
.
Controller
=
i
nfo
->
isdn_driver
+
1
;
cmd
.
parm
.
cmsg
.
adr
.
Controller
=
i
sdn_slot_driver
(
info
->
isdn_slot
)
+
1
;
cmd
.
parm
.
cmsg
.
para
[
0
]
=
l
+
1
;
strncpy
(
&
cmd
.
parm
.
cmsg
.
para
[
1
],
msg
,
l
);
cmd
.
parm
.
cmsg
.
para
[
l
+
1
]
=
0xd
;
cmd
.
command
=
CAPI_PUT_MESSAGE
;
/* info->dialing = 1;
strcpy(dev->num[i], n);
isdn_info_update();
*/
isdn_
command
(
&
cmd
);
isdn_
slot_command
(
info
->
isdn_slot
,
CAPI_PUT_MESSAGE
,
&
cmd
);
}
}
...
...
@@ -1173,6 +1099,7 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
{
int
c
;
int
total
=
0
;
int
di
;
modem_info
*
info
=
(
modem_info
*
)
tty
->
driver_data
;
atemu
*
m
=
&
info
->
emu
;
...
...
@@ -1186,8 +1113,9 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
c
=
count
;
if
(
c
>
info
->
xmit_size
-
info
->
xmit_count
)
c
=
info
->
xmit_size
-
info
->
xmit_count
;
if
(
info
->
isdn_driver
>=
0
&&
c
>
dev
->
drv
[
info
->
isdn_driver
]
->
maxbufsize
)
c
=
dev
->
drv
[
info
->
isdn_driver
]
->
maxbufsize
;
di
=
isdn_slot_driver
(
info
->
isdn_slot
);
if
(
di
>=
0
&&
c
>
dev
->
drv
[
di
]
->
maxbufsize
)
c
=
dev
->
drv
[
di
]
->
maxbufsize
;
if
(
c
<=
0
)
break
;
if
((
info
->
online
>
1
)
...
...
@@ -1247,12 +1175,9 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
if
(
info
->
vonline
&
4
)
{
/* ETX seen */
isdn_ctrl
c
;
c
.
command
=
ISDN_CMD_FAXCMD
;
c
.
driver
=
info
->
isdn_driver
;
c
.
arg
=
info
->
isdn_channel
;
c
.
parm
.
aux
.
cmd
=
ISDN_FAX_CLASS1_CTRL
;
c
.
parm
.
aux
.
subcmd
=
ETX
;
isdn_
command
(
&
c
);
isdn_
slot_command
(
info
->
isdn_slot
,
ISDN_CMD_FAXCMD
,
&
c
);
}
info
->
vonline
=
0
;
#ifdef ISDN_DEBUG_MODEM_VOICE
...
...
@@ -2015,10 +1940,10 @@ modem_write_profile(atemu * m)
}
int
isdn_tty_
modem_
init
(
void
)
isdn_tty_init
(
void
)
{
modem
*
m
;
int
i
;
int
i
,
retval
;
modem_info
*
info
;
m
=
&
dev
->
mdm
;
...
...
@@ -2063,13 +1988,15 @@ isdn_tty_modem_init(void)
m
->
tty_modem
.
minor_start
=
0
;
m
->
cua_modem
.
subtype
=
ISDN_SERIAL_TYPE_CALLOUT
;
if
(
tty_register_driver
(
&
m
->
tty_modem
))
{
retval
=
tty_register_driver
(
&
m
->
tty_modem
);
if
(
retval
)
{
printk
(
KERN_WARNING
"isdn_tty: Couldn't register modem-device
\n
"
);
return
-
1
;
goto
err
;
}
if
(
tty_register_driver
(
&
m
->
cua_modem
))
{
retval
=
tty_register_driver
(
&
m
->
cua_modem
);
if
(
retval
)
{
printk
(
KERN_WARNING
"isdn_tty: Couldn't register modem-callout-device
\n
"
);
return
-
2
;
goto
err_unregister_tty
;
}
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
info
=
&
m
->
info
[
i
];
...
...
@@ -2098,24 +2025,58 @@ isdn_tty_modem_init(void)
info
->
normal_termios
=
m
->
tty_modem
.
init_termios
;
init_waitqueue_head
(
&
info
->
open_wait
);
init_waitqueue_head
(
&
info
->
close_wait
);
info
->
isdn_driver
=
-
1
;
info
->
isdn_channel
=
-
1
;
info
->
drv_index
=
-
1
;
info
->
isdn_slot
=
-
1
;
info
->
xmit_size
=
ISDN_SERIAL_XMIT_SIZE
;
skb_queue_head_init
(
&
info
->
xmit_queue
);
#ifdef CONFIG_ISDN_AUDIO
skb_queue_head_init
(
&
info
->
dtmf_queue
);
#endif
if
(
!
(
info
->
xmit_buf
=
kmalloc
(
ISDN_SERIAL_XMIT_MAX
+
5
,
GFP_KERNEL
)))
{
info
->
xmit_buf
=
kmalloc
(
ISDN_SERIAL_XMIT_MAX
+
5
,
GFP_KERNEL
);
if
(
!
info
->
xmit_buf
)
{
printk
(
KERN_ERR
"Could not allocate modem xmit-buffer
\n
"
);
return
-
3
;
#ifdef CONFIG_ISDN_TTY_FAX
kfree
(
info
->
fax
);
#endif
goto
err_unregister_cua
;
}
/* Make room for T.70 header */
info
->
xmit_buf
+=
4
;
}
return
0
;
err_unregister_cua:
for
(
i
--
;
i
>=
0
;
i
--
)
{
info
=
&
m
->
info
[
i
];
#ifdef CONFIG_ISDN_TTY_FAX
kfree
(
info
->
fax
);
#endif
kfree
(
info
->
xmit_buf
-
4
);
}
tty_unregister_driver
(
&
dev
->
mdm
.
cua_modem
);
err_unregister_tty:
tty_unregister_driver
(
&
dev
->
mdm
.
tty_modem
);
err:
return
retval
;
}
void
isdn_tty_exit
(
void
)
{
modem
*
m
=
&
dev
->
mdm
;
modem_info
*
info
;
int
i
;
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
info
=
&
m
->
info
[
i
];
isdn_tty_cleanup_xmit
(
info
);
#ifdef CONFIG_ISDN_TTY_FAX
kfree
(
info
->
fax
);
#endif
kfree
(
info
->
xmit_buf
-
4
);
}
tty_unregister_driver
(
&
dev
->
mdm
.
cua_modem
);
tty_unregister_driver
(
&
dev
->
mdm
.
tty_modem
);
}
/*
* isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx)
...
...
@@ -2227,26 +2188,21 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
#ifndef FIX_FILE_TRANSFER
(
info
->
flags
&
ISDN_ASYNC_NORMAL_ACTIVE
)
&&
#endif
(
info
->
isdn_driver
==
-
1
)
&&
(
info
->
isdn_channel
==
-
1
)
&&
(
USG_NONE
(
dev
->
usage
[
idx
])))
{
(
info
->
isdn_slot
==
-
1
)
&&
(
USG_NONE
(
isdn_slot_usage
(
idx
))))
{
int
matchret
;
if
((
matchret
=
isdn_tty_match_icall
(
eaz
,
&
info
->
emu
,
di
))
>
wret
)
wret
=
matchret
;
if
(
!
matchret
)
{
/* EAZ is matching */
info
->
isdn_driver
=
di
;
info
->
isdn_channel
=
ch
;
info
->
drv_index
=
idx
;
dev
->
m_idx
[
idx
]
=
info
->
line
;
dev
->
usage
[
idx
]
&=
ISDN_USAGE_EXCLUSIVE
;
dev
->
usage
[
idx
]
|=
isdn_calc_usage
(
si1
,
info
->
emu
.
mdmreg
[
REG_L2PROT
]);
strcpy
(
dev
->
num
[
idx
],
nr
);
info
->
isdn_slot
=
idx
;
isdn_slot_set_m_idx
(
idx
,
info
->
line
);
strcpy
(
isdn_slot_num
(
idx
),
nr
);
strcpy
(
info
->
emu
.
cpn
,
eaz
);
info
->
emu
.
mdmreg
[
REG_SI1I
]
=
si2bit
[
si1
];
info
->
emu
.
mdmreg
[
REG_PLAN
]
=
setup
->
plan
;
info
->
emu
.
mdmreg
[
REG_SCREEN
]
=
setup
->
screen
;
isdn_
info_update
(
);
isdn_
slot_set_usage
(
idx
,
(
isdn_slot_usage
(
idx
)
&
ISDN_USAGE_EXCLUSIVE
)
|
isdn_calc_usage
(
si1
,
info
->
emu
.
mdmreg
[
REG_L2PROT
])
);
restore_flags
(
flags
);
printk
(
KERN_INFO
"isdn_tty: call from %s, -> RING on ttyI%d
\n
"
,
nr
,
info
->
line
);
...
...
@@ -2276,7 +2232,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
if
(
i
<
0
)
return
0
;
if
((
mi
=
dev
->
m_idx
[
i
]
)
>=
0
)
{
if
((
mi
=
isdn_slot_m_idx
(
i
)
)
>=
0
)
{
info
=
&
dev
->
mdm
.
info
[
mi
];
switch
(
c
->
command
)
{
case
ISDN_STAT_CINF
:
...
...
@@ -2290,8 +2246,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
#ifdef ISDN_TTY_STAT_DEBUG
printk
(
KERN_DEBUG
"tty_STAT_BSENT ttyI%d
\n
"
,
info
->
line
);
#endif
if
((
info
->
isdn_driver
==
c
->
driver
)
&&
(
info
->
isdn_channel
==
c
->
arg
))
{
if
((
info
->
isdn_slot
==
isdn_dc2minor
(
c
->
driver
,
c
->
arg
)))
{
info
->
msr
|=
UART_MSR_CTS
;
if
(
info
->
send_outstanding
)
if
(
!
(
--
info
->
send_outstanding
))
...
...
@@ -2375,14 +2330,14 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
info
->
last_dir
=
0
;
info
->
dialing
=
0
;
info
->
rcvsched
=
1
;
if
(
USG_MODEM
(
dev
->
usage
[
i
]
))
{
if
(
USG_MODEM
(
isdn_slot_usage
(
i
)
))
{
if
(
info
->
emu
.
mdmreg
[
REG_L2PROT
]
==
ISDN_PROTO_L2_MODEM
)
{
strcpy
(
info
->
emu
.
connmsg
,
c
->
parm
.
num
);
isdn_tty_modem_result
(
RESULT_CONNECT
,
info
);
}
else
isdn_tty_modem_result
(
RESULT_CONNECT64000
,
info
);
}
if
(
USG_VOICE
(
dev
->
usage
[
i
]
))
if
(
USG_VOICE
(
isdn_slot_usage
(
i
)
))
isdn_tty_modem_result
(
RESULT_VCON
,
info
);
return
1
;
}
...
...
@@ -2421,7 +2376,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
#endif
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
{
info
=
&
dev
->
mdm
.
info
[
i
];
if
(
i
nfo
->
isdn_driver
==
c
->
driver
)
{
if
(
i
sdn_slot_driver
(
info
->
isdn_slot
)
==
c
->
driver
)
{
if
(
info
->
online
)
isdn_tty_modem_hup
(
info
,
1
);
}
...
...
@@ -2473,6 +2428,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
ulong
flags
;
struct
sk_buff
*
skb
=
0
;
char
*
sp
=
0
;
int
di
,
ch
;
if
(
!
msg
)
{
printk
(
KERN_WARNING
"isdn_tty: Null-Message in isdn_tty_at_cout
\n
"
);
...
...
@@ -2488,8 +2444,9 @@ isdn_tty_at_cout(char *msg, modem_info * info)
/* use queue instead of direct flip, if online and */
/* data is in queue or flip buffer is full */
di
=
isdn_slot_driver
(
info
->
isdn_slot
);
ch
=
isdn_slot_channel
(
info
->
isdn_slot
);
if
((
info
->
online
)
&&
(((
tty
->
flip
.
count
+
strlen
(
msg
))
>=
TTY_FLIPBUF_SIZE
)
||
(
!
skb_queue_empty
(
&
dev
->
drv
[
info
->
isdn_driver
]
->
rpqueue
[
info
->
isdn_channel
]))))
{
(
!
skb_queue_empty
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
]))))
{
skb
=
alloc_skb
(
strlen
(
msg
)
#ifdef CONFIG_ISDN_AUDIO
+
sizeof
(
isdn_audio_skb
)
...
...
@@ -2532,8 +2489,8 @@ isdn_tty_at_cout(char *msg, modem_info * info)
}
}
if
(
skb
)
{
__skb_queue_tail
(
&
dev
->
drv
[
info
->
isdn_driver
]
->
rpqueue
[
info
->
isdn_channel
],
skb
);
dev
->
drv
[
info
->
isdn_driver
]
->
rcvcount
[
info
->
isdn_channel
]
+=
skb
->
len
;
__skb_queue_tail
(
&
dev
->
drv
[
di
]
->
rpqueue
[
ch
],
skb
);
dev
->
drv
[
di
]
->
rcvcount
[
ch
]
+=
skb
->
len
;
restore_flags
(
flags
);
/* Schedule dequeuing */
if
((
dev
->
modempoll
)
&&
(
info
->
rcvsched
))
...
...
@@ -2551,7 +2508,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
static
void
isdn_tty_on_hook
(
modem_info
*
info
)
{
if
(
info
->
isdn_
channel
>=
0
)
{
if
(
info
->
isdn_
slot
>=
0
)
{
#ifdef ISDN_DEBUG_MODEM_HUP
printk
(
KERN_DEBUG
"Mhup in isdn_tty_on_hook
\n
"
);
#endif
...
...
@@ -2711,7 +2668,7 @@ isdn_tty_modem_result(int code, modem_info * info)
/* print CID, _before_ _every_ ring */
if
(
!
(
m
->
mdmreg
[
REG_CIDONCE
]
&
BIT_CIDONCE
))
{
isdn_tty_at_cout
(
"
\r\n
CALLER NUMBER: "
,
info
);
isdn_tty_at_cout
(
dev
->
num
[
info
->
drv_index
]
,
info
);
isdn_tty_at_cout
(
isdn_slot_num
(
info
->
isdn_slot
)
,
info
);
if
(
m
->
mdmreg
[
REG_CDN
]
&
BIT_CDN
)
{
isdn_tty_at_cout
(
"
\r\n
CALLED NUMBER: "
,
info
);
isdn_tty_at_cout
(
info
->
emu
.
cpn
,
info
);
...
...
@@ -2740,7 +2697,7 @@ isdn_tty_modem_result(int code, modem_info * info)
(
m
->
mdmreg
[
REG_RINGCNT
]
==
1
))
{
isdn_tty_at_cout
(
"
\r\n
"
,
info
);
isdn_tty_at_cout
(
"CALLER NUMBER: "
,
info
);
isdn_tty_at_cout
(
dev
->
num
[
info
->
drv_index
]
,
info
);
isdn_tty_at_cout
(
isdn_slot_num
(
info
->
isdn_slot
)
,
info
);
if
(
m
->
mdmreg
[
REG_CDN
]
&
BIT_CDN
)
{
isdn_tty_at_cout
(
"
\r\n
CALLED NUMBER: "
,
info
);
isdn_tty_at_cout
(
info
->
emu
.
cpn
,
info
);
...
...
@@ -3252,7 +3209,7 @@ isdn_tty_cmd_ATA(modem_info * info)
if
(
info
->
msr
&
UART_MSR_RI
)
{
/* Accept incoming call */
info
->
last_dir
=
0
;
strcpy
(
info
->
last_num
,
dev
->
num
[
info
->
drv_index
]
);
strcpy
(
info
->
last_num
,
isdn_slot_num
(
info
->
isdn_slot
)
);
m
->
mdmreg
[
REG_RINGCNT
]
=
0
;
info
->
msr
&=
~
UART_MSR_RI
;
l2
=
m
->
mdmreg
[
REG_L2PROT
];
...
...
@@ -3266,27 +3223,20 @@ isdn_tty_cmd_ATA(modem_info * info)
l2
=
ISDN_PROTO_L2_X75I
;
}
#endif
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL2
;
cmd
.
arg
=
info
->
isdn_channel
+
(
l2
<<
8
);
cmd
.
arg
=
l2
<<
8
;
info
->
last_l2
=
l2
;
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_SETL3
;
cmd
.
arg
=
info
->
isdn_channel
+
(
m
->
mdmreg
[
REG_L3PROT
]
<<
8
);
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_SETL2
,
&
cmd
);
cmd
.
arg
=
m
->
mdmreg
[
REG_L3PROT
]
<<
8
;
#ifdef CONFIG_ISDN_TTY_FAX
if
(
l2
==
ISDN_PROTO_L2_FAX
)
{
cmd
.
parm
.
fax
=
info
->
fax
;
info
->
fax
->
direction
=
ISDN_TTY_FAX_CONN_IN
;
}
#endif
isdn_command
(
&
cmd
);
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_ACCEPTD
;
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_SETL3
,
&
cmd
);
info
->
dialing
=
16
;
info
->
emu
.
carrierwait
=
0
;
isdn_
command
(
&
cmd
);
isdn_
slot_command
(
info
->
isdn_slot
,
ISDN_CMD_ACCEPTD
,
&
cmd
);
isdn_timer_ctrl
(
ISDN_TIMER_CARRIER
,
1
);
}
else
isdn_tty_modem_result
(
RESULT_NO_ANSWER
,
info
);
...
...
@@ -3642,12 +3592,10 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
PARSE_ERROR1
;
m
->
vpar
[
4
]
=
par1
;
m
->
vpar
[
5
]
=
par2
;
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
command
=
ISDN_CMD_AUDIO
;
cmd
.
arg
=
info
->
isdn_channel
+
(
ISDN_AUDIO_SETDD
<<
8
);
cmd
.
arg
=
ISDN_AUDIO_SETDD
<<
8
;
cmd
.
parm
.
num
[
0
]
=
par1
;
cmd
.
parm
.
num
[
1
]
=
par2
;
isdn_
command
(
&
cmd
);
isdn_
slot_command
(
info
->
isdn_slot
,
ISDN_CMD_AUDIO
,
&
cmd
);
break
;
}
else
if
(
*
p
[
0
]
==
'?'
)
{
...
...
@@ -3973,8 +3921,8 @@ isdn_tty_modem_escape(void)
int
midx
;
for
(
i
=
0
;
i
<
ISDN_MAX_CHANNELS
;
i
++
)
if
(
USG_MODEM
(
dev
->
usage
[
i
]
))
if
((
midx
=
dev
->
m_idx
[
i
]
)
>=
0
)
{
if
(
USG_MODEM
(
isdn_slot_usage
(
i
)
))
if
((
midx
=
isdn_slot_m_idx
(
i
)
)
>=
0
)
{
modem_info
*
info
=
&
dev
->
mdm
.
info
[
midx
];
if
(
info
->
online
)
{
ton
=
1
;
...
...
drivers/isdn/i4l/isdn_tty.h
View file @
ab50636c
...
...
@@ -105,7 +105,7 @@ extern void isdn_tty_modem_escape(void);
extern
void
isdn_tty_modem_ring
(
void
);
extern
void
isdn_tty_carrier_timeout
(
void
);
extern
void
isdn_tty_modem_xmit
(
void
);
extern
int
isdn_tty_
modem_
init
(
void
);
extern
int
isdn_tty_init
(
void
);
extern
void
isdn_tty_readmodem
(
void
);
extern
int
isdn_tty_find_icall
(
int
,
int
,
setup_parm
*
);
extern
void
isdn_tty_cleanup_xmit
(
modem_info
*
);
...
...
@@ -119,3 +119,6 @@ extern int isdn_tty_cmd_PLUSF_FAX(char **, modem_info *);
extern
int
isdn_tty_fax_command
(
modem_info
*
,
isdn_ctrl
*
);
extern
void
isdn_tty_fax_bitorder
(
modem_info
*
,
struct
sk_buff
*
);
#endif
extern
int
isdn_tty_init
(
void
);
extern
void
isdn_tty_exit
(
void
);
drivers/isdn/i4l/isdn_ttyfax.c
View file @
ab50636c
...
...
@@ -74,7 +74,7 @@ isdn_tty_fax_modem_result(int code, modem_info * info)
case
2
:
/* +FCON */
/* Append CPN, if enabled */
if
((
m
->
mdmreg
[
REG_CPNFCON
]
&
BIT_CPNFCON
)
&&
(
!
(
dev
->
usage
[
info
->
isdn_channel
]
&
ISDN_USAGE_OUTGOING
)))
{
(
!
(
isdn_slot_usage
(
info
->
isdn_slot
)
&
ISDN_USAGE_OUTGOING
)))
{
sprintf
(
rs
,
"/%s"
,
m
->
cpn
);
isdn_tty_at_cout
(
rs
,
info
);
}
...
...
@@ -360,12 +360,11 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
default:
PARSE_ERROR1
;
}
c
.
command
=
ISDN_CMD_FAXCMD
;
#ifdef ISDN_TTY_FAX_CMD_DEBUG
printk
(
KERN_DEBUG
"isdn_tty_cmd_FCLASS1 %d/%d/%d)
\n
"
,
c
.
parm
.
aux
.
cmd
,
c
.
parm
.
aux
.
subcmd
,
c
.
parm
.
aux
.
para
[
0
]);
#endif
if
(
info
->
isdn_
driver
<
0
)
{
if
(
info
->
isdn_
slot
<
0
)
{
save_flags
(
flags
);
cli
();
if
((
c
.
parm
.
aux
.
subcmd
==
AT_EQ_VALUE
)
||
...
...
@@ -374,32 +373,21 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
PARSE_ERROR1
;
}
/* get a temporary connection to the first free fax driver */
i
=
isdn_get_free_
channel
(
ISDN_USAGE_FAX
,
ISDN_PROTO_L2_FAX
,
ISDN_PROTO_L3_FCLASS1
,
-
1
,
-
1
,
"00"
);
i
=
isdn_get_free_
slot
(
ISDN_USAGE_FAX
,
ISDN_PROTO_L2_FAX
,
ISDN_PROTO_L3_FCLASS1
,
-
1
,
-
1
,
"00"
);
if
(
i
<
0
)
{
restore_flags
(
flags
);
PARSE_ERROR1
;
}
info
->
isdn_driver
=
dev
->
drvmap
[
i
];
info
->
isdn_channel
=
dev
->
chanmap
[
i
];
info
->
drv_index
=
i
;
dev
->
m_idx
[
i
]
=
info
->
line
;
c
.
driver
=
info
->
isdn_driver
;
c
.
arg
=
info
->
isdn_channel
;
isdn_command
(
&
c
);
isdn_free_channel
(
info
->
isdn_driver
,
info
->
isdn_channel
,
ISDN_USAGE_FAX
);
info
->
isdn_driver
=
-
1
;
info
->
isdn_channel
=
-
1
;
if
(
info
->
drv_index
>=
0
)
{
dev
->
m_idx
[
info
->
drv_index
]
=
-
1
;
info
->
drv_index
=
-
1
;
}
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_set_m_idx
(
i
,
-
1
);
info
->
isdn_slot
=
-
1
;
restore_flags
(
flags
);
}
else
{
c
.
driver
=
info
->
isdn_driver
;
c
.
arg
=
info
->
isdn_channel
;
isdn_command
(
&
c
);
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_FAXCMD
,
&
c
);
}
return
1
;
}
...
...
@@ -800,10 +788,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
printk
(
KERN_DEBUG
"isdn_tty: Fax FDR
\n
"
);
#endif
f
->
code
=
ISDN_TTY_FAX_DR
;
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_FAXCMD
;
isdn_command
(
&
cmd
);
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_FAXCMD
,
&
cmd
);
if
(
f
->
phase
==
ISDN_FAX_PHASE_B
)
{
f
->
phase
=
ISDN_FAX_PHASE_C
;
}
else
if
(
f
->
phase
==
ISDN_FAX_PHASE_D
)
{
...
...
@@ -855,10 +840,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
#endif
if
((
f
->
phase
==
ISDN_FAX_PHASE_B
)
||
(
f
->
phase
==
ISDN_FAX_PHASE_D
))
{
f
->
code
=
ISDN_TTY_FAX_DT
;
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_FAXCMD
;
isdn_command
(
&
cmd
);
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_FAXCMD
,
&
cmd
);
if
(
f
->
phase
==
ISDN_FAX_PHASE_D
)
{
f
->
phase
=
ISDN_FAX_PHASE_C
;
isdn_tty_fax_modem_result
(
7
,
info
);
/* CONNECT */
...
...
@@ -913,10 +895,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
PARSE_ERROR1
;
f
->
fet
=
par
;
f
->
code
=
ISDN_TTY_FAX_ET
;
cmd
.
driver
=
info
->
isdn_driver
;
cmd
.
arg
=
info
->
isdn_channel
;
cmd
.
command
=
ISDN_CMD_FAXCMD
;
isdn_command
(
&
cmd
);
isdn_slot_command
(
info
->
isdn_slot
,
ISDN_CMD_FAXCMD
,
&
cmd
);
#ifdef ISDN_TTY_FAX_STAT_DEBUG
printk
(
KERN_DEBUG
"isdn_tty: Fax FET=%d
\n
"
,
par
);
#endif
...
...
drivers/isdn/i4l/isdn_v110.c
View file @
ab50636c
...
...
@@ -515,14 +515,12 @@ isdn_v110_encode(isdn_v110_stream * v, struct sk_buff *skb)
}
int
isdn_v110_stat_callback
(
int
idx
,
isdn_ctrl
*
c
)
isdn_v110_stat_callback
(
struct
isdn_v110
*
iv110
,
isdn_ctrl
*
c
)
{
isdn_v110_stream
*
v
=
NULL
;
int
i
;
int
ret
;
if
(
idx
<
0
)
return
0
;
switch
(
c
->
command
)
{
case
ISDN_STAT_BSENT
:
/* Keep the send-queue of the driver filled
...
...
@@ -531,9 +529,9 @@ isdn_v110_stat_callback(int idx, isdn_ctrl * c)
* send down an Idle-Frame (or an Sync-Frame, if
* v->SyncInit != 0).
*/
if
(
!
(
v
=
dev
->
v110
[
idx
]
))
if
(
!
(
v
=
iv110
->
v110
))
return
0
;
atomic_inc
(
&
dev
->
v110use
[
idx
]
);
atomic_inc
(
&
iv110
->
v110use
);
if
(
v
->
skbidle
>
0
)
{
v
->
skbidle
--
;
ret
=
1
;
...
...
@@ -560,38 +558,38 @@ isdn_v110_stat_callback(int idx, isdn_ctrl * c)
}
else
break
;
}
atomic_dec
(
&
dev
->
v110use
[
idx
]
);
atomic_dec
(
&
iv110
->
v110use
);
return
ret
;
case
ISDN_STAT_DHUP
:
case
ISDN_STAT_BHUP
:
while
(
1
)
{
atomic_inc
(
&
dev
->
v110use
[
idx
]
);
if
(
atomic_dec_and_test
(
&
dev
->
v110use
[
idx
]
))
{
isdn_v110_close
(
dev
->
v110
[
idx
]
);
dev
->
v110
[
idx
]
=
NULL
;
atomic_inc
(
&
iv110
->
v110use
);
if
(
atomic_dec_and_test
(
&
iv110
->
v110use
))
{
isdn_v110_close
(
iv110
->
v110
);
iv110
->
v110
=
NULL
;
break
;
}
sti
();
}
break
;
case
ISDN_STAT_BCONN
:
if
(
dev
->
v110emu
[
idx
]
&&
(
dev
->
v110
[
idx
]
==
NULL
))
{
if
(
iv110
->
v110emu
&&
(
iv110
->
v110
==
NULL
))
{
int
hdrlen
=
dev
->
drv
[
c
->
driver
]
->
interface
->
hl_hdrlen
;
int
maxsize
=
dev
->
drv
[
c
->
driver
]
->
interface
->
maxbufsize
;
atomic_inc
(
&
dev
->
v110use
[
idx
]
);
switch
(
dev
->
v110emu
[
idx
]
)
{
atomic_inc
(
&
iv110
->
v110use
);
switch
(
iv110
->
v110emu
)
{
case
ISDN_PROTO_L2_V11096
:
dev
->
v110
[
idx
]
=
isdn_v110_open
(
V110_9600
,
hdrlen
,
maxsize
);
iv110
->
v110
=
isdn_v110_open
(
V110_9600
,
hdrlen
,
maxsize
);
break
;
case
ISDN_PROTO_L2_V11019
:
dev
->
v110
[
idx
]
=
isdn_v110_open
(
V110_19200
,
hdrlen
,
maxsize
);
iv110
->
v110
=
isdn_v110_open
(
V110_19200
,
hdrlen
,
maxsize
);
break
;
case
ISDN_PROTO_L2_V11038
:
dev
->
v110
[
idx
]
=
isdn_v110_open
(
V110_38400
,
hdrlen
,
maxsize
);
iv110
->
v110
=
isdn_v110_open
(
V110_38400
,
hdrlen
,
maxsize
);
break
;
default:
;
}
if
((
v
=
dev
->
v110
[
idx
]
))
{
if
((
v
=
iv110
->
v110
))
{
while
(
v
->
SyncInit
)
{
struct
sk_buff
*
skb
=
isdn_v110_sync
(
v
);
if
(
dev
->
drv
[
c
->
driver
]
->
interface
->
writebuf_skb
(
c
->
driver
,
c
->
arg
,
1
,
skb
)
<=
0
)
{
...
...
@@ -603,8 +601,8 @@ isdn_v110_stat_callback(int idx, isdn_ctrl * c)
v
->
skbidle
++
;
}
}
else
printk
(
KERN_WARNING
"isdn_v110: Couldn't open stream
for chan %d
\n
"
,
idx
);
atomic_dec
(
&
dev
->
v110use
[
idx
]
);
printk
(
KERN_WARNING
"isdn_v110: Couldn't open stream
\n
"
);
atomic_dec
(
&
iv110
->
v110use
);
}
break
;
default:
...
...
drivers/isdn/i4l/isdn_v110.h
View file @
ab50636c
...
...
@@ -9,8 +9,14 @@
*
*/
#ifndef _isdn_v110_h_
#define _isdn_v110_h_
#ifndef ISDN_V110_H
#define ISDN_V110_H
struct
isdn_v110
{
int
v110emu
;
/* V.110 emulator-mode 0=none */
atomic_t
v110use
;
/* Usage-Semaphore for stream */
isdn_v110_stream
*
v110
;
/* V.110 private data */
};
/*
* isdn_v110_encode will take raw data and encode it using V.110
...
...
@@ -23,7 +29,7 @@ extern struct sk_buff *isdn_v110_encode(isdn_v110_stream *, struct sk_buff *);
*/
extern
struct
sk_buff
*
isdn_v110_decode
(
isdn_v110_stream
*
,
struct
sk_buff
*
);
extern
int
isdn_v110_stat_callback
(
int
,
isdn_ctrl
*
);
extern
int
isdn_v110_stat_callback
(
struct
isdn_v110
*
v110
,
isdn_ctrl
*
);
extern
void
isdn_v110_close
(
isdn_v110_stream
*
v
);
#endif
drivers/isdn/isdnloop/isdnloop.c
View file @
ab50636c
...
...
@@ -757,6 +757,10 @@ isdnloop_vstphone(isdnloop_card * card, char *phone, int caller)
int
i
;
static
char
nphone
[
30
];
if
(
!
card
)
{
printk
(
"BUG!!!
\n
"
);
return
""
;
}
switch
(
card
->
ptype
)
{
case
ISDN_PTYPE_EURO
:
if
(
caller
)
{
...
...
@@ -775,7 +779,7 @@ isdnloop_vstphone(isdnloop_card * card, char *phone, int caller)
return
(
&
phone
[
strlen
(
phone
)
-
1
]);
break
;
}
return
(
"
\0
"
)
;
return
""
;
}
/*
...
...
@@ -882,7 +886,7 @@ isdnloop_parse_cmd(isdnloop_card * card)
isdnloop_vstphone
(
card
,
cmd
.
parm
.
setup
.
eazmsn
,
1
),
cmd
.
parm
.
setup
.
si1
,
cmd
.
parm
.
setup
.
si2
,
isdnloop_vstphone
(
card
->
rcard
[
ch
],
isdnloop_vstphone
(
card
->
rcard
[
ch
-
1
],
cmd
.
parm
.
setup
.
phone
,
0
));
isdnloop_fake
(
card
->
rcard
[
ch
-
1
],
buf
,
card
->
rch
[
ch
-
1
]
+
1
);
/* Fall through */
...
...
include/linux/isdn.h
View file @
ab50636c
...
...
@@ -245,18 +245,12 @@ typedef struct {
#define ISDN_TIMER_MODEMPLUS 2
#define ISDN_TIMER_MODEMRING 4
#define ISDN_TIMER_MODEMXMIT 8
#define ISDN_TIMER_NETDIAL 16
#define ISDN_TIMER_NETHANGUP 32
#define ISDN_TIMER_CARRIER 256
/* Wait for Carrier */
#define ISDN_TIMER_FAST (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMPLUS | \
ISDN_TIMER_MODEMXMIT)
#define ISDN_TIMER_SLOW (ISDN_TIMER_MODEMRING | ISDN_TIMER_NETHANGUP | \
ISDN_TIMER_NETDIAL | ISDN_TIMER_CARRIER)
/* Timeout-Values for isdn_net_dial() */
#define ISDN_TIMER_DTIMEOUT10 (10*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1)))
#define ISDN_TIMER_DTIMEOUT15 (15*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1)))
#define ISDN_TIMER_DTIMEOUT60 (60*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1)))
ISDN_TIMER_CARRIER)
/* GLOBAL_FLAGS */
#define ISDN_GLOBAL_STOPPED 1
...
...
@@ -291,9 +285,10 @@ typedef struct {
typedef
struct
isdn_net_local_s
{
ulong
magic
;
char
name
[
10
];
/* Name of device */
struct
timer_list
dial_timer
;
/* dial timeout */
int
dial_event
;
/* event in case of timer expiry */
struct
net_device_stats
stats
;
/* Ethernet Statistics */
int
isdn_device
;
/* Index to isdn-device */
int
isdn_channel
;
/* Index to isdn-channel */
int
isdn_slot
;
/* Index to isdn device/channel */
int
ppp_slot
;
/* PPPD device slot number */
int
pre_device
;
/* Preselected isdn-device */
int
pre_channel
;
/* Preselected isdn-channel */
...
...
@@ -302,7 +297,6 @@ typedef struct isdn_net_local_s {
int
dialretry
;
/* Counter for Dialout-retries */
int
dialmax
;
/* Max. Number of Dial-retries */
int
cbdelay
;
/* Delay before Callback starts */
int
dtimer
;
/* Timeout-counter for dialing */
char
msn
[
ISDN_MSNLEN
];
/* MSNs/EAZs for this interface */
u_char
cbhup
;
/* Flag: Reject Call before Callback*/
u_char
dialstate
;
/* State for dialing */
...
...
@@ -387,12 +381,12 @@ typedef struct isdn_net_local_s {
/* the interface itself */
typedef
struct
isdn_net_dev_s
{
isdn_net_local
*
local
;
isdn_net_local
local
;
isdn_net_local
*
queue
;
/* circular list of all bundled
channels, which are currently
online */
spinlock_t
queue_lock
;
/* lock to protect queue */
void
*
next
;
/* Pointer to next isdn-interface
*/
struct
list_head
global_list
;
/* global list of all isdn_net_devs
*/
struct
net_device
dev
;
/* interface to upper levels */
#ifdef CONFIG_ISDN_PPP
ippp_bundle
*
pb
;
/* pointer to the common bundle structure
...
...
@@ -480,9 +474,7 @@ typedef struct modem_info {
/* 2 = B-Channel is up, deliver d.*/
int
dialing
;
/* Dial in progress or ATA */
int
rcvsched
;
/* Receive needs schedule */
int
isdn_driver
;
/* Index to isdn-driver */
int
isdn_channel
;
/* Index to isdn-channel */
int
drv_index
;
/* Index to dev->usage */
int
isdn_slot
;
/* Index to isdn-driver/channel */
int
ncarrier
;
/* Flag: schedule NO CARRIER */
unsigned
char
last_cause
[
8
];
/* Last cause message */
unsigned
char
last_num
[
ISDN_MSNLEN
];
...
...
@@ -608,24 +600,10 @@ typedef struct isdn_devt {
infostruct
*
infochain
;
/* List of open info-devs. */
wait_queue_head_t
info_waitq
;
/* Wait-Queue for isdninfo */
struct
timer_list
timer
;
/* Misc.-function Timer */
int
chanmap
[
ISDN_MAX_CHANNELS
];
/* Map minor->device-channel */
int
drvmap
[
ISDN_MAX_CHANNELS
];
/* Map minor->driver-index */
int
usage
[
ISDN_MAX_CHANNELS
];
/* Used by tty/ip/voice */
char
num
[
ISDN_MAX_CHANNELS
][
ISDN_MSNLEN
];
/* Remote number of active ch.*/
int
m_idx
[
ISDN_MAX_CHANNELS
];
/* Index for mdm.... */
driver
*
drv
[
ISDN_MAX_DRIVERS
];
/* Array of drivers */
isdn_net_dev
*
netdev
;
/* Linked list of net-if's */
char
drvid
[
ISDN_MAX_DRIVERS
][
20
];
/* Driver-ID */
struct
task_struct
*
profd
;
/* For iprofd */
modem
mdm
;
/* tty-driver-data */
isdn_net_dev
*
rx_netdev
[
ISDN_MAX_CHANNELS
];
/* rx netdev-pointers */
isdn_net_dev
*
st_netdev
[
ISDN_MAX_CHANNELS
];
/* stat netdev-pointers */
ulong
ibytes
[
ISDN_MAX_CHANNELS
];
/* Statistics incoming bytes */
ulong
obytes
[
ISDN_MAX_CHANNELS
];
/* Statistics outgoing bytes */
int
v110emu
[
ISDN_MAX_CHANNELS
];
/* V.110 emulator-mode 0=none */
atomic_t
v110use
[
ISDN_MAX_CHANNELS
];
/* Usage-Semaphore for stream */
isdn_v110_stream
*
v110
[
ISDN_MAX_CHANNELS
];
/* V.110 private data */
struct
semaphore
sem
;
/* serialize list access*/
unsigned
long
global_features
;
#ifdef CONFIG_DEVFS_FS
...
...
include/linux/isdnif.h
View file @
ab50636c
...
...
@@ -418,9 +418,7 @@ typedef struct {
char
display
[
85
];
/* display message data */
isdn_cmd_stat
isdn_io
;
/* ISDN IO-parameter/result */
aux_s
aux
;
/* for modem commands/indications */
#ifdef CONFIG_ISDN_TTY_FAX
T30_s
*
fax
;
/* Pointer to ttys fax struct */
#endif
ulong
userdata
;
/* User Data */
}
parm
;
}
isdn_ctrl
;
...
...
mm/mmap.c
View file @
ab50636c
...
...
@@ -422,6 +422,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
{
struct
mm_struct
*
mm
=
current
->
mm
;
struct
vm_area_struct
*
vma
,
*
prev
;
struct
inode
*
inode
=
NULL
;
unsigned
int
vm_flags
;
int
correct_wcount
=
0
;
int
error
;
...
...
@@ -469,17 +470,18 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
}
if
(
file
)
{
inode
=
file
->
f_dentry
->
d_inode
;
switch
(
flags
&
MAP_TYPE
)
{
case
MAP_SHARED
:
if
((
prot
&
PROT_WRITE
)
&&
!
(
file
->
f_mode
&
FMODE_WRITE
))
return
-
EACCES
;
/* Make sure we don't allow writing to an append-only file.. */
if
(
IS_APPEND
(
file
->
f_dentry
->
d_
inode
)
&&
(
file
->
f_mode
&
FMODE_WRITE
))
if
(
IS_APPEND
(
inode
)
&&
(
file
->
f_mode
&
FMODE_WRITE
))
return
-
EACCES
;
/* make sure there are no mandatory locks on the file. */
if
(
locks_verify_locked
(
file
->
f_dentry
->
d_
inode
))
if
(
locks_verify_locked
(
inode
))
return
-
EAGAIN
;
vm_flags
|=
VM_SHARED
|
VM_MAYSHARE
;
...
...
@@ -603,7 +605,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
vma_link
(
mm
,
vma
,
prev
,
rb_link
,
rb_parent
);
if
(
correct_wcount
)
atomic_inc
(
&
file
->
f_dentry
->
d_
inode
->
i_writecount
);
atomic_inc
(
&
inode
->
i_writecount
);
out:
mm
->
total_vm
+=
len
>>
PAGE_SHIFT
;
...
...
@@ -615,7 +617,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
unmap_and_free_vma:
if
(
correct_wcount
)
atomic_inc
(
&
file
->
f_dentry
->
d_
inode
->
i_writecount
);
atomic_inc
(
&
inode
->
i_writecount
);
vma
->
vm_file
=
NULL
;
fput
(
file
);
...
...
@@ -755,38 +757,41 @@ struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
return
prev
?
prev
->
vm_next
:
vma
;
}
#ifdef ARCH_STACK_GROWSUP
/*
* vma is the first one with address < vma->vm_end,
* and even address < vma->vm_start. Have to extend vma.
* vma is the first one with address > vma->vm_end. Have to extend vma.
*/
int
expand_stack
(
struct
vm_area_struct
*
vma
,
unsigned
long
address
)
{
unsigned
long
grow
;
if
(
!
(
vma
->
vm_flags
&
VM_GROWSUP
))
return
-
EFAULT
;
/*
* vma->vm_start/vm_end cannot change under us because the caller
* is required to hold the mmap_sem in
write
mode. We need to get
* is required to hold the mmap_sem in
read
mode. We need to get
* the spinlock only before relocating the vma range ourself.
*/
address
+=
4
+
PAGE_SIZE
-
1
;
address
&=
PAGE_MASK
;
spin_lock
(
&
vma
->
vm_mm
->
page_table_lock
);
grow
=
(
vma
->
vm_start
-
address
)
>>
PAGE_SHIFT
;
grow
=
(
address
-
vma
->
vm_end
)
>>
PAGE_SHIFT
;
/* Overcommit.. */
if
(
!
vm_enough_memory
(
grow
))
{
if
(
!
vm_enough_memory
(
grow
))
{
spin_unlock
(
&
vma
->
vm_mm
->
page_table_lock
);
return
-
ENOMEM
;
}
if
(
vma
->
vm_end
-
address
>
current
->
rlim
[
RLIMIT_STACK
].
rlim_cur
||
if
(
address
-
vma
->
vm_start
>
current
->
rlim
[
RLIMIT_STACK
].
rlim_cur
||
((
vma
->
vm_mm
->
total_vm
+
grow
)
<<
PAGE_SHIFT
)
>
current
->
rlim
[
RLIMIT_AS
].
rlim_cur
)
{
spin_unlock
(
&
vma
->
vm_mm
->
page_table_lock
);
vm_unacct_memory
(
grow
);
return
-
ENOMEM
;
}
vma
->
vm_start
=
address
;
vma
->
vm_pgoff
-=
grow
;
vma
->
vm_end
=
address
;
vma
->
vm_mm
->
total_vm
+=
grow
;
if
(
vma
->
vm_flags
&
VM_LOCKED
)
vma
->
vm_mm
->
locked_vm
+=
grow
;
...
...
@@ -794,7 +799,6 @@ int expand_stack(struct vm_area_struct * vma, unsigned long address)
return
0
;
}
#ifdef ARCH_STACK_GROWSUP
struct
vm_area_struct
*
find_extend_vma
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
{
struct
vm_area_struct
*
vma
,
*
prev
;
...
...
@@ -811,6 +815,44 @@ struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long add
return
prev
;
}
#else
/*
* vma is the first one with address < vma->vm_start. Have to extend vma.
*/
int
expand_stack
(
struct
vm_area_struct
*
vma
,
unsigned
long
address
)
{
unsigned
long
grow
;
/*
* vma->vm_start/vm_end cannot change under us because the caller
* is required to hold the mmap_sem in read mode. We need to get
* the spinlock only before relocating the vma range ourself.
*/
address
&=
PAGE_MASK
;
spin_lock
(
&
vma
->
vm_mm
->
page_table_lock
);
grow
=
(
vma
->
vm_start
-
address
)
>>
PAGE_SHIFT
;
/* Overcommit.. */
if
(
!
vm_enough_memory
(
grow
))
{
spin_unlock
(
&
vma
->
vm_mm
->
page_table_lock
);
return
-
ENOMEM
;
}
if
(
vma
->
vm_end
-
address
>
current
->
rlim
[
RLIMIT_STACK
].
rlim_cur
||
((
vma
->
vm_mm
->
total_vm
+
grow
)
<<
PAGE_SHIFT
)
>
current
->
rlim
[
RLIMIT_AS
].
rlim_cur
)
{
spin_unlock
(
&
vma
->
vm_mm
->
page_table_lock
);
vm_unacct_memory
(
grow
);
return
-
ENOMEM
;
}
vma
->
vm_start
=
address
;
vma
->
vm_pgoff
-=
grow
;
vma
->
vm_mm
->
total_vm
+=
grow
;
if
(
vma
->
vm_flags
&
VM_LOCKED
)
vma
->
vm_mm
->
locked_vm
+=
grow
;
spin_unlock
(
&
vma
->
vm_mm
->
page_table_lock
);
return
0
;
}
struct
vm_area_struct
*
find_extend_vma
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
{
struct
vm_area_struct
*
vma
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment