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
3c81501f
Commit
3c81501f
authored
Jun 16, 2003
by
Chas Williams
Committed by
David S. Miller
Jun 16, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ATM]: Keep vcc's on global list instead of per device.
parent
f6932f56
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
312 additions
and
315 deletions
+312
-315
drivers/atm/atmtcp.c
drivers/atm/atmtcp.c
+31
-18
drivers/atm/eni.c
drivers/atm/eni.c
+29
-18
drivers/atm/fore200e.c
drivers/atm/fore200e.c
+34
-20
drivers/atm/he.c
drivers/atm/he.c
+13
-39
drivers/atm/idt77252.c
drivers/atm/idt77252.c
+17
-11
include/linux/atmdev.h
include/linux/atmdev.h
+6
-5
net/atm/atm_misc.c
net/atm/atm_misc.c
+10
-6
net/atm/clip.c
net/atm/clip.c
+2
-1
net/atm/common.c
net/atm/common.c
+94
-25
net/atm/common.h
net/atm/common.h
+2
-3
net/atm/lec.c
net/atm/lec.c
+3
-2
net/atm/mpc.c
net/atm/mpc.c
+3
-2
net/atm/proc.c
net/atm/proc.c
+32
-51
net/atm/pvc.c
net/atm/pvc.c
+2
-6
net/atm/resources.c
net/atm/resources.c
+3
-74
net/atm/resources.h
net/atm/resources.h
+0
-2
net/atm/signaling.c
net/atm/signaling.c
+17
-21
net/atm/svc.c
net/atm/svc.c
+14
-11
No files found.
drivers/atm/atmtcp.c
View file @
3c81501f
...
...
@@ -153,9 +153,9 @@ 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
;
struct
sock
*
s
;
if
(
cmd
!=
ATM_SETCIRANGE
)
return
-
ENOIOCTLCMD
;
if
(
copy_from_user
(
&
ci
,(
void
*
)
arg
,
sizeof
(
ci
)))
return
-
EFAULT
;
...
...
@@ -163,14 +163,18 @@ 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
)
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
!=
dev
)
continue
;
if
((
vcc
->
vpi
>>
ci
.
vpi_bits
)
||
(
vcc
->
vci
>>
ci
.
vci_bits
))
{
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
-
EBUSY
;
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
read_unlock
(
&
vcc_sklist_lock
);
dev
->
ci_range
=
ci
;
return
0
;
}
...
...
@@ -233,9 +237,9 @@ 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
sock
*
s
;
struct
atm_vcc
*
walk
;
atmtcp_dev
=
(
struct
atm_dev
*
)
vcc
->
dev_data
;
...
...
@@ -246,19 +250,23 @@ 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
)
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
atmtcp_dev
)
continue
;
wake_up
(
&
walk
->
sleep
);
spin_unlock_irqrestore
(
&
atmtcp_dev
->
lock
,
flags
);
}
read_unlock
(
&
vcc_sklist_lock
);
}
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
;
struct
sock
*
s
;
struct
atm_vcc
*
out_vcc
=
NULL
;
struct
sk_buff
*
new_skb
;
int
result
=
0
;
...
...
@@ -270,13 +278,17 @@ 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
)
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
out_vcc
=
atm_sk
(
s
);
if
(
out_vcc
->
dev
!=
dev
)
continue
;
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
);
}
read_unlock
(
&
vcc_sklist_lock
);
if
(
!
out_vcc
)
{
atomic_inc
(
&
vcc
->
stats
->
tx_err
);
goto
done
;
...
...
@@ -366,7 +378,7 @@ int atmtcp_attach(struct atm_vcc *vcc,int itf)
if
(
itf
!=
-
1
)
dev
=
atm_dev_lookup
(
itf
);
if
(
dev
)
{
if
(
dev
->
ops
!=
&
atmtcp_v_dev_ops
)
{
atm_dev_
release
(
dev
);
atm_dev_
put
(
dev
);
return
-
EMEDIUMTYPE
;
}
if
(
PRIV
(
dev
)
->
vcc
)
return
-
EBUSY
;
...
...
@@ -378,7 +390,8 @@ int atmtcp_attach(struct atm_vcc *vcc,int itf)
if
(
error
)
return
error
;
}
PRIV
(
dev
)
->
vcc
=
vcc
;
bind_vcc
(
vcc
,
&
atmtcp_control_dev
);
vcc
->
dev
=
&
atmtcp_control_dev
;
vcc_insert_socket
(
vcc
->
sk
);
set_bit
(
ATM_VF_META
,
&
vcc
->
flags
);
set_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
vcc
->
dev_data
=
dev
;
...
...
@@ -402,7 +415,7 @@ int atmtcp_remove_persistent(int itf)
dev
=
atm_dev_lookup
(
itf
);
if
(
!
dev
)
return
-
ENODEV
;
if
(
dev
->
ops
!=
&
atmtcp_v_dev_ops
)
{
atm_dev_
release
(
dev
);
atm_dev_
put
(
dev
);
return
-
EMEDIUMTYPE
;
}
dev_data
=
PRIV
(
dev
);
...
...
@@ -410,7 +423,7 @@ int atmtcp_remove_persistent(int itf)
dev_data
->
persist
=
0
;
if
(
PRIV
(
dev
)
->
vcc
)
return
0
;
kfree
(
dev_data
);
atm_dev_
release
(
dev
);
atm_dev_
put
(
dev
);
shutdown_atm_dev
(
dev
);
return
0
;
}
...
...
drivers/atm/eni.c
View file @
3c81501f
...
...
@@ -1887,10 +1887,10 @@ static void eni_close(struct atm_vcc *vcc)
static
int
get_ci
(
struct
atm_vcc
*
vcc
,
short
*
vpi
,
int
*
vci
)
{
unsigned
long
flag
s
;
struct
sock
*
s
;
struct
atm_vcc
*
walk
;
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
read_lock
(
&
vcc_sklist_lock
);
if
(
*
vpi
==
ATM_VPI_ANY
)
*
vpi
=
0
;
if
(
*
vci
==
ATM_VCI_ANY
)
{
for
(
*
vci
=
ATM_NOT_RSV_VCI
;
*
vci
<
NR_VCI
;
(
*
vci
)
++
)
{
...
...
@@ -1898,40 +1898,47 @@ static int get_ci(struct atm_vcc *vcc,short *vpi,int *vci)
ENI_DEV
(
vcc
->
dev
)
->
rx_map
[
*
vci
])
continue
;
if
(
vcc
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
{
for
(
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
(
test_bit
(
ATM_VF_ADDR
,
&
walk
->
flags
)
&&
walk
->
vci
==
*
vci
&&
walk
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
break
;
if
(
walk
)
continue
;
}
if
(
s
)
continue
;
}
break
;
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
*
vci
==
NR_VCI
?
-
EADDRINUSE
:
0
;
}
if
(
*
vci
==
ATM_VCI_UNSPEC
)
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
0
;
}
if
(
vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
&&
ENI_DEV
(
vcc
->
dev
)
->
rx_map
[
*
vci
])
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
-
EADDRINUSE
;
}
if
(
vcc
->
qos
.
txtp
.
traffic_class
==
ATM_NONE
)
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
0
;
}
for
(
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
(
test_bit
(
ATM_VF_ADDR
,
&
walk
->
flags
)
&&
walk
->
vci
==
*
vci
&&
walk
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
{
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
-
EADDRINUSE
;
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
}
read_unlock
(
&
vcc_sklist_lock
);
return
0
;
}
...
...
@@ -2139,7 +2146,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
flag
s
;
struct
sock
*
s
;
static
const
char
*
signal
[]
=
{
"LOST"
,
"unknown"
,
"okay"
};
struct
eni_dev
*
eni_dev
=
ENI_DEV
(
dev
);
struct
atm_vcc
*
vcc
;
...
...
@@ -2212,11 +2219,15 @@ 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
)
;
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_
next
)
{
struct
eni_vcc
*
eni_vcc
;
int
length
;
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
!=
dev
)
continue
;
eni_vcc
=
ENI_VCC
(
vcc
);
if
(
--
left
)
continue
;
length
=
sprintf
(
page
,
"vcc %4d: "
,
vcc
->
vci
);
if
(
eni_vcc
->
rx
)
{
...
...
@@ -2231,10 +2242,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
);
read_unlock
(
&
vcc_sklist_lock
);
return
length
+
1
;
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
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 @
3c81501f
...
...
@@ -1069,18 +1069,22 @@ fore200e_supply(struct fore200e* fore200e)
static
struct
atm_vcc
*
fore200e_find_vcc
(
struct
fore200e
*
fore200e
,
struct
rpd
*
rpd
)
{
unsigned
long
flag
s
;
struct
sock
*
s
;
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
;
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
!=
fore200e
->
atm_dev
)
continue
;
if
(
vcc
->
vpi
==
rpd
->
atm_header
.
vpi
&&
vcc
->
vci
==
rpd
->
atm_header
.
vci
)
{
read_unlock
(
&
vcc_sklist_lock
);
return
vcc
;
}
}
spin_unlock_irqrestore
(
&
fore200e
->
atm_dev
->
lock
,
flags
);
return
vcc
;
read_unlock
(
&
vcc_sklist_lock
);
return
NULL
;
}
...
...
@@ -1350,20 +1354,23 @@ 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
;
struct
sock
*
s
;
/* find a free VPI */
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
read_lock
(
&
vcc_sklist_lock
);
if
(
*
vpi
==
ATM_VPI_ANY
)
{
for
(
*
vpi
=
0
,
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
{
for
(
*
vpi
=
0
,
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
((
walk
->
vci
==
*
vci
)
&&
(
walk
->
vpi
==
*
vpi
))
{
(
*
vpi
)
++
;
walk
=
vcc
->
dev
->
vccs
;
s
=
vcc_sklist
;
}
}
}
...
...
@@ -1371,16 +1378,19 @@ fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci)
/* find a free VCI */
if
(
*
vci
==
ATM_VCI_ANY
)
{
for
(
*
vci
=
ATM_NOT_RSV_VCI
,
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
{
for
(
*
vci
=
ATM_NOT_RSV_VCI
,
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
((
walk
->
vpi
=
*
vpi
)
&&
(
walk
->
vci
==
*
vci
))
{
*
vci
=
walk
->
vci
+
1
;
walk
=
vcc
->
dev
->
vccs
;
s
=
vcc_sklist
;
}
}
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
0
;
}
...
...
@@ -2642,7 +2652,7 @@ fore200e_module_cleanup(void)
static
int
fore200e_proc_read
(
struct
atm_dev
*
dev
,
loff_t
*
pos
,
char
*
page
)
{
unsigned
long
flag
s
;
struct
sock
*
s
;
struct
fore200e
*
fore200e
=
FORE200E_DEV
(
dev
);
int
len
,
left
=
*
pos
;
...
...
@@ -2889,8 +2899,12 @@ 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
)
{
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
!=
fore200e
->
atm_dev
)
continue
;
fore200e_vcc
=
FORE200E_VCC
(
vcc
);
...
...
@@ -2904,7 +2918,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
);
read_unlock
(
&
vcc_sklist_lock
);
return
len
;
}
...
...
drivers/atm/he.c
View file @
3c81501f
...
...
@@ -79,7 +79,6 @@
#include <linux/sonet.h>
#define USE_TASKLET
#define USE_HE_FIND_VCC
#undef USE_SCATTERGATHER
#undef USE_CHECKSUM_HW
/* still confused about this */
#define USE_RBPS
...
...
@@ -328,25 +327,24 @@ he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7)
static
__inline__
struct
atm_vcc
*
he
_find_vcc
(
struct
he_dev
*
he_dev
,
unsigned
cid
)
_
_find_vcc
(
struct
he_dev
*
he_dev
,
unsigned
cid
)
{
unsigned
long
flags
;
struct
atm_vcc
*
vcc
;
struct
sock
*
s
;
short
vpi
;
int
vci
;
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
)
{
spin_unlock_irqrestore
(
&
he_dev
->
atm_dev
->
lock
,
flags
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
==
he_dev
->
atm_dev
&&
vcc
->
vci
==
vci
&&
vcc
->
vpi
==
vpi
&&
vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
)
{
return
vcc
;
}
spin_unlock_irqrestore
(
&
he_dev
->
atm_dev
->
lock
,
flags
);
}
}
return
NULL
;
}
...
...
@@ -1566,17 +1564,6 @@ he_start(struct atm_dev *dev)
reg
|=
RX_ENABLE
;
he_writel
(
he_dev
,
reg
,
RC_CONFIG
);
#ifndef USE_HE_FIND_VCC
he_dev
->
he_vcc_table
=
kmalloc
(
sizeof
(
struct
he_vcc_table
)
*
(
1
<<
(
he_dev
->
vcibits
+
he_dev
->
vpibits
)),
GFP_KERNEL
);
if
(
he_dev
->
he_vcc_table
==
NULL
)
{
hprintk
(
"failed to alloc he_vcc_table
\n
"
);
return
-
ENOMEM
;
}
memset
(
he_dev
->
he_vcc_table
,
0
,
sizeof
(
struct
he_vcc_table
)
*
(
1
<<
(
he_dev
->
vcibits
+
he_dev
->
vpibits
)));
#endif
for
(
i
=
0
;
i
<
HE_NUM_CS_STPER
;
++
i
)
{
he_dev
->
cs_stper
[
i
].
inuse
=
0
;
he_dev
->
cs_stper
[
i
].
pcr
=
-
1
;
...
...
@@ -1712,11 +1699,6 @@ he_stop(struct he_dev *he_dev)
he_dev
->
tpd_base
,
he_dev
->
tpd_base_phys
);
#endif
#ifndef USE_HE_FIND_VCC
if
(
he_dev
->
he_vcc_table
)
kfree
(
he_dev
->
he_vcc_table
);
#endif
if
(
he_dev
->
pci_dev
)
{
pci_read_config_word
(
he_dev
->
pci_dev
,
PCI_COMMAND
,
&
command
);
command
&=
~
(
PCI_COMMAND_MEMORY
|
PCI_COMMAND_MASTER
);
...
...
@@ -1798,6 +1780,7 @@ he_service_rbrq(struct he_dev *he_dev, int group)
int
pdus_assembled
=
0
;
int
updated
=
0
;
read_lock
(
&
vcc_sklist_lock
);
while
(
he_dev
->
rbrq_head
!=
rbrq_tail
)
{
++
updated
;
...
...
@@ -1823,13 +1806,10 @@ he_service_rbrq(struct he_dev *he_dev, int group)
buf_len
=
RBRQ_BUFLEN
(
he_dev
->
rbrq_head
)
*
4
;
cid
=
RBRQ_CID
(
he_dev
->
rbrq_head
);
#ifdef USE_HE_FIND_VCC
if
(
cid
!=
lastcid
)
vcc
=
he
_find_vcc
(
he_dev
,
cid
);
vcc
=
_
_find_vcc
(
he_dev
,
cid
);
lastcid
=
cid
;
#else
vcc
=
HE_LOOKUP_VCC
(
he_dev
,
cid
);
#endif
if
(
vcc
==
NULL
)
{
hprintk
(
"vcc == NULL (cid 0x%x)
\n
"
,
cid
);
if
(
!
RBRQ_HBUF_ERR
(
he_dev
->
rbrq_head
))
...
...
@@ -1966,6 +1946,7 @@ he_service_rbrq(struct he_dev *he_dev, int group)
RBRQ_MASK
(
++
he_dev
->
rbrq_head
));
}
read_unlock
(
&
vcc_sklist_lock
);
if
(
updated
)
{
if
(
updated
>
he_dev
->
rbrq_peak
)
...
...
@@ -2565,10 +2546,6 @@ he_open(struct atm_vcc *vcc, short vpi, int vci)
#endif
spin_unlock_irqrestore
(
&
he_dev
->
global_lock
,
flags
);
#ifndef USE_HE_FIND_VCC
HE_LOOKUP_VCC
(
he_dev
,
cid
)
=
vcc
;
#endif
}
open_failed:
...
...
@@ -2634,9 +2611,6 @@ he_close(struct atm_vcc *vcc)
if
(
timeout
==
0
)
hprintk
(
"close rx timeout cid 0x%x
\n
"
,
cid
);
#ifndef USE_HE_FIND_VCC
HE_LOOKUP_VCC
(
he_dev
,
cid
)
=
NULL
;
#endif
HPRINTK
(
"close rx cid 0x%x complete
\n
"
,
cid
);
}
...
...
drivers/atm/idt77252.c
View file @
3c81501f
...
...
@@ -2403,37 +2403,43 @@ 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
flag
s
;
struct
sock
*
s
;
struct
atm_vcc
*
walk
;
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
read_lock
(
&
vcc_sklist_lock
);
if
(
*
vpi
==
ATM_VPI_ANY
)
{
*
vpi
=
0
;
walk
=
vcc
->
dev
->
vccs
;
while
(
walk
)
{
s
=
vcc_sklist
;
while
(
s
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
((
walk
->
vci
==
*
vci
)
&&
(
walk
->
vpi
==
*
vpi
))
{
(
*
vpi
)
++
;
walk
=
vcc
->
dev
->
vccs
;
s
=
vcc_sklist
;
continue
;
}
walk
=
walk
->
next
;
s
=
s
->
sk_
next
;
}
}
if
(
*
vci
==
ATM_VCI_ANY
)
{
*
vci
=
ATM_NOT_RSV_VCI
;
walk
=
vcc
->
dev
->
vccs
;
while
(
walk
)
{
s
=
vcc_sklist
;
while
(
s
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
((
walk
->
vci
==
*
vci
)
&&
(
walk
->
vpi
==
*
vpi
))
{
(
*
vci
)
++
;
walk
=
vcc
->
dev
->
vccs
;
s
=
vcc_sklist
;
continue
;
}
walk
=
walk
->
next
;
s
=
s
->
sk_
next
;
}
}
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
0
;
}
...
...
include/linux/atmdev.h
View file @
3c81501f
...
...
@@ -293,7 +293,6 @@ struct atm_vcc {
struct
k_atm_aal_stats
*
stats
;
/* pointer to AAL stats group */
wait_queue_head_t
sleep
;
/* if socket is busy */
struct
sock
*
sk
;
/* socket backpointer */
struct
atm_vcc
*
prev
,
*
next
;
/* SVC part --- may move later ------------------------------------- */
short
itf
;
/* interface number */
struct
sockaddr_atmsvc
local
;
...
...
@@ -320,8 +319,6 @@ struct atm_dev {
/* (NULL) */
const
char
*
type
;
/* device type name */
int
number
;
/* device index */
struct
atm_vcc
*
vccs
;
/* VCC table (or NULL) */
struct
atm_vcc
*
last
;
/* last VCC (or undefined) */
void
*
dev_data
;
/* per-device data */
void
*
phy_data
;
/* private PHY date */
unsigned
long
flags
;
/* device flags (ATM_DF_*) */
...
...
@@ -390,6 +387,9 @@ struct atm_skb_data {
unsigned
long
atm_options
;
/* ATM layer options */
};
extern
struct
sock
*
vcc_sklist
;
extern
rwlock_t
vcc_sklist_lock
;
#define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
struct
atm_dev
*
atm_dev_register
(
const
char
*
type
,
const
struct
atmdev_ops
*
ops
,
...
...
@@ -397,7 +397,8 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
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
);
void
vcc_insert_socket
(
struct
sock
*
sk
);
void
vcc_remove_socket
(
struct
sock
*
sk
);
/*
...
...
@@ -436,7 +437,7 @@ static inline void atm_dev_hold(struct atm_dev *dev)
}
static
inline
void
atm_dev_
release
(
struct
atm_dev
*
dev
)
static
inline
void
atm_dev_
put
(
struct
atm_dev
*
dev
)
{
atomic_dec
(
&
dev
->
refcnt
);
...
...
net/atm/atm_misc.c
View file @
3c81501f
...
...
@@ -47,15 +47,20 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
static
int
check_ci
(
struct
atm_vcc
*
vcc
,
short
vpi
,
int
vci
)
{
struct
sock
*
s
;
struct
atm_vcc
*
walk
;
for
(
walk
=
vcc
->
dev
->
vccs
;
walk
;
walk
=
walk
->
next
)
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
walk
=
atm_sk
(
s
);
if
(
walk
->
dev
!=
vcc
->
dev
)
continue
;
if
(
test_bit
(
ATM_VF_ADDR
,
&
walk
->
flags
)
&&
walk
->
vpi
==
vpi
&&
walk
->
vci
==
vci
&&
((
walk
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
&&
vcc
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
||
(
walk
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
&&
vcc
->
qos
.
rxtp
.
traffic_class
!=
ATM_NONE
)))
return
-
EADDRINUSE
;
}
/* allow VCCs with same VPI/VCI iff they don't collide on
TX/RX (but we may refuse such sharing for other reasons,
e.g. if protocol requires to have both channels) */
...
...
@@ -65,17 +70,16 @@ 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
;
spin_lock_irqsave
(
&
vcc
->
dev
->
lock
,
flags
);
read_lock
(
&
vcc_sklist_lock
);
if
(
*
vpi
!=
ATM_VPI_ANY
&&
*
vci
!=
ATM_VCI_ANY
)
{
err
=
check_ci
(
vcc
,
*
vpi
,
*
vci
);
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
read_unlock
(
&
vcc_sklist_lock
);
return
err
;
}
/* last scan may have left values out of bounds for current device */
...
...
@@ -90,7 +94,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
);
read_unlock
(
&
vcc_sklist_lock
);
return
0
;
}
if
(
*
vci
==
ATM_VCI_ANY
)
{
...
...
@@ -105,7 +109,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
);
read_unlock
(
&
vcc_sklist_lock
);
return
-
EADDRINUSE
;
}
...
...
net/atm/clip.c
View file @
3c81501f
...
...
@@ -737,7 +737,8 @@ static int atm_init_atmarp(struct atm_vcc *vcc)
set_bit
(
ATM_VF_META
,
&
vcc
->
flags
);
set_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
/* allow replies and avoid getting closed if signaling dies */
bind_vcc
(
vcc
,
&
atmarpd_dev
);
vcc
->
dev
=
&
atmarpd_dev
;
vcc_insert_socket
(
vcc
->
sk
);
vcc
->
push
=
NULL
;
vcc
->
pop
=
NULL
;
/* crash */
vcc
->
push_oam
=
NULL
;
/* crash */
...
...
net/atm/common.c
View file @
3c81501f
...
...
@@ -157,6 +157,38 @@ EXPORT_SYMBOL(br2684_ioctl_hook);
#endif
struct
sock
*
vcc_sklist
;
rwlock_t
vcc_sklist_lock
=
RW_LOCK_UNLOCKED
;
void
__vcc_insert_socket
(
struct
sock
*
sk
)
{
sk
->
sk_next
=
vcc_sklist
;
if
(
sk
->
sk_next
)
vcc_sklist
->
sk_pprev
=
&
sk
->
sk_next
;
vcc_sklist
=
sk
;
sk
->
sk_pprev
=
&
vcc_sklist
;
}
void
vcc_insert_socket
(
struct
sock
*
sk
)
{
write_lock_irq
(
&
vcc_sklist_lock
);
__vcc_insert_socket
(
sk
);
write_unlock_irq
(
&
vcc_sklist_lock
);
}
void
vcc_remove_socket
(
struct
sock
*
sk
)
{
write_lock_irq
(
&
vcc_sklist_lock
);
if
(
sk
->
sk_pprev
)
{
if
(
sk
->
sk_next
)
sk
->
sk_next
->
sk_pprev
=
sk
->
sk_pprev
;
*
sk
->
sk_pprev
=
sk
->
sk_next
;
sk
->
sk_pprev
=
NULL
;
}
write_unlock_irq
(
&
vcc_sklist_lock
);
}
static
struct
sk_buff
*
alloc_tx
(
struct
atm_vcc
*
vcc
,
unsigned
int
size
)
{
struct
sk_buff
*
skb
;
...
...
@@ -175,16 +207,45 @@ static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
}
int
atm_create
(
struct
socket
*
sock
,
int
protocol
,
int
family
)
EXPORT_SYMBOL
(
vcc_sklist
);
EXPORT_SYMBOL
(
vcc_sklist_lock
);
EXPORT_SYMBOL
(
vcc_insert_socket
);
EXPORT_SYMBOL
(
vcc_remove_socket
);
static
void
vcc_sock_destruct
(
struct
sock
*
sk
)
{
struct
atm_vcc
*
vcc
=
atm_sk
(
sk
);
if
(
atomic_read
(
&
vcc
->
sk
->
sk_rmem_alloc
))
printk
(
KERN_DEBUG
"vcc_sock_destruct: rmem leakage (%d bytes) detected.
\n
"
,
atomic_read
(
&
sk
->
sk_rmem_alloc
));
if
(
atomic_read
(
&
vcc
->
sk
->
sk_wmem_alloc
))
printk
(
KERN_DEBUG
"vcc_sock_destruct: wmem leakage (%d bytes) detected.
\n
"
,
atomic_read
(
&
sk
->
sk_wmem_alloc
));
kfree
(
sk
->
sk_protinfo
);
}
int
vcc_create
(
struct
socket
*
sock
,
int
protocol
,
int
family
)
{
struct
sock
*
sk
;
struct
atm_vcc
*
vcc
;
sock
->
sk
=
NULL
;
if
(
sock
->
type
==
SOCK_STREAM
)
return
-
EINVAL
;
if
(
!
(
sk
=
alloc_atm_vcc_sk
(
family
)))
return
-
ENOMEM
;
vcc
=
atm_sk
(
sk
);
memset
(
&
vcc
->
flags
,
0
,
sizeof
(
vcc
->
flags
));
if
(
sock
->
type
==
SOCK_STREAM
)
return
-
EINVAL
;
sk
=
sk_alloc
(
family
,
GFP_KERNEL
,
1
,
NULL
);
if
(
!
sk
)
return
-
ENOMEM
;
sock_init_data
(
NULL
,
sk
);
vcc
=
atm_sk
(
sk
)
=
kmalloc
(
sizeof
(
*
vcc
),
GFP_KERNEL
);
if
(
!
vcc
)
{
sk_free
(
sk
);
return
-
ENOMEM
;
}
memset
(
vcc
,
0
,
sizeof
(
*
vcc
));
vcc
->
sk
=
sk
;
vcc
->
dev
=
NULL
;
vcc
->
callback
=
NULL
;
memset
(
&
vcc
->
local
,
0
,
sizeof
(
struct
sockaddr_atmsvc
));
...
...
@@ -199,42 +260,49 @@ int atm_create(struct socket *sock,int protocol,int family)
vcc
->
atm_options
=
vcc
->
aal_options
=
0
;
init_waitqueue_head
(
&
vcc
->
sleep
);
sk
->
sk_sleep
=
&
vcc
->
sleep
;
sk
->
sk_destruct
=
vcc_sock_destruct
;
sock
->
sk
=
sk
;
return
0
;
}
void
atm_release_vcc_sk
(
struct
sock
*
sk
,
int
free_
sk
)
static
void
vcc_destroy_socket
(
struct
sock
*
sk
)
{
struct
atm_vcc
*
vcc
=
atm_sk
(
sk
);
struct
sk_buff
*
skb
;
clear_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
clear_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
if
(
vcc
->
dev
)
{
if
(
vcc
->
dev
->
ops
->
close
)
vcc
->
dev
->
ops
->
close
(
vcc
);
if
(
vcc
->
push
)
vcc
->
push
(
vcc
,
NULL
);
/* atmarpd has no push */
if
(
vcc
->
dev
->
ops
->
close
)
vcc
->
dev
->
ops
->
close
(
vcc
);
if
(
vcc
->
push
)
vcc
->
push
(
vcc
,
NULL
);
/* atmarpd has no push */
vcc_remove_socket
(
sk
);
/* no more receive */
while
((
skb
=
skb_dequeue
(
&
vcc
->
sk
->
sk_receive_queue
)))
{
atm_return
(
vcc
,
skb
->
truesize
);
kfree_skb
(
skb
);
}
module_put
(
vcc
->
dev
->
ops
->
owner
);
atm_dev_release
(
vcc
->
dev
);
if
(
atomic_read
(
&
vcc
->
sk
->
sk_rmem_alloc
))
printk
(
KERN_WARNING
"atm_release_vcc: strange ... "
"rmem_alloc == %d after closing
\n
"
,
atomic_read
(
&
vcc
->
sk
->
sk_rmem_alloc
));
bind_vcc
(
vcc
,
NULL
);
atm_dev_put
(
vcc
->
dev
);
}
if
(
free_sk
)
free_atm_vcc_sk
(
sk
);
}
int
atm
_release
(
struct
socket
*
sock
)
int
vcc
_release
(
struct
socket
*
sock
)
{
if
(
sock
->
sk
)
atm_release_vcc_sk
(
sock
->
sk
,
1
);
struct
sock
*
sk
=
sock
->
sk
;
if
(
sk
)
{
sock_orphan
(
sk
);
lock_sock
(
sk
);
vcc_destroy_socket
(
sock
->
sk
);
release_sock
(
sk
);
sock_put
(
sk
);
}
return
0
;
}
...
...
@@ -289,7 +357,8 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
if
(
vci
>
0
&&
vci
<
ATM_NOT_RSV_VCI
&&
!
capable
(
CAP_NET_BIND_SERVICE
))
return
-
EPERM
;
error
=
0
;
bind_vcc
(
vcc
,
dev
);
vcc
->
dev
=
dev
;
vcc_insert_socket
(
vcc
->
sk
);
switch
(
vcc
->
qos
.
aal
)
{
case
ATM_AAL0
:
error
=
atm_init_aal0
(
vcc
);
...
...
@@ -313,7 +382,7 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
if
(
!
error
)
error
=
adjust_tp
(
&
vcc
->
qos
.
txtp
,
vcc
->
qos
.
aal
);
if
(
!
error
)
error
=
adjust_tp
(
&
vcc
->
qos
.
rxtp
,
vcc
->
qos
.
aal
);
if
(
error
)
{
bind_vcc
(
vcc
,
NULL
);
vcc_remove_socket
(
vcc
->
sk
);
return
error
;
}
DPRINTK
(
"VCC %d.%d, AAL %d
\n
"
,
vpi
,
vci
,
vcc
->
qos
.
aal
);
...
...
@@ -327,7 +396,7 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
error
=
dev
->
ops
->
open
(
vcc
,
vpi
,
vci
);
if
(
error
)
{
module_put
(
dev
->
ops
->
owner
);
bind_vcc
(
vcc
,
NULL
);
vcc_remove_socket
(
vcc
->
sk
);
return
error
;
}
}
...
...
@@ -371,7 +440,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
dev
=
atm_dev_lookup
(
itf
);
error
=
__vcc_connect
(
vcc
,
dev
,
vpi
,
vci
);
if
(
error
)
{
atm_dev_
release
(
dev
);
atm_dev_
put
(
dev
);
return
error
;
}
}
else
{
...
...
@@ -385,7 +454,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
spin_unlock
(
&
atm_dev_lock
);
if
(
!
__vcc_connect
(
vcc
,
dev
,
vpi
,
vci
))
break
;
atm_dev_
release
(
dev
);
atm_dev_
put
(
dev
);
dev
=
NULL
;
spin_lock
(
&
atm_dev_lock
);
}
...
...
net/atm/common.h
View file @
3c81501f
...
...
@@ -10,8 +10,8 @@
#include <linux/poll.h>
/* for poll_table */
int
atm_create
(
struct
socket
*
sock
,
int
protocol
,
int
family
);
int
atm
_release
(
struct
socket
*
sock
);
int
vcc_create
(
struct
socket
*
sock
,
int
protocol
,
int
family
);
int
vcc
_release
(
struct
socket
*
sock
);
int
vcc_connect
(
struct
socket
*
sock
,
int
itf
,
short
vpi
,
int
vci
);
int
vcc_recvmsg
(
struct
kiocb
*
iocb
,
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
size
,
int
flags
);
...
...
@@ -24,7 +24,6 @@ int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
int
vcc_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
*
optlen
);
void
atm_release_vcc_sk
(
struct
sock
*
sk
,
int
free_sk
);
void
atm_shutdown_dev
(
struct
atm_dev
*
dev
);
int
atmpvc_init
(
void
);
...
...
net/atm/lec.c
View file @
3c81501f
...
...
@@ -48,7 +48,7 @@ extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
#include "lec.h"
#include "lec_arpc.h"
#include "resources.h"
/* for bind_vcc() */
#include "resources.h"
#if 0
#define DPRINTK printk
...
...
@@ -810,7 +810,8 @@ lecd_attach(struct atm_vcc *vcc, int arg)
lec_arp_init
(
priv
);
priv
->
itfnum
=
i
;
/* LANE2 addition */
priv
->
lecd
=
vcc
;
bind_vcc
(
vcc
,
&
lecatm_dev
);
vcc
->
dev
=
&
lecatm_dev
;
vcc_insert_socket
(
vcc
->
sk
);
vcc
->
proto_data
=
dev_lec
[
i
];
set_bit
(
ATM_VF_META
,
&
vcc
->
flags
);
...
...
net/atm/mpc.c
View file @
3c81501f
...
...
@@ -28,7 +28,7 @@
#include "lec.h"
#include "mpc.h"
#include "resources.h"
/* for bind_vcc() */
#include "resources.h"
/*
* mpc.c: Implementation of MPOA client kernel part
...
...
@@ -789,7 +789,8 @@ int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
}
mpc
->
mpoad_vcc
=
vcc
;
bind_vcc
(
vcc
,
&
mpc_dev
);
vcc
->
dev
=
&
mpc_dev
;
vcc_insert_socket
(
vcc
->
sk
);
set_bit
(
ATM_VF_META
,
&
vcc
->
flags
);
set_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
...
...
net/atm/proc.c
View file @
3c81501f
...
...
@@ -334,9 +334,7 @@ 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
sock
*
s
;
struct
atm_vcc
*
vcc
;
int
left
,
clip_info
=
0
;
...
...
@@ -349,25 +347,20 @@ static int atm_pvc_info(loff_t pos,char *buf)
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
->
sk_family
==
PF_ATMPVC
&&
vcc
->
dev
&&
!
left
--
)
{
pvc_info
(
vcc
,
buf
,
clip_info
);
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
spin_unlock
(
&
atm_dev_lock
);
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
sk
->
sk_family
==
PF_ATMPVC
&&
vcc
->
dev
&&
!
left
--
)
{
pvc_info
(
vcc
,
buf
,
clip_info
);
read_unlock
(
&
vcc_sklist_lock
);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if
(
clip_info
)
module_put
(
atm_clip_ops
->
owner
);
if
(
clip_info
)
module_put
(
atm_clip_ops
->
owner
);
#endif
return
strlen
(
buf
);
}
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
return
strlen
(
buf
);
}
}
spin_unlock
(
&
atm_dev
_lock
);
read_unlock
(
&
vcc_sklist
_lock
);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if
(
clip_info
)
module_put
(
atm_clip_ops
->
owner
);
...
...
@@ -378,10 +371,8 @@ static int atm_pvc_info(loff_t pos,char *buf)
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
;
struct
sock
*
s
;
int
left
;
if
(
!
pos
)
...
...
@@ -389,20 +380,16 @@ 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
);
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
!
left
--
)
{
vc_info
(
vcc
,
buf
);
read_unlock
(
&
vcc_sklist_lock
);
return
strlen
(
buf
);
}
}
spin_unlock
(
&
atm_dev
_lock
);
read_unlock
(
&
vcc_sklist
_lock
);
return
0
;
}
...
...
@@ -410,29 +397,23 @@ 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
sock
*
s
;
struct
atm_vcc
*
vcc
;
int
left
;
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
->
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
);
read_lock
(
&
vcc_sklist_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
vcc
=
atm_sk
(
s
);
if
(
vcc
->
sk
->
sk_family
==
PF_ATMSVC
&&
!
left
--
)
{
svc_info
(
vcc
,
buf
);
read_unlock
(
&
vcc_sklist_lock
);
return
strlen
(
buf
);
}
}
spin_unlock
(
&
atm_dev
_lock
);
read_unlock
(
&
vcc_sklist
_lock
);
return
0
;
}
...
...
net/atm/pvc.c
View file @
3c81501f
...
...
@@ -17,10 +17,6 @@
#include "resources.h"
/* devs and vccs */
#include "common.h"
/* common for PVCs and SVCs */
#ifndef NULL
#define NULL 0
#endif
static
int
pvc_shutdown
(
struct
socket
*
sock
,
int
how
)
{
...
...
@@ -109,7 +105,7 @@ static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
static
struct
proto_ops
pvc_proto_ops
=
{
.
family
=
PF_ATMPVC
,
.
release
=
atm
_release
,
.
release
=
vcc
_release
,
.
bind
=
pvc_bind
,
.
connect
=
pvc_connect
,
.
socketpair
=
sock_no_socketpair
,
...
...
@@ -131,7 +127,7 @@ static struct proto_ops pvc_proto_ops = {
static
int
pvc_create
(
struct
socket
*
sock
,
int
protocol
)
{
sock
->
ops
=
&
pvc_proto_ops
;
return
atm_create
(
sock
,
protocol
,
PF_ATMPVC
);
return
vcc_create
(
sock
,
protocol
,
PF_ATMPVC
);
}
...
...
net/atm/resources.c
View file @
3c81501f
...
...
@@ -23,11 +23,6 @@
#include "addr.h"
#ifndef NULL
#define NULL 0
#endif
LIST_HEAD
(
atm_devs
);
spinlock_t
atm_dev_lock
=
SPIN_LOCK_UNLOCKED
;
...
...
@@ -91,7 +86,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
spin_lock
(
&
atm_dev_lock
);
if
(
number
!=
-
1
)
{
if
((
inuse
=
__atm_dev_lookup
(
number
)))
{
atm_dev_
release
(
inuse
);
atm_dev_
put
(
inuse
);
spin_unlock
(
&
atm_dev_lock
);
__free_atm_dev
(
dev
);
return
NULL
;
...
...
@@ -100,7 +95,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
}
else
{
dev
->
number
=
0
;
while
((
inuse
=
__atm_dev_lookup
(
dev
->
number
)))
{
atm_dev_
release
(
inuse
);
atm_dev_
put
(
inuse
);
dev
->
number
++
;
}
}
...
...
@@ -402,78 +397,12 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
else
error
=
0
;
done:
atm_dev_
release
(
dev
);
atm_dev_
put
(
dev
);
return
error
;
}
struct
sock
*
alloc_atm_vcc_sk
(
int
family
)
{
struct
sock
*
sk
;
struct
atm_vcc
*
vcc
;
sk
=
sk_alloc
(
family
,
GFP_KERNEL
,
1
,
NULL
);
if
(
!
sk
)
return
NULL
;
vcc
=
atm_sk
(
sk
)
=
kmalloc
(
sizeof
(
*
vcc
),
GFP_KERNEL
);
if
(
!
vcc
)
{
sk_free
(
sk
);
return
NULL
;
}
sock_init_data
(
NULL
,
sk
);
memset
(
vcc
,
0
,
sizeof
(
*
vcc
));
vcc
->
sk
=
sk
;
return
sk
;
}
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
vcc
->
dev
->
vccs
=
vcc
->
next
;
if
(
vcc
->
next
)
vcc
->
next
->
prev
=
vcc
->
prev
;
else
vcc
->
dev
->
last
=
vcc
->
prev
;
spin_unlock_irqrestore
(
&
vcc
->
dev
->
lock
,
flags
);
}
}
void
free_atm_vcc_sk
(
struct
sock
*
sk
)
{
unlink_vcc
(
atm_sk
(
sk
));
sk_free
(
sk
);
}
void
bind_vcc
(
struct
atm_vcc
*
vcc
,
struct
atm_dev
*
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
)
dev
->
last
->
next
=
vcc
;
else
dev
->
vccs
=
vcc
;
dev
->
last
=
vcc
;
spin_unlock_irqrestore
(
&
dev
->
lock
,
flags
);
}
}
EXPORT_SYMBOL
(
atm_dev_register
);
EXPORT_SYMBOL
(
atm_dev_deregister
);
EXPORT_SYMBOL
(
atm_dev_lookup
);
EXPORT_SYMBOL
(
shutdown_atm_dev
);
EXPORT_SYMBOL
(
bind_vcc
);
net/atm/resources.h
View file @
3c81501f
...
...
@@ -14,8 +14,6 @@ extern struct list_head atm_devs;
extern
spinlock_t
atm_dev_lock
;
struct
sock
*
alloc_atm_vcc_sk
(
int
family
);
void
free_atm_vcc_sk
(
struct
sock
*
sk
);
int
atm_dev_ioctl
(
unsigned
int
cmd
,
unsigned
long
arg
);
...
...
net/atm/signaling.c
View file @
3c81501f
...
...
@@ -200,26 +200,21 @@ void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type,
}
static
void
purge_vcc
s
(
struct
atm_vcc
*
vcc
)
static
void
purge_vcc
(
struct
atm_vcc
*
vcc
)
{
while
(
vcc
)
{
if
(
vcc
->
sk
->
sk_family
==
PF_ATMSVC
&&
!
test_bit
(
ATM_VF_META
,
&
vcc
->
flags
))
{
set_bit
(
ATM_VF_RELEASED
,
&
vcc
->
flags
);
vcc
->
reply
=
-
EUNATCH
;
vcc
->
sk
->
sk_err
=
EUNATCH
;
wake_up
(
&
vcc
->
sleep
);
}
vcc
=
vcc
->
next
;
if
(
vcc
->
sk
->
sk_family
==
PF_ATMSVC
&&
!
test_bit
(
ATM_VF_META
,
&
vcc
->
flags
))
{
set_bit
(
ATM_VF_RELEASED
,
&
vcc
->
flags
);
vcc
->
reply
=
-
EUNATCH
;
vcc
->
sk
->
sk_err
=
EUNATCH
;
wake_up
(
&
vcc
->
sleep
);
}
}
static
void
sigd_close
(
struct
atm_vcc
*
vcc
)
{
unsigned
long
flags
;
struct
atm_dev
*
dev
;
struct
list_head
*
p
;
struct
sock
*
s
;
DPRINTK
(
"sigd_close
\n
"
);
sigd
=
NULL
;
...
...
@@ -227,14 +222,14 @@ static void sigd_close(struct atm_vcc *vcc)
printk
(
KERN_ERR
"sigd_close: closing with requests pending
\n
"
);
skb_queue_purge
(
&
vcc
->
sk
->
sk_receive_queue
);
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
);
read_lock
(
&
vcc_sklist
_lock
);
for
(
s
=
vcc_sklist
;
s
;
s
=
s
->
sk_next
)
{
struct
atm_vcc
*
vcc
=
atm_sk
(
s
);
if
(
vcc
->
dev
)
purge_vcc
(
vcc
);
}
spin_unlock
(
&
atm_dev
_lock
);
read_unlock
(
&
vcc_sklist
_lock
);
}
...
...
@@ -257,7 +252,8 @@ int sigd_attach(struct atm_vcc *vcc)
if
(
sigd
)
return
-
EADDRINUSE
;
DPRINTK
(
"sigd_attach
\n
"
);
sigd
=
vcc
;
bind_vcc
(
vcc
,
&
sigd_dev
);
vcc
->
dev
=
&
sigd_dev
;
vcc_insert_socket
(
vcc
->
sk
);
set_bit
(
ATM_VF_META
,
&
vcc
->
flags
);
set_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
wake_up
(
&
sigd_sleep
);
...
...
net/atm/svc.c
View file @
3c81501f
...
...
@@ -88,18 +88,21 @@ static void svc_disconnect(struct atm_vcc *vcc)
static
int
svc_release
(
struct
socket
*
sock
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
atm_vcc
*
vcc
;
if
(
!
sock
->
sk
)
return
0
;
vcc
=
ATM_SD
(
sock
);
DPRINTK
(
"svc_release %p
\n
"
,
vcc
);
clear_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
atm_release_vcc_sk
(
sock
->
sk
,
0
);
svc_disconnect
(
vcc
);
/* VCC pointer is used as a reference, so we must not free it
(thereby subjecting it to re-use) before all pending connections
are closed */
free_atm_vcc_sk
(
sock
->
sk
);
if
(
sk
)
{
vcc
=
ATM_SD
(
sock
);
DPRINTK
(
"svc_release %p
\n
"
,
vcc
);
clear_bit
(
ATM_VF_READY
,
&
vcc
->
flags
);
/* VCC pointer is used as a reference, so we must not free it
(thereby subjecting it to re-use) before all pending connections
are closed */
sock_hold
(
sk
);
vcc_release
(
sock
);
svc_disconnect
(
vcc
);
sock_put
(
sk
);
}
return
0
;
}
...
...
@@ -542,7 +545,7 @@ static int svc_create(struct socket *sock,int protocol)
int
error
;
sock
->
ops
=
&
svc_proto_ops
;
error
=
atm_create
(
sock
,
protocol
,
AF_ATMSVC
);
error
=
vcc_create
(
sock
,
protocol
,
AF_ATMSVC
);
if
(
error
)
return
error
;
ATM_SD
(
sock
)
->
callback
=
svc_callback
;
ATM_SD
(
sock
)
->
local
.
sas_family
=
AF_ATMSVC
;
...
...
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