Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
f82e35e3
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f82e35e3
编写于
12月 04, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
virtio-serial: convert to QEMU Object Model
Signed-off-by:
N
Anthony Liguori
<
aliguori@us.ibm.com
>
上级
3954d33a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
128 addition
and
90 deletion
+128
-90
hw/virtio-console.c
hw/virtio-console.c
+43
-26
hw/virtio-serial-bus.c
hw/virtio-serial-bus.c
+41
-27
hw/virtio-serial.h
hw/virtio-serial.h
+44
-37
未找到文件。
hw/virtio-console.c
浏览文件 @
f82e35e3
...
...
@@ -109,10 +109,9 @@ static void chr_event(void *opaque, int event)
static
int
virtconsole_initfn
(
VirtIOSerialPort
*
port
)
{
VirtConsole
*
vcon
=
DO_UPCAST
(
VirtConsole
,
port
,
port
);
VirtIOSerialPortInfo
*
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
qdev_get_info
(
&
vcon
->
port
.
dev
));
VirtIOSerialPortClass
*
k
=
VIRTIO_SERIAL_PORT_GET_CLASS
(
port
);
if
(
port
->
id
==
0
&&
!
info
->
is_console
)
{
if
(
port
->
id
==
0
&&
!
k
->
is_console
)
{
error_report
(
"Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility."
);
return
-
1
;
}
...
...
@@ -125,18 +124,27 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
return
0
;
}
static
VirtIOSerialPortInfo
virtconsole_info
=
{
.
qdev
.
name
=
"virtconsole"
,
.
qdev
.
size
=
sizeof
(
VirtConsole
),
.
is_console
=
true
,
.
init
=
virtconsole_initfn
,
.
have_data
=
flush_buf
,
.
guest_open
=
guest_open
,
.
guest_close
=
guest_close
,
.
qdev
.
props
=
(
Property
[])
{
DEFINE_PROP_CHR
(
"chardev"
,
VirtConsole
,
chr
),
DEFINE_PROP_END_OF_LIST
(),
},
static
Property
virtconsole_properties
[]
=
{
DEFINE_PROP_CHR
(
"chardev"
,
VirtConsole
,
chr
),
DEFINE_PROP_END_OF_LIST
(),
};
static
void
virtconsole_class_init
(
ObjectClass
*
klass
,
void
*
data
)
{
VirtIOSerialPortClass
*
k
=
VIRTIO_SERIAL_PORT_CLASS
(
klass
);
k
->
is_console
=
true
;
k
->
init
=
virtconsole_initfn
;
k
->
have_data
=
flush_buf
;
k
->
guest_open
=
guest_open
;
k
->
guest_close
=
guest_close
;
}
static
DeviceInfo
virtconsole_info
=
{
.
name
=
"virtconsole"
,
.
size
=
sizeof
(
VirtConsole
),
.
props
=
virtconsole_properties
,
.
class_init
=
virtconsole_class_init
,
};
static
void
virtconsole_register
(
void
)
...
...
@@ -145,17 +153,26 @@ static void virtconsole_register(void)
}
device_init
(
virtconsole_register
)
static
VirtIOSerialPortInfo
virtserialport_info
=
{
.
qdev
.
name
=
"virtserialport"
,
.
qdev
.
size
=
sizeof
(
VirtConsole
),
.
init
=
virtconsole_initfn
,
.
have_data
=
flush_buf
,
.
guest_open
=
guest_open
,
.
guest_close
=
guest_close
,
.
qdev
.
props
=
(
Property
[])
{
DEFINE_PROP_CHR
(
"chardev"
,
VirtConsole
,
chr
),
DEFINE_PROP_END_OF_LIST
(),
},
static
Property
virtserialport_properties
[]
=
{
DEFINE_PROP_CHR
(
"chardev"
,
VirtConsole
,
chr
),
DEFINE_PROP_END_OF_LIST
(),
};
static
void
virtserialport_class_init
(
ObjectClass
*
klass
,
void
*
data
)
{
VirtIOSerialPortClass
*
k
=
VIRTIO_SERIAL_PORT_CLASS
(
klass
);
k
->
init
=
virtconsole_initfn
;
k
->
have_data
=
flush_buf
;
k
->
guest_open
=
guest_open
;
k
->
guest_close
=
guest_close
;
}
static
DeviceInfo
virtserialport_info
=
{
.
name
=
"virtserialport"
,
.
size
=
sizeof
(
VirtConsole
),
.
props
=
virtserialport_properties
,
.
class_init
=
virtserialport_class_init
,
};
static
void
virtserialport_register
(
void
)
...
...
hw/virtio-serial-bus.c
浏览文件 @
f82e35e3
...
...
@@ -133,12 +133,12 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
static
void
do_flush_queued_data
(
VirtIOSerialPort
*
port
,
VirtQueue
*
vq
,
VirtIODevice
*
vdev
)
{
VirtIOSerialPort
Info
*
info
;
VirtIOSerialPort
Class
*
vsc
;
assert
(
port
);
assert
(
virtio_queue_ready
(
vq
));
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
qdev_get_info
(
&
port
->
dev
)
);
vsc
=
VIRTIO_SERIAL_PORT_GET_CLASS
(
port
);
while
(
!
port
->
throttled
)
{
unsigned
int
i
;
...
...
@@ -157,7 +157,7 @@ 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
=
info
->
have_data
(
port
,
ret
=
vsc
->
have_data
(
port
,
port
->
elem
.
out_sg
[
i
].
iov_base
+
port
->
iov_offset
,
buf_size
);
...
...
@@ -176,7 +176,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
* 1: chardevs can notify frondends
* 2: the guest driver does not spin in these cases
*/
if
(
!
info
->
is_console
)
{
if
(
!
vsc
->
is_console
)
{
virtio_serial_throttle_port
(
port
,
true
);
}
port
->
iov_idx
=
i
;
...
...
@@ -331,7 +331,7 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
static
void
handle_control_message
(
VirtIOSerial
*
vser
,
void
*
buf
,
size_t
len
)
{
struct
VirtIOSerialPort
*
port
;
struct
VirtIOSerialPortInfo
*
info
;
VirtIOSerialPortClass
*
vsc
;
struct
virtio_console_control
cpkt
,
*
gcpkt
;
uint8_t
*
buffer
;
size_t
buffer_len
;
...
...
@@ -373,7 +373,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
trace_virtio_serial_handle_control_message_port
(
port
->
id
);
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
qdev_get_info
(
&
port
->
dev
)
);
vsc
=
VIRTIO_SERIAL_PORT_GET_CLASS
(
port
);
switch
(
cpkt
.
event
)
{
case
VIRTIO_CONSOLE_PORT_READY
:
...
...
@@ -389,7 +389,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
(
info
->
is_console
)
{
if
(
vsc
->
is_console
)
{
send_control_event
(
port
,
VIRTIO_CONSOLE_CONSOLE_PORT
,
1
);
}
...
...
@@ -418,21 +418,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
(
info
->
guest_ready
)
{
info
->
guest_ready
(
port
);
if
(
vsc
->
guest_ready
)
{
vsc
->
guest_ready
(
port
);
}
break
;
case
VIRTIO_CONSOLE_PORT_OPEN
:
port
->
guest_connected
=
cpkt
.
value
;
if
(
cpkt
.
value
&&
info
->
guest_open
)
{
if
(
cpkt
.
value
&&
vsc
->
guest_open
)
{
/* Send the guest opened notification if an app is interested */
info
->
guest_open
(
port
);
vsc
->
guest_open
(
port
);
}
if
(
!
cpkt
.
value
&&
info
->
guest_close
)
{
if
(
!
cpkt
.
value
&&
vsc
->
guest_close
)
{
/* Send the guest closed notification if an app is interested */
info
->
guest_close
(
port
);
vsc
->
guest_close
(
port
);
}
break
;
}
...
...
@@ -751,7 +751,7 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id)
static
int
virtser_port_qdev_init
(
DeviceState
*
qdev
,
DeviceInfo
*
base
)
{
VirtIOSerialPort
*
port
=
DO_UPCAST
(
VirtIOSerialPort
,
dev
,
qdev
);
VirtIOSerialPort
Info
*
info
=
DO_UPCAST
(
VirtIOSerialPortInfo
,
qdev
,
base
);
VirtIOSerialPort
Class
*
vsc
=
VIRTIO_SERIAL_PORT_GET_CLASS
(
port
);
VirtIOSerialBus
*
bus
=
DO_UPCAST
(
VirtIOSerialBus
,
qbus
,
qdev
->
parent_bus
);
int
ret
,
max_nr_ports
;
bool
plugging_port0
;
...
...
@@ -759,14 +759,14 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
port
->
vser
=
bus
->
vser
;
port
->
bh
=
qemu_bh_new
(
flush_queued_data_bh
,
port
);
assert
(
info
->
have_data
);
assert
(
vsc
->
have_data
);
/*
* 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
=
info
->
is_console
&&
!
find_port_by_id
(
port
->
vser
,
0
);
plugging_port0
=
vsc
->
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"
,
...
...
@@ -793,7 +793,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
return
-
1
;
}
ret
=
info
->
init
(
port
);
ret
=
vsc
->
init
(
port
);
if
(
ret
)
{
return
ret
;
}
...
...
@@ -823,8 +823,7 @@ 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
,
qdev_get_info
(
&
port
->
dev
));
VirtIOSerialPortClass
*
vsc
=
VIRTIO_SERIAL_PORT_GET_CLASS
(
port
);
VirtIOSerial
*
vser
=
port
->
vser
;
qemu_bh_delete
(
port
->
bh
);
...
...
@@ -832,19 +831,19 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
QTAILQ_REMOVE
(
&
vser
->
ports
,
port
,
next
);
if
(
info
->
exit
)
{
info
->
exit
(
port
);
if
(
vsc
->
exit
)
{
vsc
->
exit
(
port
);
}
return
0
;
}
void
virtio_serial_port_qdev_register
(
VirtIOSerialPort
Info
*
info
)
void
virtio_serial_port_qdev_register
(
Device
Info
*
info
)
{
info
->
qdev
.
init
=
virtser_port_qdev_init
;
info
->
qdev
.
bus_info
=
&
virtser_bus_info
;
info
->
qdev
.
exit
=
virtser_port_qdev_exit
;
info
->
qdev
.
unplug
=
qdev_simple_unplug_cb
;
qdev_register
(
&
info
->
qdev
);
info
->
init
=
virtser_port_qdev_init
;
info
->
bus_info
=
&
virtser_bus_info
;
info
->
exit
=
virtser_port_qdev_exit
;
info
->
unplug
=
qdev_simple_unplug_cb
;
qdev_register
_subclass
(
info
,
TYPE_VIRTIO_SERIAL_PORT
);
}
VirtIODevice
*
virtio_serial_init
(
DeviceState
*
dev
,
virtio_serial_conf
*
conf
)
...
...
@@ -940,3 +939,18 @@ void virtio_serial_exit(VirtIODevice *vdev)
virtio_cleanup
(
vdev
);
}
static
TypeInfo
virtio_serial_port_type_info
=
{
.
name
=
TYPE_VIRTIO_SERIAL_PORT
,
.
parent
=
TYPE_DEVICE
,
.
instance_size
=
sizeof
(
VirtIOSerialPort
),
.
abstract
=
true
,
.
class_size
=
sizeof
(
VirtIOSerialPortClass
),
};
static
void
virtio_serial_register_devices
(
void
)
{
type_register_static
(
&
virtio_serial_port_type_info
);
}
device_init
(
virtio_serial_register_devices
);
hw/virtio-serial.h
浏览文件 @
f82e35e3
...
...
@@ -62,10 +62,52 @@ struct virtio_serial_conf {
/* == In-qemu interface == */
#define TYPE_VIRTIO_SERIAL_PORT "virtio-serial-port"
#define VIRTIO_SERIAL_PORT(obj) \
OBJECT_CHECK(VirtIOSerialPort, (obj), TYPE_VIRTIO_SERIAL_PORT)
#define VIRTIO_SERIAL_PORT_CLASS(klass) \
OBJECT_CLASS_CHECK(VirtIOSerialPortClass, (klass), TYPE_VIRTIO_SERIAL_PORT)
#define VIRTIO_SERIAL_PORT_GET_CLASS(obj) \
OBJECT_GET_CLASS(VirtIOSerialPortClass, (obj), TYPE_VIRTIO_SERIAL_PORT)
typedef
struct
VirtIOSerial
VirtIOSerial
;
typedef
struct
VirtIOSerialBus
VirtIOSerialBus
;
typedef
struct
VirtIOSerialPort
VirtIOSerialPort
;
typedef
struct
VirtIOSerialPortInfo
VirtIOSerialPortInfo
;
typedef
struct
VirtIOSerialPortClass
{
DeviceClass
parent_class
;
/* 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.
*/
int
(
*
init
)(
VirtIOSerialPort
*
port
);
/*
* Per-port exit function that's called when a port gets
* hot-unplugged or removed.
*/
int
(
*
exit
)(
VirtIOSerialPort
*
port
);
/* Callbacks for guest events */
/* Guest opened device. */
void
(
*
guest_open
)(
VirtIOSerialPort
*
port
);
/* Guest closed device. */
void
(
*
guest_close
)(
VirtIOSerialPort
*
port
);
/* Guest is now ready to accept data (virtqueues set up). */
void
(
*
guest_ready
)(
VirtIOSerialPort
*
port
);
/*
* Guest wrote some data to the port. This data is handed over to
* the app via this callback. The app can return a size less than
* 'len'. In this case, throttling will be enabled for this port.
*/
ssize_t
(
*
have_data
)(
VirtIOSerialPort
*
port
,
const
uint8_t
*
buf
,
size_t
len
);
}
VirtIOSerialPortClass
;
/*
* This is the state that's shared between all the ports. Some of the
...
...
@@ -131,48 +173,13 @@ struct VirtIOSerialPort {
bool
throttled
;
};
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.
*/
int
(
*
init
)(
VirtIOSerialPort
*
port
);
/*
* Per-port exit function that's called when a port gets
* hot-unplugged or removed.
*/
int
(
*
exit
)(
VirtIOSerialPort
*
port
);
/* Callbacks for guest events */
/* Guest opened device. */
void
(
*
guest_open
)(
VirtIOSerialPort
*
port
);
/* Guest closed device. */
void
(
*
guest_close
)(
VirtIOSerialPort
*
port
);
/* Guest is now ready to accept data (virtqueues set up). */
void
(
*
guest_ready
)(
VirtIOSerialPort
*
port
);
/*
* Guest wrote some data to the port. This data is handed over to
* the app via this callback. The app can return a size less than
* 'len'. In this case, throttling will be enabled for this port.
*/
ssize_t
(
*
have_data
)(
VirtIOSerialPort
*
port
,
const
uint8_t
*
buf
,
size_t
len
);
};
/* Interface to the virtio-serial bus */
/*
* Individual ports/apps should call this function to register the port
* with the virtio-serial bus
*/
void
virtio_serial_port_qdev_register
(
VirtIOSerialPort
Info
*
info
);
void
virtio_serial_port_qdev_register
(
Device
Info
*
info
);
/*
* Open a connection to the port
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录