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
nexedi
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