Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
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
Show 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
;
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
;
isdn_net_dev
*
p
=
mlp
->
netdev
;
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
);
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
(
&
master_lp
->
netdev
->
queue_lock
,
flags
);
idev
->
next
=
idev
->
last
=
idev
;
/* (re)set own pointers */
spin_unlock_irqrestore
(
&
mlp
->
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
,
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
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,35 +641,22 @@ 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
);
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
,
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 */
...
...
@@ -362,8 +353,10 @@ typedef struct isdn_net_local_s {
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
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