summaryrefslogtreecommitdiff
path: root/spice-qemu-char.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2016-12-07 18:39:10 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2017-01-27 18:08:00 +0100
commit777357d758d937c9dd83082c39aff9f1e53e9ba3 (patch)
tree20b236bf5acc7dfc20b4358bb8072dfe983c0e2d /spice-qemu-char.c
parent5bf5adaeb7245d7037f29429fb231b4b602d5b50 (diff)
downloadqemu-777357d758d937c9dd83082c39aff9f1e53e9ba3.tar.gz
chardev: qom-ify
Turn Chardev into Object. qemu_chr_alloc() is replaced by the qemu_chardev_new() constructor. It will call qemu_char_open() to open/intialize the chardev with the ChardevCommon *backend settings. The CharDriver::create() callback is turned into a ChardevClass::open() which is called from the newly introduced qemu_chardev_open(). "chardev-gdb" and "chardev-hci" are internal chardev and aren't creatable directly with -chardev. Use a new internal flag to disable them. We may want to use TYPE_USER_CREATABLE interface instead, or perhaps allow -chardev usage. Although in general we keep typename and macros private, unless the type is being used by some other file, in this patch, all types and common helper macros for qemu-char.c are in char.h. This is to help transition now (some types must be declared early, while some aren't shared) and when splitting in several units. This is to be improved later. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'spice-qemu-char.c')
-rw-r--r--spice-qemu-char.c142
1 files changed, 81 insertions, 61 deletions
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 5e5897b189..dd97c17fca 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -18,6 +18,12 @@ typedef struct SpiceChardev {
QLIST_ENTRY(SpiceChardev) next;
} SpiceChardev;
+#define TYPE_CHARDEV_SPICE "chardev-spice"
+#define TYPE_CHARDEV_SPICEVMC "chardev-spicevmc"
+#define TYPE_CHARDEV_SPICEPORT "chardev-spiceport"
+
+#define SPICE_CHARDEV(obj) OBJECT_CHECK(SpiceChardev, (obj), TYPE_CHARDEV_SPICE)
+
typedef struct SpiceCharSource {
GSource source;
SpiceChardev *scd;
@@ -29,7 +35,7 @@ static QLIST_HEAD(, SpiceChardev) spice_chars =
static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
{
SpiceChardev *scd = container_of(sin, SpiceChardev, sin);
- Chardev *chr = (Chardev *)scd;
+ Chardev *chr = CHARDEV(scd);
ssize_t out = 0;
ssize_t last_out;
uint8_t* p = (uint8_t*)buf;
@@ -73,7 +79,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
{
SpiceChardev *scd = container_of(sin, SpiceChardev, sin);
- Chardev *chr = (Chardev *)scd;
+ Chardev *chr = CHARDEV(scd);
int chr_event;
switch (event) {
@@ -92,7 +98,7 @@ static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
{
SpiceChardev *scd = container_of(sin, SpiceChardev, sin);
- Chardev *chr = (Chardev *)scd;
+ Chardev *chr = CHARDEV(scd);
if ((chr->be_open && connected) ||
(!chr->be_open && !connected)) {
@@ -173,7 +179,7 @@ static GSourceFuncs SpiceCharSourceFuncs = {
static GSource *spice_chr_add_watch(Chardev *chr, GIOCondition cond)
{
- SpiceChardev *scd = (SpiceChardev *)chr;
+ SpiceChardev *scd = SPICE_CHARDEV(chr);
SpiceCharSource *src;
assert(cond & G_IO_OUT);
@@ -187,7 +193,7 @@ static GSource *spice_chr_add_watch(Chardev *chr, GIOCondition cond)
static int spice_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
- SpiceChardev *s = (SpiceChardev *)chr;
+ SpiceChardev *s = SPICE_CHARDEV(chr);
int read_bytes;
assert(s->datalen == 0);
@@ -206,7 +212,7 @@ static int spice_chr_write(Chardev *chr, const uint8_t *buf, int len)
static void spice_chr_free(struct Chardev *chr)
{
- SpiceChardev *s = (SpiceChardev *)chr;
+ SpiceChardev *s = SPICE_CHARDEV(chr);
vmc_unregister_interface(s);
QLIST_REMOVE(s, next);
@@ -219,7 +225,7 @@ static void spice_chr_free(struct Chardev *chr)
static void spice_vmc_set_fe_open(struct Chardev *chr, int fe_open)
{
- SpiceChardev *s = (SpiceChardev *)chr;
+ SpiceChardev *s = SPICE_CHARDEV(chr);
if (fe_open) {
vmc_register_interface(s);
} else {
@@ -230,7 +236,7 @@ static void spice_vmc_set_fe_open(struct Chardev *chr, int fe_open)
static void spice_port_set_fe_open(struct Chardev *chr, int fe_open)
{
#if SPICE_SERVER_VERSION >= 0x000c02
- SpiceChardev *s = (SpiceChardev *)chr;
+ SpiceChardev *s = SPICE_CHARDEV(chr);
if (fe_open) {
spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED);
@@ -242,43 +248,29 @@ static void spice_port_set_fe_open(struct Chardev *chr, int fe_open)
static void spice_chr_accept_input(struct Chardev *chr)
{
- SpiceChardev *s = (SpiceChardev *)chr;
+ SpiceChardev *s = SPICE_CHARDEV(chr);
spice_server_char_device_wakeup(&s->sin);
}
-static Chardev *chr_open(const CharDriver *driver,
- const char *subtype,
- ChardevCommon *backend,
- Error **errp)
+static void chr_open(Chardev *chr, const char *subtype)
{
- Chardev *chr;
- SpiceChardev *s;
+ SpiceChardev *s = SPICE_CHARDEV(chr);
- chr = qemu_chr_alloc(driver, backend, errp);
- if (!chr) {
- return NULL;
- }
- s = (SpiceChardev *)chr;
s->active = false;
s->sin.subtype = g_strdup(subtype);
QLIST_INSERT_HEAD(&spice_chars, s, next);
-
- return chr;
}
-static Chardev *qemu_chr_open_spice_vmc(const CharDriver *driver,
- const char *id,
- ChardevBackend *backend,
- ChardevReturn *ret,
- bool *be_opened,
- Error **errp)
+static void qemu_chr_open_spice_vmc(Chardev *chr,
+ ChardevBackend *backend,
+ bool *be_opened,
+ Error **errp)
{
ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;
const char *type = spicevmc->type;
const char **psubtype = spice_server_char_device_recognized_subtypes();
- ChardevCommon *common = qapi_ChardevSpiceChannel_base(spicevmc);
for (; *psubtype != NULL; ++psubtype) {
if (strcmp(type, *psubtype) == 0) {
@@ -294,41 +286,33 @@ static Chardev *qemu_chr_open_spice_vmc(const CharDriver *driver,
subtypes);
g_free(subtypes);
- return NULL;
+ return;
}
*be_opened = false;
- return chr_open(driver, type, common, errp);
+ chr_open(chr, type);
}
#if SPICE_SERVER_VERSION >= 0x000c02
-static Chardev *qemu_chr_open_spice_port(const CharDriver *driver,
- const char *id,
- ChardevBackend *backend,
- ChardevReturn *ret,
- bool *be_opened,
- Error **errp)
+static void qemu_chr_open_spice_port(Chardev *chr,
+ ChardevBackend *backend,
+ bool *be_opened,
+ Error **errp)
{
ChardevSpicePort *spiceport = backend->u.spiceport.data;
const char *name = spiceport->fqdn;
- ChardevCommon *common = qapi_ChardevSpicePort_base(spiceport);
- Chardev *chr;
SpiceChardev *s;
if (name == NULL) {
error_setg(errp, "missing name parameter");
- return NULL;
+ return;
}
- chr = chr_open(driver, "port", common, errp);
- if (!chr) {
- return NULL;
- }
+ chr_open(chr, "port");
+
*be_opened = false;
- s = (SpiceChardev *)chr;
+ s = SPICE_CHARDEV(chr);
s->sin.portname = g_strdup(name);
-
- return chr;
}
void qemu_spice_register_ports(void)
@@ -374,32 +358,68 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
spiceport->fqdn = g_strdup(name);
}
+static void char_spice_class_init(ObjectClass *oc, void *data)
+{
+ ChardevClass *cc = CHARDEV_CLASS(oc);
+
+ cc->chr_write = spice_chr_write;
+ cc->chr_add_watch = spice_chr_add_watch;
+ cc->chr_accept_input = spice_chr_accept_input;
+ cc->chr_free = spice_chr_free;
+}
+
+static const TypeInfo char_spice_type_info = {
+ .name = TYPE_CHARDEV_SPICE,
+ .parent = TYPE_CHARDEV,
+ .instance_size = sizeof(SpiceChardev),
+ .class_init = char_spice_class_init,
+ .abstract = true,
+};
+
+static void char_spicevmc_class_init(ObjectClass *oc, void *data)
+{
+ ChardevClass *cc = CHARDEV_CLASS(oc);
+
+ cc->open = qemu_chr_open_spice_vmc;
+ cc->chr_set_fe_open = spice_vmc_set_fe_open;
+}
+
+static const TypeInfo char_spicevmc_type_info = {
+ .name = TYPE_CHARDEV_SPICEVMC,
+ .parent = TYPE_CHARDEV_SPICE,
+ .class_init = char_spicevmc_class_init,
+};
+
+static void char_spiceport_class_init(ObjectClass *oc, void *data)
+{
+ ChardevClass *cc = CHARDEV_CLASS(oc);
+
+ cc->open = qemu_chr_open_spice_port;
+ cc->chr_set_fe_open = spice_port_set_fe_open;
+}
+
+static const TypeInfo char_spiceport_type_info = {
+ .name = TYPE_CHARDEV_SPICEPORT,
+ .parent = TYPE_CHARDEV_SPICE,
+ .class_init = char_spiceport_class_init,
+};
+
static void register_types(void)
{
static const CharDriver vmc_driver = {
- .instance_size = sizeof(SpiceChardev),
.kind = CHARDEV_BACKEND_KIND_SPICEVMC,
.parse = qemu_chr_parse_spice_vmc,
- .create = qemu_chr_open_spice_vmc,
- .chr_write = spice_chr_write,
- .chr_add_watch = spice_chr_add_watch,
- .chr_set_fe_open = spice_vmc_set_fe_open,
- .chr_accept_input = spice_chr_accept_input,
- .chr_free = spice_chr_free,
};
static const CharDriver port_driver = {
- .instance_size = sizeof(SpiceChardev),
.kind = CHARDEV_BACKEND_KIND_SPICEPORT,
.parse = qemu_chr_parse_spice_port,
- .create = qemu_chr_open_spice_port,
- .chr_write = spice_chr_write,
- .chr_add_watch = spice_chr_add_watch,
- .chr_set_fe_open = spice_port_set_fe_open,
- .chr_accept_input = spice_chr_accept_input,
- .chr_free = spice_chr_free,
};
register_char_driver(&vmc_driver);
register_char_driver(&port_driver);
+
+ type_register_static(&char_spice_type_info);
+ type_register_static(&char_spicevmc_type_info);
+ type_register_static(&char_spiceport_type_info);
}
type_init(register_types);