Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
975f957d
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
975f957d
编写于
8月 29, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-serial.git
上级
2321fbd2
661299d9
变更
4
展开全部
隐藏空白更改
内联
并排
Showing
4 changed file
with
380 addition
and
512 deletion
+380
-512
drivers/parport/parport_serial.c
drivers/parport/parport_serial.c
+166
-173
drivers/serial/8250_pci.c
drivers/serial/8250_pci.c
+177
-297
include/linux/8250_pci.h
include/linux/8250_pci.h
+37
-2
include/linux/serialP.h
include/linux/serialP.h
+0
-40
未找到文件。
drivers/parport/parport_serial.c
浏览文件 @
975f957d
...
@@ -23,13 +23,8 @@
...
@@ -23,13 +23,8 @@
#include <linux/pci.h>
#include <linux/pci.h>
#include <linux/parport.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/parport_pc.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/list.h>
#include <linux/8250_pci.h>
#include <linux/8250_pci.h>
#include <asm/serial.h>
enum
parport_pc_pci_cards
{
enum
parport_pc_pci_cards
{
titan_110l
=
0
,
titan_110l
=
0
,
titan_210l
,
titan_210l
,
...
@@ -168,182 +163,147 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
...
@@ -168,182 +163,147 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
};
};
MODULE_DEVICE_TABLE
(
pci
,
parport_serial_pci_tbl
);
MODULE_DEVICE_TABLE
(
pci
,
parport_serial_pci_tbl
);
struct
pci_board_no_ids
{
/*
int
flags
;
* This table describes the serial "geometry" of these boards. Any
int
num_ports
;
* quirks for these can be found in drivers/serial/8250_pci.c
int
base_baud
;
*
int
uart_offset
;
* Cards not tested are marked n/t
int
reg_shift
;
* If you have one of these cards and it works for you, please tell me..
int
(
*
init_fn
)(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
*/
int
enable
);
static
struct
pciserial_board
pci_parport_serial_boards
[]
__devinitdata
=
{
int
first_uart_offset
;
[
titan_110l
]
=
{
};
.
flags
=
FL_BASE1
|
FL_BASE_BARS
,
.
num_ports
=
1
,
static
int
__devinit
siig10x_init_fn
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
)
.
base_baud
=
921600
,
{
.
uart_offset
=
8
,
return
pci_siig10x_fn
(
dev
,
enable
);
},
}
[
titan_210l
]
=
{
.
flags
=
FL_BASE1
|
FL_BASE_BARS
,
static
int
__devinit
siig20x_init_fn
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
)
.
num_ports
=
2
,
{
.
base_baud
=
921600
,
return
pci_siig20x_fn
(
dev
,
enable
);
.
uart_offset
=
8
,
}
},
[
netmos_9xx5_combo
]
=
{
static
int
__devinit
netmos_serial_init
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
int
enable
)
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
{
.
num_ports
=
1
,
board
->
num_ports
=
dev
->
subsystem_device
&
0xf
;
.
base_baud
=
115200
,
return
0
;
.
uart_offset
=
8
,
}
},
[
netmos_9855
]
=
{
static
struct
pci_board_no_ids
pci_boards
[]
__devinitdata
=
{
.
flags
=
FL_BASE2
|
FL_BASE_BARS
,
/*
.
num_ports
=
1
,
* PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
.
base_baud
=
115200
,
* Offset to get to next UART's registers,
.
uart_offset
=
8
,
* Register shift to use for memory-mapped I/O,
},
* Initialization function, first UART offset
[
avlab_1s1p
]
=
{
/* n/t */
*/
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
// Cards not tested are marked n/t
.
base_baud
=
115200
,
// If you have one of these cards and it works for you, please tell me..
.
uart_offset
=
8
,
},
/* titan_110l */
{
SPCI_FL_BASE1
|
SPCI_FL_BASE_TABLE
,
1
,
921600
},
[
avlab_1s1p_650
]
=
{
/* nt */
/* titan_210l */
{
SPCI_FL_BASE1
|
SPCI_FL_BASE_TABLE
,
2
,
921600
},
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
/* netmos_9xx5_combo */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
,
0
,
0
,
netmos_serial_init
},
.
num_ports
=
1
,
/* netmos_9855 */
{
SPCI_FL_BASE2
|
SPCI_FL_BASE_TABLE
,
1
,
115200
,
0
,
0
,
netmos_serial_init
},
.
base_baud
=
115200
,
/* avlab_1s1p (n/t) */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
uart_offset
=
8
,
/* avlab_1s1p_650 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
},
/* avlab_1s1p_850 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
[
avlab_1s1p_850
]
=
{
/* nt */
/* avlab_1s2p (n/t) */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
/* avlab_1s2p_650 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
num_ports
=
1
,
/* avlab_1s2p_850 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
1
,
115200
},
.
base_baud
=
115200
,
/* avlab_2s1p (n/t) */
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
2
,
115200
},
.
uart_offset
=
8
,
/* avlab_2s1p_650 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
2
,
115200
},
},
/* avlab_2s1p_850 (nt)*/
{
SPCI_FL_BASE0
|
SPCI_FL_BASE_TABLE
,
2
,
115200
},
[
avlab_1s2p
]
=
{
/* n/t */
/* siig_1s1p_10x */
{
SPCI_FL_BASE2
,
1
,
460800
,
0
,
0
,
siig10x_init_fn
},
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
/* siig_2s1p_10x */
{
SPCI_FL_BASE2
,
1
,
921600
,
0
,
0
,
siig10x_init_fn
},
.
num_ports
=
1
,
/* siig_2p1s_20x */
{
SPCI_FL_BASE0
,
1
,
921600
,
0
,
0
,
siig20x_init_fn
},
.
base_baud
=
115200
,
/* siig_1s1p_20x */
{
SPCI_FL_BASE0
,
1
,
921600
,
0
,
0
,
siig20x_init_fn
},
.
uart_offset
=
8
,
/* siig_2s1p_20x */
{
SPCI_FL_BASE0
,
1
,
921600
,
0
,
0
,
siig20x_init_fn
},
},
[
avlab_1s2p_650
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_1s2p_850
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
1
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_2s1p
]
=
{
/* n/t */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
2
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_2s1p_650
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
2
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
avlab_2s1p_850
]
=
{
/* nt */
.
flags
=
FL_BASE0
|
FL_BASE_BARS
,
.
num_ports
=
2
,
.
base_baud
=
115200
,
.
uart_offset
=
8
,
},
[
siig_1s1p_10x
]
=
{
.
flags
=
FL_BASE2
,
.
num_ports
=
1
,
.
base_baud
=
460800
,
.
uart_offset
=
8
,
},
[
siig_2s1p_10x
]
=
{
.
flags
=
FL_BASE2
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
[
siig_2p1s_20x
]
=
{
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
[
siig_1s1p_20x
]
=
{
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
[
siig_2s1p_20x
]
=
{
.
flags
=
FL_BASE0
,
.
num_ports
=
1
,
.
base_baud
=
921600
,
.
uart_offset
=
8
,
},
};
};
struct
parport_serial_private
{
struct
parport_serial_private
{
int
num_ser
;
struct
serial_private
*
serial
;
int
line
[
20
];
struct
pci_board_no_ids
ser
;
int
num_par
;
int
num_par
;
struct
parport
*
port
[
PARPORT_MAX
];
struct
parport
*
port
[
PARPORT_MAX
];
struct
parport_pc_pci
par
;
struct
parport_pc_pci
par
;
};
};
static
int
__devinit
get_pci_port
(
struct
pci_dev
*
dev
,
struct
pci_board_no_ids
*
board
,
struct
serial_struct
*
req
,
int
idx
)
{
unsigned
long
port
;
int
base_idx
;
int
max_port
;
int
offset
;
base_idx
=
SPCI_FL_GET_BASE
(
board
->
flags
);
if
(
board
->
flags
&
SPCI_FL_BASE_TABLE
)
base_idx
+=
idx
;
if
(
board
->
flags
&
SPCI_FL_REGION_SZ_CAP
)
{
max_port
=
pci_resource_len
(
dev
,
base_idx
)
/
8
;
if
(
idx
>=
max_port
)
return
1
;
}
offset
=
board
->
first_uart_offset
;
/* Timedia/SUNIX uses a mixture of BARs and offsets */
/* Ugh, this is ugly as all hell --- TYT */
if
(
dev
->
vendor
==
PCI_VENDOR_ID_TIMEDIA
)
/* 0x1409 */
switch
(
idx
)
{
case
0
:
base_idx
=
0
;
break
;
case
1
:
base_idx
=
0
;
offset
=
8
;
break
;
case
2
:
base_idx
=
1
;
break
;
case
3
:
base_idx
=
1
;
offset
=
8
;
break
;
case
4
:
/* BAR 2*/
case
5
:
/* BAR 3 */
case
6
:
/* BAR 4*/
case
7
:
base_idx
=
idx
-
2
;
/* BAR 5*/
}
port
=
pci_resource_start
(
dev
,
base_idx
)
+
offset
;
if
((
board
->
flags
&
SPCI_FL_BASE_TABLE
)
==
0
)
port
+=
idx
*
(
board
->
uart_offset
?
board
->
uart_offset
:
8
);
if
(
pci_resource_flags
(
dev
,
base_idx
)
&
IORESOURCE_IO
)
{
int
high_bits_offset
=
((
sizeof
(
long
)
-
sizeof
(
int
))
*
8
);
req
->
port
=
port
;
if
(
high_bits_offset
)
req
->
port_high
=
port
>>
high_bits_offset
;
else
req
->
port_high
=
0
;
return
0
;
}
req
->
io_type
=
SERIAL_IO_MEM
;
req
->
iomem_base
=
ioremap
(
port
,
board
->
uart_offset
);
req
->
iomem_reg_shift
=
board
->
reg_shift
;
req
->
port
=
0
;
return
req
->
iomem_base
?
0
:
1
;
}
/* Register the serial port(s) of a PCI card. */
/* Register the serial port(s) of a PCI card. */
static
int
__devinit
serial_register
(
struct
pci_dev
*
dev
,
static
int
__devinit
serial_register
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
const
struct
pci_device_id
*
id
)
{
{
struct
pci_board_no_ids
*
board
;
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
serial_struct
serial_req
;
struct
pciserial_board
*
board
;
int
base_baud
;
struct
serial_private
*
serial
;
int
k
;
int
success
=
0
;
priv
->
ser
=
pci_boards
[
id
->
driver_data
];
board
=
&
priv
->
ser
;
if
(
board
->
init_fn
&&
((
board
->
init_fn
)
(
dev
,
board
,
1
)
!=
0
))
return
1
;
base_baud
=
board
->
base_baud
;
if
(
!
base_baud
)
base_baud
=
BASE_BAUD
;
memset
(
&
serial_req
,
0
,
sizeof
(
serial_req
));
for
(
k
=
0
;
k
<
board
->
num_ports
;
k
++
)
{
int
line
;
if
(
priv
->
num_ser
==
ARRAY_SIZE
(
priv
->
line
))
{
board
=
&
pci_parport_serial_boards
[
id
->
driver_data
];
printk
(
KERN_WARNING
serial
=
pciserial_init_ports
(
dev
,
board
);
"parport_serial: %s: only %u serial lines "
"supported (%d reported)
\n
"
,
pci_name
(
dev
),
ARRAY_SIZE
(
priv
->
line
),
board
->
num_ports
);
break
;
}
serial_req
.
irq
=
dev
->
irq
;
if
(
IS_ERR
(
serial
))
if
(
get_pci_port
(
dev
,
board
,
&
serial_req
,
k
))
return
PTR_ERR
(
serial
);
break
;
serial_req
.
flags
=
ASYNC_SKIP_TEST
|
ASYNC_AUTOPROBE
;
serial_req
.
baud_base
=
base_baud
;
line
=
register_serial
(
&
serial_req
);
if
(
line
<
0
)
{
printk
(
KERN_DEBUG
"parport_serial: register_serial failed
\n
"
);
continue
;
}
priv
->
line
[
priv
->
num_ser
++
]
=
line
;
success
=
1
;
}
return
success
?
0
:
1
;
priv
->
serial
=
serial
;
return
0
;
}
}
/* Register the parallel port(s) of a PCI card. */
/* Register the parallel port(s) of a PCI card. */
...
@@ -411,7 +371,7 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
...
@@ -411,7 +371,7 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
priv
=
kmalloc
(
sizeof
*
priv
,
GFP_KERNEL
);
priv
=
kmalloc
(
sizeof
*
priv
,
GFP_KERNEL
);
if
(
!
priv
)
if
(
!
priv
)
return
-
ENOMEM
;
return
-
ENOMEM
;
priv
->
num_ser
=
priv
->
num_par
=
0
;
memset
(
priv
,
0
,
sizeof
(
struct
parport_serial_private
))
;
pci_set_drvdata
(
dev
,
priv
);
pci_set_drvdata
(
dev
,
priv
);
err
=
pci_enable_device
(
dev
);
err
=
pci_enable_device
(
dev
);
...
@@ -444,15 +404,12 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
...
@@ -444,15 +404,12 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
int
i
;
int
i
;
pci_set_drvdata
(
dev
,
NULL
);
// Serial ports
// Serial ports
for
(
i
=
0
;
i
<
priv
->
num_ser
;
i
++
)
{
if
(
priv
->
serial
)
unregister_serial
(
priv
->
line
[
i
]
);
pciserial_remove_ports
(
priv
->
serial
);
if
(
priv
->
ser
.
init_fn
)
(
priv
->
ser
.
init_fn
)
(
dev
,
&
priv
->
ser
,
0
);
}
pci_set_drvdata
(
dev
,
NULL
);
// Parallel ports
// Parallel ports
for
(
i
=
0
;
i
<
priv
->
num_par
;
i
++
)
for
(
i
=
0
;
i
<
priv
->
num_par
;
i
++
)
parport_pc_unregister_port
(
priv
->
port
[
i
]);
parport_pc_unregister_port
(
priv
->
port
[
i
]);
...
@@ -461,11 +418,47 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
...
@@ -461,11 +418,47 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
return
;
return
;
}
}
static
int
parport_serial_pci_suspend
(
struct
pci_dev
*
dev
,
pm_message_t
state
)
{
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
if
(
priv
->
serial
)
pciserial_suspend_ports
(
priv
->
serial
);
/* FIXME: What about parport? */
pci_save_state
(
dev
);
pci_set_power_state
(
dev
,
pci_choose_state
(
dev
,
state
));
return
0
;
}
static
int
parport_serial_pci_resume
(
struct
pci_dev
*
dev
)
{
struct
parport_serial_private
*
priv
=
pci_get_drvdata
(
dev
);
pci_set_power_state
(
dev
,
PCI_D0
);
pci_restore_state
(
dev
);
/*
* The device may have been disabled. Re-enable it.
*/
pci_enable_device
(
dev
);
if
(
priv
->
serial
)
pciserial_resume_ports
(
priv
->
serial
);
/* FIXME: What about parport? */
return
0
;
}
static
struct
pci_driver
parport_serial_pci_driver
=
{
static
struct
pci_driver
parport_serial_pci_driver
=
{
.
name
=
"parport_serial"
,
.
name
=
"parport_serial"
,
.
id_table
=
parport_serial_pci_tbl
,
.
id_table
=
parport_serial_pci_tbl
,
.
probe
=
parport_serial_pci_probe
,
.
probe
=
parport_serial_pci_probe
,
.
remove
=
__devexit_p
(
parport_serial_pci_remove
),
.
remove
=
__devexit_p
(
parport_serial_pci_remove
),
.
suspend
=
parport_serial_pci_suspend
,
.
resume
=
parport_serial_pci_resume
,
};
};
...
...
drivers/serial/8250_pci.c
浏览文件 @
975f957d
此差异已折叠。
点击以展开。
include/linux/8250_pci.h
浏览文件 @
975f957d
int
pci_siig10x_fn
(
struct
pci_dev
*
dev
,
int
enable
);
/*
int
pci_siig20x_fn
(
struct
pci_dev
*
dev
,
int
enable
);
* Definitions for PCI support.
*/
#define FL_BASE_MASK 0x0007
#define FL_BASE0 0x0000
#define FL_BASE1 0x0001
#define FL_BASE2 0x0002
#define FL_BASE3 0x0003
#define FL_BASE4 0x0004
#define FL_GET_BASE(x) (x & FL_BASE_MASK)
/* Use successive BARs (PCI base address registers),
else use offset into some specified BAR */
#define FL_BASE_BARS 0x0008
/* do not assign an irq */
#define FL_NOIRQ 0x0080
/* Use the Base address register size to cap number of ports */
#define FL_REGION_SZ_CAP 0x0100
struct
pciserial_board
{
unsigned
int
flags
;
unsigned
int
num_ports
;
unsigned
int
base_baud
;
unsigned
int
uart_offset
;
unsigned
int
reg_shift
;
unsigned
int
first_offset
;
};
struct
serial_private
;
struct
serial_private
*
pciserial_init_ports
(
struct
pci_dev
*
dev
,
struct
pciserial_board
*
board
);
void
pciserial_remove_ports
(
struct
serial_private
*
priv
);
void
pciserial_suspend_ports
(
struct
serial_private
*
priv
);
void
pciserial_resume_ports
(
struct
serial_private
*
priv
);
include/linux/serialP.h
浏览文件 @
975f957d
...
@@ -140,44 +140,4 @@ struct rs_multiport_struct {
...
@@ -140,44 +140,4 @@ struct rs_multiport_struct {
#define ALPHA_KLUDGE_MCR 0
#define ALPHA_KLUDGE_MCR 0
#endif
#endif
/*
* Definitions for PCI support.
*/
#define SPCI_FL_BASE_MASK 0x0007
#define SPCI_FL_BASE0 0x0000
#define SPCI_FL_BASE1 0x0001
#define SPCI_FL_BASE2 0x0002
#define SPCI_FL_BASE3 0x0003
#define SPCI_FL_BASE4 0x0004
#define SPCI_FL_GET_BASE(x) (x & SPCI_FL_BASE_MASK)
#define SPCI_FL_IRQ_MASK (0x0007 << 4)
#define SPCI_FL_IRQBASE0 (0x0000 << 4)
#define SPCI_FL_IRQBASE1 (0x0001 << 4)
#define SPCI_FL_IRQBASE2 (0x0002 << 4)
#define SPCI_FL_IRQBASE3 (0x0003 << 4)
#define SPCI_FL_IRQBASE4 (0x0004 << 4)
#define SPCI_FL_GET_IRQBASE(x) ((x & SPCI_FL_IRQ_MASK) >> 4)
/* Use successive BARs (PCI base address registers),
else use offset into some specified BAR */
#define SPCI_FL_BASE_TABLE 0x0100
/* Use successive entries in the irq resource table */
#define SPCI_FL_IRQ_TABLE 0x0200
/* Use the irq resource table instead of dev->irq */
#define SPCI_FL_IRQRESOURCE 0x0400
/* Use the Base address register size to cap number of ports */
#define SPCI_FL_REGION_SZ_CAP 0x0800
/* Do not use irq sharing for this device */
#define SPCI_FL_NO_SHIRQ 0x1000
/* This is a PNP device */
#define SPCI_FL_ISPNP 0x2000
#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE|SPCI_FL_ISPNP)
#endif
/* _LINUX_SERIAL_H */
#endif
/* _LINUX_SERIAL_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录