char: rename CharBackend->CharFrontend

The actual backend is "Chardev", CharBackend is the frontend side of
it (whatever talks to the backend), let's rename it for readability.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Link: https://lore.kernel.org/r/20251022074612.1258413-1-marcandre.lureau@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Marc-André Lureau 2025-10-22 11:46:10 +04:00 committed by Paolo Bonzini
parent dc72ba5dc4
commit 1b21518f73
89 changed files with 428 additions and 429 deletions

View file

@ -30,9 +30,9 @@
#include "chardev/char-io.h"
#include "chardev-internal.h"
int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
int qemu_chr_fe_write(CharFrontend *c, const uint8_t *buf, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return 0;
@ -41,9 +41,9 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
return qemu_chr_write(s, buf, len, false);
}
int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
int qemu_chr_fe_write_all(CharFrontend *c, const uint8_t *buf, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return 0;
@ -52,9 +52,9 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
return qemu_chr_write(s, buf, len, true);
}
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
int qemu_chr_fe_read_all(CharFrontend *c, uint8_t *buf, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
int offset = 0;
int res;
@ -95,9 +95,9 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
return offset;
}
int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
int qemu_chr_fe_ioctl(CharFrontend *c, int cmd, void *arg)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
int res;
if (!s || !CHARDEV_GET_CLASS(s)->chr_ioctl || qemu_chr_replay(s)) {
@ -109,11 +109,11 @@ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
return res;
}
int qemu_chr_fe_get_msgfd(CharBackend *be)
int qemu_chr_fe_get_msgfd(CharFrontend *c)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
int fd;
int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1;
int res = (qemu_chr_fe_get_msgfds(c, &fd, 1) == 1) ? fd : -1;
if (s && qemu_chr_replay(s)) {
error_report("Replay: get msgfd is not supported "
"for serial devices yet");
@ -122,9 +122,9 @@ int qemu_chr_fe_get_msgfd(CharBackend *be)
return res;
}
int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
int qemu_chr_fe_get_msgfds(CharFrontend *c, int *fds, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return -1;
@ -134,9 +134,9 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
CHARDEV_GET_CLASS(s)->get_msgfds(s, fds, len) : -1;
}
int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
int qemu_chr_fe_set_msgfds(CharFrontend *c, int *fds, int num)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return -1;
@ -146,9 +146,9 @@ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
CHARDEV_GET_CLASS(s)->set_msgfds(s, fds, num) : -1;
}
void qemu_chr_fe_accept_input(CharBackend *be)
void qemu_chr_fe_accept_input(CharFrontend *c)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return;
@ -160,7 +160,7 @@ void qemu_chr_fe_accept_input(CharBackend *be)
qemu_notify_event();
}
void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
void qemu_chr_fe_printf(CharFrontend *c, const char *fmt, ...)
{
char buf[CHR_READ_BUF_LEN];
va_list ap;
@ -168,28 +168,28 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
vsnprintf(buf, sizeof(buf), fmt, ap);
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(be, (uint8_t *)buf, strlen(buf));
qemu_chr_fe_write_all(c, (uint8_t *)buf, strlen(buf));
va_end(ap);
}
Chardev *qemu_chr_fe_get_driver(CharBackend *be)
Chardev *qemu_chr_fe_get_driver(CharFrontend *c)
{
/* this is unsafe for the users that support chardev hotswap */
assert(be->chr_be_change == NULL);
return be->chr;
assert(c->chr_be_change == NULL);
return c->chr;
}
bool qemu_chr_fe_backend_connected(CharBackend *be)
bool qemu_chr_fe_backend_connected(CharFrontend *c)
{
return !!be->chr;
return !!c->chr;
}
bool qemu_chr_fe_backend_open(CharBackend *be)
bool qemu_chr_fe_backend_open(CharFrontend *c)
{
return be->chr && be->chr->be_open;
return c->chr && c->chr->be_open;
}
bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
bool qemu_chr_fe_init(CharFrontend *c, Chardev *s, Error **errp)
{
unsigned int tag = 0;
@ -197,49 +197,49 @@ bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
if (CHARDEV_IS_MUX(s)) {
MuxChardev *d = MUX_CHARDEV(s);
if (!mux_chr_attach_frontend(d, b, &tag, errp)) {
if (!mux_chr_attach_frontend(d, c, &tag, errp)) {
return false;
}
} else if (s->be) {
} else if (s->fe) {
error_setg(errp, "chardev '%s' is already in use", s->label);
return false;
} else {
s->be = b;
s->fe = c;
}
}
b->fe_is_open = false;
b->tag = tag;
b->chr = s;
c->fe_is_open = false;
c->tag = tag;
c->chr = s;
return true;
}
void qemu_chr_fe_deinit(CharBackend *b, bool del)
void qemu_chr_fe_deinit(CharFrontend *c, bool del)
{
assert(b);
assert(c);
if (b->chr) {
qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL, NULL, true);
if (b->chr->be == b) {
b->chr->be = NULL;
if (c->chr) {
qemu_chr_fe_set_handlers(c, NULL, NULL, NULL, NULL, NULL, NULL, true);
if (c->chr->fe == c) {
c->chr->fe = NULL;
}
if (CHARDEV_IS_MUX(b->chr)) {
MuxChardev *d = MUX_CHARDEV(b->chr);
mux_chr_detach_frontend(d, b->tag);
if (CHARDEV_IS_MUX(c->chr)) {
MuxChardev *d = MUX_CHARDEV(c->chr);
mux_chr_detach_frontend(d, c->tag);
}
if (del) {
Object *obj = OBJECT(b->chr);
Object *obj = OBJECT(c->chr);
if (obj->parent) {
object_unparent(obj);
} else {
object_unref(obj);
}
}
b->chr = NULL;
c->chr = NULL;
}
}
void qemu_chr_fe_set_handlers_full(CharBackend *b,
void qemu_chr_fe_set_handlers_full(CharFrontend *c,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
@ -252,7 +252,7 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
Chardev *s;
bool fe_open;
s = b->chr;
s = c->chr;
if (!s) {
return;
}
@ -263,20 +263,20 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
} else {
fe_open = true;
}
b->chr_can_read = fd_can_read;
b->chr_read = fd_read;
b->chr_event = fd_event;
b->chr_be_change = be_change;
b->opaque = opaque;
c->chr_can_read = fd_can_read;
c->chr_read = fd_read;
c->chr_event = fd_event;
c->chr_be_change = be_change;
c->opaque = opaque;
qemu_chr_be_update_read_handlers(s, context);
if (set_open) {
qemu_chr_fe_set_open(b, fe_open);
qemu_chr_fe_set_open(c, fe_open);
}
if (fe_open) {
qemu_chr_fe_take_focus(b);
qemu_chr_fe_take_focus(c);
/* We're connecting to an already opened device, so let's make sure we
also get the open event */
if (sync_state && s->be_open) {
@ -285,7 +285,7 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
}
}
void qemu_chr_fe_set_handlers(CharBackend *b,
void qemu_chr_fe_set_handlers(CharFrontend *c,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
@ -294,62 +294,62 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
GMainContext *context,
bool set_open)
{
qemu_chr_fe_set_handlers_full(b, fd_can_read, fd_read, fd_event, be_change,
qemu_chr_fe_set_handlers_full(c, fd_can_read, fd_read, fd_event, be_change,
opaque, context, set_open,
true);
}
void qemu_chr_fe_take_focus(CharBackend *b)
void qemu_chr_fe_take_focus(CharFrontend *c)
{
if (!b->chr) {
if (!c->chr) {
return;
}
if (CHARDEV_IS_MUX(b->chr)) {
mux_set_focus(b->chr, b->tag);
if (CHARDEV_IS_MUX(c->chr)) {
mux_set_focus(c->chr, c->tag);
}
}
int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp)
int qemu_chr_fe_wait_connected(CharFrontend *c, Error **errp)
{
if (!be->chr) {
if (!c->chr) {
error_setg(errp, "missing associated backend");
return -1;
}
return qemu_chr_wait_connected(be->chr, errp);
return qemu_chr_wait_connected(c->chr, errp);
}
void qemu_chr_fe_set_echo(CharBackend *be, bool echo)
void qemu_chr_fe_set_echo(CharFrontend *c, bool echo)
{
Chardev *chr = be->chr;
Chardev *chr = c->chr;
if (chr && CHARDEV_GET_CLASS(chr)->chr_set_echo) {
CHARDEV_GET_CLASS(chr)->chr_set_echo(chr, echo);
}
}
void qemu_chr_fe_set_open(CharBackend *be, bool is_open)
void qemu_chr_fe_set_open(CharFrontend *c, bool is_open)
{
Chardev *chr = be->chr;
Chardev *chr = c->chr;
if (!chr) {
return;
}
if (be->fe_is_open == is_open) {
if (c->fe_is_open == is_open) {
return;
}
be->fe_is_open = is_open;
c->fe_is_open = is_open;
if (CHARDEV_GET_CLASS(chr)->chr_set_fe_open) {
CHARDEV_GET_CLASS(chr)->chr_set_fe_open(chr, is_open);
}
}
guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
guint qemu_chr_fe_add_watch(CharFrontend *c, GIOCondition cond,
FEWatchFunc func, void *user_data)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
GSource *src;
guint tag;
@ -369,9 +369,9 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
return tag;
}
void qemu_chr_fe_disconnect(CharBackend *be)
void qemu_chr_fe_disconnect(CharFrontend *c)
{
Chardev *chr = be->chr;
Chardev *chr = c->chr;
if (chr && CHARDEV_GET_CLASS(chr)->chr_disconnect) {
CHARDEV_GET_CLASS(chr)->chr_disconnect(chr);

View file

@ -54,7 +54,7 @@ static int hub_chr_write(Chardev *chr, const uint8_t *buf, int len)
d->be_eagain_ind = -1;
for (i = 0; i < d->be_cnt; i++) {
if (!d->backends[i].be.chr->be_open) {
if (!d->backends[i].fe.chr->be_open) {
/* Skip closed backend */
continue;
}
@ -64,7 +64,7 @@ static int hub_chr_write(Chardev *chr, const uint8_t *buf, int len)
ret = MIN(written, ret);
continue;
}
r = qemu_chr_fe_write(&d->backends[i].be, buf, len);
r = qemu_chr_fe_write(&d->backends[i].fe, buf, len);
if (r < 0) {
if (errno == EAGAIN) {
/* Set index and expect to be called soon on watch wake up */
@ -84,7 +84,7 @@ static int hub_chr_write(Chardev *chr, const uint8_t *buf, int len)
static int hub_chr_can_read(void *opaque)
{
HubCharBackend *backend = opaque;
CharBackend *fe = backend->hub->parent.be;
CharFrontend *fe = backend->hub->parent.fe;
if (fe && fe->chr_can_read) {
return fe->chr_can_read(fe->opaque);
@ -96,7 +96,7 @@ static int hub_chr_can_read(void *opaque)
static void hub_chr_read(void *opaque, const uint8_t *buf, int size)
{
HubCharBackend *backend = opaque;
CharBackend *fe = backend->hub->parent.be;
CharFrontend *fe = backend->hub->parent.fe;
if (fe && fe->chr_read) {
fe->chr_read(fe->opaque, buf, size);
@ -107,7 +107,7 @@ static void hub_chr_event(void *opaque, QEMUChrEvent event)
{
HubCharBackend *backend = opaque;
HubChardev *d = backend->hub;
CharBackend *fe = d->parent.be;
CharFrontend *fe = d->parent.fe;
if (event == CHR_EVENT_OPENED) {
/*
@ -147,7 +147,7 @@ static GSource *hub_chr_add_watch(Chardev *s, GIOCondition cond)
}
assert(d->be_eagain_ind < d->be_cnt);
chr = qemu_chr_fe_get_driver(&d->backends[d->be_eagain_ind].be);
chr = qemu_chr_fe_get_driver(&d->backends[d->be_eagain_ind].fe);
cc = CHARDEV_GET_CLASS(chr);
if (!cc->chr_add_watch) {
return NULL;
@ -167,7 +167,7 @@ static bool hub_chr_attach_chardev(HubChardev *d, Chardev *chr,
d->parent.label);
return false;
}
ret = qemu_chr_fe_init(&d->backends[d->be_cnt].be, chr, errp);
ret = qemu_chr_fe_init(&d->backends[d->be_cnt].fe, chr, errp);
if (ret) {
d->backends[d->be_cnt].hub = d;
d->backends[d->be_cnt].be_ind = d->be_cnt;
@ -183,7 +183,7 @@ static void char_hub_finalize(Object *obj)
int i;
for (i = 0; i < d->be_cnt; i++) {
qemu_chr_fe_deinit(&d->backends[i].be, false);
qemu_chr_fe_deinit(&d->backends[i].fe, false);
}
}
@ -193,7 +193,7 @@ static void hub_chr_update_read_handlers(Chardev *chr)
int i;
for (i = 0; i < d->be_cnt; i++) {
qemu_chr_fe_set_handlers_full(&d->backends[i].be,
qemu_chr_fe_set_handlers_full(&d->backends[i].fe,
hub_chr_can_read,
hub_chr_read,
hub_chr_event,

View file

@ -128,10 +128,10 @@ static void mux_print_help(Chardev *chr)
static void mux_chr_send_event(MuxChardev *d, unsigned int mux_nr,
QEMUChrEvent event)
{
CharBackend *be = d->backends[mux_nr];
CharFrontend *fe = d->frontends[mux_nr];
if (be && be->chr_event) {
be->chr_event(be->opaque, event);
if (fe && fe->chr_event) {
fe->chr_event(fe->opaque, event);
}
}
@ -200,11 +200,11 @@ static void mux_chr_accept_input(Chardev *chr)
{
MuxChardev *d = MUX_CHARDEV(chr);
int m = d->focus;
CharBackend *be = d->backends[m];
CharFrontend *fe = d->frontends[m];
while (be && d->prod[m] != d->cons[m] &&
be->chr_can_read && be->chr_can_read(be->opaque)) {
be->chr_read(be->opaque,
while (fe && d->prod[m] != d->cons[m] &&
fe->chr_can_read && fe->chr_can_read(fe->opaque)) {
fe->chr_read(fe->opaque,
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
}
}
@ -213,14 +213,14 @@ static int mux_chr_can_read(void *opaque)
{
MuxChardev *d = MUX_CHARDEV(opaque);
int m = d->focus;
CharBackend *be = d->backends[m];
CharFrontend *fe = d->frontends[m];
if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) {
return 1;
}
if (be && be->chr_can_read) {
return be->chr_can_read(be->opaque);
if (fe && fe->chr_can_read) {
return fe->chr_can_read(fe->opaque);
}
return 0;
@ -231,7 +231,7 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
Chardev *chr = CHARDEV(opaque);
MuxChardev *d = MUX_CHARDEV(opaque);
int m = d->focus;
CharBackend *be = d->backends[m];
CharFrontend *fe = d->frontends[m];
int i;
mux_chr_accept_input(opaque);
@ -239,9 +239,9 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
for (i = 0; i < size; i++)
if (mux_proc_byte(chr, d, buf[i])) {
if (d->prod[m] == d->cons[m] &&
be && be->chr_can_read &&
be->chr_can_read(be->opaque)) {
be->chr_read(be->opaque, &buf[i], 1);
fe && fe->chr_can_read &&
fe->chr_can_read(fe->opaque)) {
fe->chr_read(fe->opaque, &buf[i], 1);
} else {
d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
}
@ -289,9 +289,9 @@ static void char_mux_finalize(Object *obj)
bit = -1;
while ((bit = find_next_bit(&d->mux_bitset, MAX_MUX, bit + 1)) < MAX_MUX) {
CharBackend *be = d->backends[bit];
CharFrontend *be = d->frontends[bit];
be->chr = NULL;
d->backends[bit] = NULL;
d->frontends[bit] = NULL;
}
d->mux_bitset = 0;
qemu_chr_fe_deinit(&d->chr, false);
@ -311,7 +311,7 @@ static void mux_chr_update_read_handlers(Chardev *chr)
chr->gcontext, true, false);
}
bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
bool mux_chr_attach_frontend(MuxChardev *d, CharFrontend *c,
unsigned int *tag, Error **errp)
{
unsigned int bit;
@ -328,7 +328,7 @@ bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
}
d->mux_bitset |= (1ul << bit);
d->backends[bit] = b;
d->frontends[bit] = c;
*tag = bit;
return true;
@ -341,7 +341,7 @@ bool mux_chr_detach_frontend(MuxChardev *d, unsigned int tag)
}
d->mux_bitset &= ~(1ul << tag);
d->backends[tag] = NULL;
d->frontends[tag] = NULL;
return true;
}
@ -357,7 +357,7 @@ void mux_set_focus(Chardev *chr, unsigned int focus)
}
d->focus = focus;
chr->be = d->backends[focus];
chr->fe = d->frontends[focus];
mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
}

View file

@ -53,13 +53,13 @@ Object *get_chardevs_root(void)
static void chr_be_event(Chardev *s, QEMUChrEvent event)
{
CharBackend *be = s->be;
CharFrontend *fe = s->fe;
if (!be || !be->chr_event) {
if (!fe || !fe->chr_event) {
return;
}
be->chr_event(be->opaque, event);
fe->chr_event(fe->opaque, event);
}
void qemu_chr_be_event(Chardev *s, QEMUChrEvent event)
@ -197,21 +197,21 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all)
int qemu_chr_be_can_write(Chardev *s)
{
CharBackend *be = s->be;
CharFrontend *fe = s->fe;
if (!be || !be->chr_can_read) {
if (!fe || !fe->chr_can_read) {
return 0;
}
return be->chr_can_read(be->opaque);
return fe->chr_can_read(fe->opaque);
}
void qemu_chr_be_write_impl(Chardev *s, const uint8_t *buf, int len)
{
CharBackend *be = s->be;
CharFrontend *fe = s->fe;
if (be && be->chr_read) {
be->chr_read(be->opaque, buf, len);
if (fe && fe->chr_read) {
fe->chr_read(fe->opaque, buf, len);
}
}
@ -307,8 +307,8 @@ static void char_finalize(Object *obj)
{
Chardev *chr = CHARDEV(obj);
if (chr->be) {
chr->be->chr = NULL;
if (chr->fe) {
chr->fe->chr = NULL;
}
g_free(chr->filename);
g_free(chr->label);
@ -335,7 +335,7 @@ static bool qemu_chr_is_busy(Chardev *s)
MuxChardev *d = MUX_CHARDEV(s);
return d->mux_bitset != 0;
} else {
return s->be != NULL;
return s->fe != NULL;
}
}
@ -798,7 +798,7 @@ static int qmp_query_chardev_foreach(Object *obj, void *data)
value->label = g_strdup(chr->label);
value->filename = g_strdup(chr->filename);
value->frontend_open = chr->be && chr->be->fe_is_open;
value->frontend_open = chr->fe && chr->fe->fe_is_open;
QAPI_LIST_PREPEND(*list, value);
@ -1112,7 +1112,7 @@ err:
ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
Error **errp)
{
CharBackend *be;
CharFrontend *fe;
const ChardevClass *cc, *cc_new;
Chardev *chr, *chr_new;
bool closed_sent = false;
@ -1136,14 +1136,14 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
return NULL;
}
be = chr->be;
if (!be) {
fe = chr->fe;
if (!fe) {
/* easy case */
object_unparent(OBJECT(chr));
return qmp_chardev_add(id, backend, errp);
}
if (!be->chr_be_change) {
if (!fe->chr_be_change) {
error_setg(errp, "Chardev user does not support chardev hotswap");
return NULL;
}
@ -1171,13 +1171,13 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
closed_sent = true;
}
chr->be = NULL;
qemu_chr_fe_init(be, chr_new, &error_abort);
chr->fe = NULL;
qemu_chr_fe_init(fe, chr_new, &error_abort);
if (be->chr_be_change(be->opaque) < 0) {
if (fe->chr_be_change(fe->opaque) < 0) {
error_setg(errp, "Chardev '%s' change failed", chr_new->label);
chr_new->be = NULL;
qemu_chr_fe_init(be, chr, &error_abort);
chr_new->fe = NULL;
qemu_chr_fe_init(fe, chr, &error_abort);
if (closed_sent) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}

View file

@ -37,9 +37,9 @@
struct MuxChardev {
Chardev parent;
/* Linked frontends */
CharBackend *backends[MAX_MUX];
/* Linked backend */
CharBackend chr;
CharFrontend *frontends[MAX_MUX];
/* frontend of the underlying muxed chardev */
CharFrontend chr;
unsigned long mux_bitset;
int focus;
bool term_got_escape;
@ -64,8 +64,8 @@ typedef struct HubCharBackend HubCharBackend;
* `hub->backends` array
*/
struct HubCharBackend {
HubChardev *hub;
CharBackend be;
HubChardev *hub;
CharFrontend fe;
unsigned int be_ind;
};
@ -108,7 +108,7 @@ DECLARE_INSTANCE_CHECKER(HubChardev, HUB_CHARDEV,
#define CHARDEV_IS_HUB(chr) \
object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_HUB)
bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
bool mux_chr_attach_frontend(MuxChardev *d, CharFrontend *c,
unsigned int *tag, Error **errp);
bool mux_chr_detach_frontend(MuxChardev *d, unsigned int tag);
void mux_set_focus(Chardev *chr, unsigned int focus);