aboutsummaryrefslogtreecommitdiff
path: root/hw/char
diff options
context:
space:
mode:
authorAndreas Färber <afaerber@suse.de>2012-11-25 02:37:14 +0100
committerAndreas Färber <afaerber@suse.de>2013-06-07 12:14:45 +0200
commitdb895a1e6a97e919f9b86d60c969377357b05066 (patch)
tree72f6786abe90f7fa77d2f10416df73cb9d62e35a /hw/char
parenta3dcca567a1d4a5c79fb9c8fe2d9a21a4a7cebd5 (diff)
isa: Use realizefn for ISADevice
Drop ISADeviceClass::init and the resulting no-op initfn and let children implement their own realizefn. Adapt error handling. Split off an instance_init where sensible. Signed-off-by: Andreas Färber <afaerber@suse.de>
Diffstat (limited to 'hw/char')
-rw-r--r--hw/char/debugcon.c23
-rw-r--r--hw/char/parallel.c29
-rw-r--r--hw/char/serial-isa.c20
-rw-r--r--hw/char/serial-pci.c17
-rw-r--r--hw/char/serial.c22
5 files changed, 74 insertions, 37 deletions
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 3b0637d44f..f254841aec 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -81,27 +81,32 @@ static const MemoryRegionOps debugcon_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static void debugcon_init_core(DebugconState *s)
+static void debugcon_realize_core(DebugconState *s, Error **errp)
{
if (!s->chr) {
- fprintf(stderr, "Can't create debugcon device, empty char device\n");
- exit(1);
+ error_setg(errp, "Can't create debugcon device, empty char device");
+ return;
}
qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
}
-static int debugcon_isa_initfn(ISADevice *dev)
+static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
{
+ ISADevice *d = ISA_DEVICE(dev);
ISADebugconState *isa = ISA_DEBUGCON_DEVICE(dev);
DebugconState *s = &isa->state;
+ Error *err = NULL;
- debugcon_init_core(s);
+ debugcon_realize_core(s, &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
memory_region_init_io(&s->io, &debugcon_ops, s,
TYPE_ISA_DEBUGCON_DEVICE, 1);
- memory_region_add_subregion(isa_address_space_io(dev),
+ memory_region_add_subregion(isa_address_space_io(d),
isa->iobase, &s->io);
- return 0;
}
static Property debugcon_isa_properties[] = {
@@ -114,8 +119,8 @@ static Property debugcon_isa_properties[] = {
static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
- ic->init = debugcon_isa_initfn;
+
+ dc->realize = debugcon_isa_realizefn;
dc->props = debugcon_isa_properties;
}
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 8e48284520..caa9eb4de4 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -477,29 +477,35 @@ static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
PORTIO_END_OF_LIST(),
};
-static int parallel_isa_initfn(ISADevice *dev)
+static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
{
static int index;
+ ISADevice *isadev = ISA_DEVICE(dev);
ISAParallelState *isa = ISA_PARALLEL(dev);
ParallelState *s = &isa->state;
int base;
uint8_t dummy;
if (!s->chr) {
- fprintf(stderr, "Can't create parallel device, empty char device\n");
- exit(1);
+ error_setg(errp, "Can't create parallel device, empty char device");
+ return;
}
- if (isa->index == -1)
+ if (isa->index == -1) {
isa->index = index;
- if (isa->index >= MAX_PARALLEL_PORTS)
- return -1;
- if (isa->iobase == -1)
+ }
+ if (isa->index >= MAX_PARALLEL_PORTS) {
+ error_setg(errp, "Max. supported number of parallel ports is %d.",
+ MAX_PARALLEL_PORTS);
+ return;
+ }
+ if (isa->iobase == -1) {
isa->iobase = isa_parallel_io[isa->index];
+ }
index++;
base = isa->iobase;
- isa_init_irq(dev, &s->irq, isa->isairq);
+ isa_init_irq(isadev, &s->irq, isa->isairq);
qemu_register_reset(parallel_reset, s);
if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
@@ -507,12 +513,11 @@ static int parallel_isa_initfn(ISADevice *dev)
s->status = dummy;
}
- isa_register_portio_list(dev, base,
+ isa_register_portio_list(isadev, base,
(s->hw_driver
? &isa_parallel_portio_hw_list[0]
: &isa_parallel_portio_sw_list[0]),
s, "parallel");
- return 0;
}
/* Memory mapped interface */
@@ -599,8 +604,8 @@ static Property parallel_isa_properties[] = {
static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
- ic->init = parallel_isa_initfn;
+
+ dc->realize = parallel_isa_realizefn;
dc->props = parallel_isa_properties;
}
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 342b4ccbe3..6e7e0dd057 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -44,9 +44,10 @@ static const int isa_serial_irq[MAX_SERIAL_PORTS] = {
4, 3, 4, 3
};
-static int serial_isa_initfn(ISADevice *dev)
+static void serial_isa_realizefn(DeviceState *dev, Error **errp)
{
static int index;
+ ISADevice *isadev = ISA_DEVICE(dev);
ISASerialState *isa = ISA_SERIAL(dev);
SerialState *s = &isa->state;
@@ -54,7 +55,9 @@ static int serial_isa_initfn(ISADevice *dev)
isa->index = index;
}
if (isa->index >= MAX_SERIAL_PORTS) {
- return -1;
+ error_setg(errp, "Max. supported number of ISA serial ports is %d.",
+ MAX_SERIAL_PORTS);
+ return;
}
if (isa->iobase == -1) {
isa->iobase = isa_serial_io[isa->index];
@@ -65,13 +68,12 @@ static int serial_isa_initfn(ISADevice *dev)
index++;
s->baudbase = 115200;
- isa_init_irq(dev, &s->irq, isa->isairq);
- serial_init_core(s);
- qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
+ isa_init_irq(isadev, &s->irq, isa->isairq);
+ serial_realize_core(s, errp);
+ qdev_set_legacy_instance_id(dev, isa->iobase, 3);
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
- isa_register_ioport(dev, &s->io, isa->iobase);
- return 0;
+ isa_register_ioport(isadev, &s->io, isa->iobase);
}
static const VMStateDescription vmstate_isa_serial = {
@@ -96,8 +98,8 @@ static Property serial_isa_properties[] = {
static void serial_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
- ic->init = serial_isa_initfn;
+
+ dc->realize = serial_isa_realizefn;
dc->vmsd = &vmstate_isa_serial;
dc->props = serial_isa_properties;
}
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 2138e35851..3bec8ebe7b 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -27,6 +27,7 @@
#include "hw/char/serial.h"
#include "hw/pci/pci.h"
+#include "qapi/qmp/qerror.h"
#define PCI_SERIAL_MAX_PORTS 4
@@ -49,9 +50,15 @@ static int serial_pci_init(PCIDevice *dev)
{
PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
SerialState *s = &pci->state;
+ Error *err = NULL;
s->baudbase = 115200;
- serial_init_core(s);
+ serial_realize_core(s, &err);
+ if (err != NULL) {
+ qerror_report_err(err);
+ error_free(err);
+ return -1;
+ }
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
s->irq = pci->dev.irq[0];
@@ -80,6 +87,7 @@ static int multi_serial_pci_init(PCIDevice *dev)
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
SerialState *s;
+ Error *err = NULL;
int i;
switch (pc->device_id) {
@@ -102,7 +110,12 @@ static int multi_serial_pci_init(PCIDevice *dev)
for (i = 0; i < pci->ports; i++) {
s = pci->state + i;
s->baudbase = 115200;
- serial_init_core(s);
+ serial_realize_core(s, &err);
+ if (err != NULL) {
+ qerror_report_err(err);
+ error_free(err);
+ return -1;
+ }
s->irq = pci->irqs[i];
pci->name[i] = g_strdup_printf("uart #%d", i+1);
memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8);
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 66b6348867..f2701e8c54 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -670,11 +670,11 @@ static void serial_reset(void *opaque)
qemu_irq_lower(s->irq);
}
-void serial_init_core(SerialState *s)
+void serial_realize_core(SerialState *s, Error **errp)
{
if (!s->chr) {
- fprintf(stderr, "Can't create serial device, empty char device\n");
- exit(1);
+ error_setg(errp, "Can't create serial device, empty char device");
+ return;
}
s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
@@ -713,13 +713,19 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr, MemoryRegion *system_io)
{
SerialState *s;
+ Error *err = NULL;
s = g_malloc0(sizeof(SerialState));
s->irq = irq;
s->baudbase = baudbase;
s->chr = chr;
- serial_init_core(s);
+ serial_realize_core(s, &err);
+ if (err != NULL) {
+ fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_free(err);
+ exit(1);
+ }
vmstate_register(NULL, base, &vmstate_serial, s);
@@ -769,6 +775,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
CharDriverState *chr, enum device_endian end)
{
SerialState *s;
+ Error *err = NULL;
s = g_malloc0(sizeof(SerialState));
@@ -777,7 +784,12 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
s->baudbase = baudbase;
s->chr = chr;
- serial_init_core(s);
+ serial_realize_core(s, &err);
+ if (err != NULL) {
+ fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_free(err);
+ exit(1);
+ }
vmstate_register(NULL, base, &vmstate_serial, s);
memory_region_init_io(&s->io, &serial_mm_ops[end], s,