All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/24] qdev: bus management updates.
@ 2009-09-25 19:42 Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 01/24] unbreak usb pass-through on linux Gerd Hoffmann
                   ` (25 more replies)
  0 siblings, 26 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

One more respin, even more improvements.

  hotplug, meet qdev.
  qdev, meet hotplug.

Changes summary:

  * allow embedded bus structs.
  * add bus release function.
  * added device destruction callback to qdev devices.
  * make qdev hotplug-aware (NEW!).
  * make busses use the new features.

End result is that you can use qdev_unplug() to unplug a device.
Depending on the bus this will either not work at all (ISA), ask the
guest OS to release the device (PCI+ACPI) or just zap it (USB).

Using the destruction callback everything will be released properly when
a device is zapped.  qdev will walk the child bus(es) if present and zap
all connected devices too.

You can pci_del the scsi adapter and all scsi disks will be deleted too.
You can pci_del the usb controller and all usb devices connected will be
deleted too.  You can unplug usb hubs, all connected devices will go away
too.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 01/24] unbreak usb pass-through on linux.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 02/24] allow qdev busses allocations be inplace Gerd Hoffmann
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Changes:
  * Re-add the 'dev->fd = fd;' line which the qdev patches dropped
    by mistake.
  * call qdev_init() so the newly created usb device is plugged into
    a usb port and thus actually visible to the guest.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 usb-linux.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index c434e4f..2b7b092 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -922,6 +922,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
 
     dev->bus_num = bus_num;
     dev->addr = addr;
+    dev->fd = fd;
 
     /* read the device description */
     dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
@@ -979,6 +980,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
 
     hostdev_link(dev);
 
+    qdev_init(&d->qdev);
     return (USBDevice *) dev;
 
 fail:
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 02/24] allow qdev busses allocations be inplace
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 01/24] unbreak usb pass-through on linux Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 03/24] switch scsi bus to inplace allocation Gerd Hoffmann
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

A bus usually is instanciated by the parent device.  The accociated bus
state can usually be embeeded into the parent device state struct, there
is no need for separate allocation and pointer indirection.

This patch adds a non-allocating qbus_create variant.  We keep track of
whenever qdev allocated the struct or not.  Will be needed later in this
patch series when we'll fix bus unplugging.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qdev.c |   15 ++++++++++++---
 hw/qdev.h |    3 +++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 43b1beb..43372c1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -502,13 +502,12 @@ static BusState *qbus_find(const char *path)
     }
 }
 
-BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
+void qbus_create_inplace(BusState *bus, BusInfo *info,
+                         DeviceState *parent, const char *name)
 {
-    BusState *bus;
     char *buf;
     int i,len;
 
-    bus = qemu_mallocz(info->size);
     bus->info = info;
     bus->parent = parent;
 
@@ -537,6 +536,16 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
         parent->num_child_bus++;
     }
+
+}
+
+BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
+{
+    BusState *bus;
+
+    bus = qemu_mallocz(info->size);
+    bus->qdev_allocated = 1;
+    qbus_create_inplace(bus, info, parent, name);
     return bus;
 }
 
diff --git a/hw/qdev.h b/hw/qdev.h
index 623ded5..ccc45b9 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -47,6 +47,7 @@ struct BusState {
     DeviceState *parent;
     BusInfo *info;
     const char *name;
+    int qdev_allocated;
     QLIST_HEAD(, DeviceState) children;
     QLIST_ENTRY(BusState) sibling;
 };
@@ -144,6 +145,8 @@ BusState *qdev_get_parent_bus(DeviceState *dev);
 
 /*** BUS API. ***/
 
+void qbus_create_inplace(BusState *bus, BusInfo *info,
+                         DeviceState *parent, const char *name);
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
 
 #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 03/24] switch scsi bus to inplace allocation.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 01/24] unbreak usb pass-through on linux Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 02/24] allow qdev busses allocations be inplace Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 04/24] switch usb " Gerd Hoffmann
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/esp.c        |   10 +++++-----
 hw/lsi53c895a.c |   12 ++++++------
 hw/scsi-bus.c   |    9 +++------
 hw/scsi-disk.h  |    4 ++--
 hw/usb-msd.c    |    6 +++---
 5 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index 9a5a8fb..5d86020 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -63,7 +63,7 @@ struct ESPState {
     uint8_t ti_buf[TI_BUFSZ];
     uint32_t sense;
     uint32_t dma;
-    SCSIBus *bus;
+    SCSIBus bus;
     SCSIDevice *current_dev;
     uint8_t cmdbuf[TI_BUFSZ];
     uint32_t cmdlen;
@@ -191,7 +191,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
         s->async_len = 0;
     }
 
-    if (target >= ESP_MAX_DEVS || !s->bus->devs[target]) {
+    if (target >= ESP_MAX_DEVS || !s->bus.devs[target]) {
         // No such drive
         s->rregs[ESP_RSTAT] = 0;
         s->rregs[ESP_RINTR] = INTR_DC;
@@ -199,7 +199,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
         esp_raise_irq(s);
         return 0;
     }
-    s->current_dev = s->bus->devs[target];
+    s->current_dev = s->bus.devs[target];
     return dmalen;
 }
 
@@ -672,8 +672,8 @@ static int esp_init1(SysBusDevice *dev)
 
     qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
 
-    s->bus = scsi_bus_new(&dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
-    scsi_bus_legacy_handle_cmdline(s->bus);
+    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
+    scsi_bus_legacy_handle_cmdline(&s->bus);
     return 0;
 }
 
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 62bdca8..7c45391 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -193,7 +193,7 @@ typedef struct {
      * 2 if processing DMA from lsi_execute_script.
      * 3 if a DMA operation is in progress.  */
     int waiting;
-    SCSIBus *bus;
+    SCSIBus bus;
     SCSIDevice *current_dev;
     int current_lun;
     /* The tag is a combination of the device ID and the SCSI tag.  */
@@ -585,7 +585,7 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
     id = (tag >> 8) & 0xf;
     s->ssid = id | 0x80;
     DPRINTF("Reselected target %d\n", id);
-    s->current_dev = s->bus->devs[id];
+    s->current_dev = s->bus.devs[id];
     s->current_tag = tag;
     s->scntl1 |= LSI_SCNTL1_CON;
     lsi_set_phase(s, PHASE_MI);
@@ -1041,7 +1041,7 @@ again:
                 }
                 s->sstat0 |= LSI_SSTAT0_WOA;
                 s->scntl1 &= ~LSI_SCNTL1_IARB;
-                if (id >= LSI_MAX_DEVS || !s->bus->devs[id]) {
+                if (id >= LSI_MAX_DEVS || !s->bus.devs[id]) {
                     DPRINTF("Selected absent target %d\n", id);
                     lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
                     lsi_disconnect(s);
@@ -1052,7 +1052,7 @@ again:
                 /* ??? Linux drivers compain when this is set.  Maybe
                    it only applies in low-level mode (unimplemented).
                 lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
-                s->current_dev = s->bus->devs[id];
+                s->current_dev = s->bus.devs[id];
                 s->current_tag = id << 8;
                 s->scntl1 |= LSI_SCNTL1_CON;
                 if (insn & (1 << 3)) {
@@ -2178,8 +2178,8 @@ static int lsi_scsi_init(PCIDevice *dev)
 
     lsi_soft_reset(s);
 
-    s->bus = scsi_bus_new(&dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete);
-    scsi_bus_legacy_handle_cmdline(s->bus);
+    scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete);
+    scsi_bus_legacy_handle_cmdline(&s->bus);
     register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s);
     return 0;
 }
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 16afa05..881e363 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -15,17 +15,14 @@ static struct BusInfo scsi_bus_info = {
 static int next_scsi_bus;
 
 /* Create a scsi bus, and attach devices to it.  */
-SCSIBus *scsi_bus_new(DeviceState *host, int tcq, int ndev,
-                      scsi_completionfn complete)
+void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
+                  scsi_completionfn complete)
 {
-    SCSIBus *bus;
-
-    bus = FROM_QBUS(SCSIBus, qbus_create(&scsi_bus_info, host, NULL));
+    qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL);
     bus->busnr = next_scsi_bus++;
     bus->tcq = tcq;
     bus->ndev = ndev;
     bus->complete = complete;
-    return bus;
 }
 
 static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
diff --git a/hw/scsi-disk.h b/hw/scsi-disk.h
index febde44..b6b6c12 100644
--- a/hw/scsi-disk.h
+++ b/hw/scsi-disk.h
@@ -52,8 +52,8 @@ struct SCSIBus {
     SCSIDevice *devs[8];
 };
 
-SCSIBus *scsi_bus_new(DeviceState *host, int tcq, int ndev,
-                      scsi_completionfn complete);
+void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
+                  scsi_completionfn complete);
 void scsi_qdev_register(SCSIDeviceInfo *info);
 
 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index aa0ce6a..6b9c8a5 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -45,7 +45,7 @@ typedef struct {
     uint32_t data_len;
     uint32_t residue;
     uint32_t tag;
-    SCSIBus *bus;
+    SCSIBus bus;
     DriveInfo *dinfo;
     SCSIDevice *scsi_dev;
     int result;
@@ -527,8 +527,8 @@ static int usb_msd_initfn(USBDevice *dev)
     }
 
     s->dev.speed = USB_SPEED_FULL;
-    s->bus = scsi_bus_new(&s->dev.qdev, 0, 1, usb_msd_command_complete);
-    s->scsi_dev = scsi_bus_legacy_add_drive(s->bus, s->dinfo, 0);
+    scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
+    s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->dinfo, 0);
     usb_msd_handle_reset(dev);
     return 0;
 }
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 04/24] switch usb bus to inplace allocation.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 03/24] switch scsi bus to inplace allocation Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 05/24] switch ide " Gerd Hoffmann
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb-bus.c  |    7 ++-----
 hw/usb-musb.c |    6 +++---
 hw/usb-ohci.c |    6 +++---
 hw/usb-uhci.c |    6 +++---
 hw/usb.h      |    2 +-
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 03933f1..2cac1e8 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -14,16 +14,13 @@ static struct BusInfo usb_bus_info = {
 static int next_usb_bus = 0;
 static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
 
-USBBus *usb_bus_new(DeviceState *host)
+void usb_bus_new(USBBus *bus, DeviceState *host)
 {
-    USBBus *bus;
-
-    bus = FROM_QBUS(USBBus, qbus_create(&usb_bus_info, host, NULL));
+    qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
     bus->busnr = next_usb_bus++;
     QTAILQ_INIT(&bus->free);
     QTAILQ_INIT(&bus->used);
     QTAILQ_INSERT_TAIL(&busses, bus, next);
-    return bus;
 }
 
 USBBus *usb_bus_find(int busnr)
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index 9eb0d63..09ec5a1 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -281,7 +281,7 @@ typedef struct {
 
 struct MUSBState {
     qemu_irq *irqs;
-    USBBus *bus;
+    USBBus bus;
     USBPort port;
 
     int idx;
@@ -331,8 +331,8 @@ struct MUSBState {
         s->ep[i].epnum = i;
     }
 
-    s->bus = usb_bus_new(NULL /* FIXME */);
-    usb_register_port(s->bus, &s->port, s, 0, musb_attach);
+    usb_bus_new(&s->bus, NULL /* FIXME */);
+    usb_register_port(&s->bus, &s->port, s, 0, musb_attach);
 
     return s;
 }
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 6e428c4..48ccd49 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -65,7 +65,7 @@ enum ohci_type {
 };
 
 typedef struct {
-    USBBus *bus;
+    USBBus bus;
     qemu_irq irq;
     enum ohci_type type;
     int mem;
@@ -1690,10 +1690,10 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
     ohci->irq = irq;
     ohci->type = type;
 
-    ohci->bus = usb_bus_new(dev);
+    usb_bus_new(&ohci->bus, dev);
     ohci->num_ports = num_ports;
     for (i = 0; i < num_ports; i++) {
-        usb_register_port(ohci->bus, &ohci->rhport[i].port, ohci, i, ohci_attach);
+        usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, ohci_attach);
     }
 
     ohci->async_td = 0;
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 6807413..a3ed9b2 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -122,7 +122,7 @@ typedef struct UHCIPort {
 
 typedef struct UHCIState {
     PCIDevice dev;
-    USBBus *bus;
+    USBBus bus;
     uint16_t cmd; /* cmd register */
     uint16_t status;
     uint16_t intr; /* interrupt enable register */
@@ -1083,9 +1083,9 @@ static int usb_uhci_common_initfn(UHCIState *s)
     pci_conf[0x3d] = 4; // interrupt pin 3
     pci_conf[0x60] = 0x10; // release number
 
-    s->bus = usb_bus_new(&s->dev.qdev);
+    usb_bus_new(&s->bus, &s->dev.qdev);
     for(i = 0; i < NB_PORTS; i++) {
-        usb_register_port(s->bus, &s->ports[i].port, s, i, uhci_attach);
+        usb_register_port(&s->bus, &s->ports[i].port, s, i, uhci_attach);
     }
     s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
 
diff --git a/hw/usb.h b/hw/usb.h
index 7c5cf83..467cddb 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -303,7 +303,7 @@ struct USBBus {
     QTAILQ_ENTRY(USBBus) next;
 };
 
-USBBus *usb_bus_new(DeviceState *host);
+void usb_bus_new(USBBus *bus, DeviceState *host);
 USBBus *usb_bus_find(int busnr);
 void usb_qdev_register(USBDeviceInfo *info);
 void usb_qdev_register_many(USBDeviceInfo *info);
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 05/24] switch ide bus to inplace allocation.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 04/24] switch usb " Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 06/24] inplace allocation for pci, split irq init Gerd Hoffmann
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/ide/internal.h |    2 +-
 hw/ide/isa.c      |   24 ++++++++++++------------
 hw/ide/pci.c      |   42 +++++++++++++++++++++---------------------
 hw/ide/qdev.c     |    7 ++-----
 4 files changed, 36 insertions(+), 39 deletions(-)

diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 9df759d..029bf80 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -551,7 +551,7 @@ void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1,
 void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
 
 /* hw/ide/qdev.c */
-IDEBus *ide_bus_new(DeviceState *dev);
+void ide_bus_new(IDEBus *idebus, DeviceState *dev);
 IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
 
 #endif /* HW_IDE_INTERNAL_H */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index d2fe0c0..3205f40 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -37,7 +37,7 @@
 
 typedef struct ISAIDEState {
     ISADevice dev;
-    IDEBus    *bus;
+    IDEBus    bus;
     uint32_t  iobase;
     uint32_t  iobase2;
     uint32_t  isairq;
@@ -48,18 +48,18 @@ static void isa_ide_save(QEMUFile* f, void *opaque)
 {
     ISAIDEState *s = opaque;
 
-    idebus_save(f, s->bus);
-    ide_save(f, &s->bus->ifs[0]);
-    ide_save(f, &s->bus->ifs[1]);
+    idebus_save(f, &s->bus);
+    ide_save(f, &s->bus.ifs[0]);
+    ide_save(f, &s->bus.ifs[1]);
 }
 
 static int isa_ide_load(QEMUFile* f, void *opaque, int version_id)
 {
     ISAIDEState *s = opaque;
 
-    idebus_load(f, s->bus, version_id);
-    ide_load(f, &s->bus->ifs[0], version_id);
-    ide_load(f, &s->bus->ifs[1], version_id);
+    idebus_load(f, &s->bus, version_id);
+    ide_load(f, &s->bus.ifs[0], version_id);
+    ide_load(f, &s->bus.ifs[1], version_id);
     return 0;
 }
 
@@ -67,10 +67,10 @@ static int isa_ide_initfn(ISADevice *dev)
 {
     ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
 
-    s->bus = ide_bus_new(&s->dev.qdev);
-    ide_init_ioport(s->bus, s->iobase, s->iobase2);
+    ide_bus_new(&s->bus, &s->dev.qdev);
+    ide_init_ioport(&s->bus, s->iobase, s->iobase2);
     isa_init_irq(dev, &s->irq, s->isairq);
-    ide_init2(s->bus, NULL, NULL, s->irq);
+    ide_init2(&s->bus, NULL, NULL, s->irq);
     register_savevm("isa-ide", 0, 3, isa_ide_save, isa_ide_load, s);
     return 0;
 };
@@ -90,9 +90,9 @@ int isa_ide_init(int iobase, int iobase2, int isairq,
 
     s = DO_UPCAST(ISAIDEState, dev, dev);
     if (hd0)
-        ide_create_drive(s->bus, 0, hd0);
+        ide_create_drive(&s->bus, 0, hd0);
     if (hd1)
-        ide_create_drive(s->bus, 1, hd1);
+        ide_create_drive(&s->bus, 1, hd1);
     return 0;
 }
 
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 89ecd44..bddf541 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -51,7 +51,7 @@
 
 typedef struct PCIIDEState {
     PCIDevice dev;
-    IDEBus *bus[2];
+    IDEBus bus[2];
     BMDMAState bmdma[2];
     int type; /* see IDE_TYPE_xxx */
     uint32_t secondary;
@@ -66,7 +66,7 @@ static void ide_map(PCIDevice *pci_dev, int region_num,
     IDEBus *bus;
 
     if (region_num <= 3) {
-        bus = d->bus[(region_num >> 1)];
+        bus = &d->bus[(region_num >> 1)];
         if (region_num & 1) {
             register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
             register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
@@ -252,9 +252,9 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
 
     for(i = 0;i < 2; i++) {
         BMDMAState *bm = &d->bmdma[i];
-        d->bus[i]->bmdma = bm;
+        d->bus[i].bmdma = bm;
         bm->pci_dev = DO_UPCAST(PCIIDEState, dev, pci_dev);
-        bm->bus = d->bus[i];
+        bm->bus = d->bus+i;
         qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
 
         register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
@@ -294,13 +294,13 @@ static void pci_ide_save(QEMUFile* f, void *opaque)
 
     /* per IDE interface data */
     for(i = 0; i < 2; i++) {
-        idebus_save(f, d->bus[i]);
+        idebus_save(f, d->bus+i);
     }
 
     /* per IDE drive data */
     for(i = 0; i < 2; i++) {
-        ide_save(f, &d->bus[i]->ifs[0]);
-        ide_save(f, &d->bus[i]->ifs[1]);
+        ide_save(f, &d->bus[i].ifs[0]);
+        ide_save(f, &d->bus[i].ifs[1]);
     }
 }
 
@@ -330,13 +330,13 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
 
     /* per IDE interface data */
     for(i = 0; i < 2; i++) {
-        idebus_load(f, d->bus[i], version_id);
+        idebus_load(f, d->bus+i, version_id);
     }
 
     /* per IDE drive data */
     for(i = 0; i < 2; i++) {
-        ide_load(f, &d->bus[i]->ifs[0], version_id);
-        ide_load(f, &d->bus[i]->ifs[1], version_id);
+        ide_load(f, &d->bus[i].ifs[0], version_id);
+        ide_load(f, &d->bus[i].ifs[1], version_id);
     }
     return 0;
 }
@@ -351,7 +351,7 @@ static void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
     for (i = 0; i < 4; i++) {
         if (hd_table[i] == NULL)
             continue;
-        ide_create_drive(d->bus[bus[i]], unit[i], hd_table[i]);
+        ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]);
     }
 }
 
@@ -427,10 +427,10 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
     pci_conf[0x3d] = 0x01; // interrupt on pin 1
 
     irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
-    d->bus[0] = ide_bus_new(&d->dev.qdev);
-    d->bus[1] = ide_bus_new(&d->dev.qdev);
-    ide_init2(d->bus[0], NULL, NULL, irq[0]);
-    ide_init2(d->bus[1], NULL, NULL, irq[1]);
+    ide_bus_new(&d->bus[0], &d->dev.qdev);
+    ide_bus_new(&d->bus[1], &d->dev.qdev);
+    ide_init2(&d->bus[0], NULL, NULL, irq[0]);
+    ide_init2(&d->bus[1], NULL, NULL, irq[1]);
 
     register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
     qemu_register_reset(cmd646_reset, d);
@@ -482,13 +482,13 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
 
     register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
 
-    d->bus[0] = ide_bus_new(&d->dev.qdev);
-    d->bus[1] = ide_bus_new(&d->dev.qdev);
-    ide_init_ioport(d->bus[0], 0x1f0, 0x3f6);
-    ide_init_ioport(d->bus[1], 0x170, 0x376);
+    ide_bus_new(&d->bus[0], &d->dev.qdev);
+    ide_bus_new(&d->bus[1], &d->dev.qdev);
+    ide_init_ioport(&d->bus[0], 0x1f0, 0x3f6);
+    ide_init_ioport(&d->bus[1], 0x170, 0x376);
 
-    ide_init2(d->bus[0], NULL, NULL, isa_reserve_irq(14));
-    ide_init2(d->bus[1], NULL, NULL, isa_reserve_irq(15));
+    ide_init2(&d->bus[0], NULL, NULL, isa_reserve_irq(14));
+    ide_init2(&d->bus[1], NULL, NULL, isa_reserve_irq(15));
     return 0;
 }
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index d467e3a..c562bc6 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -29,12 +29,9 @@ static struct BusInfo ide_bus_info = {
     .size  = sizeof(IDEBus),
 };
 
-IDEBus *ide_bus_new(DeviceState *dev)
+void ide_bus_new(IDEBus *idebus, DeviceState *dev)
 {
-    IDEBus *idebus;
-
-    idebus = FROM_QBUS(IDEBus, qbus_create(&ide_bus_info, dev, NULL));
-    return idebus;
+    qbus_create_inplace(&idebus->qbus, &ide_bus_info, dev, NULL);
 }
 
 static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 06/24] inplace allocation for pci, split irq init.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 05/24] switch ide " Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 07/24] convert pci bridge to qdev Gerd Hoffmann
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

This patch allows carrying the pcibus struct inplace.  Separate
allocation is possible as well.  It also splits pci_register_bus into
two parts (irq setup is separate now).

Followup patches will use this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci.c |   43 +++++++++++++++++++++++++++++++++----------
 hw/pci.h |    5 +++++
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 64d70ed..ad508a5 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -98,24 +98,47 @@ static void pci_bus_reset(void *opaque)
     }
 }
 
-PCIBus *pci_register_bus(DeviceState *parent, const char *name,
-                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         void *irq_opaque, int devfn_min, int nirq)
+void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+                         const char *name, int devfn_min)
 {
-    PCIBus *bus;
     static int nbus = 0;
 
-    bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, parent, name));
-    bus->set_irq = set_irq;
-    bus->map_irq = map_irq;
-    bus->irq_opaque = irq_opaque;
+    qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     bus->devfn_min = devfn_min;
-    bus->nirq = nirq;
-    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
     bus->next = first_bus;
     first_bus = bus;
     vmstate_register(nbus++, &vmstate_pcibus, bus);
     qemu_register_reset(pci_bus_reset, bus);
+}
+
+PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
+{
+    PCIBus *bus;
+
+    bus = qemu_mallocz(sizeof(*bus));
+    bus->qbus.qdev_allocated = 1;
+    pci_bus_new_inplace(bus, parent, name, devfn_min);
+    return bus;
+}
+
+void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+                  void *irq_opaque, int nirq)
+{
+    bus->set_irq = set_irq;
+    bus->map_irq = map_irq;
+    bus->irq_opaque = irq_opaque;
+    bus->nirq = nirq;
+    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
+}
+
+PCIBus *pci_register_bus(DeviceState *parent, const char *name,
+                         pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+                         void *irq_opaque, int devfn_min, int nirq)
+{
+    PCIBus *bus;
+
+    bus = pci_bus_new(parent, name, devfn_min);
+    pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
     return bus;
 }
 
diff --git a/hw/pci.h b/hw/pci.h
index caba5c8..2b6a0f2 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -248,6 +248,11 @@ int pci_device_load(PCIDevice *s, QEMUFile *f);
 
 typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
+void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+                         const char *name, int devfn_min);
+PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min);
+void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+                  void *irq_opaque, int nirq);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque, int devfn_min, int nirq);
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 07/24] convert pci bridge to qdev
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 06/24] inplace allocation for pci, split irq init Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 08/24] piix_pci: kill PIIX3IrqState Gerd Hoffmann
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Also switch secondary pci busses to inplace allocation.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci.c |   66 +++++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index ad508a5..608792a 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -142,18 +142,16 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
     return bus;
 }
 
-static PCIBus *pci_register_secondary_bus(PCIDevice *dev,
-                                          pci_map_irq_fn map_irq,
-                                          const char *name)
+static void pci_register_secondary_bus(PCIBus *bus,
+                                       PCIDevice *dev,
+                                       pci_map_irq_fn map_irq,
+                                       const char *name)
 {
-    PCIBus *bus;
-
-    bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name));
+    qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
     bus->map_irq = map_irq;
     bus->parent_dev = dev;
     bus->next = dev->bus->next;
     dev->bus->next = bus;
-    return bus;
 }
 
 int pci_bus_num(PCIBus *s)
@@ -858,7 +856,9 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
 
 typedef struct {
     PCIDevice dev;
-    PCIBus *bus;
+    PCIBus bus;
+    uint32_t vid;
+    uint32_t did;
 } PCIBridge;
 
 static void pci_bridge_write_config(PCIDevice *d,
@@ -867,7 +867,7 @@ static void pci_bridge_write_config(PCIDevice *d,
     PCIBridge *s = (PCIBridge *)d;
 
     pci_default_write_config(d, address, val, len);
-    s->bus->bus_num = d->config[PCI_SECONDARY_BUS];
+    s->bus.bus_num = d->config[PCI_SECONDARY_BUS];
 }
 
 PCIBus *pci_find_bus(int bus_num)
@@ -890,15 +890,12 @@ PCIDevice *pci_find_device(int bus_num, int slot, int function)
     return bus->devices[PCI_DEVFN(slot, function)];
 }
 
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
-                        pci_map_irq_fn map_irq, const char *name)
+static int pci_bridge_initfn(PCIDevice *dev)
 {
-    PCIBridge *s;
-    s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
-                                         devfn, NULL, pci_bridge_write_config);
+    PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
 
-    pci_config_set_vendor_id(s->dev.config, vid);
-    pci_config_set_device_id(s->dev.config, did);
+    pci_config_set_vendor_id(s->dev.config, s->vid);
+    pci_config_set_device_id(s->dev.config, s->did);
 
     s->dev.config[0x04] = 0x06; // command = bus master, pci mem
     s->dev.config[0x05] = 0x00;
@@ -911,9 +908,23 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
     s->dev.config[PCI_HEADER_TYPE] =
         PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
     s->dev.config[0x1E] = 0xa0; // secondary status
+    return 0;
+}
 
-    s->bus = pci_register_secondary_bus(&s->dev, map_irq, name);
-    return s->bus;
+PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
+                        pci_map_irq_fn map_irq, const char *name)
+{
+    PCIDevice *dev;
+    PCIBridge *s;
+
+    dev = pci_create_noinit(bus, devfn, "pci-bridge");
+    qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
+    qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
+    qdev_init(&dev->qdev);
+
+    s = DO_UPCAST(PCIBridge, dev, dev);
+    pci_register_secondary_bus(&s->bus, &s->dev, map_irq, name);
+    return &s->bus;
 }
 
 static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
@@ -1074,3 +1085,22 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
                        r->addr, r->addr + r->size - 1);
     }
 }
+
+static PCIDeviceInfo bridge_info = {
+    .qdev.name    = "pci-bridge",
+    .qdev.size    = sizeof(PCIBridge),
+    .init         = pci_bridge_initfn,
+    .config_write = pci_bridge_write_config,
+    .qdev.props   = (Property[]) {
+        DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
+        DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void pci_register_devices(void)
+{
+    pci_qdev_register(&bridge_info);
+}
+
+device_init(pci_register_devices)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 08/24] piix_pci: kill PIIX3IrqState
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 07/24] convert pci bridge to qdev Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 09/24] qdev: device free fixups Gerd Hoffmann
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The splitted init + irq setup for the pci bus untangles a initialization
order issue and allows to remove the PIIX3IrqState struct.  We can
carry the state directly in PIIX3State insted.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/piix_pci.c |   37 +++++++++++++++++--------------------
 1 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index edd6df0..0be3b02 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -36,18 +36,14 @@ typedef PCIHostState I440FXState;
 typedef struct PIIX3State {
     PCIDevice dev;
     int pci_irq_levels[4];
-} PIIX3State;
-
-typedef struct PIIX3IrqState {
-    PIIX3State *piix3;
     qemu_irq *pic;
-} PIIX3IrqState;
+} PIIX3State;
 
 struct PCII440FXState {
     PCIDevice dev;
     target_phys_addr_t isa_page_descs[384 / 4];
     uint8_t smm_enabled;
-    PIIX3IrqState *irq_state;
+    PIIX3State *piix3;
 };
 
 static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
@@ -167,7 +163,7 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 
     if (version_id == 2)
         for (i = 0; i < 4; i++)
-            d->irq_state->piix3->pci_irq_levels[i] = qemu_get_be32(f);
+            d->piix3->pci_irq_levels[i] = qemu_get_be32(f);
 
     return 0;
 }
@@ -232,23 +228,24 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
     PCIBus *b;
     PCIDevice *d;
     I440FXState *s;
-    PIIX3IrqState *irq_state = qemu_malloc(sizeof(*irq_state));
+    PIIX3State *piix3;
 
-    irq_state->pic = pic;
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
-    b = pci_register_bus(&s->busdev.qdev, "pci.0",
-                         piix3_set_irq, pci_slot_get_pirq, irq_state, 0, 4);
+    b = pci_bus_new(&s->busdev.qdev, NULL, 0);
     s->bus = b;
     qdev_init(dev);
 
     d = pci_create_simple(b, 0, "i440FX");
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
-    (*pi440fx_state)->irq_state = irq_state;
 
-    irq_state->piix3 = DO_UPCAST(PIIX3State, dev,
+    piix3 = DO_UPCAST(PIIX3State, dev,
                                  pci_create_simple(b, -1, "PIIX3"));
-    *piix3_devfn = irq_state->piix3->dev.devfn;
+    piix3->pic = pic;
+    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+    (*pi440fx_state)->piix3 = piix3;
+
+    *piix3_devfn = piix3->dev.devfn;
 
     return b;
 }
@@ -258,22 +255,22 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
 static void piix3_set_irq(void *opaque, int irq_num, int level)
 {
     int i, pic_irq, pic_level;
-    PIIX3IrqState *irq_state = opaque;
+    PIIX3State *piix3 = opaque;
 
-    irq_state->piix3->pci_irq_levels[irq_num] = level;
+    piix3->pci_irq_levels[irq_num] = level;
 
     /* now we change the pic irq level according to the piix irq mappings */
     /* XXX: optimize */
-    pic_irq = irq_state->piix3->dev.config[0x60 + irq_num];
+    pic_irq = piix3->dev.config[0x60 + irq_num];
     if (pic_irq < 16) {
         /* The pic level is the logical OR of all the PCI irqs mapped
            to it */
         pic_level = 0;
         for (i = 0; i < 4; i++) {
-            if (pic_irq == irq_state->piix3->dev.config[0x60 + i])
-                pic_level |= irq_state->piix3->pci_irq_levels[i];
+            if (pic_irq == piix3->dev.config[0x60 + i])
+                pic_level |= piix3->pci_irq_levels[i];
         }
-        qemu_set_irq(irq_state->pic[pic_irq], pic_level);
+        qemu_set_irq(piix3->pic[pic_irq], pic_level);
     }
 }
 
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 09/24] qdev: device free fixups.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 08/24] piix_pci: kill PIIX3IrqState Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 10/24] Add exit callback to DeviceInfo Gerd Hoffmann
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Two bug fixes:
 * When freeing a device we unregister even stuff we didn't register in
   the first place because the ->init() callback failed.
 * When freeing a device with child busses attached, we fail to zap the
   child bus (and the devices attached to it).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qdev.c |   35 +++++++++++++++++++++++++++++++----
 hw/qdev.h |    7 +++++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 43372c1..4931da1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -102,6 +102,7 @@ DeviceState *qdev_create(BusState *bus, const char *name)
     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
     qdev_prop_set_compat(dev);
     QLIST_INSERT_HEAD(&bus->children, dev, sibling);
+    dev->state = DEV_STATE_CREATED;
     return dev;
 }
 
@@ -216,6 +217,7 @@ int qdev_init(DeviceState *dev)
 {
     int rc;
 
+    assert(dev->state == DEV_STATE_CREATED);
     rc = dev->info->init(dev, dev->info);
     if (rc < 0)
         return rc;
@@ -223,18 +225,27 @@ int qdev_init(DeviceState *dev)
         qemu_register_reset(dev->info->reset, dev);
     if (dev->info->vmsd)
         vmstate_register(-1, dev->info->vmsd, dev);
+    dev->state = DEV_STATE_INITIALIZED;
     return 0;
 }
 
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
+    BusState *bus;
+
+    if (dev->state == DEV_STATE_INITIALIZED) {
+        while (dev->num_child_bus) {
+            bus = QLIST_FIRST(&dev->child_bus);
+            qbus_free(bus);
+        }
 #if 0 /* FIXME: need sane vmstate_unregister function */
-    if (dev->info->vmsd)
-        vmstate_unregister(dev->info->vmsd, dev);
+        if (dev->info->vmsd)
+            vmstate_unregister(dev->info->vmsd, dev);
 #endif
-    if (dev->info->reset)
-        qemu_unregister_reset(dev->info->reset, dev);
+        if (dev->info->reset)
+            qemu_unregister_reset(dev->info->reset, dev);
+    }
     QLIST_REMOVE(dev, sibling);
     qemu_free(dev);
 }
@@ -549,6 +560,22 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
     return bus;
 }
 
+void qbus_free(BusState *bus)
+{
+    DeviceState *dev;
+
+    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
+        qdev_free(dev);
+    }
+    if (bus->parent) {
+        QLIST_REMOVE(bus, sibling);
+        bus->parent->num_child_bus--;
+    }
+    if (bus->qdev_allocated) {
+        qemu_free(bus);
+    }
+}
+
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
diff --git a/hw/qdev.h b/hw/qdev.h
index ccc45b9..c036aff 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -19,10 +19,16 @@ typedef struct BusState BusState;
 
 typedef struct BusInfo BusInfo;
 
+enum DevState {
+    DEV_STATE_CREATED = 1,
+    DEV_STATE_INITIALIZED,
+};
+
 /* This structure should not be accessed directly.  We declare it here
    so that it can be embedded in individual device state structures.  */
 struct DeviceState {
     const char *id;
+    enum DevState state;
     DeviceInfo *info;
     BusState *parent_bus;
     int num_gpio_out;
@@ -148,6 +154,7 @@ BusState *qdev_get_parent_bus(DeviceState *dev);
 void qbus_create_inplace(BusState *bus, BusInfo *info,
                          DeviceState *parent, const char *name);
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
+void qbus_free(BusState *bus);
 
 #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
 
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 10/24] Add exit callback to DeviceInfo.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 09/24] qdev: device free fixups Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 11/24] Implement scsi device destruction Gerd Hoffmann
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

This adds a exit callback for device destruction to DeviceInfo, so
we can hook cleanups into qdev device destruction.

Followup patches will put that into use.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qdev.c |    2 ++
 hw/qdev.h |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 4931da1..a25245a 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -245,6 +245,8 @@ void qdev_free(DeviceState *dev)
 #endif
         if (dev->info->reset)
             qemu_unregister_reset(dev->info->reset, dev);
+        if (dev->info->exit)
+            dev->info->exit(dev);
     }
     QLIST_REMOVE(dev, sibling);
     qemu_free(dev);
diff --git a/hw/qdev.h b/hw/qdev.h
index c036aff..0db2d32 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -107,6 +107,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 /*** Device API.  ***/
 
 typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
+typedef int (*qdev_exitfn)(DeviceState *dev);
 
 struct DeviceInfo {
     const char *name;
@@ -124,6 +125,7 @@ struct DeviceInfo {
 
     /* Private to qdev / bus.  */
     qdev_initfn init;
+    qdev_exitfn exit;
     BusInfo *bus_info;
     struct DeviceInfo *next;
 };
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 11/24] Implement scsi device destruction
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 10/24] Add exit callback to DeviceInfo Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 12/24] pci: use qdev for " Gerd Hoffmann
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/scsi-bus.c     |   24 +++++++++++++++++++++---
 hw/scsi-disk.c    |    6 ------
 hw/scsi-generic.c |    2 --
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 881e363..27defc4 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -30,6 +30,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
     SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
     SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
     SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+    int rc = -1;
 
     if (dev->id == -1) {
         for (dev->id = 0; dev->id < bus->ndev; dev->id++) {
@@ -43,21 +44,38 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
     }
 
     if (bus->devs[dev->id]) {
-        bus->devs[dev->id]->info->destroy(bus->devs[dev->id]);
+        qdev_free(&bus->devs[dev->id]->qdev);
     }
     bus->devs[dev->id] = dev;
 
     dev->info = info;
-    return dev->info->init(dev);
+    rc = dev->info->init(dev);
+    if (rc != 0) {
+        bus->devs[dev->id] = NULL;
+    }
 
 err:
-    return -1;
+    return rc;
+}
+
+static int scsi_qdev_exit(DeviceState *qdev)
+{
+    SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+
+    assert(bus->devs[dev->id] != NULL);
+    if (bus->devs[dev->id]->info->destroy) {
+        bus->devs[dev->id]->info->destroy(bus->devs[dev->id]);
+    }
+    bus->devs[dev->id] = NULL;
+    return 0;
 }
 
 void scsi_qdev_register(SCSIDeviceInfo *info)
 {
     info->qdev.bus_info = &scsi_bus_info;
     info->qdev.init     = scsi_qdev_init;
+    info->qdev.exit     = scsi_qdev_exit;
     qdev_register(&info->qdev);
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index de8e314..0f029f8 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -936,11 +936,6 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
     }
 }
 
-static void scsi_destroy(SCSIDevice *d)
-{
-    qemu_free(d);
-}
-
 static int scsi_disk_initfn(SCSIDevice *dev)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
@@ -974,7 +969,6 @@ static SCSIDeviceInfo scsi_disk_info = {
     .qdev.desc    = "virtual scsi disk or cdrom",
     .qdev.size    = sizeof(SCSIDiskState),
     .init         = scsi_disk_initfn,
-    .destroy      = scsi_destroy,
     .send_command = scsi_send_command,
     .read_data    = scsi_read_data,
     .write_data   = scsi_write_data,
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index f8c010b..86d1e54 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -668,8 +668,6 @@ static void scsi_destroy(SCSIDevice *d)
         qemu_free(r);
         r = n;
     }
-
-    qemu_free(d);
 }
 
 static int scsi_generic_initfn(SCSIDevice *dev)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 12/24] pci: use qdev for device destruction.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 11/24] Implement scsi device destruction Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 13/24] pci: move unregister from PCIDevice to PCIDeviceInfo Gerd Hoffmann
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

pci_unregister_device is static now and hooked into Devicestate->exit.
qdev_free(pci_device) works now.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-hotplug.c |    2 +-
 hw/pci.c         |    5 +++--
 hw/pci.h         |    2 --
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index f3dc421..255decd 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -247,6 +247,6 @@ void pci_device_hot_remove_success(int pcibus, int slot)
         break;
     }
 
-    pci_unregister_device(d);
+    qdev_free(&d->qdev);
 }
 
diff --git a/hw/pci.c b/hw/pci.c
index 608792a..a6cd630 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -399,8 +399,9 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
     }
 }
 
-int pci_unregister_device(PCIDevice *pci_dev)
+static int pci_unregister_device(DeviceState *dev)
 {
+    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
     int ret = 0;
 
     if (pci_dev->unregister)
@@ -412,7 +413,6 @@ int pci_unregister_device(PCIDevice *pci_dev)
 
     qemu_free_irqs(pci_dev->irq);
     pci_dev->bus->devices[pci_dev->devfn] = NULL;
-    qdev_free(&pci_dev->qdev);
     return 0;
 }
 
@@ -945,6 +945,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 void pci_qdev_register(PCIDeviceInfo *info)
 {
     info->qdev.init = pci_qdev_init;
+    info->qdev.exit = pci_unregister_device;
     info->qdev.bus_info = &pci_bus_info;
     qdev_register(&info->qdev);
 }
diff --git a/hw/pci.h b/hw/pci.h
index 2b6a0f2..0ba7e6c 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -185,7 +185,6 @@ struct PCIDevice {
     /* do not access the following fields */
     PCIConfigReadFunc *config_read;
     PCIConfigWriteFunc *config_write;
-    PCIUnregisterFunc *unregister;
 
     /* IRQ objects for the INTA-INTD pins.  */
     qemu_irq *irq;
@@ -224,7 +223,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write);
-int pci_unregister_device(PCIDevice *pci_dev);
 
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             uint32_t size, int type,
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 13/24] pci: move unregister from PCIDevice to PCIDeviceInfo
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 12/24] pci: use qdev for " Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 14/24] usb: hook unplug into qdev, cleanups + fixes Gerd Hoffmann
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

One more cleanup while being at it ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/e1000.c      |    2 +-
 hw/eepro100.c   |    5 +++--
 hw/lsi53c895a.c |    2 +-
 hw/pci.c        |    7 +++++--
 hw/pci.h        |    1 +
 hw/pcnet.c      |    3 +--
 hw/rtl8139.c    |    3 +--
 hw/virtio-pci.c |    1 -
 8 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 95c471c..f123bda 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1129,7 +1129,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
     qemu_format_nic_info_str(d->vc, macaddr);
 
     register_savevm(info_str, -1, 2, nic_save, nic_load, d);
-    d->dev.unregister = pci_e1000_uninit;
     qemu_register_reset(e1000_reset, d);
     e1000_reset(d);
     return 0;
@@ -1139,6 +1138,7 @@ static PCIDeviceInfo e1000_info = {
     .qdev.name = "e1000",
     .qdev.size = sizeof(E1000State),
     .init      = pci_e1000_init,
+    .exit      = pci_e1000_uninit,
 };
 
 static void e1000_register_devices(void)
diff --git a/hw/eepro100.c b/hw/eepro100.c
index d3b7c3d..ea9c338 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1733,8 +1733,6 @@ static int nic_init(PCIDevice *pci_dev, uint32_t device)
 
     logout("\n");
 
-    s->dev.unregister = pci_nic_uninit;
-
     s->device = device;
 
     pci_reset(s);
@@ -1793,14 +1791,17 @@ static PCIDeviceInfo eepro100_info[] = {
         .qdev.name = "i82551",
         .qdev.size = sizeof(EEPRO100State),
         .init      = pci_i82551_init,
+        .exit      = pci_nic_uninit,
     },{
         .qdev.name = "i82557b",
         .qdev.size = sizeof(EEPRO100State),
         .init      = pci_i82557b_init,
+        .exit      = pci_nic_uninit,
     },{
         .qdev.name = "i82559er",
         .qdev.size = sizeof(EEPRO100State),
         .init      = pci_i82559er_init,
+        .exit      = pci_nic_uninit,
     },{
         /* end of list */
     }
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 7c45391..a4d3a57 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2174,7 +2174,6 @@ static int lsi_scsi_init(PCIDevice *dev)
     s->queue = qemu_malloc(sizeof(lsi_queue));
     s->queue_len = 1;
     s->active_commands = 0;
-    s->dev.unregister = lsi_scsi_uninit;
 
     lsi_soft_reset(s);
 
@@ -2189,6 +2188,7 @@ static PCIDeviceInfo lsi_info = {
     .qdev.alias = "lsi",
     .qdev.size  = sizeof(LSIState),
     .init       = lsi_scsi_init,
+    .exit       = lsi_scsi_uninit,
 };
 
 static void lsi53c895a_register_devices(void)
diff --git a/hw/pci.c b/hw/pci.c
index a6cd630..3221a6c 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -26,6 +26,7 @@
 #include "monitor.h"
 #include "net.h"
 #include "sysemu.h"
+#include "msix.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -402,13 +403,15 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
 static int pci_unregister_device(DeviceState *dev)
 {
     PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
+    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->info);
     int ret = 0;
 
-    if (pci_dev->unregister)
-        ret = pci_dev->unregister(pci_dev);
+    if (info->exit)
+        ret = info->exit(pci_dev);
     if (ret)
         return ret;
 
+    msix_uninit(pci_dev);
     pci_unregister_io_regions(pci_dev);
 
     qemu_free_irqs(pci_dev->irq);
diff --git a/hw/pci.h b/hw/pci.h
index 0ba7e6c..5e781d8 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -329,6 +329,7 @@ typedef int (*pci_qdev_initfn)(PCIDevice *dev);
 typedef struct {
     DeviceInfo qdev;
     pci_qdev_initfn init;
+    PCIUnregisterFunc *exit;
     PCIConfigReadFunc *config_read;
     PCIConfigWriteFunc *config_write;
 } PCIDeviceInfo;
diff --git a/hw/pcnet.c b/hw/pcnet.c
index ae98a20..ee0c98c 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -2039,8 +2039,6 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
         sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
 #endif
 
-    pci_dev->unregister = pci_pcnet_uninit;
-
     pci_conf = pci_dev->config;
 
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
@@ -2170,6 +2168,7 @@ static PCIDeviceInfo pcnet_info = {
     .qdev.name = "pcnet",
     .qdev.size = sizeof(PCIPCNetState),
     .init      = pci_pcnet_init,
+    .exit      = pci_pcnet_uninit,
 };
 
 static void pcnet_register_devices(void)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 83cb1ff..db9cb5a 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3443,8 +3443,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
     RTL8139State * s = DO_UPCAST(RTL8139State, dev, dev);
     uint8_t *pci_conf;
 
-    s->dev.unregister = pci_rtl8139_uninit;
-
     pci_conf = s->dev.config;
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
@@ -3493,6 +3491,7 @@ static PCIDeviceInfo rtl8139_info = {
     .qdev.size  = sizeof(RTL8139State),
     .qdev.reset = rtl8139_reset,
     .init       = pci_rtl8139_init,
+    .exit       = pci_rtl8139_uninit,
 };
 
 static void rtl8139_register_devices(void)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index bd5a7c4..c6fbaac 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -417,7 +417,6 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
                          msix_bar_size(&proxy->pci_dev),
                          PCI_ADDRESS_SPACE_MEM,
                          msix_mmio_map);
-        proxy->pci_dev.unregister = msix_uninit;
     } else
         vdev->nvectors = 0;
 
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 14/24] usb: hook unplug into qdev, cleanups + fixes.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 13/24] pci: move unregister from PCIDevice to PCIDeviceInfo Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error Gerd Hoffmann
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Hook into DeviceInfo->exit().

handle_destroy() must not free the state struct, this is handled
by the new usb_qdev_exit() function now.

qdev_free(usb_device) works now.

Fix usb hub to qdev_free() all connected devices on unplug.
Unplugging a usb hub works now.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb-bt.c     |    1 -
 hw/usb-bus.c    |   57 +++++++++++++++++++++++++++++++++++++++++++++++-------
 hw/usb-hid.c    |    1 -
 hw/usb-hub.c    |    6 ++++-
 hw/usb-msd.c    |    2 -
 hw/usb-serial.c |    1 -
 hw/usb-wacom.c  |    1 -
 hw/usb.h        |    2 +
 8 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index 4c60d42..3b085cc 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -614,7 +614,6 @@ static void usb_bt_handle_destroy(USBDevice *dev)
     s->hci->opaque = NULL;
     s->hci->evt_recv = NULL;
     s->hci->acl_recv = NULL;
-    qemu_free(s);
 }
 
 static int usb_bt_initfn(USBDevice *dev)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 2cac1e8..d0b59dd 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -50,10 +50,22 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
     return rc;
 }
 
+static int usb_qdev_exit(DeviceState *qdev)
+{
+    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+
+    usb_device_detach(dev);
+    if (dev->info->handle_destroy) {
+        dev->info->handle_destroy(dev);
+    }
+    return 0;
+}
+
 void usb_qdev_register(USBDeviceInfo *info)
 {
     info->qdev.bus_info = &usb_bus_info;
     info->qdev.init     = usb_qdev_init;
+    info->qdev.exit     = usb_qdev_exit;
     qdev_register(&info->qdev);
 }
 
@@ -101,6 +113,14 @@ void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
     bus->nfree++;
 }
 
+void usb_unregister_port(USBBus *bus, USBPort *port)
+{
+    if (port->dev)
+        qdev_free(&port->dev->qdev);
+    QTAILQ_REMOVE(&bus->free, port, next);
+    bus->nfree--;
+}
+
 static void do_attach(USBDevice *dev)
 {
     USBBus *bus = usb_bus_from_device(dev);
@@ -136,6 +156,34 @@ int usb_device_attach(USBDevice *dev)
     return 0;
 }
 
+int usb_device_detach(USBDevice *dev)
+{
+    USBBus *bus = usb_bus_from_device(dev);
+    USBPort *port;
+
+    if (!dev->attached) {
+        fprintf(stderr, "Warning: tried to detach unattached usb device %s\n",
+                dev->devname);
+        return -1;
+    }
+    dev->attached--;
+
+    QTAILQ_FOREACH(port, &bus->used, next) {
+        if (port->dev == dev)
+            break;
+    }
+    assert(port != NULL);
+
+    QTAILQ_REMOVE(&bus->used, port, next);
+    bus->nused--;
+
+    usb_attach(port, NULL);
+
+    QTAILQ_INSERT_TAIL(&bus->free, port, next);
+    bus->nfree++;
+    return 0;
+}
+
 int usb_device_delete_addr(int busnr, int addr)
 {
     USBBus *bus;
@@ -152,16 +200,9 @@ int usb_device_delete_addr(int busnr, int addr)
     }
     if (!port)
         return -1;
-
     dev = port->dev;
-    QTAILQ_REMOVE(&bus->used, port, next);
-    bus->nused--;
-
-    usb_attach(port, NULL);
-    dev->info->handle_destroy(dev);
 
-    QTAILQ_INSERT_TAIL(&bus->free, port, next);
-    bus->nfree++;
+    qdev_free(&dev->qdev);
     return 0;
 }
 
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 3bf06fa..d1cc45e 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -843,7 +843,6 @@ static void usb_hid_handle_destroy(USBDevice *dev)
     if (s->kind != USB_KEYBOARD)
         qemu_remove_mouse_event_handler(s->ptr.eh_entry);
     /* TODO: else */
-    qemu_free(s);
 }
 
 static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 0a39986..e5a0938 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -517,8 +517,12 @@ static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p)
 static void usb_hub_handle_destroy(USBDevice *dev)
 {
     USBHubState *s = (USBHubState *)dev;
+    int i;
 
-    qemu_free(s);
+    for (i = 0; i < s->nb_ports; i++) {
+        usb_unregister_port(usb_bus_from_device(dev),
+                            &s->ports[i].port);
+    }
 }
 
 static int usb_hub_initfn(USBDevice *dev)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 6b9c8a5..843a22f 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -512,9 +512,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
 {
     MSDState *s = (MSDState *)dev;
 
-    s->scsi_dev->info->destroy(s->scsi_dev);
     drive_uninit(s->dinfo->bdrv);
-    qemu_free(s);
 }
 
 static int usb_msd_initfn(USBDevice *dev)
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 091ab2c..e2379c4 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -486,7 +486,6 @@ static void usb_serial_handle_destroy(USBDevice *dev)
     USBSerialState *s = (USBSerialState *)dev;
 
     qemu_chr_close(s->cs);
-    qemu_free(s);
 }
 
 static int usb_serial_can_read(void *opaque)
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index 55f06bf..3ea7241 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -389,7 +389,6 @@ static void usb_wacom_handle_destroy(USBDevice *dev)
     USBWacomState *s = (USBWacomState *) dev;
 
     qemu_remove_mouse_event_handler(s->eh_entry);
-    qemu_free(s);
 }
 
 static int usb_wacom_initfn(USBDevice *dev)
diff --git a/hw/usb.h b/hw/usb.h
index 467cddb..be4fcf6 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -311,7 +311,9 @@ USBDevice *usb_create(USBBus *bus, const char *name);
 USBDevice *usb_create_simple(USBBus *bus, const char *name);
 void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
                        usb_attachfn attach);
+void usb_unregister_port(USBBus *bus, USBPort *port);
 int usb_device_attach(USBDevice *dev);
+int usb_device_detach(USBDevice *dev);
 int usb_device_delete_addr(int busnr, int addr);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (13 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 14/24] usb: hook unplug into qdev, cleanups + fixes Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-28 20:40   ` Markus Armbruster
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands Gerd Hoffmann
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 qemu-config.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/qemu-config.c b/qemu-config.c
index 39bf6a9..89b2b7c 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -1,6 +1,7 @@
 #include "qemu-common.h"
 #include "qemu-option.h"
 #include "qemu-config.h"
+#include "sysemu.h"
 
 QemuOptsList qemu_drive_opts = {
     .name = "drive",
@@ -166,7 +167,7 @@ int qemu_set_option(const char *str)
 
     rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
     if (rc < 3 || str[offset] != '=') {
-        fprintf(stderr, "can't parse: \"%s\"\n", str);
+        qemu_error("can't parse: \"%s\"\n", str);
         return -1;
     }
 
@@ -175,19 +176,19 @@ int qemu_set_option(const char *str)
             break;
     }
     if (lists[i] == NULL) {
-        fprintf(stderr, "there is no option group \"%s\"\n", group);
+        qemu_error("there is no option group \"%s\"\n", group);
         return -1;
     }
 
     opts = qemu_opts_find(lists[i], id);
     if (!opts) {
-        fprintf(stderr, "there is no %s \"%s\" defined\n",
+        qemu_error("there is no %s \"%s\" defined\n",
                 lists[i]->name, id);
         return -1;
     }
 
     if (-1 == qemu_opt_set(opts, arg, str+offset+1)) {
-        fprintf(stderr, "failed to set \"%s\" for %s \"%s\"\n",
+        qemu_error("failed to set \"%s\" for %s \"%s\"\n",
                 arg, lists[i]->name, id);
         return -1;
     }
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (14 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-28 20:32   ` Markus Armbruster
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 17/24] usb: hotplug windup Gerd Hoffmann
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Adds device_add and device_del commands.  device_add accepts accepts
the same syntax like the -device command line switch.  device_del
expects a device id.  So you should tag your devices with ids if you
want to remove them later on, like this:

  device_add pci-ohci,id=ohci
  device_del ohci

Unplugging via pci_del or usb_del works too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qdev.c       |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h       |   12 +++++++-
 qemu-monitor.hx |   16 +++++++++++
 vl.c            |    2 +
 4 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index a25245a..00cb849 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -31,6 +31,8 @@
 #include "monitor.h"
 
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
+static int qdev_hotplug = 0;
+
 static BusState *main_system_bus;
 
 static DeviceInfo *device_info_list;
@@ -102,6 +104,10 @@ DeviceState *qdev_create(BusState *bus, const char *name)
     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
     qdev_prop_set_compat(dev);
     QLIST_INSERT_HEAD(&bus->children, dev, sibling);
+    if (qdev_hotplug) {
+        assert(bus->allow_hotplug);
+        dev->hotplugged = 1;
+    }
     dev->state = DEV_STATE_CREATED;
     return dev;
 }
@@ -192,6 +198,11 @@ DeviceState *qdev_device_add(QemuOpts *opts)
                    path ? path : info->bus_info->name, info->name);
         return NULL;
     }
+    if (qdev_hotplug && !bus->allow_hotplug) {
+        qemu_error("Bus %s does not support hotplugging\n",
+                   bus->name);
+        return NULL;
+    }
 
     /* create device, set properties */
     qdev = qdev_create(bus, driver);
@@ -229,6 +240,24 @@ int qdev_init(DeviceState *dev)
     return 0;
 }
 
+int qdev_unplug(DeviceState *dev)
+{
+    if (!dev->parent_bus->allow_hotplug) {
+        qemu_error("Bus %s does not support hotplugging\n",
+                   dev->parent_bus->name);
+        return -1;
+    }
+    return dev->info->unplug(dev);
+}
+
+/* can be used as ->unplug() callback for the simple cases */
+int qdev_simple_unplug_cb(DeviceState *dev)
+{
+    /* just zap it */
+    qdev_free(dev);
+    return 0;
+}
+
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
@@ -252,6 +281,15 @@ void qdev_free(DeviceState *dev)
     qemu_free(dev);
 }
 
+void qdev_machine_creation_done(void)
+{
+    /*
+     * ok, initial machine setup is done, starting from now we can
+     * only create hotpluggable devices
+     */
+    qdev_hotplug = 1;
+}
+
 /* Get a character (serial) device interface.  */
 CharDriverState *qdev_init_chardev(DeviceState *dev)
 {
@@ -370,6 +408,24 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
     return NULL;
 }
 
+static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
+{
+    DeviceState *dev, *ret;
+    BusState *child;
+
+    QLIST_FOREACH(dev, &bus->children, sibling) {
+        if (dev->id && strcmp(dev->id, id) == 0)
+            return dev;
+        QLIST_FOREACH(child, &dev->child_bus, sibling) {
+            ret = qdev_find_recursive(child, id);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+    return NULL;
+}
+
 static void qbus_list_bus(DeviceState *dev, char *dest, int len)
 {
     BusState *child;
@@ -647,3 +703,26 @@ void do_info_qdm(Monitor *mon)
         monitor_printf(mon, "%s\n", msg);
     }
 }
+
+void do_device_add(Monitor *mon, const QDict *qdict)
+{
+    QemuOpts *opts;
+
+    opts = qemu_opts_parse(&qemu_device_opts,
+                           qdict_get_str(qdict, "config"), "driver");
+    if (opts)
+        qdev_device_add(opts);
+}
+
+void do_device_del(Monitor *mon, const QDict *qdict)
+{
+    const char *id = qdict_get_str(qdict, "id");
+    DeviceState *dev;
+
+    dev = qdev_find_recursive(main_system_bus, id);
+    if (NULL == dev) {
+        qemu_error("Device '%s' not found\n", id);
+        return;
+    }
+    qdev_unplug(dev);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 0db2d32..8b6e4fe 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -29,6 +29,7 @@ enum DevState {
 struct DeviceState {
     const char *id;
     enum DevState state;
+    int hotplugged;
     DeviceInfo *info;
     BusState *parent_bus;
     int num_gpio_out;
@@ -53,6 +54,7 @@ struct BusState {
     DeviceState *parent;
     BusInfo *info;
     const char *name;
+    int allow_hotplug;
     int qdev_allocated;
     QLIST_HEAD(, DeviceState) children;
     QLIST_ENTRY(BusState) sibling;
@@ -97,7 +99,10 @@ struct CompatProperty {
 DeviceState *qdev_create(BusState *bus, const char *name);
 DeviceState *qdev_device_add(QemuOpts *opts);
 int qdev_init(DeviceState *dev);
+int qdev_unplug(DeviceState *dev);
 void qdev_free(DeviceState *dev);
+int qdev_simple_unplug_cb(DeviceState *dev);
+void qdev_machine_creation_done(void);
 
 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
 void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
@@ -107,7 +112,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 /*** Device API.  ***/
 
 typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
-typedef int (*qdev_exitfn)(DeviceState *dev);
+typedef int (*qdev_event)(DeviceState *dev);
 
 struct DeviceInfo {
     const char *name;
@@ -125,7 +130,8 @@ struct DeviceInfo {
 
     /* Private to qdev / bus.  */
     qdev_initfn init;
-    qdev_exitfn exit;
+    qdev_event unplug;
+    qdev_event exit;
     BusInfo *bus_info;
     struct DeviceInfo *next;
 };
@@ -164,6 +170,8 @@ void qbus_free(BusState *bus);
 
 void do_info_qtree(Monitor *mon);
 void do_info_qdm(Monitor *mon);
+void do_device_add(Monitor *mon, const QDict *qdict);
+void do_device_del(Monitor *mon, const QDict *qdict);
 
 /*** qdev-properties.c ***/
 
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 9f91873..e4afe62 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -369,6 +369,22 @@ hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
 command @code{info usb} to see the devices you can remove.
 ETEXI
 
+    { "device_add", "config:s", do_device_add,
+      "device", "add device, like -device on the command line" },
+STEXI
+@item device_add @var{config}
+
+Add device.
+ETEXI
+
+    { "device_del", "id:s", do_device_del,
+      "device", "remove device" },
+STEXI
+@item device_del @var{id}
+
+Remove device @var{id}.
+ETEXI
+
     { "cpu", "index:i", do_cpu_set,
       "index", "set the default CPU" },
 STEXI
diff --git a/vl.c b/vl.c
index eb01da7..7df9328 100644
--- a/vl.c
+++ b/vl.c
@@ -5869,6 +5869,8 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+    qdev_machine_creation_done();
+
     if (loadvm) {
         if (load_vmstate(cur_mon, loadvm) < 0) {
             autostart = 0;
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 17/24] usb: hotplug windup
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (15 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 18/24] scsi: " Gerd Hoffmann
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb-bus.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index d0b59dd..0c63279 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -18,6 +18,7 @@ void usb_bus_new(USBBus *bus, DeviceState *host)
 {
     qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
     bus->busnr = next_usb_bus++;
+    bus->qbus.allow_hotplug = 1; /* Yes, we can */
     QTAILQ_INIT(&bus->free);
     QTAILQ_INIT(&bus->used);
     QTAILQ_INSERT_TAIL(&busses, bus, next);
@@ -65,6 +66,7 @@ void usb_qdev_register(USBDeviceInfo *info)
 {
     info->qdev.bus_info = &usb_bus_info;
     info->qdev.init     = usb_qdev_init;
+    info->qdev.unplug   = qdev_simple_unplug_cb;
     info->qdev.exit     = usb_qdev_exit;
     qdev_register(&info->qdev);
 }
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 18/24] scsi: hotplug windup
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (16 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 17/24] usb: hotplug windup Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 19/24] pci: " Gerd Hoffmann
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/scsi-bus.c |    2 ++
 hw/usb-msd.c  |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 27defc4..fe8991e 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -23,6 +23,7 @@ void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
     bus->tcq = tcq;
     bus->ndev = ndev;
     bus->complete = complete;
+    bus->qbus.allow_hotplug = 1;
 }
 
 static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
@@ -75,6 +76,7 @@ void scsi_qdev_register(SCSIDeviceInfo *info)
 {
     info->qdev.bus_info = &scsi_bus_info;
     info->qdev.init     = scsi_qdev_init;
+    info->qdev.unplug   = qdev_simple_unplug_cb;
     info->qdev.exit     = scsi_qdev_exit;
     qdev_register(&info->qdev);
 }
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 843a22f..a19b31d 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -527,6 +527,7 @@ static int usb_msd_initfn(USBDevice *dev)
     s->dev.speed = USB_SPEED_FULL;
     scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
     s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->dinfo, 0);
+    s->bus.qbus.allow_hotplug = 0;
     usb_msd_handle_reset(dev);
     return 0;
 }
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 19/24] pci: hotplug windup
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (17 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 18/24] scsi: " Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 20/24] pci: windup acpi-based hotplug Gerd Hoffmann
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Create qdev infrastructure for pci hotplug.  PCI bus implementations
must register a handler for hotplug.  Creating a new PCI device will
automagically hot-plug it in case the PCI bus in question supports this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci.c |   25 +++++++++++++++++++++++--
 hw/pci.h |    2 ++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 3221a6c..03ad90f 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -41,6 +41,7 @@ struct PCIBus {
     int devfn_min;
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
+    pci_hotplug_fn hotplug;
     uint32_t config_reg; /* XXX: suppress */
     void *irq_opaque;
     PCIDevice *devices[256];
@@ -132,6 +133,12 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
     bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
 }
 
+void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug)
+{
+    bus->qbus.allow_hotplug = 1;
+    bus->hotplug = hotplug;
+}
+
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque, int devfn_min, int nirq)
@@ -935,19 +942,33 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     PCIDevice *pci_dev = (PCIDevice *)qdev;
     PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
     PCIBus *bus;
-    int devfn;
+    int devfn, rc;
 
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
     devfn = pci_dev->devfn;
     pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
                                      info->config_read, info->config_write);
     assert(pci_dev);
-    return info->init(pci_dev);
+    rc = info->init(pci_dev);
+    if (rc != 0)
+        return rc;
+    if (qdev->hotplugged)
+        bus->hotplug(pci_dev, 1);
+    return 0;
+}
+
+static int pci_unplug_device(DeviceState *qdev)
+{
+    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+
+    dev->bus->hotplug(dev, 0);
+    return 0;
 }
 
 void pci_qdev_register(PCIDeviceInfo *info)
 {
     info->qdev.init = pci_qdev_init;
+    info->qdev.unplug = pci_unplug_device;
     info->qdev.exit = pci_unregister_device;
     info->qdev.bus_info = &pci_bus_info;
     qdev_register(&info->qdev);
diff --git a/hw/pci.h b/hw/pci.h
index 5e781d8..c678353 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -246,11 +246,13 @@ int pci_device_load(PCIDevice *s, QEMUFile *f);
 
 typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
+typedef int (*pci_hotplug_fn)(PCIDevice *pci_dev, int state);
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name, int devfn_min);
 PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min);
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);
+void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque, int devfn_min, int nirq);
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 20/24] pci: windup acpi-based hotplug
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (18 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 19/24] pci: " Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 21/24] drive cleanup fixes Gerd Hoffmann
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Switch over acpi-based PCI hotplug for pc over to the new
qdev-based pci hotplugging.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/acpi.c        |   41 +++++++++++++++++++++--------------------
 hw/pc.c          |    3 +--
 hw/pc.h          |    2 +-
 hw/pci-hotplug.c |   15 ++-------------
 sysemu.h         |    7 +------
 5 files changed, 26 insertions(+), 42 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index b14b9f4..5091044 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -694,20 +694,30 @@ static uint32_t pciej_read(void *opaque, uint32_t addr)
 
 static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 {
-#if defined (TARGET_I386)
+    BusState *bus = opaque;
+    DeviceState *qdev;
+    PCIDevice *dev;
     int slot = ffs(val) - 1;
 
-    pci_device_hot_remove_success(0, slot);
+    QLIST_FOREACH(qdev, &bus->children, sibling) {
+        dev = DO_UPCAST(PCIDevice, qdev, qdev);
+        if (PCI_SLOT(dev->devfn) == slot) {
+#if defined (TARGET_I386)
+            pci_device_hot_remove_success(dev);
 #endif
+            qdev_free(qdev);
+        }
+    }
+
 
 #if defined(DEBUG)
     printf("pciej write %x <== %d\n", addr, val);
 #endif
 }
 
-static void piix4_device_hot_add(int bus, int slot, int state);
+static int piix4_device_hotplug(PCIDevice *dev, int state);
 
-void piix4_acpi_system_hot_add_init(void)
+void piix4_acpi_system_hot_add_init(PCIBus *bus)
 {
     register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
     register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
@@ -715,10 +725,10 @@ void piix4_acpi_system_hot_add_init(void)
     register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
     register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
 
-    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
-    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, NULL);
+    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
+    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, bus);
 
-    qemu_system_device_hot_add_register(piix4_device_hot_add);
+    pci_bus_hotplug(bus, piix4_device_hotplug);
 }
 
 static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
@@ -733,8 +743,10 @@ static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
     p->down |= (1 << slot);
 }
 
-static void piix4_device_hot_add(int bus, int slot, int state)
+static int piix4_device_hotplug(PCIDevice *dev, int state)
 {
+    int slot = PCI_SLOT(dev->devfn);
+
     pci0_status.up = 0;
     pci0_status.down = 0;
     if (state)
@@ -745,18 +757,7 @@ static void piix4_device_hot_add(int bus, int slot, int state)
         qemu_set_irq(pm_state->irq, 1);
         qemu_set_irq(pm_state->irq, 0);
     }
-}
-
-static qemu_system_device_hot_add_t device_hot_add_callback;
-void qemu_system_device_hot_add_register(qemu_system_device_hot_add_t callback)
-{
-    device_hot_add_callback = callback;
-}
-
-void qemu_system_device_hot_add(int pcibus, int slot, int state)
-{
-    if (device_hot_add_callback)
-        device_hot_add_callback(pcibus, slot, state);
+    return 0;
 }
 
 struct acpi_table_header
diff --git a/hw/pc.c b/hw/pc.c
index bc2875e..ce31629 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1354,8 +1354,6 @@ static void pc_init1(ram_addr_t ram_size,
             pci_nic_init(nd, "e1000", NULL);
     }
 
-    piix4_acpi_system_hot_add_init();
-
     if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
         fprintf(stderr, "qemu: too many IDE bus\n");
         exit(1);
@@ -1406,6 +1404,7 @@ static void pc_init1(ram_addr_t ram_size,
             qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
             qdev_init(eeprom);
         }
+        piix4_acpi_system_hot_add_init(pci_bus);
     }
 
     if (i440fx_state) {
diff --git a/hw/pc.h b/hw/pc.h
index c9cdd4a..cf4ff39 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -106,7 +106,7 @@ int acpi_table_add(const char *table_desc);
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                        qemu_irq sci_irq);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
-void piix4_acpi_system_hot_add_init(void);
+void piix4_acpi_system_hot_add_init(PCIBus *bus);
 
 /* hpet.c */
 extern int no_hpet;
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 255decd..ac3d1ae 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -181,8 +181,6 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "invalid type: %s\n", type);
 
     if (dev) {
-        qemu_system_device_hot_add(pci_bus_num(dev->bus),
-                                   PCI_SLOT(dev->devfn), 1);
         monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
                        0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
                        PCI_FUNC(dev->devfn));
@@ -206,8 +204,7 @@ void pci_device_hot_remove(Monitor *mon, const char *pci_addr)
         monitor_printf(mon, "slot %d empty\n", slot);
         return;
     }
-
-    qemu_system_device_hot_add(bus, slot, 0);
+    qdev_unplug(&d->qdev);
 }
 
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict)
@@ -226,16 +223,10 @@ static int pci_match_fn(void *dev_private, void *arg)
 /*
  * OS has executed _EJ0 method, we now can remove the device
  */
-void pci_device_hot_remove_success(int pcibus, int slot)
+void pci_device_hot_remove_success(PCIDevice *d)
 {
-    PCIDevice *d = pci_find_device(pcibus, slot, 0);
     int class_code;
 
-    if (!d) {
-        monitor_printf(cur_mon, "invalid slot %d\n", slot);
-        return;
-    }
-
     class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
 
     switch(class_code) {
@@ -246,7 +237,5 @@ void pci_device_hot_remove_success(int pcibus, int slot)
         destroy_nic(pci_match_fn, d);
         break;
     }
-
-    qdev_free(&d->qdev);
 }
 
diff --git a/sysemu.h b/sysemu.h
index 8bf90ee..0ebbb03 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -197,11 +197,6 @@ BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type);
 extern QemuOpts *drive_add(const char *file, const char *fmt, ...);
 extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error);
 
-/* acpi */
-typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state);
-void qemu_system_device_hot_add_register(qemu_system_device_hot_add_t callback);
-void qemu_system_device_hot_add(int pcibus, int slot, int state);
-
 /* device-hotplug */
 
 typedef int (dev_match_fn)(void *dev_private, void *arg);
@@ -215,7 +210,7 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 void pci_device_hot_remove(Monitor *mon, const char *pci_addr);
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
-void pci_device_hot_remove_success(int pcibus, int slot);
+void pci_device_hot_remove_success(PCIDevice *dev);
 
 /* serial ports */
 
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 21/24] drive cleanup fixes.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (19 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 20/24] pci: windup acpi-based hotplug Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 22/24] refactor drive_hot_add Gerd Hoffmann
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Changes:
  * drive_uninit() wants a DriveInfo now.
  * drive_uninit() also calls bdrv_delete(),
    so callers don't need to do that.
  * drive_uninit() calls are moved over to the ->exit()
    callbacks, destroy_bdrvs() is zapped.
  * setting bdrv->private is not needed any more as the
    only user (destroy_bdrvs) is gone.
  * usb-storage needs no drive_uninit, scsi-disk will
    handle that.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/device-hotplug.c |   18 ------------------
 hw/pci-hotplug.c    |    3 ---
 hw/scsi-disk.c      |    8 ++++++++
 hw/scsi-generic.c   |    2 ++
 hw/usb-msd.c        |    8 --------
 hw/virtio-blk.c     |    1 -
 hw/virtio-pci.c     |    9 +++++++++
 sysemu.h            |    3 +--
 vl.c                |   16 +++++-----------
 9 files changed, 25 insertions(+), 43 deletions(-)

diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index 69779ca..c0cfd31 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -62,21 +62,3 @@ void destroy_nic(dev_match_fn *match_fn, void *arg)
         }
     }
 }
-
-void destroy_bdrvs(dev_match_fn *match_fn, void *arg)
-{
-    DriveInfo *dinfo;
-    struct BlockDriverState *bs;
-
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        bs = dinfo->bdrv;
-        if (bs) {
-            if (bs->private && match_fn(bs->private, arg)) {
-                drive_uninit(bs);
-                bdrv_delete(bs);
-            }
-        }
-    }
-}
-
-
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index ac3d1ae..6a08555 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -230,9 +230,6 @@ void pci_device_hot_remove_success(PCIDevice *d)
     class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
 
     switch(class_code) {
-    case PCI_BASE_CLASS_STORAGE:
-        destroy_bdrvs(pci_match_fn, d);
-        break;
     case PCI_BASE_CLASS_NETWORK:
         destroy_nic(pci_match_fn, d);
         break;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 0f029f8..3940726 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -936,6 +936,13 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
     }
 }
 
+static void scsi_destroy(SCSIDevice *dev)
+{
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+
+    drive_uninit(s->dinfo);
+}
+
 static int scsi_disk_initfn(SCSIDevice *dev)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
@@ -969,6 +976,7 @@ static SCSIDeviceInfo scsi_disk_info = {
     .qdev.desc    = "virtual scsi disk or cdrom",
     .qdev.size    = sizeof(SCSIDiskState),
     .init         = scsi_disk_initfn,
+    .destroy      = scsi_destroy,
     .send_command = scsi_send_command,
     .read_data    = scsi_read_data,
     .write_data   = scsi_write_data,
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 86d1e54..6a89989 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -668,6 +668,8 @@ static void scsi_destroy(SCSIDevice *d)
         qemu_free(r);
         r = n;
     }
+
+    drive_uninit(s->dinfo);
 }
 
 static int scsi_generic_initfn(SCSIDevice *dev)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index a19b31d..e090014 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -508,13 +508,6 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
     return ret;
 }
 
-static void usb_msd_handle_destroy(USBDevice *dev)
-{
-    MSDState *s = (MSDState *)dev;
-
-    drive_uninit(s->dinfo->bdrv);
-}
-
 static int usb_msd_initfn(USBDevice *dev)
 {
     MSDState *s = DO_UPCAST(MSDState, dev, dev);
@@ -599,7 +592,6 @@ static struct USBDeviceInfo msd_info = {
     .handle_reset   = usb_msd_handle_reset,
     .handle_control = usb_msd_handle_control,
     .handle_data    = usb_msd_handle_data,
-    .handle_destroy = usb_msd_handle_destroy,
     .qdev.props     = (Property[]) {
         DEFINE_PROP_DRIVE("drive", MSDState, dinfo),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 2d6d71a..2630b99 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -504,7 +504,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo)
         strncpy(s->serial_str, ps, sizeof(s->serial_str));
     else
         snprintf(s->serial_str, sizeof(s->serial_str), "0");
-    s->bs->private = dev;
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
     bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
 
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c6fbaac..7b86bfc 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -458,6 +458,14 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
     return 0;
 }
 
+static int virtio_blk_exit_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    drive_uninit(proxy->dinfo);
+    return 0;
+}
+
 static int virtio_console_init_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
@@ -519,6 +527,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.name = "virtio-blk-pci",
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_blk_init_pci,
+        .exit      = virtio_blk_exit_pci,
         .qdev.props = (Property[]) {
             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
             DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo),
diff --git a/sysemu.h b/sysemu.h
index 0ebbb03..3f0d3bf 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -188,7 +188,7 @@ extern QTAILQ_HEAD(driveoptlist, DriveOpt) driveopts;
 extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 extern DriveInfo *drive_get_by_id(const char *id);
 extern int drive_get_max_bus(BlockInterfaceType type);
-extern void drive_uninit(BlockDriverState *bdrv);
+extern void drive_uninit(DriveInfo *dinfo);
 extern const char *drive_get_serial(BlockDriverState *bdrv);
 extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv);
 
@@ -203,7 +203,6 @@ typedef int (dev_match_fn)(void *dev_private, void *arg);
 
 DriveInfo *add_init_drive(const char *opts);
 void destroy_nic(dev_match_fn *match_fn, void *arg);
-void destroy_bdrvs(dev_match_fn *match_fn, void *arg);
 
 /* pci-hotplug */
 void pci_device_hot_add(Monitor *mon, const QDict *qdict);
diff --git a/vl.c b/vl.c
index 7df9328..3f4bb22 100644
--- a/vl.c
+++ b/vl.c
@@ -1875,18 +1875,12 @@ static void bdrv_format_print(void *opaque, const char *name)
     fprintf(stderr, " %s", name);
 }
 
-void drive_uninit(BlockDriverState *bdrv)
+void drive_uninit(DriveInfo *dinfo)
 {
-    DriveInfo *dinfo;
-
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if (dinfo->bdrv != bdrv)
-            continue;
-        qemu_opts_del(dinfo->opts);
-        QTAILQ_REMOVE(&drives, dinfo, next);
-        qemu_free(dinfo);
-        break;
-    }
+    qemu_opts_del(dinfo->opts);
+    bdrv_delete(dinfo->bdrv);
+    QTAILQ_REMOVE(&drives, dinfo, next);
+    qemu_free(dinfo);
 }
 
 DriveInfo *drive_init(QemuOpts *opts, void *opaque,
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 22/24] refactor drive_hot_add
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (20 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 21/24] drive cleanup fixes Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 23/24] allow if=none for drive_add Gerd Hoffmann
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

move pci device lookup into the "case IF_SCSI" section, so we
can do something else for other interface types.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-hotplug.c |   38 +++++++++++++++++++-------------------
 1 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 6a08555..562b6b8 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -54,48 +54,48 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
     int dom, pci_bus;
     unsigned slot;
     int type, bus;
-    int success = 0;
     PCIDevice *dev;
-    DriveInfo *dinfo;
+    DriveInfo *dinfo = NULL;
     const char *pci_addr = qdict_get_str(qdict, "pci_addr");
     const char *opts = qdict_get_str(qdict, "opts");
     BusState *scsibus;
 
-    if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
-        return;
-    }
-
-    dev = pci_find_device(pci_bus, slot, 0);
-    if (!dev) {
-        monitor_printf(mon, "no pci device with address %s\n", pci_addr);
-        return;
-    }
-
     dinfo = add_init_drive(opts);
     if (!dinfo)
-        return;
+        goto err;
     if (dinfo->devaddr) {
         monitor_printf(mon, "Parameter addr not supported\n");
-        return;
+        goto err;
     }
     type = dinfo->type;
     bus = drive_get_max_bus (type);
 
     switch (type) {
     case IF_SCSI:
-        success = 1;
+        if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
+            goto err;
+        }
+        dev = pci_find_device(pci_bus, slot, 0);
+        if (!dev) {
+            monitor_printf(mon, "no pci device with address %s\n", pci_addr);
+            goto err;
+        }
         scsibus = QLIST_FIRST(&dev->qdev.child_bus);
         scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus),
                                   dinfo, dinfo->unit);
+        monitor_printf(mon, "OK bus %d, unit %d\n",
+                       dinfo->bus,
+                       dinfo->unit);
         break;
     default:
         monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
+        goto err;
     }
+    return;
 
-    if (success)
-        monitor_printf(mon, "OK bus %d, unit %d\n",
-                       dinfo->bus,
-                       dinfo->unit);
+err:
+    if (dinfo)
+        drive_uninit(dinfo);
     return;
 }
 
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 23/24] allow if=none for drive_add
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (21 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 22/24] refactor drive_hot_add Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 24/24] store a pointer to QemuOpts in DeviceState, release it when zapping a device Gerd Hoffmann
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Allow adding unconnected host drives by specifying if=none like it is
possible with -drive.  They can be put in use with drive attributes,
like this:

  drive_add dummy if=none,id=mydisk,file=/some/disk.img
  device_add virtio-blk-pci,drive=mydisk

which is the monitor aequivalent to these command line switches:

  -drive if=none,id=mydisk,file=/some/disk.img
  -device virtio-blk-pci,drive=mydisk

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-hotplug.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 562b6b8..3924419 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -87,6 +87,9 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
                        dinfo->bus,
                        dinfo->unit);
         break;
+    case IF_NONE:
+        monitor_printf(mon, "OK\n");
+        break;
     default:
         monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
         goto err;
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH 24/24] store a pointer to QemuOpts in DeviceState, release it when zapping a device.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (22 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 23/24] allow if=none for drive_add Gerd Hoffmann
@ 2009-09-25 19:42 ` Gerd Hoffmann
  2009-09-25 20:57 ` [Qemu-devel] [PATCH 00/24] qdev: bus management updates Anthony Liguori
  2009-09-28 20:40 ` Markus Armbruster
  25 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-25 19:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qdev.c |    3 +++
 hw/qdev.h |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 00cb849..ae24df7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -218,6 +218,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         qdev_free(qdev);
         return NULL;
     }
+    qdev->opts = opts;
     return qdev;
 }
 
@@ -276,6 +277,8 @@ void qdev_free(DeviceState *dev)
             qemu_unregister_reset(dev->info->reset, dev);
         if (dev->info->exit)
             dev->info->exit(dev);
+        if (dev->opts)
+            qemu_opts_del(dev->opts);
     }
     QLIST_REMOVE(dev, sibling);
     qemu_free(dev);
diff --git a/hw/qdev.h b/hw/qdev.h
index 8b6e4fe..1884160 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -29,6 +29,7 @@ enum DevState {
 struct DeviceState {
     const char *id;
     enum DevState state;
+    QemuOpts *opts;
     int hotplugged;
     DeviceInfo *info;
     BusState *parent_bus;
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 00/24] qdev: bus management updates.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (23 preceding siblings ...)
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 24/24] store a pointer to QemuOpts in DeviceState, release it when zapping a device Gerd Hoffmann
@ 2009-09-25 20:57 ` Anthony Liguori
  2009-09-28 20:40 ` Markus Armbruster
  25 siblings, 0 replies; 33+ messages in thread
From: Anthony Liguori @ 2009-09-25 20:57 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Gerd Hoffmann wrote:
>   Hi,
>
> One more respin, even more improvements.
>
>   hotplug, meet qdev.
>   qdev, meet hotplug.
>
> Changes summary:
>
>   * allow embedded bus structs.
>   * add bus release function.
>   * added device destruction callback to qdev devices.
>   * make qdev hotplug-aware (NEW!).
>   * make busses use the new features.
>
> End result is that you can use qdev_unplug() to unplug a device.
> Depending on the bus this will either not work at all (ISA), ask the
> guest OS to release the device (PCI+ACPI) or just zap it (USB).
>
> Using the destruction callback everything will be released properly when
> a device is zapped.  qdev will walk the child bus(es) if present and zap
> all connected devices too.
>
> You can pci_del the scsi adapter and all scsi disks will be deleted too.
> You can pci_del the usb controller and all usb devices connected will be
> deleted too.  You can unplug usb hubs, all connected devices will go away
> too.
>   

Very nice!

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands.
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands Gerd Hoffmann
@ 2009-09-28 20:32   ` Markus Armbruster
  2009-09-29  9:08     ` Gerd Hoffmann
  0 siblings, 1 reply; 33+ messages in thread
From: Markus Armbruster @ 2009-09-28 20:32 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Gerd Hoffmann <kraxel@redhat.com> writes:

> From: Gerd Hoffmann <kraxel@redhat.com>
> Subject: [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor
> 	commands.
> To: qemu-devel@nongnu.org
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Date: Fri, 25 Sep 2009 21:42:41 +0200
>
> Adds device_add and device_del commands.  device_add accepts accepts
> the same syntax like the -device command line switch.  device_del
> expects a device id.  So you should tag your devices with ids if you
> want to remove them later on, like this:
>
>   device_add pci-ohci,id=ohci
>   device_del ohci
>
> Unplugging via pci_del or usb_del works too.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/qdev.c       |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/qdev.h       |   12 +++++++-
>  qemu-monitor.hx |   16 +++++++++++
>  vl.c            |    2 +
>  4 files changed, 107 insertions(+), 2 deletions(-)
>
> diff --git a/hw/qdev.c b/hw/qdev.c
> index a25245a..00cb849 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -31,6 +31,8 @@
>  #include "monitor.h"
>  
>  /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
> +static int qdev_hotplug = 0;
> +

I see the "nasty hack" part, but I don't see how qdev_create() accepts a
null bus now:

>  static BusState *main_system_bus;
>  
>  static DeviceInfo *device_info_list;
> @@ -102,6 +104,10 @@ DeviceState *qdev_create(BusState *bus, const char *name)
>      qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
>      qdev_prop_set_compat(dev);
>      QLIST_INSERT_HEAD(&bus->children, dev, sibling);

It still derefences bus.

> +    if (qdev_hotplug) {
> +        assert(bus->allow_hotplug);
> +        dev->hotplugged = 1;
> +    }
>      dev->state = DEV_STATE_CREATED;
>      return dev;
>  }
> @@ -192,6 +198,11 @@ DeviceState *qdev_device_add(QemuOpts *opts)
>                     path ? path : info->bus_info->name, info->name);
>          return NULL;
>      }
> +    if (qdev_hotplug && !bus->allow_hotplug) {
> +        qemu_error("Bus %s does not support hotplugging\n",
> +                   bus->name);
> +        return NULL;
> +    }
>  
>      /* create device, set properties */
>      qdev = qdev_create(bus, driver);
[...]

As far as I can see, all qdev_hotplug does is telling qdev_device_add()
and qdev_create() that this is a hotplug.

What about something like:

DeviceState *qdev_device_add(QemuOpts *opts, int hotplug)
{
[...]
    if (hotplug && !bus->allow_hotplug) {
        qemu_error("Bus %s does not support hotplugging\n",
                   bus->name);
        return NULL;
    }

    /* create device, set properties */
    qdev = qdev_create(bus, driver);
    if (hotplug) {
        dev->hotplugged = 1;
[...]
}

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error
  2009-09-25 19:42 ` [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error Gerd Hoffmann
@ 2009-09-28 20:40   ` Markus Armbruster
  2009-09-29  8:57     ` Gerd Hoffmann
  0 siblings, 1 reply; 33+ messages in thread
From: Markus Armbruster @ 2009-09-28 20:40 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

This is to make it available for monitor code.  I can't see any use in
this patch series, but it's a good change all the same.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 00/24] qdev: bus management updates.
  2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
                   ` (24 preceding siblings ...)
  2009-09-25 20:57 ` [Qemu-devel] [PATCH 00/24] qdev: bus management updates Anthony Liguori
@ 2009-09-28 20:40 ` Markus Armbruster
  25 siblings, 0 replies; 33+ messages in thread
From: Markus Armbruster @ 2009-09-28 20:40 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

We've seen patches 01-14 before, and they're still good.  The rest is
new, and just as good.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error
  2009-09-28 20:40   ` Markus Armbruster
@ 2009-09-29  8:57     ` Gerd Hoffmann
  0 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-29  8:57 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

On 09/28/09 22:40, Markus Armbruster wrote:
> This is to make it available for monitor code.  I can't see any use in
> this patch series, but it's a good change all the same.

Patch #16 does.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands.
  2009-09-28 20:32   ` Markus Armbruster
@ 2009-09-29  9:08     ` Gerd Hoffmann
  2009-09-29 12:25       ` Markus Armbruster
  0 siblings, 1 reply; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-29  9:08 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

>>   /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
>> +static int qdev_hotplug = 0;
>> +
>
> I see the "nasty hack" part, but I don't see how qdev_create() accepts a
> null bus now:
>
>>   static BusState *main_system_bus;

The (existing) "nasty hack" comment belongs to the main_system_bus 
variable and should stay there of course to avoid confusion ...

>>       /* create device, set properties */
>>       qdev = qdev_create(bus, driver);
> [...]
>
> As far as I can see, all qdev_hotplug does is telling qdev_device_add()
> and qdev_create() that this is a hotplug.

Yes.

> What about something like:
>
> DeviceState *qdev_device_add(QemuOpts *opts, int hotplug)
> {
> [...]
>      if (hotplug&&  !bus->allow_hotplug) {
>          qemu_error("Bus %s does not support hotplugging\n",
>                     bus->name);
>          return NULL;
>      }
>
>      /* create device, set properties */
>      qdev = qdev_create(bus, driver);
>      if (hotplug) {
>          dev->hotplugged = 1;

I started that way.  Doesn't fly.  Not every device creation goes 
through qdev_device_add().  Thus you'll have to do this in 
qdev_create(), which in turn means that you would have to add a hotplug 
parameter to tons of functions just to pass it down to qdev_create ...

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands.
  2009-09-29  9:08     ` Gerd Hoffmann
@ 2009-09-29 12:25       ` Markus Armbruster
  2009-09-29 13:23         ` Gerd Hoffmann
  0 siblings, 1 reply; 33+ messages in thread
From: Markus Armbruster @ 2009-09-29 12:25 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Gerd Hoffmann <kraxel@redhat.com> writes:

[...]
>>
>> As far as I can see, all qdev_hotplug does is telling qdev_device_add()
>> and qdev_create() that this is a hotplug.
>
> Yes.
>
>> What about something like:
>>
>> DeviceState *qdev_device_add(QemuOpts *opts, int hotplug)
>> {
>> [...]
>>      if (hotplug&&  !bus->allow_hotplug) {
>>          qemu_error("Bus %s does not support hotplugging\n",
>>                     bus->name);
>>          return NULL;
>>      }
>>
>>      /* create device, set properties */
>>      qdev = qdev_create(bus, driver);
>>      if (hotplug) {
>>          dev->hotplugged = 1;
>
> I started that way.  Doesn't fly.  Not every device creation goes
> through qdev_device_add().  Thus you'll have to do this in
> qdev_create(), which in turn means that you would have to add a
> hotplug parameter to tons of functions just to pass it down to
> qdev_create ...

Isn't it sufficient if every *hotplug* device creation goes through
qdev_device_add()?

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands.
  2009-09-29 12:25       ` Markus Armbruster
@ 2009-09-29 13:23         ` Gerd Hoffmann
  0 siblings, 0 replies; 33+ messages in thread
From: Gerd Hoffmann @ 2009-09-29 13:23 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

   Hi,

>> I started that way.  Doesn't fly.  Not every device creation goes
>> through qdev_device_add().  Thus you'll have to do this in
>> qdev_create(), which in turn means that you would have to add a
>> hotplug parameter to tons of functions just to pass it down to
>> qdev_create ...
>
> Isn't it sufficient if every *hotplug* device creation goes through
> qdev_device_add()?

That isn't the case too.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2009-09-29 13:23 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-25 19:42 [Qemu-devel] [PATCH 00/24] qdev: bus management updates Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 01/24] unbreak usb pass-through on linux Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 02/24] allow qdev busses allocations be inplace Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 03/24] switch scsi bus to inplace allocation Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 04/24] switch usb " Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 05/24] switch ide " Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 06/24] inplace allocation for pci, split irq init Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 07/24] convert pci bridge to qdev Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 08/24] piix_pci: kill PIIX3IrqState Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 09/24] qdev: device free fixups Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 10/24] Add exit callback to DeviceInfo Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 11/24] Implement scsi device destruction Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 12/24] pci: use qdev for " Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 13/24] pci: move unregister from PCIDevice to PCIDeviceInfo Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 14/24] usb: hook unplug into qdev, cleanups + fixes Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 15/24] switch qemu-config to qemu_error Gerd Hoffmann
2009-09-28 20:40   ` Markus Armbruster
2009-09-29  8:57     ` Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 16/24] qdev hotplug: infrastructure and monitor commands Gerd Hoffmann
2009-09-28 20:32   ` Markus Armbruster
2009-09-29  9:08     ` Gerd Hoffmann
2009-09-29 12:25       ` Markus Armbruster
2009-09-29 13:23         ` Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 17/24] usb: hotplug windup Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 18/24] scsi: " Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 19/24] pci: " Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 20/24] pci: windup acpi-based hotplug Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 21/24] drive cleanup fixes Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 22/24] refactor drive_hot_add Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 23/24] allow if=none for drive_add Gerd Hoffmann
2009-09-25 19:42 ` [Qemu-devel] [PATCH 24/24] store a pointer to QemuOpts in DeviceState, release it when zapping a device Gerd Hoffmann
2009-09-25 20:57 ` [Qemu-devel] [PATCH 00/24] qdev: bus management updates Anthony Liguori
2009-09-28 20:40 ` Markus Armbruster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.