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
5f7e3b2f
Commit
5f7e3b2f
authored
Feb 29, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://gkernel.bkbits.net/net-drivers-2.5
into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents
77dd8f26
dc36ad08
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
32 additions
and
129 deletions
+32
-129
drivers/net/Kconfig
drivers/net/Kconfig
+8
-10
drivers/net/hp100.c
drivers/net/hp100.c
+11
-5
drivers/net/hydra.c
drivers/net/hydra.c
+0
-4
drivers/net/r8169.c
drivers/net/r8169.c
+8
-5
drivers/net/wireless/airo_cs.c
drivers/net/wireless/airo_cs.c
+1
-19
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/netwave_cs.c
+2
-23
drivers/net/wireless/ray_cs.c
drivers/net/wireless/ray_cs.c
+2
-18
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.c
+0
-27
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/wl3501_cs.c
+0
-18
No files found.
drivers/net/Kconfig
View file @
5f7e3b2f
...
@@ -1676,25 +1676,23 @@ config VIA_RHINE
...
@@ -1676,25 +1676,23 @@ config VIA_RHINE
select CRC32
select CRC32
select MII
select MII
help
help
If you have a VIA "rhine" based network card (Rhine-I (3043),
If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
Rhine-2 (VT86c100A) or Rhine-III (VT6105)), say Y here.
Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
Ethernet functions can also be found integrated on South Bridges
(e.g. VT8235).
To compile this driver as a module, choose M here and read
To compile this driver as a module, choose M here. The module
<file:Documentation/networking/net-modules.txt>. The module
will be called via-rhine.
will be called via-rhine.
config VIA_RHINE_MMIO
config VIA_RHINE_MMIO
bool "Use MMIO instead of PIO
(EXPERIMENTAL)
"
bool "Use MMIO instead of PIO"
depends on VIA_RHINE
&& EXPERIMENTAL
depends on VIA_RHINE
help
help
This instructs the driver to use PCI shared memory (MMIO) instead of
This instructs the driver to use PCI shared memory (MMIO) instead of
programmed I/O ports (PIO). Enabling this gives an improvement in
programmed I/O ports (PIO). Enabling this gives an improvement in
processing time in parts of the driver.
processing time in parts of the driver.
It is not known if this works reliably on all "rhine" based cards,
If unsure, say Y.
but it has been tested successfully on some DFE-530TX adapters.
If unsure, say N.
config LAN_SAA9730
config LAN_SAA9730
bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)"
bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)"
...
...
drivers/net/hp100.c
View file @
5f7e3b2f
...
@@ -201,6 +201,7 @@ static struct eisa_device_id hp100_eisa_tbl[] = {
...
@@ -201,6 +201,7 @@ static struct eisa_device_id hp100_eisa_tbl[] = {
{
"HWP1990"
},
/* HP J2577 */
{
"HWP1990"
},
/* HP J2577 */
{
"CPX0301"
},
/* ReadyLink ENET100-VG4 */
{
"CPX0301"
},
/* ReadyLink ENET100-VG4 */
{
"CPX0401"
},
/* FreedomLine 100/VG */
{
"CPX0401"
},
/* FreedomLine 100/VG */
{
""
}
/* Mandatory final entry ! */
};
};
MODULE_DEVICE_TABLE
(
eisa
,
hp100_eisa_tbl
);
MODULE_DEVICE_TABLE
(
eisa
,
hp100_eisa_tbl
);
#endif
#endif
...
@@ -326,16 +327,21 @@ static __init const char *hp100_read_id(int ioaddr)
...
@@ -326,16 +327,21 @@ static __init const char *hp100_read_id(int ioaddr)
return
str
;
return
str
;
}
}
static
__init
int
hp100_isa_probe1
(
struct
net_device
*
dev
,
int
addr
)
static
__init
int
hp100_isa_probe1
(
struct
net_device
*
dev
,
int
io
addr
)
{
{
const
char
*
sig
;
const
char
*
sig
;
int
i
;
int
i
;
if
(
!
request_region
(
addr
,
HP100_REGION_SIZE
,
"hp100"
))
if
(
!
request_region
(
ioaddr
,
HP100_REGION_SIZE
,
"hp100"
))
goto
err
;
if
(
hp100_inw
(
HW_ID
)
!=
HP100_HW_ID_CASCADE
)
{
release_region
(
ioaddr
,
HP100_REGION_SIZE
);
goto
err
;
goto
err
;
}
sig
=
hp100_read_id
(
addr
);
sig
=
hp100_read_id
(
io
addr
);
release_region
(
addr
,
HP100_REGION_SIZE
);
release_region
(
io
addr
,
HP100_REGION_SIZE
);
if
(
sig
==
NULL
)
if
(
sig
==
NULL
)
goto
err
;
goto
err
;
...
@@ -347,7 +353,7 @@ static __init int hp100_isa_probe1(struct net_device *dev, int addr)
...
@@ -347,7 +353,7 @@ static __init int hp100_isa_probe1(struct net_device *dev, int addr)
}
}
if
(
i
<
ARRAY_SIZE
(
hp100_isa_tbl
))
if
(
i
<
ARRAY_SIZE
(
hp100_isa_tbl
))
return
hp100_probe1
(
dev
,
addr
,
HP100_BUS_ISA
,
NULL
);
return
hp100_probe1
(
dev
,
io
addr
,
HP100_BUS_ISA
,
NULL
);
err:
err:
return
-
ENODEV
;
return
-
ENODEV
;
...
...
drivers/net/hydra.c
View file @
5f7e3b2f
...
@@ -142,10 +142,6 @@ static int __devinit hydra_init(struct zorro_dev *z)
...
@@ -142,10 +142,6 @@ static int __devinit hydra_init(struct zorro_dev *z)
ei_status
.
reg_offset
=
hydra_offsets
;
ei_status
.
reg_offset
=
hydra_offsets
;
dev
->
open
=
&
hydra_open
;
dev
->
open
=
&
hydra_open
;
dev
->
stop
=
&
hydra_close
;
dev
->
stop
=
&
hydra_close
;
#ifdef MODULE
ei_status
.
priv
=
(
unsigned
long
)
root_hydra_dev
;
root_hydra_dev
=
dev
;
#endif
NS8390_init
(
dev
,
0
);
NS8390_init
(
dev
,
0
);
err
=
register_netdev
(
dev
);
err
=
register_netdev
(
dev
);
...
...
drivers/net/r8169.c
View file @
5f7e3b2f
...
@@ -871,7 +871,6 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
...
@@ -871,7 +871,6 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
void
*
ioaddr
)
void
*
ioaddr
)
{
{
unsigned
long
dirty_tx
,
tx_left
=
0
;
unsigned
long
dirty_tx
,
tx_left
=
0
;
int
entry
=
tp
->
cur_tx
%
NUM_TX_DESC
;
assert
(
dev
!=
NULL
);
assert
(
dev
!=
NULL
);
assert
(
tp
!=
NULL
);
assert
(
tp
!=
NULL
);
...
@@ -881,14 +880,18 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
...
@@ -881,14 +880,18 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
tx_left
=
tp
->
cur_tx
-
dirty_tx
;
tx_left
=
tp
->
cur_tx
-
dirty_tx
;
while
(
tx_left
>
0
)
{
while
(
tx_left
>
0
)
{
int
entry
=
dirty_tx
%
NUM_TX_DESC
;
if
((
tp
->
TxDescArray
[
entry
].
status
&
OWNbit
)
==
0
)
{
if
((
tp
->
TxDescArray
[
entry
].
status
&
OWNbit
)
==
0
)
{
dev_kfree_skb_irq
(
tp
->
struct
sk_buff
*
skb
=
tp
->
Tx_skbuff
[
entry
];
Tx_skbuff
[
dirty_tx
%
NUM_TX_DESC
]);
tp
->
Tx_skbuff
[
dirty_tx
%
NUM_TX_DESC
]
=
NULL
;
tp
->
stats
.
tx_bytes
+=
skb
->
len
>=
ETH_ZLEN
?
skb
->
len
:
ETH_ZLEN
;
tp
->
stats
.
tx_packets
++
;
tp
->
stats
.
tx_packets
++
;
dev_kfree_skb_irq
(
skb
);
tp
->
Tx_skbuff
[
entry
]
=
NULL
;
dirty_tx
++
;
dirty_tx
++
;
tx_left
--
;
tx_left
--
;
entry
++
;
}
}
}
}
...
...
drivers/net/wireless/airo_cs.c
View file @
5f7e3b2f
...
@@ -264,11 +264,8 @@ static void airo_detach(dev_link_t *link)
...
@@ -264,11 +264,8 @@ static void airo_detach(dev_link_t *link)
if
(
*
linkp
==
NULL
)
if
(
*
linkp
==
NULL
)
return
;
return
;
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
airo_release
(
link
);
airo_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
return
;
}
if
(
((
local_info_t
*
)
link
->
priv
)
->
eth_dev
)
{
if
(
((
local_info_t
*
)
link
->
priv
)
->
eth_dev
)
{
stop_airo_card
(
((
local_info_t
*
)
link
->
priv
)
->
eth_dev
,
0
);
stop_airo_card
(
((
local_info_t
*
)
link
->
priv
)
->
eth_dev
,
0
);
...
@@ -504,18 +501,6 @@ static void airo_release(dev_link_t *link)
...
@@ -504,18 +501,6 @@ static void airo_release(dev_link_t *link)
{
{
DEBUG
(
0
,
"airo_release(0x%p)
\n
"
,
link
);
DEBUG
(
0
,
"airo_release(0x%p)
\n
"
,
link
);
/*
If the device is currently in use, we won't release until it
is actually closed, because until then, we can't be sure that
no one will try to access the device or its data structures.
*/
if
(
link
->
open
)
{
DEBUG
(
1
,
"airo_cs: release postponed, '%s' still open
\n
"
,
link
->
dev
->
dev_name
);
link
->
state
|=
DEV_STALE_CONFIG
;
return
;
}
/* Unlink the device chain */
/* Unlink the device chain */
link
->
dev
=
NULL
;
link
->
dev
=
NULL
;
...
@@ -533,9 +518,6 @@ static void airo_release(dev_link_t *link)
...
@@ -533,9 +518,6 @@ static void airo_release(dev_link_t *link)
if
(
link
->
irq
.
AssignedIRQ
)
if
(
link
->
irq
.
AssignedIRQ
)
pcmcia_release_irq
(
link
->
handle
,
&
link
->
irq
);
pcmcia_release_irq
(
link
->
handle
,
&
link
->
irq
);
link
->
state
&=
~
DEV_CONFIG
;
link
->
state
&=
~
DEV_CONFIG
;
if
(
link
->
state
&
DEV_STALE_CONFIG
)
airo_detach
(
link
);
}
}
/*======================================================================
/*======================================================================
...
...
drivers/net/wireless/netwave_cs.c
View file @
5f7e3b2f
...
@@ -544,14 +544,8 @@ static void netwave_detach(dev_link_t *link)
...
@@ -544,14 +544,8 @@ static void netwave_detach(dev_link_t *link)
the release() function is called, that will trigger a proper
the release() function is called, that will trigger a proper
detach().
detach().
*/
*/
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
netwave_release
(
link
);
netwave_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
DEBUG
(
1
,
"netwave_cs: detach postponed, '%s' still "
"locked
\n
"
,
link
->
dev
->
dev_name
);
return
;
}
}
/* Break the link with Card Services */
/* Break the link with Card Services */
if
(
link
->
handle
)
if
(
link
->
handle
)
...
@@ -1130,17 +1124,6 @@ static void netwave_release(dev_link_t *link)
...
@@ -1130,17 +1124,6 @@ static void netwave_release(dev_link_t *link)
DEBUG
(
0
,
"netwave_release(0x%p)
\n
"
,
link
);
DEBUG
(
0
,
"netwave_release(0x%p)
\n
"
,
link
);
/*
If the device is currently in use, we won't release until it
is actually closed.
*/
if
(
link
->
open
)
{
printk
(
KERN_DEBUG
"netwave_cs: release postponed, '%s' still open
\n
"
,
link
->
dev
->
dev_name
);
link
->
state
|=
DEV_STALE_CONFIG
;
return
;
}
/* Don't bother checking to see if these succeed or not */
/* Don't bother checking to see if these succeed or not */
if
(
link
->
win
)
{
if
(
link
->
win
)
{
iounmap
(
priv
->
ramBase
);
iounmap
(
priv
->
ramBase
);
...
@@ -1151,9 +1134,6 @@ static void netwave_release(dev_link_t *link)
...
@@ -1151,9 +1134,6 @@ static void netwave_release(dev_link_t *link)
pcmcia_release_irq
(
link
->
handle
,
&
link
->
irq
);
pcmcia_release_irq
(
link
->
handle
,
&
link
->
irq
);
link
->
state
&=
~
DEV_CONFIG
;
link
->
state
&=
~
DEV_CONFIG
;
if
(
link
->
state
&
DEV_STALE_CONFIG
)
netwave_detach
(
link
);
}
}
/*
/*
...
@@ -1703,8 +1683,7 @@ static int netwave_close(struct net_device *dev) {
...
@@ -1703,8 +1683,7 @@ static int netwave_close(struct net_device *dev) {
link
->
open
--
;
link
->
open
--
;
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
netwave_release
(
link
);
return
0
;
return
0
;
}
}
...
...
drivers/net/wireless/ray_cs.c
View file @
5f7e3b2f
...
@@ -454,11 +454,8 @@ static void ray_detach(dev_link_t *link)
...
@@ -454,11 +454,8 @@ static void ray_detach(dev_link_t *link)
the release() function is called, that will trigger a proper
the release() function is called, that will trigger a proper
detach().
detach().
*/
*/
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
ray_release
(
link
);
ray_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
return
;
}
/* Break the link with Card Services */
/* Break the link with Card Services */
if
(
link
->
handle
)
if
(
link
->
handle
)
...
@@ -872,15 +869,7 @@ static void ray_release(dev_link_t *link)
...
@@ -872,15 +869,7 @@ static void ray_release(dev_link_t *link)
int
i
;
int
i
;
DEBUG
(
1
,
"ray_release(0x%p)
\n
"
,
link
);
DEBUG
(
1
,
"ray_release(0x%p)
\n
"
,
link
);
/* If the device is currently in use, we won't release until it
is actually closed.
*/
if
(
link
->
open
)
{
DEBUG
(
1
,
"ray_cs: release postponed, '%s' still open
\n
"
,
link
->
dev
->
dev_name
);
link
->
state
|=
DEV_STALE_CONFIG
;
return
;
}
del_timer
(
&
local
->
timer
);
del_timer
(
&
local
->
timer
);
link
->
state
&=
~
DEV_CONFIG
;
link
->
state
&=
~
DEV_CONFIG
;
...
@@ -900,9 +889,6 @@ static void ray_release(dev_link_t *link)
...
@@ -900,9 +889,6 @@ static void ray_release(dev_link_t *link)
if
(
i
!=
CS_SUCCESS
)
DEBUG
(
0
,
"ReleaseIRQ ret = %x
\n
"
,
i
);
if
(
i
!=
CS_SUCCESS
)
DEBUG
(
0
,
"ReleaseIRQ ret = %x
\n
"
,
i
);
DEBUG
(
2
,
"ray_release ending
\n
"
);
DEBUG
(
2
,
"ray_release ending
\n
"
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
ray_detach
(
link
);
}
}
/*=============================================================================
/*=============================================================================
...
@@ -1724,8 +1710,6 @@ static int ray_dev_close(struct net_device *dev)
...
@@ -1724,8 +1710,6 @@ static int ray_dev_close(struct net_device *dev)
link
->
open
--
;
link
->
open
--
;
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
ray_release
(
link
);
/* In here, we should stop the hardware (stop card from beeing active)
/* In here, we should stop the hardware (stop card from beeing active)
* and set local->card_status to CARD_AWAITING_PARAM, so that while the
* and set local->card_status to CARD_AWAITING_PARAM, so that while the
...
...
drivers/net/wireless/wavelan_cs.c
View file @
5f7e3b2f
...
@@ -4155,18 +4155,6 @@ wv_pcmcia_release(dev_link_t *link)
...
@@ -4155,18 +4155,6 @@ wv_pcmcia_release(dev_link_t *link)
printk
(
KERN_DEBUG
"%s: -> wv_pcmcia_release(0x%p)
\n
"
,
dev
->
name
,
link
);
printk
(
KERN_DEBUG
"%s: -> wv_pcmcia_release(0x%p)
\n
"
,
dev
->
name
,
link
);
#endif
#endif
/* If the device is currently in use, we won't release until it is
* actually closed. */
if
(
link
->
open
)
{
#ifdef DEBUG_CONFIG_INFO
printk
(
KERN_DEBUG
"%s: wv_pcmcia_release: release postponed, device still open
\n
"
,
dev
->
name
);
#endif
link
->
state
|=
DEV_STALE_CONFIG
;
return
;
}
/* Don't bother checking to see if these succeed or not */
/* Don't bother checking to see if these succeed or not */
iounmap
((
u_char
*
)
dev
->
mem_start
);
iounmap
((
u_char
*
)
dev
->
mem_start
);
pcmcia_release_window
(
link
->
win
);
pcmcia_release_window
(
link
->
win
);
...
@@ -4179,9 +4167,6 @@ wv_pcmcia_release(dev_link_t *link)
...
@@ -4179,9 +4167,6 @@ wv_pcmcia_release(dev_link_t *link)
#ifdef DEBUG_CONFIG_TRACE
#ifdef DEBUG_CONFIG_TRACE
printk
(
KERN_DEBUG
"%s: <- wv_pcmcia_release()
\n
"
,
dev
->
name
);
printk
(
KERN_DEBUG
"%s: <- wv_pcmcia_release()
\n
"
,
dev
->
name
);
#endif
#endif
if
(
link
->
state
&
DEV_STALE_CONFIG
)
wavelan_detach
(
link
);
}
}
/************************ INTERRUPT HANDLING ************************/
/************************ INTERRUPT HANDLING ************************/
...
@@ -4634,10 +4619,6 @@ wavelan_close(struct net_device * dev)
...
@@ -4634,10 +4619,6 @@ wavelan_close(struct net_device * dev)
/* Power down the module */
/* Power down the module */
hacr_write
(
base
,
HACR_DEFAULT
&
(
~
HACR_PWR_STAT
));
hacr_write
(
base
,
HACR_DEFAULT
&
(
~
HACR_PWR_STAT
));
}
}
else
/* The card is no more there (flag is activated in wv_pcmcia_release) */
if
(
link
->
state
&
DEV_STALE_CONFIG
)
wv_pcmcia_release
(
link
);
#ifdef DEBUG_CALLBACK_TRACE
#ifdef DEBUG_CALLBACK_TRACE
printk
(
KERN_DEBUG
"%s: <-wavelan_close()
\n
"
,
dev
->
name
);
printk
(
KERN_DEBUG
"%s: <-wavelan_close()
\n
"
,
dev
->
name
);
...
@@ -4802,14 +4783,6 @@ wavelan_detach(dev_link_t * link)
...
@@ -4802,14 +4783,6 @@ wavelan_detach(dev_link_t * link)
{
{
/* Some others haven't done their job : give them another chance */
/* Some others haven't done their job : give them another chance */
wv_pcmcia_release
(
link
);
wv_pcmcia_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
#ifdef DEBUG_CONFIG_INFO
printk
(
KERN_DEBUG
"wavelan_detach: detach postponed,"
" '%s' still locked
\n
"
,
link
->
dev
->
dev_name
);
#endif
return
;
}
}
}
/* Break the link with Card Services */
/* Break the link with Card Services */
...
...
drivers/net/wireless/wl3501_cs.c
View file @
5f7e3b2f
...
@@ -1306,10 +1306,6 @@ static int wl3501_close(struct net_device *dev)
...
@@ -1306,10 +1306,6 @@ static int wl3501_close(struct net_device *dev)
/* Mask interrupts from the SUTRO */
/* Mask interrupts from the SUTRO */
wl3501_block_interrupt
(
this
);
wl3501_block_interrupt
(
this
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
link
->
state
|=
DEV_RELEASE_PENDING
;
wl3501_release
(
link
);
}
rc
=
0
;
rc
=
0
;
printk
(
KERN_INFO
"%s: WL3501 closed
\n
"
,
dev
->
name
);
printk
(
KERN_INFO
"%s: WL3501 closed
\n
"
,
dev
->
name
);
out:
out:
...
@@ -2220,15 +2216,6 @@ static void wl3501_release(dev_link_t *link)
...
@@ -2220,15 +2216,6 @@ static void wl3501_release(dev_link_t *link)
{
{
struct
net_device
*
dev
=
link
->
priv
;
struct
net_device
*
dev
=
link
->
priv
;
/* If the device is currently in use, we won't release until it is
* actually closed. */
if
(
link
->
open
)
{
dprintk
(
1
,
"release postponed, '%s' still open"
,
link
->
dev
->
dev_name
);
link
->
state
|=
DEV_STALE_CONFIG
;
goto
out
;
}
/* Unlink the device chain */
/* Unlink the device chain */
if
(
link
->
dev
)
{
if
(
link
->
dev
)
{
unregister_netdev
(
dev
);
unregister_netdev
(
dev
);
...
@@ -2240,11 +2227,6 @@ static void wl3501_release(dev_link_t *link)
...
@@ -2240,11 +2227,6 @@ static void wl3501_release(dev_link_t *link)
pcmcia_release_io
(
link
->
handle
,
&
link
->
io
);
pcmcia_release_io
(
link
->
handle
,
&
link
->
io
);
pcmcia_release_irq
(
link
->
handle
,
&
link
->
irq
);
pcmcia_release_irq
(
link
->
handle
,
&
link
->
irq
);
link
->
state
&=
~
DEV_CONFIG
;
link
->
state
&=
~
DEV_CONFIG
;
if
(
link
->
state
&
DEV_STALE_CONFIG
)
wl3501_detach
(
link
);
out:
return
;
}
}
/**
/**
...
...
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