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
861c1242
Commit
861c1242
authored
May 15, 2003
by
Chas Williams
Committed by
Hideaki Yoshifuji
May 15, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ATM]: Add refcounting to atmdev.
parent
7f080bc0
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
315 additions
and
186 deletions
+315
-186
drivers/atm/atmtcp.c
drivers/atm/atmtcp.c
+25
-5
drivers/atm/eni.c
drivers/atm/eni.c
+22
-4
drivers/atm/fore200e.c
drivers/atm/fore200e.c
+12
-0
drivers/atm/he.c
drivers/atm/he.c
+7
-1
drivers/atm/idt77252.c
drivers/atm/idt77252.c
+3
-0
include/linux/atmdev.h
include/linux/atmdev.h
+23
-5
net/atm/addr.c
net/atm/addr.c
+22
-27
net/atm/atm_misc.c
net/atm/atm_misc.c
+10
-2
net/atm/clip.c
net/atm/clip.c
+1
-0
net/atm/common.c
net/atm/common.c
+48
-43
net/atm/lec.c
net/atm/lec.c
+1
-0
net/atm/mpc.c
net/atm/mpc.c
+1
-0
net/atm/proc.c
net/atm/proc.c
+54
-30
net/atm/resources.c
net/atm/resources.c
+75
-54
net/atm/resources.h
net/atm/resources.h
+1
-1
net/atm/signaling.c
net/atm/signaling.c
+10
-14
No files found.
drivers/atm/atmtcp.c
View file @
861c1242
...
...
@@ -153,6 +153,7 @@ static void atmtcp_v_close(struct atm_vcc *vcc)
static
int
atmtcp_v_ioctl
(
struct
atm_dev
*
dev
,
unsigned
int
cmd
,
void
*
arg
)
{
unsigned
long
flags
;
struct
atm_cirange
ci
;
struct
atm_vcc
*
vcc
;
...
...
@@ -162,9 +163,14 @@ static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
if
(
ci
.
vci_bits
==
ATM_CI_MAX
)
ci
.
vci_bits
=
MAX_VCI_BITS
;
if
(
ci
.
vpi_bits
>
MAX_VPI_BITS
||
ci
.
vpi_bits
<
0
||
ci
.
vci_bits
>
MAX_VCI_BITS
||
ci
.
vci_bits
<
0
)
return
-
EINVAL
;
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
vcc
=
dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
((
vcc
->
vpi
>>
ci
.
vpi_bits
)
||
(
vcc
->
vci
>>
ci
.
vci_bits
))
return
-
EBUSY
;
(
vcc
->
vci
>>
ci
.
vci_bits
))
{
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
-
EBUSY
;
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
dev
->
ci_range
=
ci
;
return
0
;
}
...
...
@@ -227,6 +233,7 @@ static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
static
void
atmtcp_c_close
(
struct
atm_vcc
*
vcc
)
{
unsigned
long
flags
;
struct
atm_dev
*
atmtcp_dev
;
struct
atmtcp_dev_data
*
dev_data
;
struct
atm_vcc
*
walk
;
...
...
@@ -239,13 +246,16 @@ static void atmtcp_c_close(struct atm_vcc *vcc)
kfree
(
dev_data
);
shutdown_atm_dev
(
atmtcp_dev
);
vcc
->
dev_data
=
NULL
;
spin_lock_irqsave
(
&
atmtcp_dev
->
lock
,
flags
);
for
(
walk
=
atmtcp_dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
wake_up
(
&
walk
->
sleep
);
spin_unlock_irqrestore
(
&
atmtcp_dev
->
lock
,
flags
);
}
static
int
atmtcp_c_send
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
)
{
unsigned
long
flags
;
struct
atm_dev
*
dev
;
struct
atmtcp_hdr
*
hdr
;
struct
atm_vcc
*
out_vcc
;
...
...
@@ -260,11 +270,13 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
(
struct
atmtcp_control
*
)
skb
->
data
);
goto
done
;
}
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
out_vcc
=
dev
->
vccs
;
out_vcc
;
out_vcc
=
out_vcc
->
next
)
if
(
out_vcc
->
vpi
==
ntohs
(
hdr
->
vpi
)
&&
out_vcc
->
vci
==
ntohs
(
hdr
->
vci
)
&&
out_vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
)
break
;
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
if
(
!
out_vcc
)
{
atomic_inc
(
&
vcc
->
stats
->
tx_err
);
goto
done
;
...
...
@@ -318,6 +330,7 @@ static struct atm_dev atmtcp_control_dev = {
.
ops
=
&
atmtcp_c_dev_ops
,
.
type
=
"atmtcp"
,
.
number
=
999
,
.
lock
=
SPIN_LOCK_UNLOCKED
};
...
...
@@ -350,9 +363,12 @@ int atmtcp_attach(struct atm_vcc *vcc,int itf)
struct
atm_dev
*
dev
;
dev
=
NULL
;
if
(
itf
!=
-
1
)
dev
=
atm_
find_dev
(
itf
);
if
(
itf
!=
-
1
)
dev
=
atm_
dev_lookup
(
itf
);
if
(
dev
)
{
if
(
dev
->
ops
!=
&
atmtcp_v_dev_ops
)
return
-
EMEDIUMTYPE
;
if
(
dev
->
ops
!=
&
atmtcp_v_dev_ops
)
{
atm_dev_release
(
dev
);
return
-
EMEDIUMTYPE
;
}
if
(
PRIV
(
dev
)
->
vcc
)
return
-
EBUSY
;
}
else
{
...
...
@@ -383,14 +399,18 @@ int atmtcp_remove_persistent(int itf)
struct
atm_dev
*
dev
;
struct
atmtcp_dev_data
*
dev_data
;
dev
=
atm_
find_dev
(
itf
);
dev
=
atm_
dev_lookup
(
itf
);
if
(
!
dev
)
return
-
ENODEV
;
if
(
dev
->
ops
!=
&
atmtcp_v_dev_ops
)
return
-
EMEDIUMTYPE
;
if
(
dev
->
ops
!=
&
atmtcp_v_dev_ops
)
{
atm_dev_release
(
dev
);
return
-
EMEDIUMTYPE
;
}
dev_data
=
PRIV
(
dev
);
if
(
!
dev_data
->
persist
)
return
0
;
dev_data
->
persist
=
0
;
if
(
PRIV
(
dev
)
->
vcc
)
return
0
;
kfree
(
dev_data
);
atm_dev_release
(
dev
);
shutdown_atm_dev
(
dev
);
return
0
;
}
...
...
drivers/atm/eni.c
View file @
861c1242
...
...
@@ -1887,8 +1887,10 @@ static void eni_close(struct atm_vcc *vcc)
static
int
get_ci
(
struct
atm_vcc
*
vcc
,
short
*
vpi
,
int
*
vci
)
{
unsigned
long
flags
;
struct
atm_vcc
*
walk
;
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
if
(
*
vpi
==
ATM_VPI_ANY
)
*
vpi
=
0
;
if
(
*
vci
==
ATM_VCI_ANY
)
{
for
(
*
vci
=
ATM_NOT_RSV_VCI
;
*
vci
<
NR_VCI
;
(
*
vci
)
++
)
{
...
...
@@ -1907,17 +1909,29 @@ static int get_ci(struct atm_vcc *vcc,short *vpi,int *vci)
}
break
;
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
*
vci
==
NR_VCI
?
-
EADDRINUSE
:
0
;
}
if
(
*
vci
==
ATM_VCI_UNSPEC
)
return
0
;
if
(
*
vci
==
ATM_VCI_UNSPEC
)
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
0
;
}
if
(
vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
&&
ENI_DEV
(
vcc
->
dev
)
->
rx_map
[
*
vci
])
ENI_DEV
(
vcc
->
dev
)
->
rx_map
[
*
vci
])
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
-
EADDRINUSE
;
if
(
vcc
->
qos
.
txtp
.
traffic_class
==
ATM_NONE
)
return
0
;
}
if
(
vcc
->
qos
.
txtp
.
traffic_class
==
ATM_NONE
)
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
0
;
}
for
(
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
if
(
test_bit
(
ATM_VF_ADDR
,
&
walk
->
flags
)
&&
walk
->
vci
==
*
vci
&&
walk
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
walk
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
-
EADDRINUSE
;
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
0
;
}
...
...
@@ -2125,6 +2139,7 @@ static unsigned char eni_phy_get(struct atm_dev *dev,unsigned long addr)
static
int
eni_proc_read
(
struct
atm_dev
*
dev
,
loff_t
*
pos
,
char
*
page
)
{
unsigned
long
flags
;
static
const
char
*
signal
[]
=
{
"LOST"
,
"unknown"
,
"okay"
};
struct
eni_dev
*
eni_dev
=
ENI_DEV
(
dev
);
struct
atm_vcc
*
vcc
;
...
...
@@ -2197,6 +2212,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
return
sprintf
(
page
,
"%10sbacklog %u packets
\n
"
,
""
,
skb_queue_len
(
&
tx
->
backlog
));
}
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
vcc
=
dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
{
struct
eni_vcc
*
eni_vcc
=
ENI_VCC
(
vcc
);
int
length
;
...
...
@@ -2215,8 +2231,10 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
length
+=
sprintf
(
page
+
length
,
"tx[%d], txing %d bytes"
,
eni_vcc
->
tx
->
index
,
eni_vcc
->
txing
);
page
[
length
]
=
'\n'
;
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
length
+
1
;
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
for
(
i
=
0
;
i
<
eni_dev
->
free_len
;
i
++
)
{
struct
eni_free
*
fe
=
eni_dev
->
free_list
+
i
;
unsigned
long
offset
;
...
...
drivers/atm/fore200e.c
View file @
861c1242
...
...
@@ -1074,13 +1074,16 @@ fore200e_supply(struct fore200e* fore200e)
static
struct
atm_vcc
*
fore200e_find_vcc
(
struct
fore200e
*
fore200e
,
struct
rpd
*
rpd
)
{
unsigned
long
flags
;
struct
atm_vcc
*
vcc
;
spin_lock_irqsave
(
&
fore200e
->
atm_dev
->
lock
,
flags
);
for
(
vcc
=
fore200e
->
atm_dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
{
if
(
vcc
->
vpi
==
rpd
->
atm_header
.
vpi
&&
vcc
->
vci
==
rpd
->
atm_header
.
vci
)
break
;
}
spin_unlock_irqrestore
(
&
fore200e
->
atm_dev
->
lock
,
flags
);
return
vcc
;
}
...
...
@@ -1352,9 +1355,13 @@ fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc*
static
int
fore200e_walk_vccs
(
struct
atm_vcc
*
vcc
,
short
*
vpi
,
int
*
vci
)
{
unsigned
long
flags
;
struct
atm_vcc
*
walk
;
/* find a free VPI */
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
if
(
*
vpi
==
ATM_VPI_ANY
)
{
for
(
*
vpi
=
0
,
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
{
...
...
@@ -1378,6 +1385,8 @@ fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci)
}
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
0
;
}
...
...
@@ -2638,6 +2647,7 @@ fore200e_module_cleanup(void)
static
int
fore200e_proc_read
(
struct
atm_dev
*
dev
,
loff_t
*
pos
,
char
*
page
)
{
unsigned
long
flags
;
struct
fore200e
*
fore200e
=
FORE200E_DEV
(
dev
);
int
len
,
left
=
*
pos
;
...
...
@@ -2884,6 +2894,7 @@ fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page)
len
=
sprintf
(
page
,
"
\n
"
" VCCs:
\n
address
\t
VPI.VCI:AAL
\t
(min/max tx PDU size) (min/max rx PDU size)
\n
"
);
spin_lock_irqsave
(
&
fore200e
->
atm_dev
->
lock
,
flags
);
for
(
vcc
=
fore200e
->
atm_dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
{
fore200e_vcc
=
FORE200E_VCC
(
vcc
);
...
...
@@ -2898,6 +2909,7 @@ fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page)
fore200e_vcc
->
rx_max_pdu
);
}
spin_unlock_irqrestore
(
&
fore200e
->
atm_dev
->
lock
,
flags
);
return
len
;
}
...
...
drivers/atm/he.c
View file @
861c1242
...
...
@@ -345,6 +345,7 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
static
__inline__
struct
atm_vcc
*
he_find_vcc
(
struct
he_dev
*
he_dev
,
unsigned
cid
)
{
unsigned
long
flags
;
struct
atm_vcc
*
vcc
;
short
vpi
;
int
vci
;
...
...
@@ -352,10 +353,15 @@ he_find_vcc(struct he_dev *he_dev, unsigned cid)
vpi
=
cid
>>
he_dev
->
vcibits
;
vci
=
cid
&
((
1
<<
he_dev
->
vcibits
)
-
1
);
spin_lock_irqsave
(
&
he_dev
->
atm_dev
->
lock
,
flags
);
for
(
vcc
=
he_dev
->
atm_dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
(
vcc
->
vci
==
vci
&&
vcc
->
vpi
==
vpi
&&
vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
)
return
vcc
;
&&
vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
)
{
spin_unlock_irqrestore
(
&
he_dev
->
atm_dev
->
lock
,
flags
);
return
vcc
;
}
spin_unlock_irqrestore
(
&
he_dev
->
atm_dev
->
lock
,
flags
);
return
NULL
;
}
...
...
drivers/atm/idt77252.c
View file @
861c1242
...
...
@@ -2402,8 +2402,10 @@ idt77252_init_rx(struct idt77252_dev *card, struct vc_map *vc,
static
int
idt77252_find_vcc
(
struct
atm_vcc
*
vcc
,
short
*
vpi
,
int
*
vci
)
{
unsigned
long
flags
;
struct
atm_vcc
*
walk
;
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
if
(
*
vpi
==
ATM_VPI_ANY
)
{
*
vpi
=
0
;
walk
=
vcc
->
dev
->
vccs
;
...
...
@@ -2430,6 +2432,7 @@ idt77252_find_vcc(struct atm_vcc *vcc, short *vpi, int *vci)
}
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
0
;
}
...
...
include/linux/atmdev.h
View file @
861c1242
...
...
@@ -331,6 +331,8 @@ struct atm_dev {
struct
k_atm_dev_stats
stats
;
/* statistics */
char
signal
;
/* signal status (ATM_PHY_SIG_*) */
int
link_rate
;
/* link rate (default: OC3) */
atomic_t
refcnt
;
/* reference count */
spinlock_t
lock
;
/* protect internal members */
#ifdef CONFIG_PROC_FS
struct
proc_dir_entry
*
proc_entry
;
/* proc entry */
char
*
proc_name
;
/* proc entry name */
...
...
@@ -392,7 +394,7 @@ struct atm_skb_data {
struct
atm_dev
*
atm_dev_register
(
const
char
*
type
,
const
struct
atmdev_ops
*
ops
,
int
number
,
unsigned
long
*
flags
);
/* number == -1: pick first available */
struct
atm_dev
*
atm_
find_dev
(
int
number
);
struct
atm_dev
*
atm_
dev_lookup
(
int
number
);
void
atm_dev_deregister
(
struct
atm_dev
*
dev
);
void
shutdown_atm_dev
(
struct
atm_dev
*
dev
);
void
bind_vcc
(
struct
atm_vcc
*
vcc
,
struct
atm_dev
*
dev
);
...
...
@@ -403,30 +405,46 @@ void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev);
*
*/
static
__inline__
int
atm_guess_pdu2truesize
(
int
pdu_size
)
static
inline
int
atm_guess_pdu2truesize
(
int
pdu_size
)
{
return
((
pdu_size
+
15
)
&
~
15
)
+
sizeof
(
struct
sk_buff
);
}
static
__inline__
void
atm_force_charge
(
struct
atm_vcc
*
vcc
,
int
truesize
)
static
inline
void
atm_force_charge
(
struct
atm_vcc
*
vcc
,
int
truesize
)
{
atomic_add
(
truesize
,
&
vcc
->
sk
->
rmem_alloc
);
}
static
__inline__
void
atm_return
(
struct
atm_vcc
*
vcc
,
int
truesize
)
static
inline
void
atm_return
(
struct
atm_vcc
*
vcc
,
int
truesize
)
{
atomic_sub
(
truesize
,
&
vcc
->
sk
->
rmem_alloc
);
}
static
__inline__
int
atm_may_send
(
struct
atm_vcc
*
vcc
,
unsigned
int
size
)
static
inline
int
atm_may_send
(
struct
atm_vcc
*
vcc
,
unsigned
int
size
)
{
return
(
size
+
atomic_read
(
&
vcc
->
sk
->
wmem_alloc
))
<
vcc
->
sk
->
sndbuf
;
}
static
inline
void
atm_dev_hold
(
struct
atm_dev
*
dev
)
{
atomic_inc
(
&
dev
->
refcnt
);
}
static
inline
void
atm_dev_release
(
struct
atm_dev
*
dev
)
{
atomic_dec
(
&
dev
->
refcnt
);
if
((
atomic_read
(
&
dev
->
refcnt
)
==
1
)
&&
test_bit
(
ATM_DF_CLOSE
,
&
dev
->
flags
))
shutdown_atm_dev
(
dev
);
}
int
atm_charge
(
struct
atm_vcc
*
vcc
,
int
truesize
);
struct
sk_buff
*
atm_alloc_charge
(
struct
atm_vcc
*
vcc
,
int
pdu_size
,
int
gfp_flags
);
...
...
net/atm/addr.c
View file @
861c1242
...
...
@@ -36,14 +36,6 @@ static int identical(struct sockaddr_atmsvc *a,struct sockaddr_atmsvc *b)
}
/*
* Avoid modification of any list of local interfaces while reading it
* (which may involve page faults and therefore rescheduling)
*/
static
DECLARE_MUTEX
(
local_lock
);
extern
spinlock_t
atm_dev_lock
;
static
void
notify_sigd
(
struct
atm_dev
*
dev
)
{
struct
sockaddr_atmpvc
pvc
;
...
...
@@ -52,46 +44,46 @@ static void notify_sigd(struct atm_dev *dev)
sigd_enq
(
NULL
,
as_itf_notify
,
NULL
,
&
pvc
,
NULL
);
}
/*
* This is called from atm_ioctl only. You must hold the lock as a caller
*/
void
atm_reset_addr
(
struct
atm_dev
*
dev
)
{
unsigned
long
flags
;
struct
atm_dev_addr
*
this
;
down
(
&
local_lock
);
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
while
(
dev
->
local
)
{
this
=
dev
->
local
;
dev
->
local
=
this
->
next
;
kfree
(
this
);
}
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
notify_sigd
(
dev
);
}
int
atm_add_addr
(
struct
atm_dev
*
dev
,
struct
sockaddr_atmsvc
*
addr
)
{
unsigned
long
flags
;
struct
atm_dev_addr
**
walk
;
int
error
;
error
=
check_addr
(
addr
);
if
(
error
)
return
error
;
down
(
&
local_lock
);
if
(
error
)
return
error
;
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
walk
=
&
dev
->
local
;
*
walk
;
walk
=
&
(
*
walk
)
->
next
)
if
(
identical
(
&
(
*
walk
)
->
addr
,
addr
))
{
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
-
EEXIST
;
}
*
walk
=
kmalloc
(
sizeof
(
struct
atm_dev_addr
),
GFP_KERNEL
);
*
walk
=
kmalloc
(
sizeof
(
struct
atm_dev_addr
),
GFP_ATOMIC
);
if
(
!*
walk
)
{
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
-
ENOMEM
;
}
(
*
walk
)
->
addr
=
*
addr
;
(
*
walk
)
->
next
=
NULL
;
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
notify_sigd
(
dev
);
return
0
;
}
...
...
@@ -99,22 +91,24 @@ int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
int
atm_del_addr
(
struct
atm_dev
*
dev
,
struct
sockaddr_atmsvc
*
addr
)
{
unsigned
long
flags
;
struct
atm_dev_addr
**
walk
,
*
this
;
int
error
;
error
=
check_addr
(
addr
);
if
(
error
)
return
error
;
down
(
&
local_lock
);
if
(
error
)
return
error
;
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
walk
=
&
dev
->
local
;
*
walk
;
walk
=
&
(
*
walk
)
->
next
)
if
(
identical
(
&
(
*
walk
)
->
addr
,
addr
))
break
;
if
(
!*
walk
)
{
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
-
ENOENT
;
}
this
=
*
walk
;
*
walk
=
this
->
next
;
kfree
(
this
);
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
notify_sigd
(
dev
);
return
0
;
}
...
...
@@ -122,24 +116,25 @@ int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
int
atm_get_addr
(
struct
atm_dev
*
dev
,
struct
sockaddr_atmsvc
*
u_buf
,
int
size
)
{
unsigned
long
flags
;
struct
atm_dev_addr
*
walk
;
int
total
;
down
(
&
local_lock
);
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
total
=
0
;
for
(
walk
=
dev
->
local
;
walk
;
walk
=
walk
->
next
)
{
total
+=
sizeof
(
struct
sockaddr_atmsvc
);
if
(
total
>
size
)
{
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
-
E2BIG
;
}
if
(
copy_to_user
(
u_buf
,
&
walk
->
addr
,
sizeof
(
struct
sockaddr_atmsvc
)))
{
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
-
EFAULT
;
}
u_buf
++
;
}
up
(
&
local_lock
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
total
;
}
net/atm/atm_misc.c
View file @
861c1242
...
...
@@ -63,13 +63,19 @@ static int check_ci(struct atm_vcc *vcc,short vpi,int vci)
int
atm_find_ci
(
struct
atm_vcc
*
vcc
,
short
*
vpi
,
int
*
vci
)
{
unsigned
long
flags
;
static
short
p
=
0
;
/* poor man's per-device cache */
static
int
c
=
0
;
short
old_p
;
int
old_c
;
int
err
;
if
(
*
vpi
!=
ATM_VPI_ANY
&&
*
vci
!=
ATM_VCI_ANY
)
return
check_ci
(
vcc
,
*
vpi
,
*
vci
);
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
if
(
*
vpi
!=
ATM_VPI_ANY
&&
*
vci
!=
ATM_VCI_ANY
)
{
err
=
check_ci
(
vcc
,
*
vpi
,
*
vci
);
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
err
;
}
/* last scan may have left values out of bounds for current device */
if
(
*
vpi
!=
ATM_VPI_ANY
)
p
=
*
vpi
;
else
if
(
p
>=
1
<<
vcc
->
dev
->
ci_range
.
vpi_bits
)
p
=
0
;
...
...
@@ -82,6 +88,7 @@ int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci)
if
(
!
check_ci
(
vcc
,
p
,
c
))
{
*
vpi
=
p
;
*
vci
=
c
;
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
0
;
}
if
(
*
vci
==
ATM_VCI_ANY
)
{
...
...
@@ -96,6 +103,7 @@ int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci)
}
}
while
(
old_p
!=
p
||
old_c
!=
c
);
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
return
-
EADDRINUSE
;
}
...
...
net/atm/clip.c
View file @
861c1242
...
...
@@ -717,6 +717,7 @@ static struct atm_dev atmarpd_dev = {
.
ops
=
&
atmarpd_dev_ops
,
.
type
=
"arpd"
,
.
number
=
999
,
.
lock
=
SPIN_LOCK_UNLOCKED
};
...
...
net/atm/common.c
View file @
861c1242
...
...
@@ -115,7 +115,6 @@ EXPORT_SYMBOL(br2684_ioctl_hook);
#define DPRINTK(format,args...)
#endif
spinlock_t
atm_dev_lock
=
SPIN_LOCK_UNLOCKED
;
static
struct
sk_buff
*
alloc_tx
(
struct
atm_vcc
*
vcc
,
unsigned
int
size
)
{
...
...
@@ -175,19 +174,17 @@ void atm_release_vcc_sk(struct sock *sk,int free_sk)
atm_return
(
vcc
,
skb
->
truesize
);
kfree_skb
(
skb
);
}
spin_lock
(
&
atm_dev_lock
);
fops_put
(
vcc
->
dev
->
ops
);
module_put
(
vcc
->
dev
->
ops
->
owner
);
atm_dev_release
(
vcc
->
dev
);
if
(
atomic_read
(
&
vcc
->
sk
->
rmem_alloc
))
printk
(
KERN_WARNING
"atm_release_vcc: strange ... "
"rmem_alloc == %d after closing
\n
"
,
atomic_read
(
&
vcc
->
sk
->
rmem_alloc
));
bind_vcc
(
vcc
,
NULL
);
}
else
spin_lock
(
&
atm_dev_lock
);
}
if
(
free_sk
)
free_atm_vcc_sk
(
sk
);
spin_unlock
(
&
atm_dev_lock
);
}
...
...
@@ -280,11 +277,11 @@ static int atm_do_connect_dev(struct atm_vcc *vcc,struct atm_dev *dev,int vpi,
vcc
->
qos
.
txtp
.
min_pcr
,
vcc
->
qos
.
txtp
.
max_pcr
,
vcc
->
qos
.
txtp
.
max_sdu
);
DPRINTK
(
" RX: %d, PCR %d..%d, SDU %d
\n
"
,
vcc
->
qos
.
rxtp
.
traffic_class
,
vcc
->
qos
.
rxtp
.
min_pcr
,
vcc
->
qos
.
rxtp
.
max_pcr
,
vcc
->
qos
.
rxtp
.
max_sdu
);
fops_get
(
dev
->
ops
);
__module_get
(
dev
->
ops
->
owner
);
if
(
dev
->
ops
->
open
)
{
error
=
dev
->
ops
->
open
(
vcc
,
vpi
,
vci
);
if
(
error
)
{
fops_put
(
dev
->
ops
);
module_put
(
dev
->
ops
->
owner
);
bind_vcc
(
vcc
,
NULL
);
return
error
;
}
...
...
@@ -298,14 +295,13 @@ static int atm_do_connect(struct atm_vcc *vcc,int itf,int vpi,int vci)
struct
atm_dev
*
dev
;
int
return_val
;
spin_lock
(
&
atm_dev_lock
);
dev
=
atm_find_dev
(
itf
);
dev
=
atm_dev_lookup
(
itf
);
if
(
!
dev
)
return_val
=
-
ENODEV
;
else
else
{
return_val
=
atm_do_connect_dev
(
vcc
,
dev
,
vpi
,
vci
);
spin_unlock
(
&
atm_dev_lock
);
if
(
return_val
)
atm_dev_release
(
dev
);
}
return
return_val
;
}
...
...
@@ -336,15 +332,20 @@ int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
}
else
{
struct
atm_dev
*
dev
=
NULL
;
struct
list_head
*
p
;
struct
list_head
*
p
,
*
next
;
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
{
spin_lock
(
&
atm_dev_lock
);
list_for_each
_safe
(
p
,
next
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
if
(
!
atm_do_connect_dev
(
vcc
,
dev
,
vpi
,
vci
))
break
;
atm_dev_hold
(
dev
);
spin_unlock
(
&
atm_dev_lock
);
if
(
!
atm_do_connect_dev
(
vcc
,
dev
,
vpi
,
vci
))
break
;
atm_dev_release
(
dev
);
dev
=
NULL
;
spin_lock
(
&
atm_dev_lock
);
}
spin_unlock
(
&
atm_dev_lock
);
spin_unlock
(
&
atm_dev_lock
);
if
(
!
dev
)
return
-
ENODEV
;
}
if
(
vpi
==
ATM_VPI_UNSPEC
||
vci
==
ATM_VCI_UNSPEC
)
...
...
@@ -562,7 +563,6 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
int
error
,
len
,
size
,
number
,
ret_val
;
ret_val
=
0
;
spin_lock
(
&
atm_dev_lock
);
vcc
=
ATM_SD
(
sock
);
switch
(
cmd
)
{
case
SIOCOUTQ
:
...
...
@@ -600,14 +600,17 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
goto
done
;
}
size
=
0
;
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
size
+=
sizeof
(
int
);
if
(
size
>
len
)
{
spin_unlock
(
&
atm_dev_lock
);
ret_val
=
-
E2BIG
;
goto
done
;
}
tmp_buf
=
kmalloc
(
size
,
GFP_KERNEL
);
tmp_buf
=
kmalloc
(
size
,
GFP_ATOMIC
);
if
(
!
tmp_buf
)
{
spin_unlock
(
&
atm_dev_lock
);
ret_val
=
-
ENOMEM
;
goto
done
;
}
...
...
@@ -616,6 +619,7 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
*
tmp_p
++
=
dev
->
number
;
}
spin_unlock
(
&
atm_dev_lock
);
ret_val
=
((
copy_to_user
(
buf
,
tmp_buf
,
size
))
||
put_user
(
size
,
&
((
struct
atm_iobuf
*
)
arg
)
->
length
)
)
?
-
EFAULT
:
0
;
...
...
@@ -840,7 +844,7 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
ret_val
=
-
EFAULT
;
goto
done
;
}
if
(
!
(
dev
=
atm_
find_dev
(
number
)))
{
if
(
!
(
dev
=
atm_
dev_lookup
(
number
)))
{
ret_val
=
-
ENODEV
;
goto
done
;
}
...
...
@@ -851,14 +855,14 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
size
=
strlen
(
dev
->
type
)
+
1
;
if
(
copy_to_user
(
buf
,
dev
->
type
,
size
))
{
ret_val
=
-
EFAULT
;
goto
done
;
goto
done
_release
;
}
break
;
case
ATM_GETESI
:
size
=
ESI_LEN
;
if
(
copy_to_user
(
buf
,
dev
->
esi
,
size
))
{
ret_val
=
-
EFAULT
;
goto
done
;
goto
done
_release
;
}
break
;
case
ATM_SETESI
:
...
...
@@ -868,7 +872,7 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
for
(
i
=
0
;
i
<
ESI_LEN
;
i
++
)
if
(
dev
->
esi
[
i
])
{
ret_val
=
-
EEXIST
;
goto
done
;
goto
done
_release
;
}
}
/* fall through */
...
...
@@ -878,20 +882,20 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
goto
done
;
goto
done
_release
;
}
if
(
copy_from_user
(
esi
,
buf
,
ESI_LEN
))
{
ret_val
=
-
EFAULT
;
goto
done
;
goto
done
_release
;
}
memcpy
(
dev
->
esi
,
esi
,
ESI_LEN
);
ret_val
=
ESI_LEN
;
goto
done
;
goto
done
_release
;
}
case
ATM_GETSTATZ
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
goto
done
;
goto
done
_release
;
}
/* fall through */
case
ATM_GETSTAT
:
...
...
@@ -899,27 +903,27 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
error
=
fetch_stats
(
dev
,
buf
,
cmd
==
ATM_GETSTATZ
);
if
(
error
)
{
ret_val
=
error
;
goto
done
;
goto
done
_release
;
}
break
;
case
ATM_GETCIRANGE
:
size
=
sizeof
(
struct
atm_cirange
);
if
(
copy_to_user
(
buf
,
&
dev
->
ci_range
,
size
))
{
ret_val
=
-
EFAULT
;
goto
done
;
goto
done
_release
;
}
break
;
case
ATM_GETLINKRATE
:
size
=
sizeof
(
int
);
if
(
copy_to_user
(
buf
,
&
dev
->
link_rate
,
size
))
{
ret_val
=
-
EFAULT
;
goto
done
;
goto
done
_release
;
}
break
;
case
ATM_RSTADDR
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
goto
done
;
goto
done
_release
;
}
atm_reset_addr
(
dev
);
break
;
...
...
@@ -927,20 +931,20 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
case
ATM_DELADDR
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
goto
done
;
goto
done
_release
;
}
{
struct
sockaddr_atmsvc
addr
;
if
(
copy_from_user
(
&
addr
,
buf
,
sizeof
(
addr
)))
{
ret_val
=
-
EFAULT
;
goto
done
;
goto
done
_release
;
}
if
(
cmd
==
ATM_ADDADDR
)
ret_val
=
atm_add_addr
(
dev
,
&
addr
);
else
ret_val
=
atm_del_addr
(
dev
,
&
addr
);
goto
done
;
goto
done
_release
;
}
case
ATM_GETADDR
:
size
=
atm_get_addr
(
dev
,
buf
,
len
);
...
...
@@ -951,13 +955,13 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
write the length" */
ret_val
=
put_user
(
size
,
&
((
struct
atmif_sioc
*
)
arg
)
->
length
)
?
-
EFAULT
:
0
;
goto
done
;
goto
done
_release
;
case
ATM_SETLOOP
:
if
(
__ATM_LM_XTRMT
((
int
)
(
long
)
buf
)
&&
__ATM_LM_XTLOC
((
int
)
(
long
)
buf
)
>
__ATM_LM_XTRMT
((
int
)
(
long
)
buf
))
{
ret_val
=
-
EINVAL
;
goto
done
;
goto
done
_release
;
}
/* fall through */
case
ATM_SETCIRANGE
:
...
...
@@ -967,18 +971,18 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
case
SONET_SETFRAMING
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
ret_val
=
-
EPERM
;
goto
done
;
goto
done
_release
;
}
/* fall through */
default:
if
(
!
dev
->
ops
->
ioctl
)
{
ret_val
=
-
EINVAL
;
goto
done
;
goto
done
_release
;
}
size
=
dev
->
ops
->
ioctl
(
dev
,
cmd
,
buf
);
if
(
size
<
0
)
{
ret_val
=
(
size
==
-
ENOIOCTLCMD
?
-
EINVAL
:
size
);
goto
done
;
goto
done
_release
;
}
}
...
...
@@ -987,9 +991,10 @@ int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
-
EFAULT
:
0
;
else
ret_val
=
0
;
done_release:
atm_dev_release
(
dev
);
done:
spin_unlock
(
&
atm_dev_lock
);
done:
return
ret_val
;
}
...
...
net/atm/lec.c
View file @
861c1242
...
...
@@ -554,6 +554,7 @@ static struct atm_dev lecatm_dev = {
.
ops
=
&
lecdev_ops
,
.
type
=
"lec"
,
.
number
=
999
,
/* dummy device number */
.
lock
=
SPIN_LOCK_UNLOCKED
};
/*
...
...
net/atm/mpc.c
View file @
861c1242
...
...
@@ -746,6 +746,7 @@ static struct atm_dev mpc_dev = {
.
ops
=
&
mpc_ops
,
.
type
=
"mpc"
,
.
number
=
42
,
.
lock
=
SPIN_LOCK_UNLOCKED
/* members not explicitly initialised will be 0 */
};
...
...
net/atm/proc.c
View file @
861c1242
...
...
@@ -86,6 +86,7 @@ static void dev_info(const struct atm_dev *dev,char *buf)
add_stats
(
buf
,
"0"
,
&
dev
->
stats
.
aal0
);
strcat
(
buf
,
" "
);
add_stats
(
buf
,
"5"
,
&
dev
->
stats
.
aal5
);
sprintf
(
strchr
(
buf
,
0
),
"
\t
[%d]"
,
atomic_read
(
&
dev
->
refcnt
));
strcat
(
buf
,
"
\n
"
);
}
...
...
@@ -163,7 +164,7 @@ static void atmarp_info(struct net_device *dev,struct atmarp_entry *entry,
#endif
static
void
pvc_info
(
struct
atm_vcc
*
vcc
,
char
*
buf
)
static
void
pvc_info
(
struct
atm_vcc
*
vcc
,
char
*
buf
,
int
clip_info
)
{
static
const
char
*
class_name
[]
=
{
"off"
,
"UBR"
,
"CBR"
,
"VBR"
,
"ABR"
};
static
const
char
*
aal_name
[]
=
{
...
...
@@ -180,8 +181,7 @@ static void pvc_info(struct atm_vcc *vcc,char *buf)
class_name
[
vcc
->
qos
.
rxtp
.
traffic_class
],
vcc
->
qos
.
txtp
.
min_pcr
,
class_name
[
vcc
->
qos
.
txtp
.
traffic_class
]);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if
(
try_atm_clip_ops
())
{
if
(
vcc
->
push
==
atm_clip_ops
->
clip_push
)
{
if
(
clip_info
&&
(
vcc
->
push
==
atm_clip_ops
->
clip_push
))
{
struct
clip_vcc
*
clip_vcc
=
CLIP_VCC
(
vcc
);
struct
net_device
*
dev
;
...
...
@@ -193,8 +193,6 @@ static void pvc_info(struct atm_vcc *vcc,char *buf)
else
off
+=
sprintf
(
buf
+
off
,
"None"
);
}
module_put
(
atm_clip_ops
->
owner
);
}
#endif
strcpy
(
buf
+
off
,
"
\n
"
);
}
...
...
@@ -314,16 +312,19 @@ static int atm_devices_info(loff_t pos,char *buf)
if
(
!
pos
)
{
return
sprintf
(
buf
,
"Itf Type ESI/
\"
MAC
\"
addr "
"AAL(TX,err,RX,err,drop) ...
\n
"
);
"AAL(TX,err,RX,err,drop) ...
[refcnt]
\n
"
);
}
left
=
pos
-
1
;
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
if
(
left
--
==
0
)
{
dev_info
(
dev
,
buf
);
spin_unlock
(
&
atm_dev_lock
);
return
strlen
(
buf
);
}
}
spin_unlock
(
&
atm_dev_lock
);
return
0
;
}
...
...
@@ -334,31 +335,50 @@ static int atm_devices_info(loff_t pos,char *buf)
static
int
atm_pvc_info
(
loff_t
pos
,
char
*
buf
)
{
unsigned
long
flags
;
struct
atm_dev
*
dev
;
struct
list_head
*
p
;
struct
atm_vcc
*
vcc
;
int
left
;
int
left
,
clip_info
=
0
;
if
(
!
pos
)
{
return
sprintf
(
buf
,
"Itf VPI VCI AAL RX(PCR,Class) "
"TX(PCR,Class)
\n
"
);
}
left
=
pos
-
1
;
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if
(
try_atm_clip_ops
())
clip_info
=
1
;
#endif
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
vcc
=
dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
(
vcc
->
sk
->
family
==
PF_ATMPVC
&&
vcc
->
dev
&&
!
left
--
)
{
pvc_info
(
vcc
,
buf
);
if
(
vcc
->
sk
->
family
==
PF_ATMPVC
&&
vcc
->
dev
&&
!
left
--
)
{
pvc_info
(
vcc
,
buf
,
clip_info
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
spin_unlock
(
&
atm_dev_lock
);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if
(
clip_info
)
module_put
(
atm_clip_ops
->
owner
);
#endif
return
strlen
(
buf
);
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
spin_unlock
(
&
atm_dev_lock
);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if
(
clip_info
)
module_put
(
atm_clip_ops
->
owner
);
#endif
return
0
;
}
static
int
atm_vc_info
(
loff_t
pos
,
char
*
buf
)
{
unsigned
long
flags
;
struct
atm_dev
*
dev
;
struct
list_head
*
p
;
struct
atm_vcc
*
vcc
;
...
...
@@ -369,19 +389,20 @@ static int atm_vc_info(loff_t pos,char *buf)
"Address"
,
" Itf VPI VCI Fam Flags Reply Send buffer"
" Recv buffer
\n
"
);
left
=
pos
-
1
;
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
vcc
=
dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
(
!
left
--
)
{
vc_info
(
vcc
,
buf
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
spin_unlock
(
&
atm_dev_lock
);
return
strlen
(
buf
);
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
for
(
vcc
=
nodev_vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
(
!
left
--
)
{
vc_info
(
vcc
,
buf
);
return
strlen
(
buf
);
}
spin_unlock
(
&
atm_dev_lock
);
return
0
;
}
...
...
@@ -389,6 +410,7 @@ static int atm_vc_info(loff_t pos,char *buf)
static
int
atm_svc_info
(
loff_t
pos
,
char
*
buf
)
{
unsigned
long
flags
;
struct
atm_dev
*
dev
;
struct
list_head
*
p
;
struct
atm_vcc
*
vcc
;
...
...
@@ -397,19 +419,21 @@ static int atm_svc_info(loff_t pos,char *buf)
if
(
!
pos
)
return
sprintf
(
buf
,
"Itf VPI VCI State Remote
\n
"
);
left
=
pos
-
1
;
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
for
(
vcc
=
dev
->
vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
(
vcc
->
sk
->
family
==
PF_ATMSVC
&&
!
left
--
)
{
svc_info
(
vcc
,
buf
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
spin_unlock
(
&
atm_dev_lock
);
return
strlen
(
buf
);
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
for
(
vcc
=
nodev_vccs
;
vcc
;
vcc
=
vcc
->
next
)
if
(
vcc
->
sk
->
family
==
PF_ATMSVC
&&
!
left
--
)
{
svc_info
(
vcc
,
buf
);
return
strlen
(
buf
);
}
spin_unlock
(
&
atm_dev_lock
);
return
0
;
}
...
...
net/atm/resources.c
View file @
861c1242
...
...
@@ -27,10 +27,8 @@
LIST_HEAD
(
atm_devs
);
struct
atm_vcc
*
nodev_vccs
=
NULL
;
extern
spinlock_t
atm_dev_lock
;
spinlock_t
atm_dev_lock
=
SPIN_LOCK_UNLOCKED
;
/* Caller must hold atm_dev_lock. */
static
struct
atm_dev
*
__alloc_atm_dev
(
const
char
*
type
)
{
struct
atm_dev
*
dev
;
...
...
@@ -42,67 +40,78 @@ static struct atm_dev *__alloc_atm_dev(const char *type)
dev
->
type
=
type
;
dev
->
signal
=
ATM_PHY_SIG_UNKNOWN
;
dev
->
link_rate
=
ATM_OC3_PCR
;
list_add_tail
(
&
dev
->
dev_list
,
&
atm_devs
);
spin_lock_init
(
&
dev
->
lock
);
return
dev
;
}
/* Caller must hold atm_dev_lock. */
static
void
__free_atm_dev
(
struct
atm_dev
*
dev
)
{
list_del
(
&
dev
->
dev_list
);
kfree
(
dev
);
}
/* Caller must hold atm_dev_lock. */
struct
atm_dev
*
atm_find_dev
(
int
number
)
static
struct
atm_dev
*
__atm_dev_lookup
(
int
number
)
{
struct
atm_dev
*
dev
;
struct
list_head
*
p
;
list_for_each
(
p
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
if
(
dev
->
ops
&&
dev
->
number
==
number
)
if
((
dev
->
ops
)
&&
(
dev
->
number
==
number
))
{
atm_dev_hold
(
dev
);
return
dev
;
}
}
return
NULL
;
}
struct
atm_dev
*
atm_dev_register
(
const
char
*
type
,
const
struct
atmdev_ops
*
ops
,
int
number
,
unsigned
long
*
flags
)
struct
atm_dev
*
atm_dev_lookup
(
int
number
)
{
struct
atm_dev
*
dev
;
spin_lock
(
&
atm_dev_lock
);
dev
=
__atm_dev_lookup
(
number
);
spin_unlock
(
&
atm_dev_lock
);
return
dev
;
}
struct
atm_dev
*
atm_dev_register
(
const
char
*
type
,
const
struct
atmdev_ops
*
ops
,
int
number
,
unsigned
long
*
flags
)
{
struct
atm_dev
*
dev
,
*
inuse
;
dev
=
__alloc_atm_dev
(
type
);
if
(
!
dev
)
{
printk
(
KERN_ERR
"atm_dev_register: no space for dev %s
\n
"
,
type
);
goto
done
;
return
NULL
;
}
spin_lock
(
&
atm_dev_lock
);
if
(
number
!=
-
1
)
{
if
(
atm_find_dev
(
number
))
{
if
((
inuse
=
__atm_dev_lookup
(
number
)))
{
atm_dev_release
(
inuse
);
spin_unlock
(
&
atm_dev_lock
);
__free_atm_dev
(
dev
);
dev
=
NULL
;
goto
done
;
return
NULL
;
}
dev
->
number
=
number
;
}
else
{
dev
->
number
=
0
;
while
(
atm_find_dev
(
dev
->
number
))
while
((
inuse
=
__atm_dev_lookup
(
dev
->
number
)))
{
atm_dev_release
(
inuse
);
dev
->
number
++
;
}
dev
->
vccs
=
dev
->
last
=
NULL
;
dev
->
dev_data
=
NULL
;
barrier
();
}
dev
->
ops
=
ops
;
if
(
flags
)
dev
->
flags
=
*
flags
;
else
memset
(
&
dev
->
flags
,
0
,
sizeof
(
dev
->
flags
));
memset
(
&
dev
->
stats
,
0
,
sizeof
(
dev
->
stats
));
atomic_set
(
&
dev
->
refcnt
,
1
);
list_add_tail
(
&
dev
->
dev_list
,
&
atm_devs
);
spin_unlock
(
&
atm_dev_lock
);
#ifdef CONFIG_PROC_FS
if
(
ops
->
proc_read
)
{
...
...
@@ -110,33 +119,50 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
printk
(
KERN_ERR
"atm_dev_register: "
"atm_proc_dev_register failed for dev %s
\n
"
,
type
);
spin_lock
(
&
atm_dev_lock
);
list_del
(
&
dev
->
dev_list
);
spin_unlock
(
&
atm_dev_lock
);
__free_atm_dev
(
dev
);
dev
=
NULL
;
goto
done
;
return
NULL
;
}
}
#endif
done:
spin_unlock
(
&
atm_dev_lock
);
return
dev
;
}
void
atm_dev_deregister
(
struct
atm_dev
*
dev
)
{
unsigned
long
warning_time
;
#ifdef CONFIG_PROC_FS
if
(
dev
->
ops
->
proc_read
)
atm_proc_dev_deregister
(
dev
);
#endif
spin_lock
(
&
atm_dev_lock
);
__free_atm_dev
(
dev
);
list_del
(
&
dev
->
dev_list
);
spin_unlock
(
&
atm_dev_lock
);
warning_time
=
jiffies
;
while
(
atomic_read
(
&
dev
->
refcnt
)
!=
1
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
HZ
/
4
);
current
->
state
=
TASK_RUNNING
;
if
((
jiffies
-
warning_time
)
>
10
*
HZ
)
{
printk
(
KERN_EMERG
"atm_dev_deregister: waiting for "
"dev %d to become free. Usage count = %d
\n
"
,
dev
->
number
,
atomic_read
(
&
dev
->
refcnt
));
warning_time
=
jiffies
;
}
}
__free_atm_dev
(
dev
);
}
void
shutdown_atm_dev
(
struct
atm_dev
*
dev
)
{
if
(
dev
->
vccs
)
{
if
(
atomic_read
(
&
dev
->
refcnt
)
>
1
)
{
set_bit
(
ATM_DF_CLOSE
,
&
dev
->
flags
);
return
;
}
...
...
@@ -161,44 +187,44 @@ struct sock *alloc_atm_vcc_sk(int family)
sock_init_data
(
NULL
,
sk
);
memset
(
vcc
,
0
,
sizeof
(
*
vcc
));
vcc
->
sk
=
sk
;
if
(
nodev_vccs
)
nodev_vccs
->
prev
=
vcc
;
vcc
->
prev
=
NULL
;
vcc
->
next
=
nodev_vccs
;
nodev_vccs
=
vcc
;
return
sk
;
}
static
void
unlink_vcc
(
struct
atm_vcc
*
vcc
,
struct
atm_dev
*
hold_dev
)
static
void
unlink_vcc
(
struct
atm_vcc
*
vcc
)
{
unsigned
long
flags
;
if
(
vcc
->
dev
)
{
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
if
(
vcc
->
prev
)
vcc
->
prev
->
next
=
vcc
->
next
;
else
if
(
vcc
->
dev
)
vcc
->
dev
->
vccs
=
vcc
->
next
;
else
nodev_vccs
=
vcc
->
next
;
vcc
->
dev
->
vccs
=
vcc
->
next
;
if
(
vcc
->
next
)
vcc
->
next
->
prev
=
vcc
->
prev
;
else
if
(
vcc
->
dev
)
else
vcc
->
dev
->
last
=
vcc
->
prev
;
if
(
vcc
->
dev
&&
vcc
->
dev
!=
hold_dev
&&
!
vcc
->
dev
->
vccs
&&
test_bit
(
ATM_DF_CLOSE
,
&
vcc
->
dev
->
flags
))
shutdown_atm_dev
(
vcc
->
dev
);
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
}
}
void
free_atm_vcc_sk
(
struct
sock
*
sk
)
{
unlink_vcc
(
atm_sk
(
sk
)
,
NULL
);
unlink_vcc
(
atm_sk
(
sk
));
sk_free
(
sk
);
}
void
bind_vcc
(
struct
atm_vcc
*
vcc
,
struct
atm_dev
*
dev
)
{
unlink_vcc
(
vcc
,
dev
);
unsigned
long
flags
;
unlink_vcc
(
vcc
);
vcc
->
dev
=
dev
;
if
(
dev
)
{
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
vcc
->
next
=
NULL
;
vcc
->
prev
=
dev
->
last
;
if
(
dev
->
vccs
)
...
...
@@ -206,17 +232,12 @@ void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev)
else
dev
->
vccs
=
vcc
;
dev
->
last
=
vcc
;
}
else
{
if
(
nodev_vccs
)
nodev_vccs
->
prev
=
vcc
;
vcc
->
next
=
nodev_vccs
;
vcc
->
prev
=
NULL
;
nodev_vccs
=
vcc
;
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
}
EXPORT_SYMBOL
(
atm_dev_register
);
EXPORT_SYMBOL
(
atm_dev_deregister
);
EXPORT_SYMBOL
(
atm_
find_dev
);
EXPORT_SYMBOL
(
atm_
dev_lookup
);
EXPORT_SYMBOL
(
shutdown_atm_dev
);
EXPORT_SYMBOL
(
bind_vcc
);
net/atm/resources.h
View file @
861c1242
...
...
@@ -11,7 +11,7 @@
extern
struct
list_head
atm_devs
;
extern
s
truct
atm_vcc
*
nodev_vccs
;
/* VCCs not linked to any device */
extern
s
pinlock_t
atm_dev_lock
;
struct
sock
*
alloc_atm_vcc_sk
(
int
family
);
...
...
net/atm/signaling.c
View file @
861c1242
...
...
@@ -33,7 +33,6 @@
struct
atm_vcc
*
sigd
=
NULL
;
static
DECLARE_WAIT_QUEUE_HEAD
(
sigd_sleep
);
extern
spinlock_t
atm_dev_lock
;
static
void
sigd_put_skb
(
struct
sk_buff
*
skb
)
{
...
...
@@ -211,6 +210,7 @@ static void purge_vccs(struct atm_vcc *vcc)
static
void
sigd_close
(
struct
atm_vcc
*
vcc
)
{
unsigned
long
flags
;
struct
atm_dev
*
dev
;
struct
list_head
*
p
;
...
...
@@ -219,33 +219,29 @@ static void sigd_close(struct atm_vcc *vcc)
if
(
skb_peek
(
&
vcc
->
sk
->
receive_queue
))
printk
(
KERN_ERR
"sigd_close: closing with requests pending
\n
"
);
skb_queue_purge
(
&
vcc
->
sk
->
receive_queue
);
purge_vccs
(
nodev_vccs
);
spin_lock
(
&
atm_dev_lock
);
spin_lock
(
&
atm_dev_lock
);
list_for_each
(
p
,
&
atm_devs
)
{
dev
=
list_entry
(
p
,
struct
atm_dev
,
dev_list
);
spin_lock_irqsave
(
&
dev
->
lock
,
flags
);
purge_vccs
(
dev
->
vccs
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
spin_unlock
(
&
atm_dev_lock
);
spin_unlock
(
&
atm_dev_lock
);
}
static
struct
atmdev_ops
sigd_dev_ops
=
{
.
close
=
sigd_close
,
.
close
=
sigd_close
,
.
send
=
sigd_send
};
static
struct
atm_dev
sigd_dev
=
{
&
sigd_dev_ops
,
NULL
,
/* no PHY */
"sig"
,
/* type */
999
,
/* dummy device number */
NULL
,
NULL
,
/* pretend not to have any VCCs */
NULL
,
NULL
,
/* no data */
0
,
/* no flags */
NULL
,
/* no local address */
{
0
}
/* no ESI, no statistics */
.
ops
=
&
sigd_dev_ops
,
.
type
=
"sig"
,
.
number
=
999
,
.
lock
=
SPIN_LOCK_UNLOCKED
};
...
...
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