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
dc863677
Commit
dc863677
authored
Feb 25, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
478dafdd
701daef7
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
127 additions
and
53 deletions
+127
-53
drivers/serial/21285.c
drivers/serial/21285.c
+4
-3
drivers/serial/8250.c
drivers/serial/8250.c
+68
-6
drivers/serial/amba.c
drivers/serial/amba.c
+4
-3
drivers/serial/anakin.c
drivers/serial/anakin.c
+4
-3
drivers/serial/clps711x.c
drivers/serial/clps711x.c
+4
-3
drivers/serial/core.c
drivers/serial/core.c
+24
-21
drivers/serial/sa1100.c
drivers/serial/sa1100.c
+4
-3
drivers/serial/sunsu.c
drivers/serial/sunsu.c
+4
-3
drivers/serial/uart00.c
drivers/serial/uart00.c
+4
-3
include/linux/serial.h
include/linux/serial.h
+1
-0
include/linux/serial_core.h
include/linux/serial_core.h
+6
-5
No files found.
drivers/serial/21285.c
View file @
dc863677
...
...
@@ -237,7 +237,7 @@ serial21285_set_termios(struct uart_port *port, struct termios *termios,
struct
termios
*
old
)
{
unsigned
long
flags
;
unsigned
int
quot
,
h_lcr
;
unsigned
int
baud
,
quot
,
h_lcr
;
/*
* We don't support modem control lines.
...
...
@@ -253,7 +253,8 @@ serial21285_set_termios(struct uart_port *port, struct termios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
switch
(
termios
->
c_cflag
&
CSIZE
)
{
case
CS5
:
...
...
@@ -286,7 +287,7 @@ serial21285_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
/*
* Which character status flags are we interested in?
...
...
drivers/serial/8250.c
View file @
dc863677
...
...
@@ -159,7 +159,8 @@ static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = {
{
"16C950/954"
,
128
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
},
{
"ST16654"
,
64
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
|
UART_STARTECH
},
{
"XR16850"
,
128
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
|
UART_STARTECH
},
{
"RSA"
,
2048
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
}
{
"RSA"
,
2048
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
},
{
"NS16550A"
,
16
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
|
UART_NATSEMI
}
};
static
_INLINE_
unsigned
int
serial_in
(
struct
uart_8250_port
*
up
,
int
offset
)
...
...
@@ -481,6 +482,40 @@ static void autoconfig_16550a(struct uart_8250_port *up)
return
;
}
/*
* Check for a National Semiconductor SuperIO chip.
* Attempt to switch to bank 2, read the value of the LOOP bit
* from EXCR1. Switch back to bank 0, change it in MCR. Then
* switch back to bank 2, read it from EXCR1 again and check
* it's changed. If so, set baud_base in EXCR2 to 921600.
*/
serial_outp
(
up
,
UART_LCR
,
0
);
status1
=
serial_in
(
up
,
UART_MCR
);
serial_outp
(
up
,
UART_LCR
,
0xE0
);
status2
=
serial_in
(
up
,
0x02
);
/* EXCR1 */
if
(
!
((
status2
^
status1
)
&
UART_MCR_LOOP
))
{
serial_outp
(
up
,
UART_LCR
,
0
);
serial_outp
(
up
,
UART_MCR
,
status1
^
UART_MCR_LOOP
);
serial_outp
(
up
,
UART_LCR
,
0xE0
);
status2
=
serial_in
(
up
,
0x02
);
/* EXCR1 */
serial_outp
(
up
,
UART_LCR
,
0
);
serial_outp
(
up
,
UART_MCR
,
status1
);
if
((
status2
^
status1
)
&
UART_MCR_LOOP
)
{
serial_outp
(
up
,
UART_LCR
,
0xE0
);
status1
=
serial_in
(
up
,
0x04
);
/* EXCR1 */
status1
&=
~
0xB0
;
/* Disable LOCK, mask out PRESL[01] */
status1
|=
0x10
;
/* 1.625 divisor for baud_base --> 921600 */
serial_outp
(
up
,
0x04
,
status1
);
serial_outp
(
up
,
UART_LCR
,
0
);
up
->
port
.
type
=
PORT_NS16550A
;
up
->
port
.
uartclk
=
921600
*
16
;
return
;
}
}
/*
* No EFR. Try to detect a TI16750, which only sets bit 5 of
* the IIR when 64 byte FIFO mode is enabled when DLAB is set.
...
...
@@ -1318,6 +1353,26 @@ static void serial8250_shutdown(struct uart_port *port)
serial_unlink_irq_chain
(
up
);
}
static
unsigned
int
serial8250_get_divisor
(
struct
uart_port
*
port
,
unsigned
int
baud
)
{
unsigned
int
quot
;
/*
* Handle magic divisors for baud rates above baud_base on
* SMSC SuperIO chips.
*/
if
((
port
->
flags
&
UPF_MAGIC_MULTIPLIER
)
&&
baud
==
(
port
->
uartclk
/
4
))
quot
=
0x8001
;
else
if
((
port
->
flags
&
UPF_MAGIC_MULTIPLIER
)
&&
baud
==
(
port
->
uartclk
/
8
))
quot
=
0x8002
;
else
quot
=
uart_get_divisor
(
port
,
baud
);
return
quot
;
}
static
void
serial8250_set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
...
...
@@ -1325,7 +1380,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
struct
uart_8250_port
*
up
=
(
struct
uart_8250_port
*
)
port
;
unsigned
char
cval
,
fcr
=
0
;
unsigned
long
flags
;
unsigned
int
quot
;
unsigned
int
baud
,
quot
;
switch
(
termios
->
c_cflag
&
CSIZE
)
{
case
CS5
:
...
...
@@ -1357,7 +1412,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
serial8250_get_divisor
(
port
,
baud
);
/*
* Work around a bug in the Oxford Semiconductor 952 rev B
...
...
@@ -1369,7 +1425,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
quot
++
;
if
(
uart_config
[
up
->
port
.
type
].
flags
&
UART_USE_FIFO
)
{
if
(
(
up
->
port
.
uartclk
/
quot
)
<
(
2400
*
16
)
)
if
(
baud
<
2400
)
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_TRIGGER_1
;
#ifdef CONFIG_SERIAL_8250_RSA
else
if
(
up
->
port
.
type
==
PORT_RSA
)
...
...
@@ -1390,7 +1446,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
up
->
port
.
read_status_mask
=
UART_LSR_OE
|
UART_LSR_THRE
|
UART_LSR_DR
;
if
(
termios
->
c_iflag
&
INPCK
)
...
...
@@ -1434,7 +1490,13 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
serial_outp
(
up
,
UART_EFR
,
termios
->
c_cflag
&
CRTSCTS
?
UART_EFR_CTS
:
0
);
}
if
(
uart_config
[
up
->
port
.
type
].
flags
&
UART_NATSEMI
)
{
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
serial_outp
(
up
,
UART_LCR
,
0xe0
);
}
else
{
serial_outp
(
up
,
UART_LCR
,
cval
|
UART_LCR_DLAB
);
/* set DLAB */
}
serial_outp
(
up
,
UART_DLL
,
quot
&
0xff
);
/* LS of divisor */
serial_outp
(
up
,
UART_DLM
,
quot
>>
8
);
/* MS of divisor */
if
(
up
->
port
.
type
==
PORT_16750
)
...
...
drivers/serial/amba.c
View file @
dc863677
...
...
@@ -408,12 +408,13 @@ ambauart_set_termios(struct uart_port *port, struct termios *termios,
{
unsigned
int
lcr_h
,
old_cr
;
unsigned
long
flags
;
unsigned
int
quot
;
unsigned
int
baud
,
quot
;
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
switch
(
termios
->
c_cflag
&
CSIZE
)
{
case
CS5
:
...
...
@@ -444,7 +445,7 @@ ambauart_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
port
->
read_status_mask
=
AMBA_UARTRSR_OE
;
if
(
termios
->
c_iflag
&
INPCK
)
...
...
drivers/serial/anakin.c
View file @
dc863677
...
...
@@ -287,7 +287,7 @@ anakin_set_termios(struct uart_port *port, struct termios *termios,
struct
termios
*
old
)
{
unsigned
long
flags
;
unsigned
int
quot
;
unsigned
int
baud
,
quot
;
/*
* We don't support parity, stop bits, or anything other
...
...
@@ -304,11 +304,12 @@ anakin_set_termios(struct uart_port *port, struct termios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
while
(
!
(
anakin_in
(
port
,
0x10
)
&
TXEMPTY
))
barrier
();
...
...
drivers/serial/clps711x.c
View file @
dc863677
...
...
@@ -320,7 +320,7 @@ static void
clps711xuart_set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
ubrlcr
,
quot
;
unsigned
int
ubrlcr
,
baud
,
quot
;
unsigned
long
flags
;
/*
...
...
@@ -331,7 +331,8 @@ clps711xuart_set_termios(struct uart_port *port, struct termios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
switch
(
termios
->
c_cflag
&
CSIZE
)
{
case
CS5
:
...
...
@@ -362,7 +363,7 @@ clps711xuart_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
port
->
read_status_mask
=
UARTDR_OVERR
;
if
(
termios
->
c_iflag
&
INPCK
)
...
...
drivers/serial/core.c
View file @
dc863677
...
...
@@ -271,7 +271,7 @@ static void uart_shutdown(struct uart_info *info)
*/
void
uart_update_timeout
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
quot
)
unsigned
int
baud
)
{
unsigned
int
bits
;
...
...
@@ -305,7 +305,7 @@ uart_update_timeout(struct uart_port *port, unsigned int cflag,
* Figure the timeout to send the above number of bits.
* Add .02 seconds of slop
*/
port
->
timeout
=
(
HZ
*
bits
)
/
(
port
->
uartclk
/
(
16
*
quot
))
+
HZ
/
50
;
port
->
timeout
=
(
HZ
*
bits
)
/
baud
+
HZ
/
50
;
}
EXPORT_SYMBOL
(
uart_update_timeout
);
...
...
@@ -321,6 +321,12 @@ EXPORT_SYMBOL(uart_update_timeout);
* Decode the termios structure into a numeric baud rate,
* taking account of the magic 38400 baud rate (with spd_*
* flags), and mapping the %B0 rate to 9600 baud.
*
* If the new baud rate is invalid, try the old termios setting.
* If it's still invalid, we try 9600 baud.
*
* Update the @termios structure to reflect the baud rate
* we're actually going to be using.
*/
unsigned
int
uart_get_baud_rate
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
...
...
@@ -383,26 +389,14 @@ EXPORT_SYMBOL(uart_get_baud_rate);
/**
* uart_get_divisor - return uart clock divisor
* @port: uart_port structure describing the port.
* @termios: desired termios settings
* @old_termios: the original port settings, or NULL
*
* Calculate the uart clock divisor for the port. If the
* divisor is invalid, try the old termios setting. If
* the divisor is still invalid, we try 9600 baud.
* @baud: desired baud rate
*
* Update the @termios structure to reflect the baud rate
* we're actually going to be using.
*
* If 9600 baud fails, we return a zero divisor.
* Calculate the uart clock divisor for the port.
*/
unsigned
int
uart_get_divisor
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old_termios
)
uart_get_divisor
(
struct
uart_port
*
port
,
unsigned
int
baud
)
{
unsigned
int
quot
,
baud
,
max
=
port
->
uartclk
/
16
;
/* Determine divisor based on baud rate */
baud
=
uart_get_baud_rate
(
port
,
termios
,
old_termios
,
0
,
max
);
unsigned
int
quot
;
/*
* Old custom speed handling.
...
...
@@ -832,8 +826,17 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo)
goto
exit
;
if
(
info
->
flags
&
UIF_INITIALIZED
)
{
if
(((
old_flags
^
port
->
flags
)
&
UPF_SPD_MASK
)
||
old_custom_divisor
!=
port
->
custom_divisor
)
old_custom_divisor
!=
port
->
custom_divisor
)
{
/* If they're setting up a custom divisor or speed,
* instead of clearing it, then bitch about it. No
* need to rate-limit; it's CAP_SYS_ADMIN only. */
if
(
port
->
flags
&
UPF_SPD_MASK
)
{
printk
(
KERN_NOTICE
"%s sets custom speed on %s%d. This is deprecated.
\n
"
,
current
->
comm
,
info
->
tty
->
driver
.
name
,
info
->
port
->
line
);
}
uart_change_speed
(
info
,
NULL
);
}
}
else
retval
=
uart_startup
(
info
,
1
);
exit:
...
...
@@ -2024,11 +2027,11 @@ static int uart_pm(struct pm_dev *dev, pm_request_t rqst, void *data)
switch
(
rqst
)
{
case
PM_SUSPEND
:
case
PM_RESUME
:
err
=
uart_pm_set_state
(
state
,
(
int
)
data
,
dev
->
state
);
err
=
uart_pm_set_state
(
state
,
(
int
)
(
long
)
data
,
dev
->
state
);
break
;
case
PM_SET_WAKEUP
:
err
=
uart_pm_set_wakeup
(
state
,
(
int
)
data
);
err
=
uart_pm_set_wakeup
(
state
,
(
int
)
(
long
)
data
);
break
;
}
return
err
;
...
...
drivers/serial/sa1100.c
View file @
dc863677
...
...
@@ -441,7 +441,7 @@ sa1100_set_termios(struct uart_port *port, struct termios *termios,
{
struct
sa1100_port
*
sport
=
(
struct
sa1100_port
*
)
port
;
unsigned
long
flags
;
unsigned
int
utcr0
,
old_utcr3
,
quot
;
unsigned
int
utcr0
,
old_utcr3
,
baud
,
quot
;
unsigned
int
old_csize
=
old
?
old
->
c_cflag
&
CSIZE
:
CS8
;
/*
...
...
@@ -470,7 +470,8 @@ sa1100_set_termios(struct uart_port *port, struct termios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
spin_lock_irqsave
(
&
sport
->
port
.
lock
,
flags
);
...
...
@@ -507,7 +508,7 @@ sa1100_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
/*
* disable interrupts and drain transmitter
...
...
drivers/serial/sunsu.c
View file @
dc863677
...
...
@@ -852,7 +852,7 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
cflag
,
quot
);
uart_update_timeout
(
port
,
cflag
,
(
port
->
uartclk
/
(
16
*
quot
))
);
up
->
port
.
read_status_mask
=
UART_LSR_OE
|
UART_LSR_THRE
|
UART_LSR_DR
;
if
(
iflag
&
INPCK
)
...
...
@@ -919,12 +919,13 @@ static void
sunsu_set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
quot
;
unsigned
int
baud
,
quot
;
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
sunsu_change_speed
(
port
,
termios
->
c_cflag
,
termios
->
c_iflag
,
quot
);
}
...
...
drivers/serial/uart00.c
View file @
dc863677
...
...
@@ -317,7 +317,7 @@ static void
uart00_set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
uart_mc
,
old_ies
,
quot
;
unsigned
int
uart_mc
,
old_ies
,
baud
,
quot
;
unsigned
long
flags
;
/*
...
...
@@ -328,7 +328,8 @@ uart00_set_termios(struct uart_port *port, struct termios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
baud
=
uart_get_baud_rate
(
port
,
termios
,
old
,
0
,
port
->
uartclk
/
16
);
quot
=
uart_get_divisor
(
port
,
baud
);
/* byte size and parity */
switch
(
termios
->
c_cflag
&
CSIZE
)
{
...
...
@@ -358,7 +359,7 @@ uart00_set_termios(struct uart_port *port, struct termios *termios,
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
baud
);
port
->
read_status_mask
=
UART_RDS_OE_MSK
;
if
(
termios
->
c_iflag
&
INPCK
)
...
...
include/linux/serial.h
View file @
dc863677
...
...
@@ -91,6 +91,7 @@ struct serial_uart_config {
#define UART_CLEAR_FIFO 0x01
#define UART_USE_FIFO 0x02
#define UART_STARTECH 0x04
#define UART_NATSEMI 0x08
/*
* Definitions for async_struct (and serial_struct) flags field
...
...
include/linux/serial_core.h
View file @
dc863677
...
...
@@ -37,7 +37,8 @@
#define PORT_16654 11
#define PORT_16850 12
#define PORT_RSA 13
#define PORT_MAX_8250 13
/* max port ID */
#define PORT_NS16550A 14
#define PORT_MAX_8250 14
/* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
...
...
@@ -172,6 +173,7 @@ struct uart_port {
#define UPF_LOW_LATENCY (1 << 13)
#define UPF_BUGGY_UART (1 << 14)
#define UPF_AUTOPROBE (1 << 15)
#define UPF_MAGIC_MULTIPLIER (1 << 16)
#define UPF_BOOT_ONLYMCA (1 << 22)
#define UPF_CONS_FLOW (1 << 23)
#define UPF_SHARE_IRQ (1 << 24)
...
...
@@ -179,7 +181,7 @@ struct uart_port {
#define UPF_RESOURCES (1 << 30)
#define UPF_IOREMAP (1 << 31)
#define UPF_CHANGE_MASK (0x7fff)
#define UPF_CHANGE_MASK (0x
1
7fff)
#define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY)
unsigned
int
mctrl
;
/* current modem ctrl settings */
...
...
@@ -279,12 +281,11 @@ void uart_write_wakeup(struct uart_port *port);
* Baud rate helpers.
*/
void
uart_update_timeout
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
quot
);
unsigned
int
baud
);
unsigned
int
uart_get_baud_rate
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
,
unsigned
int
min
,
unsigned
int
max
);
unsigned
int
uart_get_divisor
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old_termios
);
unsigned
int
uart_get_divisor
(
struct
uart_port
*
port
,
unsigned
int
baud
);
/*
* Console helpers.
...
...
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