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
b2b109e8
Commit
b2b109e8
authored
Sep 30, 2002
by
Kai Germaschewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge zephyr:src/kernel/v2.5/linux-2.5.isdn
into tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linux-2.5.isdn
parents
2b9fa51a
0066476b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
387 additions
and
461 deletions
+387
-461
drivers/isdn/i4l/isdn_ciscohdlck.c
drivers/isdn/i4l/isdn_ciscohdlck.c
+9
-8
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_net.c
+196
-197
drivers/isdn/i4l/isdn_net.h
drivers/isdn/i4l/isdn_net.h
+61
-53
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/i4l/isdn_ppp.c
+89
-168
include/linux/isdn.h
include/linux/isdn.h
+30
-24
include/linux/isdn_ppp.h
include/linux/isdn_ppp.h
+2
-11
No files found.
drivers/isdn/i4l/isdn_ciscohdlck.c
View file @
b2b109e8
...
...
@@ -164,7 +164,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
p
+=
put_u32
(
p
,
lp
->
cisco_yourseq
);
p
+=
put_u16
(
p
,
0xffff
);
// reliablity, always 0xffff
isdn_net_write_super
(
lp
,
skb
);
isdn_net_write_super
(
idev
,
skb
);
lp
->
cisco_timer
.
expires
=
jiffies
+
lp
->
cisco_keepalive_period
*
HZ
;
...
...
@@ -174,6 +174,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
static
void
isdn_net_ciscohdlck_slarp_send_request
(
isdn_net_local
*
lp
)
{
isdn_net_dev
*
idev
=
lp
->
netdev
;
struct
sk_buff
*
skb
;
unsigned
char
*
p
;
...
...
@@ -194,7 +195,7 @@ isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
p
+=
put_u32
(
p
,
0
);
// netmask
p
+=
put_u16
(
p
,
0
);
// unused
isdn_net_write_super
(
lp
,
skb
);
isdn_net_write_super
(
idev
,
skb
);
}
static
void
...
...
@@ -218,7 +219,7 @@ isdn_ciscohdlck_connected(isdn_net_local *lp)
lp
->
cisco_timer
.
expires
=
jiffies
+
lp
->
cisco_keepalive_period
*
HZ
;
add_timer
(
&
lp
->
cisco_timer
);
}
isdn_net_dev
ice_wake_queue
(
lp
);
isdn_net_dev
_wake_queue
(
lp
->
netdev
);
}
static
void
...
...
@@ -232,13 +233,14 @@ isdn_ciscohdlck_disconnected(isdn_net_local *lp)
static
void
isdn_net_ciscohdlck_slarp_send_reply
(
isdn_net_local
*
lp
)
{
isdn_net_dev
*
idev
=
lp
->
netdev
;
struct
sk_buff
*
skb
;
unsigned
char
*
p
;
struct
in_device
*
in_dev
=
NULL
;
u32
addr
=
0
;
/* local ipv4 address */
u32
mask
=
0
;
/* local netmask */
if
((
in_dev
=
lp
->
netdev
->
dev
.
ip_ptr
)
!=
NULL
)
{
if
((
in_dev
=
lp
->
dev
.
ip_ptr
)
!=
NULL
)
{
/* take primary(first) address of interface */
struct
in_ifaddr
*
ifa
=
in_dev
->
ifa_list
;
if
(
ifa
!=
NULL
)
{
...
...
@@ -265,7 +267,7 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
p
+=
put_u32
(
p
,
mask
);
// netmask
p
+=
put_u16
(
p
,
0
);
// unused
isdn_net_write_super
(
lp
,
skb
);
isdn_net_write_super
(
idev
,
skb
);
}
static
void
...
...
@@ -335,10 +337,9 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
}
static
void
isdn_ciscohdlck_receive
(
isdn_net_
dev
*
idev
,
isdn_net_local
*
olp
,
isdn_ciscohdlck_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_local
*
lp
=
&
idev
->
local
;
unsigned
char
*
p
;
u8
addr
;
u8
ctrl
;
...
...
@@ -371,7 +372,7 @@ isdn_ciscohdlck_receive(isdn_net_dev *idev, isdn_net_local *olp,
goto
out_free
;
default:
/* no special cisco protocol */
isdn_net_reset_huptimer
(
idev
,
olp
->
net
dev
);
isdn_net_reset_huptimer
(
lp
,
i
dev
);
skb
->
protocol
=
htons
(
type
);
netif_rx
(
skb
);
return
;
...
...
drivers/isdn/i4l/isdn_net.c
View file @
b2b109e8
...
...
@@ -92,15 +92,16 @@ LIST_HEAD(isdn_net_devs); /* Linked list of isdn_net_dev's */
* Find out if the netdevice has been ifup-ed yet.
* For slaves, look at the corresponding master.
*/
static
__inline__
int
isdn_net_device_started
(
isdn_net_dev
*
n
)
static
inline
int
isdn_net_device_started
(
isdn_net_dev
*
idev
)
{
isdn_net_local
*
lp
=
&
n
->
local
;
struct
net_device
*
dev
;
if
(
lp
->
master
)
dev
=
lp
->
master
;
if
(
idev
->
master
)
dev
=
&
idev
->
master
->
dev
;
else
dev
=
&
n
->
dev
;
dev
=
&
idev
->
local
.
dev
;
return
netif_running
(
dev
);
}
...
...
@@ -108,12 +109,13 @@ static __inline__ int isdn_net_device_started(isdn_net_dev *n)
* stop the network -> net_device queue.
* For slaves, stop the corresponding master interface.
*/
static
__inline__
void
isdn_net_device_stop_queue
(
isdn_net_local
*
lp
)
static
inline
void
isdn_net_dev_stop_queue
(
isdn_net_dev
*
idev
)
{
if
(
lp
->
master
)
netif_stop_queue
(
lp
->
master
);
if
(
idev
->
master
)
netif_stop_queue
(
&
idev
->
master
->
dev
);
else
netif_stop_queue
(
&
lp
->
netdev
->
dev
);
netif_stop_queue
(
&
idev
->
local
.
dev
);
}
/*
...
...
@@ -121,57 +123,61 @@ static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp)
* master or slave) is busy. It's busy iff all (master and slave)
* queues are busy
*/
static
__inline__
int
isdn_net_device_busy
(
isdn_net_local
*
lp
)
static
inline
int
isdn_net_device_busy
(
isdn_net_dev
*
idev
)
{
isdn_net_
local
*
nlp
;
isdn_net_
dev
*
nd
;
isdn_net_
dev
*
ndev
;
isdn_net_
local
*
mlp
;
unsigned
long
flags
;
if
(
!
isdn_net_
lp_busy
(
lp
))
if
(
!
isdn_net_
dev_busy
(
idev
))
return
0
;
if
(
lp
->
master
)
nd
=
((
isdn_net_local
*
)
lp
->
master
->
priv
)
->
netdev
;
if
(
idev
->
master
)
mlp
=
idev
->
master
;
else
nd
=
lp
->
netdev
;
mlp
=
&
idev
->
local
;
spin_lock_irqsave
(
&
nd
->
queue_lock
,
flags
);
n
lp
=
lp
->
next
;
while
(
n
lp
!=
lp
)
{
if
(
!
isdn_net_
lp_busy
(
nlp
))
{
spin_unlock_irqrestore
(
&
nd
->
queue_lock
,
flags
);
spin_lock_irqsave
(
&
mlp
->
queue_lock
,
flags
);
n
dev
=
idev
->
next
;
while
(
n
dev
!=
idev
)
{
if
(
!
isdn_net_
dev_busy
(
ndev
))
{
spin_unlock_irqrestore
(
&
mlp
->
queue_lock
,
flags
);
return
0
;
}
n
lp
=
nlp
->
next
;
n
dev
=
ndev
->
next
;
}
spin_unlock_irqrestore
(
&
nd
->
queue_lock
,
flags
);
spin_unlock_irqrestore
(
&
mlp
->
queue_lock
,
flags
);
return
1
;
}
static
__inline__
void
isdn_net_inc_frame_cnt
(
isdn_net_local
*
lp
)
static
inline
void
isdn_net_inc_frame_cnt
(
isdn_net_dev
*
idev
)
{
atomic_inc
(
&
lp
->
frame_cnt
);
if
(
isdn_net_device_busy
(
lp
))
isdn_net_dev
ice_stop_queue
(
lp
);
atomic_inc
(
&
idev
->
frame_cnt
);
if
(
isdn_net_device_busy
(
idev
))
isdn_net_dev
_stop_queue
(
idev
);
}
static
__inline__
void
isdn_net_dec_frame_cnt
(
isdn_net_local
*
lp
)
static
inline
void
isdn_net_dec_frame_cnt
(
isdn_net_dev
*
idev
)
{
atomic_dec
(
&
lp
->
frame_cnt
);
atomic_dec
(
&
idev
->
frame_cnt
);
if
(
!
(
isdn_net_device_busy
(
lp
)))
{
if
(
!
skb_queue_empty
(
&
lp
->
super_tx_queue
))
{
queue_task
(
&
lp
->
tqueue
,
&
tq_immediate
);
if
(
!
(
isdn_net_device_busy
(
idev
)))
{
if
(
!
skb_queue_empty
(
&
idev
->
super_tx_queue
))
{
queue_task
(
&
idev
->
tqueue
,
&
tq_immediate
);
mark_bh
(
IMMEDIATE_BH
);
}
else
{
isdn_net_dev
ice_wake_queue
(
lp
);
isdn_net_dev
_wake_queue
(
idev
);
}
}
}
static
__inline__
void
isdn_net_zero_frame_cnt
(
isdn_net_local
*
lp
)
static
inline
void
isdn_net_zero_frame_cnt
(
isdn_net_dev
*
idev
)
{
atomic_set
(
&
lp
->
frame_cnt
,
0
);
atomic_set
(
&
idev
->
frame_cnt
,
0
);
}
/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just
...
...
@@ -208,7 +214,7 @@ int isdn_net_online(isdn_net_dev *idev)
/* Prototypes */
static
int
isdn_net_force_dial_
lp
(
isdn_net_local
*
);
static
int
isdn_net_force_dial_
idev
(
isdn_net_dev
*
);
static
int
isdn_net_start_xmit
(
struct
sk_buff
*
,
struct
net_device
*
);
static
void
do_dialout
(
isdn_net_local
*
lp
);
static
int
isdn_net_set_encap
(
isdn_net_dev
*
p
,
int
encap
);
...
...
@@ -269,14 +275,14 @@ isdn_net_unbind_channel(isdn_net_local * lp)
if
(
lp
->
ops
->
unbind
)
lp
->
ops
->
unbind
(
lp
);
skb_queue_purge
(
&
lp
->
super_tx_queue
);
skb_queue_purge
(
&
idev
->
super_tx_queue
);
if
(
!
lp
->
master
)
{
/* reset only master device */
if
(
!
idev
->
master
)
{
/* reset only master device */
/* Moral equivalent of dev_purge_queues():
BEWARE! This chunk of code cannot be called from hardware
interrupt handler. I hope it is true. --ANK
*/
qdisc_reset
(
lp
->
netdev
->
dev
.
qdisc
);
qdisc_reset
(
lp
->
dev
.
qdisc
);
}
idev
->
dialstate
=
ST_NULL
;
if
(
idev
->
isdn_slot
>=
0
)
{
...
...
@@ -376,23 +382,23 @@ static void isdn_net_hup_timer(unsigned long data)
mod_timer
(
&
idev
->
hup_timer
,
idev
->
hup_timer
.
expires
+
HZ
);
}
static
void
isdn_net_lp_disconnected
(
isdn_net_
local
*
lp
)
static
void
isdn_net_lp_disconnected
(
isdn_net_
dev
*
idev
)
{
isdn_net_rm_from_bundle
(
lp
);
isdn_net_rm_from_bundle
(
idev
);
}
static
void
isdn_net_connected
(
isdn_net_
local
*
lp
)
static
void
isdn_net_connected
(
isdn_net_
dev
*
idev
)
{
isdn_net_
dev
*
idev
=
lp
->
netdev
;
isdn_net_
local
*
lp
=
&
idev
->
local
;
idev
->
dialstate
=
ST_ACTIVE
;
idev
->
hup_timer
.
expires
=
jiffies
+
HZ
;
add_timer
(
&
idev
->
hup_timer
);
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
);
if
(
idev
->
master
)
{
/* is lp a slave? */
isdn_net_
local
*
mlp
=
idev
->
master
;
isdn_net_add_to_bundle
(
mlp
,
idev
);
}
}
printk
(
KERN_INFO
"isdn_net: %s connected
\n
"
,
idev
->
name
);
...
...
@@ -412,7 +418,7 @@ static void isdn_net_connected(isdn_net_local *lp)
if
(
lp
->
ops
->
connected
)
lp
->
ops
->
connected
(
lp
);
else
isdn_net_dev
ice_wake_queue
(
lp
);
isdn_net_dev
_wake_queue
(
idev
);
}
/*
...
...
@@ -562,7 +568,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
switch
(
pr
)
{
case
ISDN_STAT_BSENT
:
/* A packet has successfully been sent out */
isdn_net_dec_frame_cnt
(
lp
);
isdn_net_dec_frame_cnt
(
idev
);
lp
->
stats
.
tx_packets
++
;
lp
->
stats
.
tx_bytes
+=
c
->
parm
.
length
;
return
1
;
...
...
@@ -570,7 +576,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
if
(
lp
->
ops
->
disconnected
)
lp
->
ops
->
disconnected
(
lp
);
isdn_net_lp_disconnected
(
lp
);
isdn_net_lp_disconnected
(
idev
);
isdn_slot_all_eaz
(
idev
->
isdn_slot
);
printk
(
KERN_INFO
"%s: remote hangup
\n
"
,
idev
->
name
);
printk
(
KERN_INFO
"%s: Chargesum is %d
\n
"
,
idev
->
name
,
...
...
@@ -637,7 +643,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
case
ISDN_STAT_BCONN
:
del_timer
(
&
idev
->
dial_timer
);
isdn_slot_set_usage
(
idev
->
isdn_slot
,
isdn_slot_usage
(
idev
->
isdn_slot
)
|
ISDN_USAGE_OUTGOING
);
isdn_net_connected
(
lp
);
isdn_net_connected
(
idev
);
return
1
;
case
ISDN_STAT_DHUP
:
del_timer
(
&
idev
->
dial_timer
);
...
...
@@ -676,7 +682,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
case
ISDN_STAT_BCONN
:
del_timer
(
&
idev
->
dial_timer
);
isdn_slot_set_rx_netdev
(
idev
->
isdn_slot
,
idev
);
isdn_net_connected
(
lp
);
isdn_net_connected
(
idev
);
return
1
;
case
ISDN_STAT_DHUP
:
del_timer
(
&
idev
->
dial_timer
);
...
...
@@ -716,21 +722,20 @@ isdn_net_hangup(isdn_net_dev *idev)
return
;
// FIXME ugly and recursive
if
(
lp
->
slave
!=
NULL
)
{
isdn_net_local
*
slp
=
(
isdn_net_local
*
)
lp
->
slave
->
priv
;
isdn_net_dev
*
sidev
=
slp
->
netdev
;
if
(
isdn_net_bound
(
sidev
))
{
if
(
idev
->
slave
)
{
isdn_net_dev
*
sdev
=
idev
->
slave
;
if
(
isdn_net_bound
(
sdev
))
{
printk
(
KERN_INFO
"isdn_net: hang up slave %s before %s
\n
"
,
s
i
dev
->
name
,
idev
->
name
);
isdn_net_hangup
(
s
i
dev
);
sdev
->
name
,
idev
->
name
);
isdn_net_hangup
(
sdev
);
}
}
printk
(
KERN_INFO
"isdn_net: local hangup %s
\n
"
,
idev
->
name
);
if
(
lp
->
ops
->
disconnected
)
lp
->
ops
->
disconnected
(
lp
);
isdn_net_lp_disconnected
(
lp
);
isdn_net_lp_disconnected
(
idev
);
isdn_slot_command
(
idev
->
isdn_slot
,
ISDN_CMD_HANGUP
,
&
cmd
);
printk
(
KERN_INFO
"%s: Chargesum is %d
\n
"
,
idev
->
name
,
idev
->
charge
);
...
...
@@ -846,24 +851,25 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
* not received from the network layer, but e.g. frames from ipppd, CCP
* reset frames etc.
*/
void
isdn_net_write_super
(
isdn_net_local
*
lp
,
struct
sk_buff
*
skb
)
void
isdn_net_write_super
(
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
if
(
in_irq
())
{
// we can't grab the lock from irq context,
// so we just queue the packet
skb_queue_tail
(
&
lp
->
super_tx_queue
,
skb
);
queue_task
(
&
lp
->
tqueue
,
&
tq_immediate
);
skb_queue_tail
(
&
idev
->
super_tx_queue
,
skb
);
queue_task
(
&
idev
->
tqueue
,
&
tq_immediate
);
mark_bh
(
IMMEDIATE_BH
);
return
;
}
spin_lock_bh
(
&
lp
->
xmit_lock
);
if
(
!
isdn_net_
lp_busy
(
lp
))
{
isdn_net_writebuf_skb
(
lp
,
skb
);
spin_lock_bh
(
&
idev
->
xmit_lock
);
if
(
!
isdn_net_
dev_busy
(
idev
))
{
isdn_net_writebuf_skb
(
idev
,
skb
);
}
else
{
skb_queue_tail
(
&
lp
->
super_tx_queue
,
skb
);
skb_queue_tail
(
&
idev
->
super_tx_queue
,
skb
);
}
spin_unlock_bh
(
&
lp
->
xmit_lock
);
spin_unlock_bh
(
&
idev
->
xmit_lock
);
}
/*
...
...
@@ -871,32 +877,32 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
*/
static
void
isdn_net_softint
(
void
*
private
)
{
isdn_net_
local
*
lp
=
private
;
isdn_net_
dev
*
idev
=
private
;
struct
sk_buff
*
skb
;
spin_lock_bh
(
&
lp
->
xmit_lock
);
while
(
!
isdn_net_
lp_busy
(
lp
))
{
skb
=
skb_dequeue
(
&
lp
->
super_tx_queue
);
spin_lock_bh
(
&
idev
->
xmit_lock
);
while
(
!
isdn_net_
dev_busy
(
idev
))
{
skb
=
skb_dequeue
(
&
idev
->
super_tx_queue
);
if
(
!
skb
)
break
;
isdn_net_writebuf_skb
(
lp
,
skb
);
isdn_net_writebuf_skb
(
idev
,
skb
);
}
spin_unlock_bh
(
&
lp
->
xmit_lock
);
spin_unlock_bh
(
&
idev
->
xmit_lock
);
}
/*
* all frames sent from the (net) LL to a HL driver should go via this function
* it's serialized by the caller holding the
lp
->xmit_lock spinlock
* it's serialized by the caller holding the
idev
->xmit_lock spinlock
*/
void
isdn_net_writebuf_skb
(
isdn_net_
local
*
lp
,
struct
sk_buff
*
skb
)
void
isdn_net_writebuf_skb
(
isdn_net_
dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_
dev
*
idev
=
lp
->
netdev
;
isdn_net_
local
*
lp
=
&
idev
->
local
;
int
ret
;
int
len
=
skb
->
len
;
/* save len */
/* before obtaining the lock the caller should have checked that
the lp isn't busy */
if
(
isdn_net_
lp_busy
(
lp
))
{
if
(
isdn_net_
dev_busy
(
idev
))
{
isdn_BUG
();
goto
error
;
}
...
...
@@ -913,7 +919,7 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
}
idev
->
transcount
+=
len
;
isdn_net_inc_frame_cnt
(
lp
);
isdn_net_inc_frame_cnt
(
idev
);
return
;
error:
...
...
@@ -936,34 +942,29 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
static
int
isdn_net_xmit
(
struct
net_device
*
ndev
,
struct
sk_buff
*
skb
)
{
isdn_net_
dev
*
nd
,
*
idev
;
isdn_net_
local
*
slp
;
isdn_net_
local
*
mlp
;
isdn_net_
dev
*
sdev
;
isdn_net_local
*
lp
=
ndev
->
priv
;
isdn_net_dev
*
idev
=
lp
->
netdev
;
int
retv
=
0
;
if
(
lp
->
master
)
{
isdn_BUG
();
dev_kfree_skb
(
skb
);
return
0
;
}
/* For the other encaps the header has already been built */
if
(
lp
->
p_encap
==
ISDN_NET_ENCAP_SYNCPPP
)
{
return
isdn_ppp_xmit
(
skb
,
ndev
);
}
nd
=
((
isdn_net_local
*
)
ndev
->
priv
)
->
netde
v
;
lp
=
isdn_net_get_locked_lp
(
nd
);
if
(
!
lp
)
{
mlp
=
ndev
->
pri
v
;
idev
=
isdn_net_get_locked_dev
(
mlp
);
if
(
!
idev
)
{
printk
(
KERN_WARNING
"%s: all channels busy - requeuing!
\n
"
,
ndev
->
name
);
return
1
;
}
idev
=
lp
->
netdev
;
/* we have our lp locked from now on */
/* we have our idev locked from now on */
lp
=
&
idev
->
local
;
/* Reset hangup-timeout */
idev
->
huptimer
=
0
;
// FIXME?
isdn_net_writebuf_skb
(
lp
,
skb
);
spin_unlock_bh
(
&
lp
->
xmit_lock
);
isdn_net_writebuf_skb
(
idev
,
skb
);
spin_unlock_bh
(
&
idev
->
xmit_lock
);
/* the following stuff is here for backwards compatibility.
* in future, start-up and hangup of slaves (based on current load)
...
...
@@ -979,27 +980,27 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
printk
(
KERN_DEBUG
"%s: %d bogocps
\n
"
,
idev
->
name
,
idev
->
cps
);
if
(
idev
->
cps
>
lp
->
triggercps
)
{
if
(
lp
->
slave
)
{
if
(
!
lp
->
sqfull
)
{
if
(
idev
->
slave
)
{
if
(
!
idev
->
sqfull
)
{
/* First time overload: set timestamp only */
lp
->
sqfull
=
1
;
lp
->
sqfull_stamp
=
jiffies
;
idev
->
sqfull
=
1
;
idev
->
sqfull_stamp
=
jiffies
;
}
else
{
/* subsequent overload: if slavedelay exceeded, start dialing */
if
(
time_after
(
jiffies
,
lp
->
sqfull_stamp
+
lp
->
slavedelay
))
{
s
lp
=
lp
->
slave
->
priv
;
if
(
!
isdn_net_bound
(
s
lp
->
net
dev
))
{
isdn_net_force_dial_
lp
((
isdn_net_local
*
)
lp
->
slave
->
pri
v
);
if
(
time_after
(
jiffies
,
idev
->
sqfull_stamp
+
lp
->
slavedelay
))
{
s
dev
=
idev
->
slave
;
if
(
!
isdn_net_bound
(
sdev
))
{
isdn_net_force_dial_
idev
(
sde
v
);
}
}
}
}
}
else
{
if
(
lp
->
sqfull
&&
time_after
(
jiffies
,
lp
->
sqfull_stamp
+
lp
->
slavedelay
+
(
10
*
HZ
)
))
{
lp
->
sqfull
=
0
;
if
(
idev
->
sqfull
&&
time_after
(
jiffies
,
idev
->
sqfull_stamp
+
lp
->
slavedelay
+
10
*
HZ
))
{
idev
->
sqfull
=
0
;
}
/* this is a hack to allow auto-hangup for slaves on moderate loads */
nd
->
queue
=
&
nd
->
local
;
mlp
->
queue
=
mlp
->
netdev
;
}
return
retv
;
...
...
@@ -1053,7 +1054,7 @@ isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev)
idev
->
dialwait_timer
=
0
;
}
if
(
isdn_net_force_dial_
lp
(
lp
)
<
0
)
if
(
isdn_net_force_dial_
idev
(
idev
)
<
0
)
goto
discard
;
/* Log packet, which triggered dialing */
...
...
@@ -1113,18 +1114,19 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static
int
isdn_net_close
(
struct
net_device
*
dev
)
{
struct
net_device
*
p
;
isdn_net_local
*
lp
=
dev
->
priv
;
isdn_net_dev
*
idev
=
lp
->
netdev
;
isdn_net_dev
*
sdev
;
if
(
lp
->
ops
->
close
)
lp
->
ops
->
close
(
lp
);
netif_stop_queue
(
dev
);
for
(
p
=
lp
->
slave
;
p
;
p
=
((
isdn_net_local
*
)
p
->
priv
)
->
slave
)
isdn_net_hangup
(
p
->
pri
v
);
for
(
sdev
=
idev
->
slave
;
sdev
;
sdev
=
sdev
->
slave
)
isdn_net_hangup
(
sde
v
);
isdn_net_hangup
(
dev
->
pri
v
);
isdn_net_hangup
(
ide
v
);
isdn_MOD_DEC_USE_COUNT
();
return
0
;
}
...
...
@@ -1143,31 +1145,29 @@ isdn_net_get_stats(struct net_device *dev)
* Got a packet from ISDN-Channel.
*/
static
void
isdn_net_receive
(
struct
net_device
*
n
dev
,
struct
sk_buff
*
skb
)
isdn_net_receive
(
isdn_net_dev
*
i
dev
,
struct
sk_buff
*
skb
)
{
isdn_net_local
*
lp
=
(
isdn_net_local
*
)
ndev
->
priv
;
isdn_net_dev
*
idev
=
lp
->
netdev
;
isdn_net_local
*
olp
=
lp
;
/* original 'lp' */
isdn_net_local
*
lp
;
struct
net_device
*
ndev
;
idev
->
transcount
+=
skb
->
len
;
lp
->
stats
.
rx_packets
++
;
lp
->
stats
.
rx_bytes
+=
skb
->
len
;
if
(
lp
->
master
)
{
if
(
idev
->
master
)
{
/* Bundling: If device is a slave-device, deliver to master, also
* handle master's statistics and hangup-timeout
*/
ndev
=
lp
->
master
;
lp
=
(
isdn_net_local
*
)
ndev
->
priv
;
lp
->
stats
.
rx_packets
++
;
lp
->
stats
.
rx_bytes
+=
skb
->
len
;
ndev
=
&
idev
->
master
->
dev
;
}
else
{
ndev
=
&
idev
->
local
.
dev
;
}
lp
=
ndev
->
priv
;
lp
->
stats
.
rx_packets
++
;
lp
->
stats
.
rx_bytes
+=
skb
->
len
;
skb
->
dev
=
ndev
;
skb
->
pkt_type
=
PACKET_HOST
;
skb
->
mac
.
raw
=
skb
->
data
;
isdn_dumppkt
(
"R:"
,
skb
->
data
,
skb
->
len
,
40
);
lp
->
ops
->
receive
(
lp
->
netdev
,
olp
,
skb
);
lp
->
ops
->
receive
(
lp
,
idev
,
skb
);
}
/*
...
...
@@ -1186,7 +1186,7 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb)
if
(
!
isdn_net_online
(
idev
))
return
0
;
isdn_net_receive
(
&
idev
->
dev
,
skb
);
isdn_net_receive
(
i
dev
,
skb
);
return
0
;
}
...
...
@@ -1394,23 +1394,23 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
/* Interface is up, now see if it's a slave. If so, see if
* it's master and parent slave is online. If not, reject the call.
*/
if
(
lp
->
master
)
{
isdn_net_
local
*
mlp
=
(
isdn_net_local
*
)
lp
->
master
->
pri
v
;
if
(
idev
->
master
)
{
isdn_net_
dev
*
pdev
=
idev
->
master
->
netde
v
;
printk
(
KERN_DEBUG
"ICALLslv: %s
\n
"
,
idev
->
name
);
printk
(
KERN_DEBUG
"master=%s
\n
"
,
mlp
->
net
dev
->
name
);
if
(
isdn_net_bound
(
mlp
->
net
dev
))
{
printk
(
KERN_DEBUG
"master=%s
\n
"
,
p
dev
->
name
);
if
(
isdn_net_bound
(
p
dev
))
{
printk
(
KERN_DEBUG
"master online
\n
"
);
/* Master is online, find parent-slave (master if first slave) */
while
(
mlp
->
slave
)
{
if
(
(
isdn_net_local
*
)
mlp
->
slave
->
priv
==
lp
)
while
(
pdev
->
slave
)
{
if
(
pdev
->
slave
==
idev
)
break
;
mlp
=
(
isdn_net_local
*
)
mlp
->
slave
->
priv
;
pdev
=
pdev
->
slave
;
}
}
else
printk
(
KERN_DEBUG
"master offline
\n
"
);
/* Found parent, if it's offline iterate next device */
printk
(
KERN_DEBUG
"mlpf: %d
\n
"
,
isdn_net_bound
(
mlp
->
net
dev
));
if
(
!
isdn_net_bound
(
mlp
->
net
dev
))
{
printk
(
KERN_DEBUG
"mlpf: %d
\n
"
,
isdn_net_bound
(
p
dev
));
if
(
!
isdn_net_bound
(
p
dev
))
{
continue
;
}
}
...
...
@@ -1474,11 +1474,11 @@ isdn_net_findif(char *name)
* from isdn_net_start_xmit().
*/
static
int
isdn_net_force_dial_
lp
(
isdn_net_local
*
lp
)
isdn_net_force_dial_
idev
(
isdn_net_dev
*
idev
)
{
isdn_net_dev
*
idev
=
lp
->
netdev
;
int
slot
;
unsigned
long
flags
;
isdn_net_local
*
lp
=
&
idev
->
local
;
if
(
isdn_net_bound
(
idev
))
return
-
EBUSY
;
...
...
@@ -1515,12 +1515,13 @@ isdn_net_force_dial_lp(isdn_net_local *lp)
* themselves.
*/
int
isdn_net_dial_req
(
isdn_net_
local
*
lp
)
isdn_net_dial_req
(
isdn_net_
dev
*
idev
)
{
isdn_net_local
*
lp
=
&
idev
->
local
;
/* is there a better error code? */
if
(
!
(
ISDN_NET_DIALMODE
(
*
lp
)
==
ISDN_NET_DM_AUTO
))
return
-
EBUSY
;
return
isdn_net_force_dial_
lp
(
lp
);
return
isdn_net_force_dial_
idev
(
idev
);
}
/*
...
...
@@ -1534,7 +1535,8 @@ isdn_net_force_dial(char *name)
if
(
!
p
)
return
-
ENODEV
;
return
(
isdn_net_force_dial_lp
(
&
p
->
local
));
return
isdn_net_force_dial_idev
(
p
);
}
/*
...
...
@@ -1544,6 +1546,7 @@ int
isdn_net_new
(
char
*
name
,
struct
net_device
*
master
)
{
int
retval
;
isdn_net_local
*
mlp
=
master
->
priv
;
isdn_net_dev
*
netdev
;
/* Avoid creating an existing interface */
...
...
@@ -1557,29 +1560,25 @@ isdn_net_new(char *name, struct net_device *master)
}
memset
(
netdev
,
0
,
sizeof
(
isdn_net_dev
));
strcpy
(
netdev
->
name
,
name
);
strcpy
(
netdev
->
dev
.
name
,
name
);
netdev
->
dev
.
priv
=
&
netdev
->
local
;
netdev
->
dev
.
init
=
isdn_net_init
;
strcpy
(
netdev
->
local
.
dev
.
name
,
name
);
netdev
->
local
.
dev
.
priv
=
&
netdev
->
local
;
netdev
->
local
.
dev
.
init
=
isdn_net_init
;
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
;
/* Put device at end of slave-chain */
while
(
p
)
{
q
=
p
;
p
=
(((
isdn_net_local
*
)
p
->
priv
)
->
slave
);
}
((
isdn_net_local
*
)
q
->
priv
)
->
slave
=
&
(
netdev
->
dev
);
isdn_net_dev
*
p
=
mlp
->
netdev
;
while
(
p
->
slave
)
p
=
p
->
slave
;
p
->
slave
=
netdev
;
}
else
{
/* Device shall be a master */
/*
* Watchdog timer (currently) for master only.
*/
netdev
->
dev
.
tx_timeout
=
isdn_net_tx_timeout
;
netdev
->
dev
.
watchdog_timeo
=
ISDN_NET_TX_TIMEOUT
;
retval
=
register_netdev
(
&
netdev
->
dev
);
netdev
->
local
.
dev
.
tx_timeout
=
isdn_net_tx_timeout
;
netdev
->
local
.
dev
.
watchdog_timeo
=
ISDN_NET_TX_TIMEOUT
;
retval
=
register_netdev
(
&
netdev
->
local
.
dev
);
if
(
retval
)
{
printk
(
KERN_WARNING
"isdn_net: Could not register net-device
\n
"
);
kfree
(
netdev
);
...
...
@@ -1588,17 +1587,17 @@ isdn_net_new(char *name, struct net_device *master)
}
netdev
->
local
.
magic
=
ISDN_NET_MAGIC
;
netdev
->
queue
=
&
netdev
->
local
;
spin_lock_init
(
&
netdev
->
queue_lock
);
netdev
->
local
.
queue
=
netdev
;
spin_lock_init
(
&
netdev
->
local
.
queue_lock
);
netdev
->
local
.
last
=
&
netdev
->
local
;
netdev
->
last
=
netdev
;
netdev
->
next
=
netdev
;
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
->
tqueue
.
sync
=
0
;
netdev
->
tqueue
.
routine
=
isdn_net_softint
;
netdev
->
tqueue
.
data
=
netdev
;
spin_lock_init
(
&
netdev
->
xmit_lock
);
netdev
->
isdn_slot
=
-
1
;
netdev
->
pre_device
=
-
1
;
...
...
@@ -1609,7 +1608,7 @@ isdn_net_new(char *name, struct net_device *master)
netdev
->
pppbind
=
-
1
;
netdev
->
local
.
p_encap
=
-
1
;
skb_queue_head_init
(
&
netdev
->
local
.
super_tx_queue
);
skb_queue_head_init
(
&
netdev
->
super_tx_queue
);
netdev
->
local
.
l2_proto
=
ISDN_PROTO_L2_X75I
;
netdev
->
local
.
l3_proto
=
ISDN_PROTO_L3_TRANS
;
netdev
->
local
.
triggercps
=
6000
;
...
...
@@ -1656,19 +1655,19 @@ isdn_net_newslave(char *parm)
if
(
!
(
m
=
isdn_net_findif
(
parm
)))
return
-
ESRCH
;
/* Master must be a real interface, not a slave */
if
(
m
->
local
.
master
)
if
(
m
->
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
);
return
isdn_net_new
(
p
+
1
,
&
m
->
local
.
dev
);
}
static
int
isdn_net_set_encap
(
isdn_net_dev
*
p
,
int
encap
)
isdn_net_set_encap
(
isdn_net_dev
*
idev
,
int
encap
)
{
isdn_net_local
*
lp
=
&
p
->
local
;
isdn_net_local
*
lp
=
&
idev
->
local
;
int
retval
=
0
;
if
(
lp
->
p_encap
==
encap
){
...
...
@@ -1676,7 +1675,7 @@ isdn_net_set_encap(isdn_net_dev *p, int encap)
retval
=
0
;
goto
out
;
}
if
(
isdn_net_device_started
(
p
))
{
if
(
isdn_net_device_started
(
idev
))
{
retval
=
-
EBUSY
;
goto
out
;
}
...
...
@@ -1693,11 +1692,11 @@ isdn_net_set_encap(isdn_net_dev *p, int encap)
lp
->
p_encap
=
encap
;
lp
->
ops
=
netif_ops
[
encap
];
p
->
dev
.
hard_header
=
lp
->
ops
->
hard_header
;
p
->
dev
.
do_ioctl
=
lp
->
ops
->
do_ioctl
;
p
->
dev
.
flags
=
lp
->
ops
->
flags
;
p
->
dev
.
type
=
lp
->
ops
->
type
;
p
->
dev
.
addr_len
=
lp
->
ops
->
addr_len
;
l
p
->
dev
.
hard_header
=
lp
->
ops
->
hard_header
;
l
p
->
dev
.
do_ioctl
=
lp
->
ops
->
do_ioctl
;
l
p
->
dev
.
flags
=
lp
->
ops
->
flags
;
l
p
->
dev
.
type
=
lp
->
ops
->
type
;
l
p
->
dev
.
addr_len
=
lp
->
ops
->
addr_len
;
if
(
lp
->
ops
->
init
)
retval
=
lp
->
ops
->
init
(
lp
);
...
...
@@ -1928,12 +1927,12 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
cfg
->
pppbind
=
idev
->
pppbind
;
cfg
->
dialtimeout
=
lp
->
dialtimeout
>=
0
?
lp
->
dialtimeout
/
HZ
:
-
1
;
cfg
->
dialwait
=
lp
->
dialwait
/
HZ
;
if
(
lp
->
slave
)
strcpy
(
cfg
->
slave
,
((
isdn_net_local
*
)
lp
->
slave
->
priv
)
->
netdev
->
name
);
if
(
idev
->
slave
)
strcpy
(
cfg
->
slave
,
idev
->
slave
->
name
);
else
cfg
->
slave
[
0
]
=
'\0'
;
if
(
lp
->
master
)
strcpy
(
cfg
->
master
,
((
isdn_net_local
*
)
lp
->
master
->
priv
)
->
netdev
->
name
);
if
(
idev
->
master
)
strcpy
(
cfg
->
master
,
idev
->
master
->
netdev
->
name
);
else
cfg
->
master
[
0
]
=
'\0'
;
...
...
@@ -2090,7 +2089,7 @@ int
isdn_net_force_hangup
(
char
*
name
)
{
isdn_net_dev
*
idev
=
isdn_net_findif
(
name
);
struct
net_device
*
q
;
isdn_net_dev
*
p
;
if
(
!
idev
)
return
-
ENODEV
;
...
...
@@ -2098,11 +2097,11 @@ isdn_net_force_hangup(char *name)
if
(
idev
->
isdn_slot
<
0
)
return
-
ENOTCONN
;
q
=
idev
->
local
.
slave
;
p
=
idev
->
slave
;
/* If this interface has slaves, do a hangup for them also. */
while
(
q
)
{
isdn_net_hangup
(
((
isdn_net_local
*
)
q
->
priv
)
->
netdev
);
q
=
(((
isdn_net_local
*
)
q
->
priv
)
->
slave
)
;
while
(
p
)
{
isdn_net_hangup
(
p
);
p
=
p
->
slave
;
}
isdn_net_hangup
(
idev
);
return
0
;
...
...
@@ -2129,19 +2128,19 @@ isdn_net_realrm(isdn_net_dev *p)
/* If interface is bound exclusive, free channel-usage */
if
(
p
->
exclusive
>=
0
)
isdn_unexclusive_channel
(
p
->
pre_device
,
p
->
pre_channel
);
if
(
p
->
local
.
master
)
{
if
(
p
->
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
(
p
->
master
->
netdev
->
slave
==
p
)
p
->
master
->
netdev
->
slave
=
p
->
slave
;
}
else
{
/* Unregister only if it's a master-device */
unregister_netdev
(
&
p
->
dev
);
unregister_netdev
(
&
p
->
local
.
dev
);
}
/* Unlink device from chain */
list_del
(
&
p
->
global_list
);
if
(
p
->
local
.
slave
)
{
if
(
p
->
slave
)
{
/* If this interface has a slave, remove it also */
char
*
slavename
=
((
isdn_net_local
*
)
(
p
->
local
.
slave
->
priv
))
->
netdev
->
name
;
char
*
slavename
=
p
->
slave
->
name
;
struct
list_head
*
l
;
list_for_each
(
l
,
&
isdn_net_devs
)
{
...
...
@@ -2191,7 +2190,7 @@ isdn_net_rmall(void)
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
(
!
p
->
master
)
{
if
((
ret
=
isdn_net_realrm
(
p
)))
{
restore_flags
(
flags
);
return
ret
;
...
...
@@ -2216,10 +2215,10 @@ isdn_iptyp_header(struct sk_buff *skb, struct net_device *dev,
}
static
void
isdn_iptyp_receive
(
isdn_net_
dev
*
p
,
isdn_net_local
*
olp
,
isdn_iptyp_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_reset_huptimer
(
p
,
olp
->
net
dev
);
isdn_net_reset_huptimer
(
lp
,
i
dev
);
get_u16
(
skb
->
data
,
&
skb
->
protocol
);
skb_pull
(
skb
,
2
);
netif_rx
(
skb
);
...
...
@@ -2247,10 +2246,10 @@ isdn_uihdlc_header(struct sk_buff *skb, struct net_device *dev,
}
static
void
isdn_uihdlc_receive
(
isdn_net_
dev
*
p
,
isdn_net_local
*
olp
,
isdn_uihdlc_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_reset_huptimer
(
p
,
olp
->
net
dev
);
isdn_net_reset_huptimer
(
lp
,
i
dev
);
skb_pull
(
skb
,
2
);
skb
->
protocol
=
htons
(
ETH_P_IP
);
netif_rx
(
skb
);
...
...
@@ -2269,10 +2268,10 @@ static struct isdn_netif_ops uihdlc_ops = {
// ======================================================================
static
void
isdn_rawip_receive
(
isdn_net_
dev
*
p
,
isdn_net_local
*
olp
,
isdn_rawip_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_reset_huptimer
(
p
,
olp
->
net
dev
);
isdn_net_reset_huptimer
(
lp
,
i
dev
);
skb
->
protocol
=
htons
(
ETH_P_IP
);
netif_rx
(
skb
);
}
...
...
@@ -2342,10 +2341,10 @@ isdn_eth_type_trans(struct sk_buff *skb, struct net_device *dev)
}
static
void
isdn_ether_receive
(
isdn_net_
dev
*
p
,
isdn_net_local
*
olp
,
isdn_ether_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_reset_huptimer
(
p
,
olp
->
net
dev
);
isdn_net_reset_huptimer
(
lp
,
i
dev
);
skb
->
protocol
=
isdn_eth_type_trans
(
skb
,
skb
->
dev
);
netif_rx
(
skb
);
}
...
...
@@ -2353,7 +2352,7 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp,
static
int
isdn_ether_open
(
isdn_net_local
*
lp
)
{
struct
net_device
*
dev
=
&
lp
->
netdev
->
dev
;
struct
net_device
*
dev
=
&
lp
->
dev
;
struct
in_device
*
in_dev
;
int
i
;
...
...
@@ -2373,7 +2372,7 @@ isdn_ether_open(isdn_net_local *lp)
static
int
isdn_ether_init
(
isdn_net_local
*
lp
)
{
struct
net_device
*
dev
=
&
lp
->
netdev
->
dev
;
struct
net_device
*
dev
=
&
lp
->
dev
;
ether_setup
(
dev
);
dev
->
tx_queue_len
=
10
;
...
...
drivers/isdn/i4l/isdn_net.h
View file @
b2b109e8
...
...
@@ -52,16 +52,16 @@ extern int isdn_net_force_hangup(char *);
extern
int
isdn_net_force_dial
(
char
*
);
extern
isdn_net_dev
*
isdn_net_findif
(
char
*
);
extern
int
isdn_net_rcv_skb
(
int
,
struct
sk_buff
*
);
extern
int
isdn_net_dial_req
(
isdn_net_
local
*
);
extern
void
isdn_net_writebuf_skb
(
isdn_net_
local
*
lp
,
struct
sk_buff
*
skb
);
extern
void
isdn_net_write_super
(
isdn_net_
local
*
lp
,
struct
sk_buff
*
skb
);
extern
int
isdn_net_online
(
isdn_net_dev
*
idev
);
extern
int
isdn_net_dial_req
(
isdn_net_
dev
*
);
extern
void
isdn_net_writebuf_skb
(
isdn_net_
dev
*
,
struct
sk_buff
*
skb
);
extern
void
isdn_net_write_super
(
isdn_net_
dev
*
,
struct
sk_buff
*
skb
);
extern
int
isdn_net_online
(
isdn_net_dev
*
);
static
inline
void
isdn_net_reset_huptimer
(
isdn_net_
dev
*
idev
,
isdn_net_dev
*
idev2
)
isdn_net_reset_huptimer
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
)
{
lp
->
netdev
->
huptimer
=
0
;
idev
->
huptimer
=
0
;
idev2
->
huptimer
=
0
;
}
#define ISDN_NET_MAX_QUEUE_LENGTH 2
...
...
@@ -69,9 +69,10 @@ isdn_net_reset_huptimer(isdn_net_dev *idev, isdn_net_dev *idev2)
/*
* is this particular channel busy?
*/
static
__inline__
int
isdn_net_lp_busy
(
isdn_net_local
*
lp
)
static
inline
int
isdn_net_dev_busy
(
isdn_net_dev
*
idev
)
{
if
(
atomic_read
(
&
lp
->
frame_cnt
)
<
ISDN_NET_MAX_QUEUE_LENGTH
)
if
(
atomic_read
(
&
idev
->
frame_cnt
)
<
ISDN_NET_MAX_QUEUE_LENGTH
)
return
0
;
else
return
1
;
...
...
@@ -81,86 +82,93 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp)
* For the given net device, this will get a non-busy channel out of the
* corresponding bundle. The returned channel is locked.
*/
static
__inline__
isdn_net_local
*
isdn_net_get_locked_lp
(
isdn_net_dev
*
nd
)
static
inline
isdn_net_dev
*
isdn_net_get_locked_dev
(
isdn_net_local
*
mlp
)
{
unsigned
long
flags
;
isdn_net_local
*
lp
;
spin_lock_irqsave
(
&
nd
->
queue_lock
,
flags
);
lp
=
nd
->
queue
;
/* get lp on top of queue */
spin_lock_bh
(
&
nd
->
queue
->
xmit_lock
);
while
(
isdn_net_lp_busy
(
nd
->
queue
))
{
spin_unlock_bh
(
&
nd
->
queue
->
xmit_lock
);
nd
->
queue
=
nd
->
queue
->
next
;
if
(
nd
->
queue
==
lp
)
{
/* not found -- should never happen */
lp
=
NULL
;
isdn_net_dev
*
idev
;
isdn_net_dev
*
head
;
spin_lock_irqsave
(
&
mlp
->
queue_lock
,
flags
);
head
=
mlp
->
queue
;
idev
=
head
;
spin_lock_bh
(
&
idev
->
xmit_lock
);
while
(
isdn_net_dev_busy
(
idev
))
{
spin_unlock_bh
(
&
idev
->
xmit_lock
);
mlp
->
queue
=
mlp
->
queue
->
next
;
idev
=
mlp
->
queue
;
if
(
idev
==
head
)
{
/* not found -- should never happen */
idev
=
NULL
;
goto
errout
;
}
spin_lock_bh
(
&
nd
->
queue
->
xmit_lock
);
spin_lock_bh
(
&
idev
->
xmit_lock
);
}
lp
=
nd
->
queue
;
nd
->
queue
=
nd
->
queue
->
next
;
idev
=
mlp
->
queue
;
mlp
->
queue
=
mlp
->
queue
->
next
;
errout:
spin_unlock_irqrestore
(
&
nd
->
queue_lock
,
flags
);
return
lp
;
spin_unlock_irqrestore
(
&
mlp
->
queue_lock
,
flags
);
return
idev
;
}
/*
* add a channel to a bundle
*/
static
__inline__
void
isdn_net_add_to_bundle
(
isdn_net_dev
*
nd
,
isdn_net_local
*
nlp
)
static
inline
void
isdn_net_add_to_bundle
(
isdn_net_local
*
mlp
,
isdn_net_dev
*
idev
)
{
isdn_net_
local
*
lp
;
isdn_net_
dev
*
qdev
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
nd
->
queue_lock
,
flags
);
spin_lock_irqsave
(
&
mlp
->
queue_lock
,
flags
);
lp
=
nd
->
queue
;
nlp
->
last
=
lp
->
last
;
lp
->
last
->
next
=
nlp
;
lp
->
last
=
nlp
;
nlp
->
next
=
lp
;
nd
->
queue
=
nlp
;
qdev
=
mlp
->
queue
;
idev
->
last
=
qdev
->
last
;
qdev
->
last
->
next
=
idev
;
qdev
->
last
=
idev
;
idev
->
next
=
qdev
;
mlp
->
queue
=
idev
;
spin_unlock_irqrestore
(
&
nd
->
queue_lock
,
flags
);
spin_unlock_irqrestore
(
&
mlp
->
queue_lock
,
flags
);
}
/*
* remove a channel from the bundle it belongs to
*/
static
__inline__
void
isdn_net_rm_from_bundle
(
isdn_net_local
*
lp
)
static
inline
void
isdn_net_rm_from_bundle
(
isdn_net_dev
*
idev
)
{
isdn_net_local
*
m
aster_lp
=
lp
;
isdn_net_local
*
mlp
;
unsigned
long
flags
;
if
(
lp
->
master
)
master_lp
=
(
isdn_net_local
*
)
lp
->
master
->
priv
;
if
(
idev
->
master
)
mlp
=
idev
->
master
;
else
mlp
=
&
idev
->
local
;
spin_lock_irqsave
(
&
master_lp
->
netdev
->
queue_lock
,
flags
);
lp
->
last
->
next
=
lp
->
next
;
lp
->
next
->
last
=
lp
->
last
;
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
;
}
spin_lock_irqsave
(
&
mlp
->
queue_lock
,
flags
);
idev
->
last
->
next
=
idev
->
next
;
idev
->
next
->
last
=
idev
->
last
;
if
(
mlp
->
queue
==
idev
)
{
mlp
->
queue
=
idev
->
next
;
}
lp
->
next
=
lp
->
last
=
lp
;
/* (re)set own pointers */
spin_unlock_irqrestore
(
&
m
aster_lp
->
netdev
->
queue_lock
,
flags
);
idev
->
next
=
idev
->
last
=
idev
;
/* (re)set own pointers */
spin_unlock_irqrestore
(
&
m
lp
->
queue_lock
,
flags
);
}
/*
* wake up the network -> net_device queue.
* For slaves, wake the corresponding master interface.
*/
static
inline
void
isdn_net_device_wake_queue
(
isdn_net_local
*
lp
)
static
inline
void
isdn_net_dev_wake_queue
(
isdn_net_dev
*
idev
)
{
if
(
lp
->
master
)
netif_wake_queue
(
lp
->
master
);
if
(
idev
->
master
)
netif_wake_queue
(
&
idev
->
master
->
dev
);
else
netif_wake_queue
(
&
lp
->
netdev
->
dev
);
netif_wake_queue
(
&
idev
->
local
.
dev
);
}
static
inline
int
isdn_net_bound
(
isdn_net_dev
*
idev
)
static
inline
int
isdn_net_bound
(
isdn_net_dev
*
idev
)
{
return
idev
->
isdn_slot
>=
0
;
}
...
...
drivers/isdn/i4l/isdn_ppp.c
View file @
b2b109e8
...
...
@@ -23,7 +23,7 @@
/* Prototypes */
static
int
isdn_ppp_fill_rq
(
unsigned
char
*
buf
,
int
len
,
int
proto
,
int
slot
);
static
int
isdn_ppp_closewait
(
int
slot
);
static
void
isdn_ppp_push_higher
(
isdn_net_
dev
*
net_dev
,
isdn_net_local
*
lp
,
static
void
isdn_ppp_push_higher
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
,
int
proto
);
static
int
isdn_ppp_if_get_unit
(
char
*
namebuf
);
static
int
isdn_ppp_set_compressor
(
struct
ippp_struct
*
is
,
struct
isdn_ppp_comp_data
*
);
...
...
@@ -59,10 +59,10 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
static
ippp_bundle
*
isdn_ppp_bundle_arr
=
NULL
;
static
int
isdn_ppp_mp_bundle_array_init
(
void
);
static
int
isdn_ppp_mp_init
(
isdn_net_local
*
lp
,
ippp_bundle
*
add_to
);
static
void
isdn_ppp_mp_receive
(
isdn_net_
dev
*
net_dev
,
isdn_net_local
*
lp
,
struct
sk_buff
*
skb
);
static
void
isdn_ppp_mp_cleanup
(
isdn_net_local
*
lp
);
static
int
isdn_ppp_mp_init
(
isdn_net_local
*
lp
,
ippp_bundle
*
add_to
);
static
void
isdn_ppp_mp_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
);
static
void
isdn_ppp_mp_cleanup
(
isdn_net_local
*
lp
);
static
int
isdn_ppp_bundle
(
struct
ippp_struct
*
,
int
unit
);
#endif
/* CONFIG_ISDN_MPP */
...
...
@@ -118,7 +118,7 @@ isdn_ppp_free(isdn_net_local * lp)
#ifdef CONFIG_ISDN_MPP
spin_lock
(
&
lp
->
netdev
->
pb
->
lock
);
#endif
isdn_net_rm_from_bundle
(
lp
);
isdn_net_rm_from_bundle
(
idev
);
#ifdef CONFIG_ISDN_MPP
if
(
lp
->
netdev
->
pb
->
ref_ct
==
1
)
/* last link in queue? */
isdn_ppp_mp_cleanup
(
lp
);
...
...
@@ -314,8 +314,6 @@ isdn_ppp_open(struct inode *ino, struct file *file)
is
->
maxcid
=
16
;
/* VJ: maxcid */
is
->
tk
=
current
;
init_waitqueue_head
(
&
is
->
wq
);
is
->
first
=
is
->
rq
+
NUM_RCV_BUFFS
-
1
;
/* receive queue */
is
->
last
=
is
->
rq
;
is
->
minor
=
minor
;
#ifdef CONFIG_ISDN_PPP_VJ
/*
...
...
@@ -337,7 +335,6 @@ static int
isdn_ppp_release
(
struct
inode
*
ino
,
struct
file
*
file
)
{
uint
minor
=
minor
(
ino
->
i_rdev
)
-
ISDN_MINOR_PPP
;
int
i
;
struct
ippp_struct
*
is
;
lock_kernel
();
...
...
@@ -356,14 +353,7 @@ isdn_ppp_release(struct inode *ino, struct file *file)
is
->
state
&=
~
IPPP_CONNECT
;
isdn_net_hangup
(
is
->
idev
);
}
for
(
i
=
0
;
i
<
NUM_RCV_BUFFS
;
i
++
)
{
if
(
is
->
rq
[
i
].
buf
)
{
kfree
(
is
->
rq
[
i
].
buf
);
is
->
rq
[
i
].
buf
=
NULL
;
}
}
is
->
first
=
is
->
rq
+
NUM_RCV_BUFFS
-
1
;
/* receive queue */
is
->
last
=
is
->
rq
;
skb_queue_purge
(
&
is
->
rq
);
#ifdef CONFIG_ISDN_PPP_VJ
/* TODO: if this was the previous master: link the slcomp to the new master */
...
...
@@ -487,7 +477,7 @@ isdn_ppp_ioctl(struct inode *ino, struct file *file, unsigned int cmd, unsigned
if
(
val
&
SC_ENABLE_IP
&&
!
(
is
->
pppcfg
&
SC_ENABLE_IP
)
&&
(
is
->
state
&
IPPP_CONNECT
))
{
if
(
idev
)
{
/* OK .. we are ready to send buffers */
netif_wake_queue
(
&
idev
->
dev
);
netif_wake_queue
(
&
idev
->
local
.
dev
);
}
}
is
->
pppcfg
=
val
;
...
...
@@ -595,12 +585,8 @@ static unsigned int
isdn_ppp_poll
(
struct
file
*
file
,
poll_table
*
wait
)
{
unsigned
int
mask
;
struct
ippp_buf_queue
*
bf
;
struct
ippp_buf_queue
*
bl
;
unsigned
long
flags
;
struct
ippp_struct
*
is
;
lock_kernel
();
is
=
file
->
private_data
;
if
(
is
->
debug
&
0x2
)
...
...
@@ -622,21 +608,15 @@ isdn_ppp_poll(struct file *file, poll_table * wait)
/* we're always ready to send .. */
mask
=
POLLOUT
|
POLLWRNORM
;
save_flags
(
flags
);
cli
();
bl
=
is
->
last
;
bf
=
is
->
first
;
/*
* if IPPP_NOBLOCK is set we return even if we have nothing to read
*/
if
(
bf
->
next
!=
bl
||
(
is
->
state
&
IPPP_NOBLOCK
)
)
{
if
(
!
skb_queue_empty
(
&
is
->
rq
)
||
is
->
state
&
IPPP_NOBLOCK
)
{
is
->
state
&=
~
IPPP_NOBLOCK
;
mask
|=
POLLIN
|
POLLRDNORM
;
}
restore_flags
(
flags
);
out:
unlock_kernel
();
return
mask
;
}
...
...
@@ -647,10 +627,8 @@ isdn_ppp_poll(struct file *file, poll_table * wait)
static
int
isdn_ppp_fill_rq
(
unsigned
char
*
buf
,
int
len
,
int
proto
,
int
slot
)
{
struct
ippp_buf_queue
*
bf
,
*
bl
;
unsigned
long
flags
;
unsigned
char
*
nbuf
;
struct
sk_buff
*
skb
;
unsigned
char
*
p
;
struct
ippp_struct
*
is
;
if
(
slot
<
0
||
slot
>=
ISDN_MAX_CHANNELS
)
{
...
...
@@ -663,36 +641,23 @@ isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
printk
(
KERN_DEBUG
"ippp: device not activated.
\n
"
);
return
0
;
}
nbuf
=
(
unsigned
char
*
)
kmalloc
(
len
+
4
,
GFP_ATOMIC
);
if
(
!
nbuf
)
{
printk
(
KERN_WARNING
"ippp: Can't alloc buf
\n
"
);
if
(
skb_queue_len
(
&
is
->
rq
)
>
IPPP_MAX_RQ_LEN
)
{
printk
(
KERN_WARNING
"ippp: Queue is full
\n
"
);
return
0
;
}
nbuf
[
0
]
=
PPP_ALLSTATIONS
;
nbuf
[
1
]
=
PPP_UI
;
nbuf
[
2
]
=
proto
>>
8
;
nbuf
[
3
]
=
proto
&
0xff
;
memcpy
(
nbuf
+
4
,
buf
,
len
);
save_flags
(
flags
);
cli
();
bf
=
is
->
first
;
bl
=
is
->
last
;
if
(
bf
==
bl
)
{
printk
(
KERN_WARNING
"ippp: Queue is full; discarding first buffer
\n
"
);
bf
=
bf
->
next
;
kfree
(
bf
->
buf
);
is
->
first
=
bf
;
skb
=
dev_alloc_skb
(
len
+
4
);
if
(
!
skb
)
{
printk
(
KERN_WARNING
"ippp: Can't alloc buf
\n
"
);
return
0
;
}
bl
->
buf
=
(
char
*
)
nbuf
;
bl
->
len
=
len
+
4
;
is
->
last
=
bl
->
next
;
restore_flags
(
flags
);
p
=
skb_put
(
skb
,
4
)
;
p
+=
put_u8
(
p
,
PPP_ALLSTATIONS
)
;
p
+=
put_u8
(
p
,
PPP_UI
);
p
+=
put_u16
(
p
,
proto
)
;
memcpy
(
skb_put
(
skb
,
len
),
buf
,
len
);
wake_up_interruptible
(
&
is
->
wq
);
skb_queue_tail
(
&
is
->
rq
,
skb
);
wake_up_interruptible
(
&
is
->
wq
);
return
len
;
}
...
...
@@ -706,54 +671,36 @@ static ssize_t
isdn_ppp_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
off
)
{
struct
ippp_struct
*
is
;
struct
ippp_buf_queue
*
b
;
unsigned
long
flags
;
unsigned
char
*
save_buf
;
struct
sk_buff
*
skb
;
int
retval
;
if
(
off
!=
&
file
->
f_pos
)
return
-
ESPIPE
;
lock_kernel
();
is
=
file
->
private_data
;
if
(
!
(
is
->
state
&
IPPP_OPEN
))
{
retval
=
0
;
goto
out
;
}
retval
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
buf
,
count
);
if
(
retval
)
goto
out
;
save_flags
(
flags
);
cli
();
b
=
is
->
first
->
next
;
save_buf
=
b
->
buf
;
if
(
!
save_buf
)
{
restore_flags
(
flags
);
skb
=
skb_dequeue
(
&
is
->
rq
);
if
(
!
skb
)
{
retval
=
-
EAGAIN
;
goto
out
;
}
if
(
b
->
len
<
count
)
count
=
b
->
len
;
b
->
buf
=
NULL
;
is
->
first
=
b
;
restore_flags
(
flags
);
if
(
copy_to_user
(
buf
,
save_buf
,
count
))
{
kfree
(
save_buf
);
if
(
skb
->
len
>
count
)
{
retval
=
-
EMSGSIZE
;
goto
out_free
;
}
if
(
copy_to_user
(
buf
,
skb
->
data
,
skb
->
len
))
{
retval
=
-
EFAULT
;
goto
out
;
goto
out
_free
;
}
kfree
(
save_buf
);
retval
=
count
;
retval
=
skb
->
len
;
out_free:
dev_kfree_skb
(
skb
);
out:
unlock_kernel
();
return
retval
;
}
...
...
@@ -834,7 +781,7 @@ isdn_ppp_write(struct file *file, const char *buf, size_t count, loff_t *off)
isdn_ppp_send_ccp
(
idev
,
&
idev
->
local
,
skb
);
/* keeps CCP/compression states in sync */
isdn_net_write_super
(
&
idev
->
local
,
skb
);
isdn_net_write_super
(
idev
,
skb
);
}
}
retval
=
count
;
...
...
@@ -881,15 +828,7 @@ isdn_ppp_init(void)
}
memset
((
char
*
)
ippp_table
[
i
],
0
,
sizeof
(
struct
ippp_struct
));
ippp_table
[
i
]
->
state
=
0
;
ippp_table
[
i
]
->
first
=
ippp_table
[
i
]
->
rq
+
NUM_RCV_BUFFS
-
1
;
ippp_table
[
i
]
->
last
=
ippp_table
[
i
]
->
rq
;
for
(
j
=
0
;
j
<
NUM_RCV_BUFFS
;
j
++
)
{
ippp_table
[
i
]
->
rq
[
j
].
buf
=
NULL
;
ippp_table
[
i
]
->
rq
[
j
].
last
=
ippp_table
[
i
]
->
rq
+
(
NUM_RCV_BUFFS
+
j
-
1
)
%
NUM_RCV_BUFFS
;
ippp_table
[
i
]
->
rq
[
j
].
next
=
ippp_table
[
i
]
->
rq
+
(
j
+
1
)
%
NUM_RCV_BUFFS
;
}
skb_queue_head_init
(
&
ippp_table
[
i
]
->
rq
);
}
return
0
;
}
...
...
@@ -963,10 +902,9 @@ static int isdn_ppp_strip_proto(struct sk_buff *skb)
/*
* handler for incoming packets on a syncPPP interface
*/
static
void
isdn_ppp_receive
(
isdn_net_
dev
*
net_dev
,
isdn_net_local
*
lp
,
static
void
isdn_ppp_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
)
{
isdn_net_dev
*
idev
=
lp
->
netdev
;
struct
ippp_struct
*
is
;
int
slot
;
int
proto
;
...
...
@@ -976,7 +914,7 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
* huptimer on LCP packets.
*/
if
(
PPP_PROTOCOL
(
skb
->
data
)
!=
PPP_LCP
)
isdn_net_reset_huptimer
(
net_dev
,
lp
->
net
dev
);
isdn_net_reset_huptimer
(
lp
,
i
dev
);
slot
=
idev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
...
...
@@ -1012,12 +950,12 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
if
(
!
(
is
->
mpppcfg
&
SC_REJ_MP_PROT
))
{
// we agreed to receive MPPP
if
(
proto
==
PPP_MP
)
{
isdn_ppp_mp_receive
(
net_dev
,
lp
,
skb
);
isdn_ppp_mp_receive
(
lp
,
idev
,
skb
);
return
;
}
}
#endif
isdn_ppp_push_higher
(
net_dev
,
lp
,
skb
,
proto
);
isdn_ppp_push_higher
(
lp
,
idev
,
skb
,
proto
);
}
/*
...
...
@@ -1026,10 +964,10 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
* note: net_dev has to be master net_dev
*/
static
void
isdn_ppp_push_higher
(
isdn_net_dev
*
net_dev
,
isdn_net_local
*
lp
,
struct
sk_buff
*
skb
,
int
proto
)
isdn_ppp_push_higher
(
isdn_net_local
*
lp
,
isdn_net_dev
*
idev
,
struct
sk_buff
*
skb
,
int
proto
)
{
isdn_net_dev
*
idev
=
lp
->
netdev
;
struct
net_device
*
dev
=
&
net_dev
->
dev
;
struct
net_device
*
dev
=
&
lp
->
dev
;
struct
ippp_struct
*
is
,
*
mis
;
int
slot
;
...
...
@@ -1041,8 +979,8 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
}
is
=
ippp_table
[
slot
];
if
(
lp
->
master
)
{
// FIXME?
slot
=
((
isdn_net_local
*
)
(
lp
->
master
->
priv
))
->
netdev
->
ppp_slot
;
if
(
idev
->
master
)
{
// FIXME?
slot
=
idev
->
master
->
netdev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
printk
(
KERN_ERR
"isdn_ppp_push_higher: master->ppp_slot(%d)
\n
"
,
slot
);
...
...
@@ -1079,12 +1017,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
->
ppp_slot
<
0
)
{
if
(
lp
->
net
dev
->
ppp_slot
<
0
)
{
printk
(
KERN_ERR
"%s: net_dev->ppp_slot(%d) out of range
\n
"
,
__FUNCTION__
,
net_
dev
->
ppp_slot
);
__FUNCTION__
,
lp
->
net
dev
->
ppp_slot
);
goto
drop_packet
;
}
if
(
slhc_remember
(
ippp_table
[
net_
dev
->
ppp_slot
]
->
slcomp
,
skb
->
data
,
skb
->
len
)
<=
0
)
{
if
(
slhc_remember
(
ippp_table
[
lp
->
net
dev
->
ppp_slot
]
->
slcomp
,
skb
->
data
,
skb
->
len
)
<=
0
)
{
printk
(
KERN_WARNING
"isdn_ppp: received illegal VJC_UNCOMP frame!
\n
"
);
goto
drop_packet
;
}
...
...
@@ -1105,12 +1043,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
->
ppp_slot
<
0
)
{
if
(
lp
->
net
dev
->
ppp_slot
<
0
)
{
printk
(
KERN_ERR
"%s: net_dev->ppp_slot(%d) out of range
\n
"
,
__FUNCTION__
,
net_
dev
->
ppp_slot
);
__FUNCTION__
,
lp
->
net
dev
->
ppp_slot
);
goto
drop_packet
;
}
pkt_len
=
slhc_uncompress
(
ippp_table
[
net_
dev
->
ppp_slot
]
->
slcomp
,
pkt_len
=
slhc_uncompress
(
ippp_table
[
lp
->
net
dev
->
ppp_slot
]
->
slcomp
,
skb
->
data
,
skb_old
->
len
);
kfree_skb
(
skb_old
);
if
(
pkt_len
<
0
)
...
...
@@ -1123,7 +1061,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
#endif
case
PPP_CCP
:
case
PPP_CCPFRAG
:
isdn_ppp_receive_ccp
(
net_
dev
,
lp
,
skb
,
proto
);
isdn_ppp_receive_ccp
(
lp
->
net
dev
,
lp
,
skb
,
proto
);
/* Dont pop up ResetReq/Ack stuff to the daemon any
longer - the job is done already */
if
(
skb
->
data
[
0
]
==
CCP_RESETREQ
||
...
...
@@ -1146,7 +1084,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
++
;
lp
->
stats
.
rx_dropped
++
;
kfree_skb
(
skb
);
}
...
...
@@ -1187,14 +1125,14 @@ static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
int
isdn_ppp_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
netdev
)
{
isdn_net_local
*
lp
,
*
mlp
;
isdn_net_local
*
mlp
;
isdn_net_dev
*
idev
;
isdn_net_dev
*
nd
;
unsigned
int
proto
=
PPP_IP
;
/* 0x21 */
struct
ippp_struct
*
ipt
,
*
ipts
;
int
slot
;
mlp
=
(
isdn_net_local
*
)
(
netdev
->
priv
)
;
mlp
=
netdev
->
priv
;
nd
=
mlp
->
netdev
;
/* get master lp */
slot
=
nd
->
ppp_slot
;
...
...
@@ -1226,13 +1164,12 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
return
0
;
}
lp
=
isdn_net_get_locked_lp
(
nd
);
if
(
!
lp
)
{
idev
=
isdn_net_get_locked_dev
(
mlp
);
if
(
!
idev
)
{
printk
(
KERN_WARNING
"%s: all channels busy - requeuing!
\n
"
,
netdev
->
name
);
return
1
;
}
/* we have our lp locked from now on */
idev
=
lp
->
netdev
;
slot
=
idev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
printk
(
KERN_ERR
"isdn_ppp_xmit: lp->ppp_slot(%d)
\n
"
,
...
...
@@ -1385,10 +1322,10 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
isdn_ppp_frame_log
(
"xmit"
,
skb
->
data
,
skb
->
len
,
32
,
ipt
->
unit
,
idev
->
ppp_slot
);
}
isdn_net_writebuf_skb
(
lp
,
skb
);
isdn_net_writebuf_skb
(
idev
,
skb
);
unlock:
spin_unlock_bh
(
&
lp
->
xmit_lock
);
spin_unlock_bh
(
&
idev
->
xmit_lock
);
return
0
;
}
...
...
@@ -1459,7 +1396,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
is
->
mp_seqno
=
0
;
if
((
lp
->
netdev
->
pb
=
isdn_ppp_mp_bundle_alloc
())
==
NULL
)
return
-
ENOMEM
;
lp
->
next
=
lp
->
last
=
lp
;
/* nobody else in a queue */
idev
->
next
=
idev
->
last
=
idev
;
/* nobody else in a queue */
lp
->
netdev
->
pb
->
frags
=
NULL
;
lp
->
netdev
->
pb
->
frames
=
0
;
lp
->
netdev
->
pb
->
seq
=
LONG_MAX
;
...
...
@@ -1479,12 +1416,12 @@ static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
static
void
isdn_ppp_mp_free_skb
(
ippp_bundle
*
mp
,
struct
sk_buff
*
skb
);
static
void
isdn_ppp_mp_print_recv_pkt
(
int
slot
,
struct
sk_buff
*
skb
);
static
void
isdn_ppp_mp_receive
(
isdn_net_
dev
*
net_dev
,
isdn_net_local
*
lp
,
struct
sk_buff
*
skb
)
static
void
isdn_ppp_mp_receive
(
isdn_net_
local
*
lp
,
isdn_net_dev
*
dev
,
struct
sk_buff
*
skb
)
{
isdn_net_dev
*
idev
=
lp
->
netdev
;
struct
ippp_struct
*
is
;
isdn_net_
local
*
lpq
;
isdn_net_
dev
*
qdev
;
ippp_bundle
*
mp
;
isdn_mppp_stats
*
stats
;
struct
sk_buff
*
newfrag
,
*
frag
,
*
start
,
*
nextf
;
...
...
@@ -1492,8 +1429,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
unsigned
long
flags
;
int
slot
;
spin_lock_irqsave
(
&
net_
dev
->
pb
->
lock
,
flags
);
mp
=
net_
dev
->
pb
;
spin_lock_irqsave
(
&
lp
->
net
dev
->
pb
->
lock
,
flags
);
mp
=
lp
->
net
dev
->
pb
;
stats
=
&
mp
->
stats
;
slot
=
idev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
...
...
@@ -1531,8 +1468,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
/* find the minimum received sequence number over all links */
is
->
last_link_seqno
=
minseq
=
newseq
;
for
(
lpq
=
net_dev
->
queue
;;)
{
slot
=
lpq
->
net
dev
->
ppp_slot
;
for
(
qdev
=
lp
->
queue
;;)
{
slot
=
q
dev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
printk
(
KERN_ERR
"%s: lpq->ppp_slot(%d)
\n
"
,
__FUNCTION__
,
slot
);
...
...
@@ -1541,7 +1478,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
if
(
MP_LT
(
lls
,
minseq
))
minseq
=
lls
;
}
if
((
lpq
=
lpq
->
next
)
==
net_dev
->
queue
)
if
((
qdev
=
qdev
->
next
)
==
lp
->
queue
)
break
;
}
if
(
MP_LT
(
minseq
,
mp
->
seq
))
...
...
@@ -1631,7 +1568,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
if
(
start
!=
NULL
&&
(
MP_FLAGS
(
frag
)
&
MP_END_FRAG
))
{
minseq
=
mp
->
seq
=
(
thisseq
+
1
)
&
MP_LONGSEQ_MASK
;
/* Reassemble the packet then dispatch it */
isdn_ppp_mp_reassembly
(
net_
dev
,
lp
,
start
,
nextf
);
isdn_ppp_mp_reassembly
(
lp
->
net
dev
,
lp
,
start
,
nextf
);
start
=
NULL
;
frag
=
NULL
;
...
...
@@ -1808,7 +1745,7 @@ void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
}
}
proto
=
isdn_ppp_strip_proto
(
skb
);
isdn_ppp_push_higher
(
net_dev
,
lp
,
skb
,
proto
);
isdn_ppp_push_higher
(
lp
,
idev
,
skb
,
proto
);
}
static
void
isdn_ppp_mp_free_skb
(
ippp_bundle
*
mp
,
struct
sk_buff
*
skb
)
...
...
@@ -1844,7 +1781,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit)
spin_lock_irqsave
(
&
p
->
pb
->
lock
,
flags
);
nidev
=
is
->
idev
;
idev
=
p
->
queue
->
netdev
;
idev
=
p
->
local
.
queue
;
if
(
nidev
->
ppp_slot
<
0
||
nidev
->
ppp_slot
>=
ISDN_MAX_CHANNELS
||
idev
->
ppp_slot
<
0
||
idev
->
ppp_slot
>=
ISDN_MAX_CHANNELS
)
{
printk
(
KERN_ERR
"ippp_bundle: binding to invalid slot %d
\n
"
,
...
...
@@ -1854,7 +1791,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit)
goto
out
;
}
isdn_net_add_to_bundle
(
p
,
&
nidev
->
local
);
isdn_net_add_to_bundle
(
&
p
->
local
,
nidev
);
ippp_table
[
nidev
->
ppp_slot
]
->
unit
=
ippp_table
[
idev
->
ppp_slot
]
->
unit
;
...
...
@@ -1978,7 +1915,7 @@ isdn_ppp_dial_slave(char *name)
#ifdef CONFIG_ISDN_MPP
isdn_net_dev
*
idev
;
isdn_net_local
*
lp
;
struct
net_device
*
sdev
;
isdn_net_dev
*
sdev
;
idev
=
isdn_net_findif
(
name
);
if
(
!
idev
)
...
...
@@ -1988,17 +1925,16 @@ isdn_ppp_dial_slave(char *name)
if
(
!
isdn_net_bound
(
idev
))
return
5
;
sdev
=
lp
->
slave
;
sdev
=
idev
->
slave
;
while
(
sdev
)
{
isdn_net_local
*
mlp
=
(
isdn_net_local
*
)
sdev
->
priv
;
if
(
!
isdn_net_bound
(
mlp
->
netdev
))
if
(
!
isdn_net_bound
(
sdev
))
break
;
sdev
=
mlp
->
slave
;
sdev
=
sdev
->
slave
;
}
if
(
!
sdev
)
return
2
;
isdn_net_dial_req
(
(
isdn_net_local
*
)
sdev
->
pri
v
);
isdn_net_dial_req
(
sde
v
);
return
0
;
#else
return
-
1
;
...
...
@@ -2009,35 +1945,20 @@ int
isdn_ppp_hangup_slave
(
char
*
name
)
{
#ifdef CONFIG_ISDN_MPP
isdn_net_dev
*
idev
;
isdn_net_local
*
lp
,
*
mlp
=
NULL
;
struct
net_device
*
sdev
;
isdn_net_dev
*
idev
,
*
sdev
;
idev
=
isdn_net_findif
(
name
);
if
(
!
idev
)
return
1
;
lp
=
&
idev
->
local
;
if
(
!
isdn_net_bound
(
idev
))
return
5
;
sdev
=
lp
->
slave
;
while
(
sdev
)
{
mlp
=
(
isdn_net_local
*
)
sdev
->
priv
;
if
(
mlp
->
slave
)
{
/* find last connected link in chain */
isdn_net_local
*
nlp
=
(
isdn_net_local
*
)
mlp
->
slave
->
priv
;
if
(
!
isdn_net_bound
(
nlp
->
netdev
))
break
;
}
else
if
(
isdn_net_bound
(
mlp
->
netdev
))
break
;
sdev
=
mlp
->
slave
;
}
if
(
!
sdev
)
sdev
=
idev
->
slave
;
if
(
!
sdev
||
!
isdn_net_bound
(
sdev
))
return
2
;
isdn_net_hangup
(
mlp
->
net
dev
);
isdn_net_hangup
(
s
dev
);
return
0
;
#else
return
-
1
;
...
...
@@ -2139,7 +2060,7 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
printk
(
KERN_DEBUG
"Sending CCP Frame:
\n
"
);
isdn_ppp_frame_log
(
"ccp-xmit"
,
skb
->
data
,
skb
->
len
,
32
,
is
->
unit
,
idev
->
ppp_slot
);
isdn_net_write_super
(
&
idev
->
local
,
skb
);
isdn_net_write_super
(
idev
,
skb
);
}
/* Allocate the reset state vector */
...
...
@@ -2557,8 +2478,8 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
is
=
ippp_table
[
idev
->
ppp_slot
];
isdn_ppp_frame_log
(
"ccp-rcv"
,
skb
->
data
,
skb
->
len
,
32
,
is
->
unit
,
idev
->
ppp_slot
);
if
(
lp
->
master
)
{
int
slot
=
((
isdn_net_local
*
)
(
lp
->
master
->
priv
))
->
netdev
->
ppp_slot
;
if
(
idev
->
master
)
{
int
slot
=
idev
->
master
->
netdev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
printk
(
KERN_ERR
"%s: slot(%d) out of range
\n
"
,
__FUNCTION__
,
slot
);
...
...
@@ -2745,8 +2666,8 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct
printk
(
KERN_DEBUG
"Received CCP frame from daemon:
\n
"
);
isdn_ppp_frame_log
(
"ccp-xmit"
,
skb
->
data
,
skb
->
len
,
32
,
is
->
unit
,
idev
->
ppp_slot
);
if
(
lp
->
master
)
{
slot
=
((
isdn_net_local
*
)
(
lp
->
master
->
priv
))
->
netdev
->
ppp_slot
;
if
(
idev
->
master
)
{
slot
=
idev
->
master
->
netdev
->
ppp_slot
;
if
(
slot
<
0
||
slot
>
ISDN_MAX_CHANNELS
)
{
printk
(
KERN_ERR
"%s: slot(%d) out of range
\n
"
,
__FUNCTION__
,
slot
);
...
...
include/linux/isdn.h
View file @
b2b109e8
...
...
@@ -294,8 +294,8 @@ struct isdn_netif_ops {
unsigned
short
flags
;
/* interface flags (a la BSD) */
unsigned
short
type
;
/* interface hardware type */
unsigned
char
addr_len
;
/* hardware address length */
void
(
*
receive
)(
struct
isdn_net_
dev_s
*
p
,
struct
isdn_net_
local_s
*
olp
,
void
(
*
receive
)(
struct
isdn_net_
local_s
*
l
p
,
struct
isdn_net_
dev_s
*
idev
,
struct
sk_buff
*
skb
);
void
(
*
connected
)(
struct
isdn_net_local_s
*
lp
);
void
(
*
disconnected
)(
struct
isdn_net_local_s
*
lp
);
...
...
@@ -329,26 +329,17 @@ typedef struct isdn_net_local_s {
u_char
l2_proto
;
/* Layer-2-protocol */
u_char
l3_proto
;
/* Layer-3-protocol */
int
sqfull
;
/* Flag: netdev-queue overloaded */
ulong
sqfull_stamp
;
/* Start-Time of overload */
ulong
slavedelay
;
/* Dynamic bundling delaytime */
int
triggercps
;
/* BogoCPS needed for trigger slave */
struct
list_head
phone
[
2
];
/* List of remote-phonenumbers */
/* phone[0] = Incoming Numbers */
/* phone[1] = Outgoing Numbers */
struct
net_device
*
master
;
/* Ptr to Master device for slaves */
struct
net_device
*
slave
;
/* Ptr to Slave device for masters */
struct
isdn_net_local_s
*
next
;
/* Ptr to next link in bundle */
struct
isdn_net_local_s
*
last
;
/* Ptr to last link in bundle */
struct
isdn_net_dev_s
*
netdev
;
/* Ptr to netdev */
struct
sk_buff_head
super_tx_queue
;
/* List of supervisory frames to */
/* be transmitted asap */
atomic_t
frame_cnt
;
/* number of frames currently */
/* queued in HL driver */
/* Ptr to orig. hard_header_cache */
spinlock_t
xmit_lock
;
/* used to protect the xmit path of */
/* a particular channel (including */
/* the frame_cnt */
struct
isdn_net_dev_s
*
queue
;
/* circular list of all bundled
channels, which are currently
online */
spinlock_t
queue_lock
;
/* lock to protect queue */
#ifdef CONFIG_ISDN_X25
struct
concap_device_ops
*
dops
;
/* callbacks used by encapsulator */
...
...
@@ -361,9 +352,11 @@ typedef struct isdn_net_local_s {
ulong
cisco_last_slarp_in
;
/* jiffie of last keepalive packet we received */
char
cisco_line_state
;
/* state of line according to keepalive packets */
char
cisco_debserint
;
/* debugging flag of cisco hdlc with slarp */
struct
timer_list
cisco_timer
;
struct
tq_struct
tqueue
;
struct
isdn_netif_ops
*
ops
;
struct
timer_list
cisco_timer
;
struct
isdn_netif_ops
*
ops
;
struct
net_device
dev
;
/* interface to upper levels */
}
isdn_net_local
;
/* the interface itself */
...
...
@@ -386,6 +379,8 @@ typedef struct isdn_net_dev_s {
int
cps
;
/* current speed of this interface */
int
transcount
;
/* byte-counter for cps-calculation */
int
last_jiffies
;
/* when transcount was reset */
int
sqfull
;
/* Flag: netdev-queue overloaded */
ulong
sqfull_stamp
;
/* Start-Time of overload */
struct
timer_list
hup_timer
;
/* auto hangup timer */
int
huptimer
;
/* Timeout-counter for auto-hangup */
...
...
@@ -397,13 +392,24 @@ typedef struct isdn_net_dev_s {
int
pppbind
;
/* ippp device for bindings */
int
ppp_slot
;
/* PPPD device slot number */
isdn_net_local
*
queue
;
/* circular list of all bundled
channels, which are currently
online */
spinlock_t
queue_lock
;
/* lock to protect queue */
spinlock_t
xmit_lock
;
/* used to protect the xmit path of */
/* a particular channel (including */
/* the frame_cnt */
struct
sk_buff_head
super_tx_queue
;
/* List of supervisory frames to */
/* be transmitted asap */
atomic_t
frame_cnt
;
/* number of frames currently */
/* queued in HL driver */
struct
tq_struct
tqueue
;
isdn_net_local
*
master
;
/* Ptr to Master device for slaves */
struct
isdn_net_dev_s
*
slave
;
/* Ptr to Slave device for masters */
struct
isdn_net_dev_s
*
next
;
/* Ptr to next link in bundle */
struct
isdn_net_dev_s
*
last
;
/* Ptr to last link in bundle */
char
name
[
10
];
/* Name of device */
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
* with the per-bundle data */
...
...
include/linux/isdn_ppp.h
View file @
b2b109e8
...
...
@@ -159,14 +159,7 @@ typedef struct {
isdn_mppp_stats
stats
;
}
ippp_bundle
;
#define NUM_RCV_BUFFS 64
struct
ippp_buf_queue
{
struct
ippp_buf_queue
*
next
;
struct
ippp_buf_queue
*
last
;
char
*
buf
;
/* NULL here indicates end of queue */
int
len
;
};
#define IPPP_MAX_RQ_LEN 8
/* The data structure for one CCP reset transaction */
enum
ippp_ccp_reset_states
{
...
...
@@ -201,9 +194,7 @@ struct ippp_ccp_reset {
struct
ippp_struct
{
struct
ippp_struct
*
next_link
;
int
state
;
struct
ippp_buf_queue
rq
[
NUM_RCV_BUFFS
];
/* packet queue for isdn_ppp_read() */
struct
ippp_buf_queue
*
first
;
/* pointer to (current) first packet */
struct
ippp_buf_queue
*
last
;
/* pointer to (current) last used packet in queue */
struct
sk_buff_head
rq
;
wait_queue_head_t
wq
;
struct
task_struct
*
tk
;
unsigned
int
mpppcfg
;
...
...
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