Fix pci_add storage not to exit on bad first argument
authorMarkus Armbruster <armbru@redhat.com>
Fri, 25 Sep 2009 01:53:49 +0000 (03:53 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 5 Oct 2009 14:32:53 +0000 (09:32 -0500)
Monitor command "pci_add ADDR storage ..." does its work in
qemu_pci_hot_add_nic().  It called pci_create(..., ADDR) to create the
device.  That's wrong, because pci_create() terminates the program
when ADDR is invalid.

Use pci_get_bus_devfn() and pci_create_noinit() instead.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/pci-hotplug.c
hw/pci.c
hw/pci.h

index d40a3bd0cdfb8a56bca4986ac92d4ed5f99ac6a8..d02f73cd7012cb3685009b6868ecf0d9933d975c 100644 (file)
@@ -114,6 +114,8 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
     DriveInfo *dinfo = NULL;
     int type = -1;
     char buf[128];
+    PCIBus *bus;
+    int devfn;
 
     if (get_param_value(buf, sizeof(buf), "if", opts)) {
         if (!strcmp(buf, "scsi"))
@@ -141,16 +143,22 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
         dinfo = NULL;
     }
 
+    bus = pci_get_bus_devfn(&devfn, devaddr);
+    if (!bus) {
+        monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
+        return NULL;
+    }
+
     switch (type) {
     case IF_SCSI:
-        dev = pci_create("lsi53c895a", devaddr);
+        dev = pci_create_noinit(bus, devfn, "lsi53c895a");
         break;
     case IF_VIRTIO:
         if (!dinfo) {
             monitor_printf(mon, "virtio requires a backing file/device.\n");
             return NULL;
         }
-        dev = pci_create("virtio-blk-pci", devaddr);
+        dev = pci_create_noinit(bus, devfn, "virtio-blk-pci");
         qdev_prop_set_drive(&dev->qdev, "drive", dinfo);
         break;
     default:
index e2f88ff75a80dceb5adf1cd151c76b6f6bdd588a..aebe0c5e94983f16c3d0d7bf813e225c14ece1b6 100644 (file)
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -317,7 +317,7 @@ int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
     return 0;
 }
 
-static PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
+PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
 {
     int dom, bus;
     unsigned slot;
index f3a034b3562b31d427dec2b26a228f313c3d97f6..76dfa0a9bda6c34ba73faf44a1becf079d4893b8 100644 (file)
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -262,6 +262,7 @@ int pci_bus_num(PCIBus *s);
 void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
 PCIBus *pci_find_bus(int bus_num);
 PCIDevice *pci_find_device(int bus_num, int slot, int function);
+PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr);
 
 int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
                      unsigned *slotp);