qemu-char: Call fe_claim / fe_release when not using qdev chr properties
chardev-frontends need to explictly check, increase and decrement the avail_connections "property" of the chardev when they are not using a qdev-chardev-property for the chardev. This fixes things like: qemu-kvm -chardev stdio,id=foo -device isa-serial,chardev=foo \ -mon chardev=foo Working, where they should fail. Most of the changes here are due to old hardware emulation code which is using serial_hds directly rather then a qdev-chardev-property. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Message-id: 1364412581-3672-3-git-send-email-hdegoede@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
44c473decd
commit
456d606923
@ -149,6 +149,11 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qemu_chr_fe_claim(s->chr) != 0) {
|
||||||
|
error_set(errp, QERR_DEVICE_IN_USE, s->chr_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME we should resubmit pending requests when the CDS reconnects. */
|
/* FIXME we should resubmit pending requests when the CDS reconnects. */
|
||||||
qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
|
qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
|
||||||
NULL, s);
|
NULL, s);
|
||||||
@ -191,6 +196,7 @@ static void rng_egd_finalize(Object *obj)
|
|||||||
|
|
||||||
if (s->chr) {
|
if (s->chr) {
|
||||||
qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
|
qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
|
||||||
|
qemu_chr_fe_release(s->chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(s->chr_name);
|
g_free(s->chr_name);
|
||||||
|
@ -3025,6 +3025,7 @@ int gdbserver_start(const char *device)
|
|||||||
if (!chr)
|
if (!chr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
|
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
|
||||||
gdb_chr_event, NULL);
|
gdb_chr_event, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1981,9 +1981,11 @@ static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
|
|||||||
memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000);
|
memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000);
|
||||||
memory_region_add_subregion(sysmem, base, &s->iomem);
|
memory_region_add_subregion(sysmem, base, &s->iomem);
|
||||||
|
|
||||||
if (chr)
|
if (chr) {
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
|
qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
|
||||||
pxa2xx_fir_rx, pxa2xx_fir_event, s);
|
pxa2xx_fir_rx, pxa2xx_fir_event, s);
|
||||||
|
}
|
||||||
|
|
||||||
register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
|
register_savevm(NULL, "pxa2xx_fir", 0, 0, pxa2xx_fir_save,
|
||||||
pxa2xx_fir_load, s);
|
pxa2xx_fir_load, s);
|
||||||
|
@ -439,6 +439,7 @@ CharDriverState *uart_hci_init(qemu_irq wakeup)
|
|||||||
s->chr.opaque = s;
|
s->chr.opaque = s;
|
||||||
s->chr.chr_write = csrhci_write;
|
s->chr.chr_write = csrhci_write;
|
||||||
s->chr.chr_ioctl = csrhci_ioctl;
|
s->chr.chr_ioctl = csrhci_ioctl;
|
||||||
|
s->chr.avail_connections = 1;
|
||||||
|
|
||||||
s->hci = qemu_next_hci();
|
s->hci = qemu_next_hci();
|
||||||
s->hci->opaque = s;
|
s->hci->opaque = s;
|
||||||
|
@ -556,6 +556,7 @@ static int ipoctal_init(IPackDevice *ip)
|
|||||||
|
|
||||||
if (ch->dev) {
|
if (ch->dev) {
|
||||||
index++;
|
index++;
|
||||||
|
qemu_chr_fe_claim_no_fail(ch->dev);
|
||||||
qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
|
qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
|
||||||
hostdev_receive, hostdev_event, ch);
|
hostdev_receive, hostdev_event, ch);
|
||||||
DPRINTF("Redirecting channel %u to %s (%s)\n",
|
DPRINTF("Redirecting channel %u to %s (%s)\n",
|
||||||
|
@ -292,6 +292,7 @@ static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *
|
|||||||
fprintf(stderr, "creating eventfd for eventfd %d failed\n", eventfd);
|
fprintf(stderr, "creating eventfd for eventfd %d failed\n", eventfd);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
|
|
||||||
/* if MSI is supported we need multiple interrupts */
|
/* if MSI is supported we need multiple interrupts */
|
||||||
if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
|
if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
|
||||||
|
@ -280,6 +280,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
|
|||||||
s->chr = chr;
|
s->chr = chr;
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
if (chr) {
|
if (chr) {
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
|
qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
|
||||||
mcf_uart_event, s);
|
mcf_uart_event, s);
|
||||||
}
|
}
|
||||||
|
@ -396,9 +396,11 @@ void sh_serial_init(MemoryRegion *sysmem,
|
|||||||
|
|
||||||
s->chr = chr;
|
s->chr = chr;
|
||||||
|
|
||||||
if (chr)
|
if (chr) {
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
|
qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1,
|
||||||
sh_serial_event, s);
|
sh_serial_event, s);
|
||||||
|
}
|
||||||
|
|
||||||
s->eri = eri_source;
|
s->eri = eri_source;
|
||||||
s->rxi = rxi_source;
|
s->rxi = rxi_source;
|
||||||
|
@ -241,9 +241,17 @@ static int con_initialise(struct XenDevice *xendev)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
xen_be_bind_evtchn(&con->xendev);
|
xen_be_bind_evtchn(&con->xendev);
|
||||||
if (con->chr)
|
if (con->chr) {
|
||||||
qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
|
if (qemu_chr_fe_claim(con->chr) == 0) {
|
||||||
NULL, con);
|
qemu_chr_add_handlers(con->chr, xencons_can_receive,
|
||||||
|
xencons_receive, NULL, con);
|
||||||
|
} else {
|
||||||
|
xen_be_printf(xendev, 0,
|
||||||
|
"xen_console_init error chardev %s already used\n",
|
||||||
|
con->chr->label);
|
||||||
|
con->chr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
|
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
|
||||||
con->ring_ref,
|
con->ring_ref,
|
||||||
@ -260,8 +268,10 @@ static void con_disconnect(struct XenDevice *xendev)
|
|||||||
if (!xendev->dev) {
|
if (!xendev->dev) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (con->chr)
|
if (con->chr) {
|
||||||
qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
|
qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
|
||||||
|
qemu_chr_fe_release(con->chr);
|
||||||
|
}
|
||||||
xen_be_unbind_evtchn(&con->xendev);
|
xen_be_unbind_evtchn(&con->xendev);
|
||||||
|
|
||||||
if (con->sring) {
|
if (con->sring) {
|
||||||
|
@ -660,6 +660,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
|
|||||||
fwd->port = port;
|
fwd->port = port;
|
||||||
fwd->slirp = s->slirp;
|
fwd->slirp = s->slirp;
|
||||||
|
|
||||||
|
qemu_chr_fe_claim_no_fail(fwd->hd);
|
||||||
qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
|
qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
|
||||||
NULL, fwd);
|
NULL, fwd);
|
||||||
}
|
}
|
||||||
|
10
qemu-char.c
10
qemu-char.c
@ -3411,6 +3411,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
|
|||||||
error_free(err);
|
error_free(err);
|
||||||
}
|
}
|
||||||
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
|
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
monitor_init(chr, MONITOR_USE_READLINE);
|
monitor_init(chr, MONITOR_USE_READLINE);
|
||||||
}
|
}
|
||||||
return chr;
|
return chr;
|
||||||
@ -3523,9 +3524,16 @@ CharDriverState *qemu_chr_find(const char *name)
|
|||||||
CharDriverState *qemu_char_get_next_serial(void)
|
CharDriverState *qemu_char_get_next_serial(void)
|
||||||
{
|
{
|
||||||
static int next_serial;
|
static int next_serial;
|
||||||
|
CharDriverState *chr;
|
||||||
|
|
||||||
/* FIXME: This function needs to go away: use chardev properties! */
|
/* FIXME: This function needs to go away: use chardev properties! */
|
||||||
return serial_hds[next_serial++];
|
|
||||||
|
while (next_serial < MAX_SERIAL_PORTS && serial_hds[next_serial]) {
|
||||||
|
chr = serial_hds[next_serial++];
|
||||||
|
qemu_chr_fe_claim_no_fail(chr);
|
||||||
|
return chr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QemuOptsList qemu_chardev_opts = {
|
QemuOptsList qemu_chardev_opts = {
|
||||||
|
Loading…
Reference in New Issue
Block a user