Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
mirror_resources
Qemu
提交
ede77d29
Q
Qemu
项目概览
mirror_resources
/
Qemu
12 个月 前同步成功
通知
4
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
Qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ede77d29
编写于
5月 31, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'amit/for-anthony' into staging
上级
ed7ec840
7edfe652
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
70 addition
and
71 deletion
+70
-71
hw/virtio-console.c
hw/virtio-console.c
+16
-31
hw/virtio-serial-bus.c
hw/virtio-serial-bus.c
+46
-37
hw/virtio-serial.h
hw/virtio-serial.h
+8
-3
未找到文件。
hw/virtio-console.c
浏览文件 @
ede77d29
...
...
@@ -74,25 +74,26 @@ static void chr_event(void *opaque, int event)
}
}
static
int
generic_port_init
(
VirtConsole
*
vcon
,
VirtIOSerialPort
*
port
)
static
int
virtconsole_initfn
(
VirtIOSerialPort
*
port
)
{
VirtConsole
*
vcon
=
DO_UPCAST
(
VirtConsole
,
port
,
port
);
VirtIOSerialPortInfo
*
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
vcon
->
port
.
dev
.
info
);
if
(
port
->
id
==
0
&&
!
info
->
is_console
)
{
error_report
(
"Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility."
);
return
-
1
;
}
if
(
vcon
->
chr
)
{
qemu_chr_add_handlers
(
vcon
->
chr
,
chr_can_read
,
chr_read
,
chr_event
,
vcon
);
vcon
->
port
.
info
->
have_data
=
flush_buf
;
vcon
->
port
.
info
->
guest_open
=
guest_open
;
vcon
->
port
.
info
->
guest_close
=
guest_close
;
info
->
have_data
=
flush_buf
;
info
->
guest_open
=
guest_open
;
info
->
guest_close
=
guest_close
;
}
return
0
;
}
/* Virtio Console Ports */
static
int
virtconsole_initfn
(
VirtIOSerialPort
*
port
)
{
VirtConsole
*
vcon
=
DO_UPCAST
(
VirtConsole
,
port
,
port
);
port
->
is_console
=
true
;
return
generic_port_init
(
vcon
,
port
);
return
0
;
}
static
int
virtconsole_exitfn
(
VirtIOSerialPort
*
port
)
...
...
@@ -113,10 +114,10 @@ static int virtconsole_exitfn(VirtIOSerialPort *port)
static
VirtIOSerialPortInfo
virtconsole_info
=
{
.
qdev
.
name
=
"virtconsole"
,
.
qdev
.
size
=
sizeof
(
VirtConsole
),
.
is_console
=
true
,
.
init
=
virtconsole_initfn
,
.
exit
=
virtconsole_exitfn
,
.
qdev
.
props
=
(
Property
[])
{
DEFINE_PROP_UINT8
(
"is_console"
,
VirtConsole
,
port
.
is_console
,
1
),
DEFINE_PROP_UINT32
(
"nr"
,
VirtConsole
,
port
.
id
,
VIRTIO_CONSOLE_BAD_ID
),
DEFINE_PROP_CHR
(
"chardev"
,
VirtConsole
,
chr
),
DEFINE_PROP_STRING
(
"name"
,
VirtConsole
,
port
.
name
),
...
...
@@ -130,26 +131,10 @@ static void virtconsole_register(void)
}
device_init
(
virtconsole_register
)
/* Generic Virtio Serial Ports */
static
int
virtserialport_initfn
(
VirtIOSerialPort
*
port
)
{
VirtConsole
*
vcon
=
DO_UPCAST
(
VirtConsole
,
port
,
port
);
if
(
port
->
id
==
0
)
{
/*
* Disallow a generic port at id 0, that's reserved for
* console ports.
*/
error_report
(
"Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility."
);
return
-
1
;
}
return
generic_port_init
(
vcon
,
port
);
}
static
VirtIOSerialPortInfo
virtserialport_info
=
{
.
qdev
.
name
=
"virtserialport"
,
.
qdev
.
size
=
sizeof
(
VirtConsole
),
.
init
=
virt
serialport
_initfn
,
.
init
=
virt
console
_initfn
,
.
exit
=
virtconsole_exitfn
,
.
qdev
.
props
=
(
Property
[])
{
DEFINE_PROP_UINT32
(
"nr"
,
VirtConsole
,
port
.
id
,
VIRTIO_CONSOLE_BAD_ID
),
...
...
hw/virtio-serial-bus.c
浏览文件 @
ede77d29
...
...
@@ -39,7 +39,7 @@ struct VirtIOSerial {
/* Arrays of ivqs and ovqs: one per port */
VirtQueue
**
ivqs
,
**
ovqs
;
VirtIOSerialBus
*
bus
;
VirtIOSerialBus
bus
;
DeviceState
*
qdev
;
...
...
@@ -129,9 +129,13 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
static
void
do_flush_queued_data
(
VirtIOSerialPort
*
port
,
VirtQueue
*
vq
,
VirtIODevice
*
vdev
)
{
VirtIOSerialPortInfo
*
info
;
assert
(
port
);
assert
(
virtio_queue_ready
(
vq
));
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
port
->
dev
.
info
);
while
(
!
port
->
throttled
)
{
unsigned
int
i
;
...
...
@@ -149,10 +153,10 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
ssize_t
ret
;
buf_size
=
port
->
elem
.
out_sg
[
i
].
iov_len
-
port
->
iov_offset
;
ret
=
port
->
info
->
have_data
(
port
,
port
->
elem
.
out_sg
[
i
].
iov_base
+
port
->
iov_offset
,
buf_size
);
ret
=
info
->
have_data
(
port
,
port
->
elem
.
out_sg
[
i
].
iov_base
+
port
->
iov_offset
,
buf_size
);
if
(
ret
<
0
&&
ret
!=
-
EAGAIN
)
{
/* We don't handle any other type of errors here */
abort
();
...
...
@@ -285,6 +289,13 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
return
0
;
}
static
void
flush_queued_data_bh
(
void
*
opaque
)
{
VirtIOSerialPort
*
port
=
opaque
;
flush_queued_data
(
port
);
}
void
virtio_serial_throttle_port
(
VirtIOSerialPort
*
port
,
bool
throttle
)
{
if
(
!
port
)
{
...
...
@@ -295,14 +306,14 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
if
(
throttle
)
{
return
;
}
flush_queued_data
(
port
);
qemu_bh_schedule
(
port
->
bh
);
}
/* Guest wants to notify us of some event */
static
void
handle_control_message
(
VirtIOSerial
*
vser
,
void
*
buf
,
size_t
len
)
{
struct
VirtIOSerialPort
*
port
;
struct
VirtIOSerialPortInfo
*
info
;
struct
virtio_console_control
cpkt
,
*
gcpkt
;
uint8_t
*
buffer
;
size_t
buffer_len
;
...
...
@@ -321,11 +332,13 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
if
(
!
port
&&
cpkt
.
event
!=
VIRTIO_CONSOLE_DEVICE_READY
)
return
;
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
port
->
dev
.
info
);
switch
(
cpkt
.
event
)
{
case
VIRTIO_CONSOLE_DEVICE_READY
:
if
(
!
cpkt
.
value
)
{
error_report
(
"virtio-serial-bus: Guest failure in adding device %s
\n
"
,
vser
->
bus
->
qbus
.
name
);
vser
->
bus
.
qbus
.
name
);
break
;
}
/*
...
...
@@ -340,7 +353,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
case
VIRTIO_CONSOLE_PORT_READY
:
if
(
!
cpkt
.
value
)
{
error_report
(
"virtio-serial-bus: Guest failure in adding port %u for device %s
\n
"
,
port
->
id
,
vser
->
bus
->
qbus
.
name
);
port
->
id
,
vser
->
bus
.
qbus
.
name
);
break
;
}
/*
...
...
@@ -350,7 +363,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
* this port is a console port so that the guest can hook it
* up to hvc.
*/
if
(
port
->
is_console
)
{
if
(
info
->
is_console
)
{
send_control_event
(
port
,
VIRTIO_CONSOLE_CONSOLE_PORT
,
1
);
}
...
...
@@ -379,21 +392,21 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
* initialised. If some app is interested in knowing about
* this event, let it know.
*/
if
(
port
->
info
->
guest_ready
)
{
port
->
info
->
guest_ready
(
port
);
if
(
info
->
guest_ready
)
{
info
->
guest_ready
(
port
);
}
break
;
case
VIRTIO_CONSOLE_PORT_OPEN
:
port
->
guest_connected
=
cpkt
.
value
;
if
(
cpkt
.
value
&&
port
->
info
->
guest_open
)
{
if
(
cpkt
.
value
&&
info
->
guest_open
)
{
/* Send the guest opened notification if an app is interested */
port
->
info
->
guest_open
(
port
);
info
->
guest_open
(
port
);
}
if
(
!
cpkt
.
value
&&
port
->
info
->
guest_close
)
{
if
(
!
cpkt
.
value
&&
info
->
guest_close
)
{
/* Send the guest closed notification if an app is interested */
port
->
info
->
guest_close
(
port
);
info
->
guest_close
(
port
);
}
break
;
}
...
...
@@ -442,11 +455,13 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSerial
*
vser
;
VirtIOSerialPort
*
port
;
VirtIOSerialPortInfo
*
info
;
vser
=
DO_UPCAST
(
VirtIOSerial
,
vdev
,
vdev
);
port
=
find_port_by_vq
(
vser
,
vq
);
info
=
port
?
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
port
->
dev
.
info
)
:
NULL
;
if
(
!
port
||
!
port
->
host_connected
||
!
port
->
info
->
have_data
)
{
if
(
!
port
||
!
port
->
host_connected
||
!
info
->
have_data
)
{
discard_vq_data
(
vq
,
vdev
);
return
;
}
...
...
@@ -467,7 +482,7 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
vser
=
DO_UPCAST
(
VirtIOSerial
,
vdev
,
vdev
);
if
(
vser
->
bus
->
max_nr_ports
>
1
)
{
if
(
vser
->
bus
.
max_nr_ports
>
1
)
{
features
|=
(
1
<<
VIRTIO_CONSOLE_F_MULTIPORT
);
}
return
features
;
...
...
@@ -644,16 +659,6 @@ static struct BusInfo virtser_bus_info = {
.
print_dev
=
virtser_bus_dev_print
,
};
static
VirtIOSerialBus
*
virtser_bus_new
(
DeviceState
*
dev
)
{
VirtIOSerialBus
*
bus
;
bus
=
FROM_QBUS
(
VirtIOSerialBus
,
qbus_create
(
&
virtser_bus_info
,
dev
,
NULL
));
bus
->
qbus
.
allow_hotplug
=
1
;
return
bus
;
}
static
void
virtser_bus_dev_print
(
Monitor
*
mon
,
DeviceState
*
qdev
,
int
indent
)
{
VirtIOSerialPort
*
port
=
DO_UPCAST
(
VirtIOSerialPort
,
dev
,
qdev
);
...
...
@@ -726,13 +731,14 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
bool
plugging_port0
;
port
->
vser
=
bus
->
vser
;
port
->
bh
=
qemu_bh_new
(
flush_queued_data_bh
,
port
);
/*
* Is the first console port we're seeing? If so, put it up at
* location 0. This is done for backward compatibility (old
* kernel, new qemu).
*/
plugging_port0
=
port
->
is_console
&&
!
find_port_by_id
(
port
->
vser
,
0
);
plugging_port0
=
info
->
is_console
&&
!
find_port_by_id
(
port
->
vser
,
0
);
if
(
find_port_by_id
(
port
->
vser
,
port
->
id
))
{
error_report
(
"virtio-serial-bus: A port already exists at id %u
\n
"
,
...
...
@@ -759,7 +765,6 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
return
-
1
;
}
port
->
info
=
info
;
ret
=
info
->
init
(
port
);
if
(
ret
)
{
return
ret
;
...
...
@@ -790,15 +795,18 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
static
int
virtser_port_qdev_exit
(
DeviceState
*
qdev
)
{
VirtIOSerialPort
*
port
=
DO_UPCAST
(
VirtIOSerialPort
,
dev
,
qdev
);
VirtIOSerialPortInfo
*
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
port
->
dev
.
info
);
VirtIOSerial
*
vser
=
port
->
vser
;
qemu_bh_delete
(
port
->
bh
);
remove_port
(
port
->
vser
,
port
->
id
);
QTAILQ_REMOVE
(
&
vser
->
ports
,
port
,
next
);
if
(
port
->
info
->
exit
)
port
->
info
->
exit
(
port
);
if
(
info
->
exit
)
{
info
->
exit
(
port
);
}
return
0
;
}
...
...
@@ -835,11 +843,12 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
vser
=
DO_UPCAST
(
VirtIOSerial
,
vdev
,
vdev
);
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
vser
->
bus
=
virtser_bus_new
(
dev
);
vser
->
bus
->
vser
=
vser
;
qbus_create_inplace
(
&
vser
->
bus
.
qbus
,
&
virtser_bus_info
,
dev
,
NULL
);
vser
->
bus
.
qbus
.
allow_hotplug
=
1
;
vser
->
bus
.
vser
=
vser
;
QTAILQ_INIT
(
&
vser
->
ports
);
vser
->
bus
->
max_nr_ports
=
conf
->
max_virtserial_ports
;
vser
->
bus
.
max_nr_ports
=
conf
->
max_virtserial_ports
;
vser
->
ivqs
=
qemu_malloc
(
conf
->
max_virtserial_ports
*
sizeof
(
VirtQueue
*
));
vser
->
ovqs
=
qemu_malloc
(
conf
->
max_virtserial_ports
*
sizeof
(
VirtQueue
*
));
...
...
@@ -859,7 +868,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
/* control queue: guest to host */
vser
->
c_ovq
=
virtio_add_queue
(
vdev
,
32
,
control_out
);
for
(
i
=
1
;
i
<
vser
->
bus
->
max_nr_ports
;
i
++
)
{
for
(
i
=
1
;
i
<
vser
->
bus
.
max_nr_ports
;
i
++
)
{
/* Add a per-port queue for host to guest transfers */
vser
->
ivqs
[
i
]
=
virtio_add_queue
(
vdev
,
128
,
handle_input
);
/* Add a per-per queue for guest to host transfers */
...
...
hw/virtio-serial.h
浏览文件 @
ede77d29
...
...
@@ -75,7 +75,6 @@ typedef struct VirtIOSerialPortInfo VirtIOSerialPortInfo;
*/
struct
VirtIOSerialPort
{
DeviceState
dev
;
VirtIOSerialPortInfo
*
info
;
QTAILQ_ENTRY
(
VirtIOSerialPort
)
next
;
...
...
@@ -119,8 +118,10 @@ struct VirtIOSerialPort {
uint32_t
iov_idx
;
uint64_t
iov_offset
;
/* Identify if this is a port that binds with hvc in the guest */
uint8_t
is_console
;
/*
* When unthrottling we use a bottom-half to call flush_queued_data.
*/
QEMUBH
*
bh
;
/* Is the corresponding guest device open? */
bool
guest_connected
;
...
...
@@ -132,6 +133,10 @@ struct VirtIOSerialPort {
struct
VirtIOSerialPortInfo
{
DeviceInfo
qdev
;
/* Is this a device that binds with hvc in the guest? */
bool
is_console
;
/*
* The per-port (or per-app) init function that's called when a
* new device is found on the bus.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录