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
c3a93e09
Commit
c3a93e09
authored
May 28, 2003
by
Chas Williams
Committed by
David S. Miller
May 28, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ATM]: lane and mpoa module refcounting and locking cleanup.
parent
29146e24
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
238 additions
and
203 deletions
+238
-203
net/atm/common.c
net/atm/common.c
+94
-77
net/atm/lec.c
net/atm/lec.c
+63
-66
net/atm/lec.h
net/atm/lec.h
+8
-4
net/atm/mpc.c
net/atm/mpc.c
+28
-27
net/atm/mpc.h
net/atm/mpc.h
+4
-2
net/atm/proc.c
net/atm/proc.c
+41
-27
No files found.
net/atm/common.c
View file @
c3a93e09
...
...
@@ -32,21 +32,61 @@
#include <linux/atmlec.h>
#include "lec.h"
#include "lec_arpc.h"
struct
atm_lane_ops
atm_lane_ops
;
#endif
#ifdef CONFIG_ATM_LANE_MODULE
struct
atm_lane_ops
*
atm_lane_ops
;
static
DECLARE_MUTEX
(
atm_lane_ops_mutex
);
void
atm_lane_ops_set
(
struct
atm_lane_ops
*
hook
)
{
down
(
&
atm_lane_ops_mutex
);
atm_lane_ops
=
hook
;
up
(
&
atm_lane_ops_mutex
);
}
int
try_atm_lane_ops
(
void
)
{
down
(
&
atm_lane_ops_mutex
);
if
(
atm_lane_ops
&&
try_module_get
(
atm_lane_ops
->
owner
))
{
up
(
&
atm_lane_ops_mutex
);
return
1
;
}
up
(
&
atm_lane_ops_mutex
);
return
0
;
}
#if defined(CONFIG_ATM_LANE_MODULE) || defined(CONFIG_ATM_MPOA_MODULE)
EXPORT_SYMBOL
(
atm_lane_ops
);
EXPORT_SYMBOL
(
try_atm_lane_ops
);
EXPORT_SYMBOL
(
atm_lane_ops_set
);
#endif
#endif
#if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
#include <linux/atmmpc.h>
#include "mpc.h"
struct
atm_mpoa_ops
atm_mpoa_ops
;
#endif
struct
atm_mpoa_ops
*
atm_mpoa_ops
;
static
DECLARE_MUTEX
(
atm_mpoa_ops_mutex
);
void
atm_mpoa_ops_set
(
struct
atm_mpoa_ops
*
hook
)
{
down
(
&
atm_mpoa_ops_mutex
);
atm_mpoa_ops
=
hook
;
up
(
&
atm_mpoa_ops_mutex
);
}
int
try_atm_mpoa_ops
(
void
)
{
down
(
&
atm_mpoa_ops_mutex
);
if
(
atm_mpoa_ops
&&
try_module_get
(
atm_mpoa_ops
->
owner
))
{
up
(
&
atm_mpoa_ops_mutex
);
return
1
;
}
up
(
&
atm_mpoa_ops_mutex
);
return
0
;
}
#ifdef CONFIG_ATM_MPOA_MODULE
EXPORT_SYMBOL
(
atm_mpoa_ops
);
#ifndef CONFIG_ATM_LANE_MODULE
EXPORT_SYMBOL
(
atm_
lane_ops
);
EXPORT_SYMBOL
(
try_atm_mpoa_ops
);
EXPORT_SYMBOL
(
atm_
mpoa_ops_set
);
#endif
#endif
...
...
@@ -728,27 +768,40 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
ret_val
=
-
EPERM
;
goto
done
;
}
if
(
atm_lane_ops
.
lecd_attach
==
NULL
)
atm_lane_init
();
if
(
atm_lane_ops
.
lecd_attach
==
NULL
)
{
/* try again */
#if defined(CONFIG_ATM_LANE_MODULE)
if
(
!
atm_lane_ops
)
request_module
(
"lec"
);
#endif
if
(
try_atm_lane_ops
())
{
error
=
atm_lane_ops
->
lecd_attach
(
vcc
,
(
int
)
arg
);
module_put
(
atm_lane_ops
->
owner
);
if
(
error
>=
0
)
sock
->
state
=
SS_CONNECTED
;
ret_val
=
error
;
}
else
ret_val
=
-
ENOSYS
;
goto
done
;
}
error
=
atm_lane_ops
.
lecd_attach
(
vcc
,
(
int
)
arg
);
if
(
error
>=
0
)
sock
->
state
=
SS_CONNECTED
;
ret_val
=
error
;
goto
done
;
case
ATMLEC_MCAST
:
if
(
!
capable
(
CAP_NET_ADMIN
))
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
else
ret_val
=
atm_lane_ops
.
mcast_attach
(
vcc
,
(
int
)
arg
);
goto
done
;
}
if
(
try_atm_lane_ops
())
{
ret_val
=
atm_lane_ops
->
mcast_attach
(
vcc
,
(
int
)
arg
);
module_put
(
atm_lane_ops
->
owner
);
}
else
ret_val
=
-
ENOSYS
;
goto
done
;
case
ATMLEC_DATA
:
if
(
!
capable
(
CAP_NET_ADMIN
))
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
else
ret_val
=
atm_lane_ops
.
vcc_attach
(
vcc
,
(
void
*
)
arg
);
goto
done
;
}
if
(
try_atm_lane_ops
())
{
ret_val
=
atm_lane_ops
->
vcc_attach
(
vcc
,
(
void
*
)
arg
);
module_put
(
atm_lane_ops
->
owner
);
}
else
ret_val
=
-
ENOSYS
;
goto
done
;
#endif
#if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
...
...
@@ -757,21 +810,29 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
ret_val
=
-
EPERM
;
goto
done
;
}
if
(
atm_mpoa_ops
.
mpoad_attach
==
NULL
)
atm_mpoa_init
();
if
(
atm_mpoa_ops
.
mpoad_attach
==
NULL
)
{
/* try again */
#if defined(CONFIG_ATM_MPOA_MODULE)
if
(
!
atm_mpoa_ops
)
request_module
(
"mpoa"
);
#endif
if
(
try_atm_mpoa_ops
())
{
error
=
atm_mpoa_ops
->
mpoad_attach
(
vcc
,
(
int
)
arg
);
module_put
(
atm_mpoa_ops
->
owner
);
if
(
error
>=
0
)
sock
->
state
=
SS_CONNECTED
;
ret_val
=
error
;
}
else
ret_val
=
-
ENOSYS
;
goto
done
;
}
error
=
atm_mpoa_ops
.
mpoad_attach
(
vcc
,
(
int
)
arg
);
if
(
error
>=
0
)
sock
->
state
=
SS_CONNECTED
;
ret_val
=
error
;
goto
done
;
case
ATMMPC_DATA
:
if
(
!
capable
(
CAP_NET_ADMIN
))
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
else
ret_val
=
atm_mpoa_ops
.
vcc_attach
(
vcc
,
arg
);
goto
done
;
}
if
(
try_atm_mpoa_ops
())
{
ret_val
=
atm_mpoa_ops
->
vcc_attach
(
vcc
,
arg
);
module_put
(
atm_mpoa_ops
->
owner
);
}
else
ret_val
=
-
ENOSYS
;
goto
done
;
#endif
#if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
...
...
@@ -1155,40 +1216,6 @@ int atm_getsockopt(struct socket *sock,int level,int optname,
}
/*
* lane_mpoa_init.c: A couple of helper functions
* to make modular LANE and MPOA client easier to implement
*/
/*
* This is how it goes:
*
* if xxxx is not compiled as module, call atm_xxxx_init_ops()
* from here
* else call atm_mpoa_init_ops() from init_module() within
* the kernel when xxxx module is loaded
*
* In either case function pointers in struct atm_xxxx_ops
* are initialized to their correct values. Either they
* point to functions in the module or in the kernel
*/
extern
struct
atm_mpoa_ops
atm_mpoa_ops
;
/* in common.c */
extern
struct
atm_lane_ops
atm_lane_ops
;
/* in common.c */
#if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
void
atm_mpoa_init
(
void
)
{
#ifndef CONFIG_ATM_MPOA_MODULE
/* not module */
atm_mpoa_init_ops
(
&
atm_mpoa_ops
);
#else
request_module
(
"mpoa"
);
#endif
return
;
}
#endif
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
struct
net_bridge_fdb_entry
*
(
*
br_fdb_get_hook
)(
struct
net_bridge
*
br
,
...
...
@@ -1199,18 +1226,8 @@ EXPORT_SYMBOL(br_fdb_get_hook);
EXPORT_SYMBOL
(
br_fdb_put_hook
);
#endif
/* defined(CONFIG_ATM_LANE_MODULE) || defined(CONFIG_BRIDGE_MODULE) */
#endif
/* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
#endif
/* defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) */
void
atm_lane_init
(
void
)
{
#ifndef CONFIG_ATM_LANE_MODULE
/* not module */
atm_lane_init_ops
(
&
atm_lane_ops
);
#else
request_module
(
"lec"
);
#endif
return
;
}
#endif
static
int
__init
atm_init
(
void
)
{
...
...
net/atm/lec.c
View file @
c3a93e09
This diff is collapsed.
Click to expand it.
net/atm/lec.h
View file @
c3a93e09
...
...
@@ -64,7 +64,8 @@ struct atm_lane_ops {
int
(
*
lecd_attach
)(
struct
atm_vcc
*
vcc
,
int
arg
);
int
(
*
mcast_attach
)(
struct
atm_vcc
*
vcc
,
int
arg
);
int
(
*
vcc_attach
)(
struct
atm_vcc
*
vcc
,
void
*
arg
);
struct
net_device
**
(
*
get_lecs
)(
void
);
struct
net_device
*
(
*
get_lec
)(
int
itf
);
struct
module
*
owner
;
};
/*
...
...
@@ -102,6 +103,7 @@ struct lec_priv {
collects all those VCCs. LANEv1 client has only one item in this
list. These entries are not aged out. */
atomic_t
lec_arp_users
;
spinlock_t
lec_arp_lock
;
struct
atm_vcc
*
mcast_vcc
;
/* Default Multicast Send VCC */
struct
atm_vcc
*
lecd
;
struct
timer_list
lec_arp_timer
;
...
...
@@ -148,14 +150,16 @@ struct lec_priv {
int
lecd_attach
(
struct
atm_vcc
*
vcc
,
int
arg
);
int
lec_vcc_attach
(
struct
atm_vcc
*
vcc
,
void
*
arg
);
int
lec_mcast_attach
(
struct
atm_vcc
*
vcc
,
int
arg
);
struct
net_device
*
*
get_dev_lec
(
void
);
struct
net_device
*
get_dev_lec
(
int
itf
);
int
make_lec
(
struct
atm_vcc
*
vcc
);
int
send_to_lecd
(
struct
lec_priv
*
priv
,
atmlec_msg_type
type
,
unsigned
char
*
mac_addr
,
unsigned
char
*
atm_addr
,
struct
sk_buff
*
data
);
void
lec_push
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
);
void
atm_lane_init
(
void
);
void
atm_lane_init_ops
(
struct
atm_lane_ops
*
ops
);
extern
struct
atm_lane_ops
*
atm_lane_ops
;
void
atm_lane_ops_set
(
struct
atm_lane_ops
*
hook
);
int
try_atm_lane_ops
(
void
);
#endif
/* _LEC_H_ */
net/atm/mpc.c
View file @
c3a93e09
...
...
@@ -251,12 +251,13 @@ void atm_mpoa_disp_qos(char *page, int *len)
static
struct
net_device
*
find_lec_by_itfnum
(
int
itf
)
{
extern
struct
atm_lane_ops
atm_lane_ops
;
/* in common.c */
if
(
atm_lane_ops
.
get_lecs
==
NULL
)
struct
net_device
*
dev
;
if
(
!
try_atm_lane_ops
())
return
NULL
;
return
atm_lane_ops
.
get_lecs
()[
itf
];
/* FIXME: something better */
dev
=
atm_lane_ops
->
get_lec
(
itf
);
module_put
(
atm_lane_ops
->
owner
);
return
dev
;
}
static
struct
mpoa_client
*
alloc_mpc
(
void
)
...
...
@@ -779,9 +780,10 @@ int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
if
(
mpc
->
dev
)
{
/* check if the lec is LANE2 capable */
priv
=
(
struct
lec_priv
*
)
mpc
->
dev
->
priv
;
if
(
priv
->
lane_version
<
2
)
if
(
priv
->
lane_version
<
2
)
{
dev_put
(
mpc
->
dev
);
mpc
->
dev
=
NULL
;
else
}
else
priv
->
lane2_ops
->
associate_indicator
=
lane2_assoc_ind
;
}
...
...
@@ -802,7 +804,7 @@ int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
send_set_mps_ctrl_addr
(
mpc
->
mps_ctrl_addr
,
mpc
);
}
MOD_INC_USE_COUNT
;
__module_get
(
THIS_MODULE
)
;
return
arg
;
}
...
...
@@ -839,6 +841,7 @@ static void mpoad_close(struct atm_vcc *vcc)
struct
lec_priv
*
priv
=
(
struct
lec_priv
*
)
mpc
->
dev
->
priv
;
priv
->
lane2_ops
->
associate_indicator
=
NULL
;
stop_mpc
(
mpc
);
dev_put
(
mpc
->
dev
);
}
mpc
->
in_ops
->
destroy_cache
(
mpc
);
...
...
@@ -851,7 +854,7 @@ static void mpoad_close(struct atm_vcc *vcc)
printk
(
"mpoa: (%s) going down
\n
"
,
(
mpc
->
dev
)
?
mpc
->
dev
->
name
:
"<unknown>"
);
MOD_DEC_USE_COUNT
;
module_put
(
THIS_MODULE
)
;
return
;
}
...
...
@@ -975,6 +978,7 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo
}
mpc
->
dev_num
=
priv
->
itfnum
;
mpc
->
dev
=
dev
;
dev_hold
(
dev
);
dprintk
(
"mpoa: (%s) was initialized
\n
"
,
dev
->
name
);
break
;
case
NETDEV_UNREGISTER
:
...
...
@@ -984,6 +988,7 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo
break
;
dprintk
(
"mpoa: device (%s) was deallocated
\n
"
,
dev
->
name
);
stop_mpc
(
mpc
);
dev_put
(
mpc
->
dev
);
mpc
->
dev
=
NULL
;
break
;
case
NETDEV_UP
:
...
...
@@ -1393,13 +1398,18 @@ static void mpc_cache_check( unsigned long checking_time )
return
;
}
void
atm_mpoa_init_ops
(
struct
atm_mpoa_ops
*
ops
)
static
struct
atm_mpoa_ops
__atm_mpoa_ops
=
{
.
mpoad_attach
=
atm_mpoa_mpoad_attach
,
.
vcc_attach
=
atm_mpoa_vcc_attach
,
.
owner
=
THIS_MODULE
};
static
__init
int
atm_mpoa_init
(
void
)
{
ops
->
mpoad_attach
=
atm_mpoa_mpoad_attach
;
ops
->
vcc_attach
=
atm_mpoa_vcc_attach
;
atm_mpoa_ops_set
(
&
__atm_mpoa_ops
);
#ifdef CONFIG_PROC_FS
if
(
mpc_proc_init
()
!=
0
)
if
(
mpc_proc_init
()
!=
0
)
printk
(
KERN_INFO
"mpoa: failed to initialize /proc/mpoa
\n
"
);
else
printk
(
KERN_INFO
"mpoa: /proc/mpoa initialized
\n
"
);
...
...
@@ -1407,22 +1417,11 @@ void atm_mpoa_init_ops(struct atm_mpoa_ops *ops)
printk
(
"mpc.c: "
__DATE__
" "
__TIME__
" initialized
\n
"
);
return
;
}
#ifdef MODULE
int
init_module
(
void
)
{
extern
struct
atm_mpoa_ops
atm_mpoa_ops
;
atm_mpoa_init_ops
(
&
atm_mpoa_ops
);
return
0
;
}
void
cleanup_module
(
void
)
void
__exit
atm_mpoa_cleanup
(
void
)
{
extern
struct
atm_mpoa_ops
atm_mpoa_ops
;
struct
mpoa_client
*
mpc
,
*
tmp
;
struct
atm_mpoa_qos
*
qos
,
*
nextqos
;
struct
lec_priv
*
priv
;
...
...
@@ -1433,8 +1432,7 @@ void cleanup_module(void)
del_timer
(
&
mpc_timer
);
unregister_netdevice_notifier
(
&
mpoa_notifier
);
atm_mpoa_ops
.
mpoad_attach
=
NULL
;
atm_mpoa_ops
.
vcc_attach
=
NULL
;
atm_mpoa_ops_set
(
NULL
);
mpc
=
mpcs
;
mpcs
=
NULL
;
...
...
@@ -1469,5 +1467,8 @@ void cleanup_module(void)
return
;
}
#endif
/* MODULE */
module_init
(
atm_mpoa_init
);
module_exit
(
atm_mpoa_cleanup
);
MODULE_LICENSE
(
"GPL"
);
net/atm/mpc.h
View file @
c3a93e09
...
...
@@ -48,11 +48,13 @@ struct atm_mpoa_qos {
struct
atm_mpoa_ops
{
int
(
*
mpoad_attach
)(
struct
atm_vcc
*
vcc
,
int
arg
);
/* attach mpoa daemon */
int
(
*
vcc_attach
)(
struct
atm_vcc
*
vcc
,
long
arg
);
/* attach shortcut vcc */
struct
module
*
owner
;
};
/* Boot/module initialization function */
void
atm_mpoa_init
(
void
);
void
atm_mpoa_init_ops
(
struct
atm_mpoa_ops
*
ops
);
extern
struct
atm_mpoa_ops
*
atm_mpoa_ops
;
int
try_atm_mpoa_ops
(
void
);
void
atm_mpoa_ops_set
(
struct
atm_mpoa_ops
*
hook
);
/* MPOA QoS operations */
struct
atm_mpoa_qos
*
atm_mpoa_add_qos
(
uint32_t
dst_ip
,
struct
atm_qos
*
qos
);
...
...
net/atm/proc.c
View file @
c3a93e09
...
...
@@ -47,7 +47,6 @@
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
#include "lec.h"
#include "lec_arpc.h"
extern
struct
atm_lane_ops
atm_lane_ops
;
/* in common.c */
#endif
static
ssize_t
proc_dev_atm_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
...
...
@@ -481,57 +480,72 @@ static int atm_arp_info(loff_t pos,char *buf)
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
static
int
atm_lec_info
(
loff_t
pos
,
char
*
buf
)
{
unsigned
long
flags
;
struct
lec_priv
*
priv
;
struct
lec_arp_table
*
entry
;
int
i
,
count
,
d
,
e
;
struct
net_device
*
*
dev_lec
;
struct
net_device
*
dev
;
if
(
!
pos
)
{
return
sprintf
(
buf
,
"Itf MAC ATM destination"
" Status Flags "
"VPI/VCI Recv VPI/VCI
\n
"
);
}
if
(
atm_lane_ops
.
get_lecs
==
NULL
)
if
(
!
try_atm_lane_ops
()
)
return
0
;
/* the lane module is not there yet */
else
dev_lec
=
atm_lane_ops
.
get_lecs
();
count
=
pos
;
for
(
d
=
0
;
d
<
MAX_LEC_ITF
;
d
++
)
{
if
(
!
dev_lec
[
d
]
||
!
(
priv
=
(
struct
lec_priv
*
)
dev_lec
[
d
]
->
priv
))
continue
;
for
(
i
=
0
;
i
<
LEC_ARP_TABLE_SIZE
;
i
++
)
{
entry
=
priv
->
lec_arp_tables
[
i
];
for
(;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev_lec
[
d
]
->
name
);
lec_info
(
entry
,
buf
+
e
);
for
(
d
=
0
;
d
<
MAX_LEC_ITF
;
d
++
)
{
dev
=
atm_lane_ops
->
get_lec
(
d
);
if
(
!
dev
||
!
(
priv
=
(
struct
lec_priv
*
)
dev
->
priv
))
continue
;
spin_lock_irqsave
(
&
priv
->
lec_arp_lock
,
flags
);
for
(
i
=
0
;
i
<
LEC_ARP_TABLE_SIZE
;
i
++
)
{
for
(
entry
=
priv
->
lec_arp_tables
[
i
];
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev
->
name
);
lec_info
(
entry
,
buf
+
e
);
spin_unlock_irqrestore
(
&
priv
->
lec_arp_lock
,
flags
);
dev_put
(
dev
);
module_put
(
atm_lane_ops
->
owner
);
return
strlen
(
buf
);
}
}
for
(
entry
=
priv
->
lec_arp_empty_ones
;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev_lec
[
d
]
->
name
);
for
(
entry
=
priv
->
lec_arp_empty_ones
;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev
->
name
);
lec_info
(
entry
,
buf
+
e
);
spin_unlock_irqrestore
(
&
priv
->
lec_arp_lock
,
flags
);
dev_put
(
dev
);
module_put
(
atm_lane_ops
->
owner
);
return
strlen
(
buf
);
}
for
(
entry
=
priv
->
lec_no_forward
;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev_lec
[
d
]
->
name
);
for
(
entry
=
priv
->
lec_no_forward
;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev
->
name
);
lec_info
(
entry
,
buf
+
e
);
spin_unlock_irqrestore
(
&
priv
->
lec_arp_lock
,
flags
);
dev_put
(
dev
);
module_put
(
atm_lane_ops
->
owner
);
return
strlen
(
buf
);
}
for
(
entry
=
priv
->
mcast_fwds
;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev_lec
[
d
]
->
name
);
for
(
entry
=
priv
->
mcast_fwds
;
entry
;
entry
=
entry
->
next
)
{
if
(
--
count
)
continue
;
e
=
sprintf
(
buf
,
"%s "
,
dev
->
name
);
lec_info
(
entry
,
buf
+
e
);
spin_unlock_irqrestore
(
&
priv
->
lec_arp_lock
,
flags
);
dev_put
(
dev
);
module_put
(
atm_lane_ops
->
owner
);
return
strlen
(
buf
);
}
spin_unlock_irqrestore
(
&
priv
->
lec_arp_lock
,
flags
);
dev_put
(
dev
);
}
module_put
(
atm_lane_ops
->
owner
);
return
0
;
}
#endif
...
...
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