aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2009-09-25 03:53:51 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-10-05 09:32:53 -0500
commit07caea315a85ebfe90851f9c2e4ef3fdd24117b5 (patch)
tree153e42950d500a7c6219539941ff7c1f81a6487b
parent9ee05825d9eaf7fe3aaed5ed04b83612ede704a0 (diff)
Fix pci_add nic not to exit on bad model
Monitor command "pci_add ADDR nic model=MODEL" uses pci_nic_init() to create the NIC. When MODEL is unknown or "?", this prints to stderr and terminates the program. Change pci_nic_init() not to treat "?" specially, and to return NULL on failure. Switch uses during startup to new convenience wrapper pci_nic_init_nofail(), which behaves just like pci_nic_init() used to do. Bonus bug fix: we now check for qdev_init() failing there. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--hw/mips_malta.c2
-rw-r--r--hw/pc.c2
-rw-r--r--hw/pci.c33
-rw-r--r--hw/pci.h2
-rw-r--r--hw/ppc440_bamboo.c2
-rw-r--r--hw/ppc_newworld.c2
-rw-r--r--hw/ppc_oldworld.c2
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/ppce500_mpc8544ds.c2
-rw-r--r--hw/r2d.c2
-rw-r--r--hw/realview.c2
-rw-r--r--hw/sun4u.c2
-rw-r--r--hw/versatilepb.c2
-rw-r--r--net.c41
-rw-r--r--net.h5
15 files changed, 71 insertions, 32 deletions
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 4b5e470e26..d0266d5245 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -489,7 +489,7 @@ static void network_init(void)
/* The malta board has a PCNet card using PCI SLOT 11 */
default_devaddr = "0b";
- pci_nic_init(nd, "pcnet", default_devaddr);
+ pci_nic_init_nofail(nd, "pcnet", default_devaddr);
}
}
diff --git a/hw/pc.c b/hw/pc.c
index 9c3e3c5b15..55e1e6394b 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1345,7 +1345,7 @@ static void pc_init1(ram_addr_t ram_size,
if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
pc_init_ne2k_isa(nd);
else
- pci_nic_init(nd, "e1000", NULL);
+ pci_nic_init_nofail(nd, "e1000", NULL);
}
if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
diff --git a/hw/pci.c b/hw/pci.c
index 295e15d07f..dfdae1cad7 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -867,21 +867,48 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
const char *default_devaddr)
{
const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
+ PCIBus *bus;
+ int devfn;
PCIDevice *pci_dev;
DeviceState *dev;
int i;
- i = qemu_check_nic_model_list(nd, pci_nic_models, default_model);
- pci_dev = pci_create(pci_nic_names[i], devaddr);
+ i = qemu_find_nic_model(nd, pci_nic_models, default_model);
+ if (i < 0)
+ return NULL;
+
+ bus = pci_get_bus_devfn(&devfn, devaddr);
+ if (!bus) {
+ qemu_error("Invalid PCI device address %s for device %s\n",
+ devaddr, pci_nic_names[i]);
+ return NULL;
+ }
+
+ pci_dev = pci_create_noinit(bus, devfn, pci_nic_names[i]);
dev = &pci_dev->qdev;
if (nd->id)
dev->id = qemu_strdup(nd->id);
dev->nd = nd;
- qdev_init(dev);
+ if (qdev_init(dev) < 0)
+ return NULL;
nd->private = dev;
return pci_dev;
}
+PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
+ const char *default_devaddr)
+{
+ PCIDevice *res;
+
+ if (qemu_show_nic_models(nd->model, pci_nic_models))
+ exit(0);
+
+ res = pci_nic_init(nd, default_model, default_devaddr);
+ if (!res)
+ exit(1);
+ return res;
+}
+
typedef struct {
PCIDevice dev;
PCIBus bus;
diff --git a/hw/pci.h b/hw/pci.h
index 76dfa0a9bd..fdfd2e0927 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -256,6 +256,8 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
int pci_nic_supported(const char *model);
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
const char *default_devaddr);
+PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
+ const char *default_devaddr);
void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
int pci_bus_num(PCIBus *s);
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 8a6b7ced92..a4882406a9 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -119,7 +119,7 @@ static void bamboo_init(ram_addr_t ram_size,
for (i = 0; i < nb_nics; i++) {
/* There are no PCI NICs on the Bamboo board, but there are
* PCI slots, so we can pick whatever default model we want. */
- pci_nic_init(&nd_table[i], "e1000", NULL);
+ pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
}
}
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 6bd5234d8f..d1a82bfb41 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -320,7 +320,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
for(i = 0; i < nb_nics; i++)
- pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
+ pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
fprintf(stderr, "qemu: too many IDE bus\n");
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index bb8c969ca2..79f17e8580 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -333,7 +333,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
serial_hds[1], ESCC_CLOCK, 4);
for(i = 0; i < nb_nics; i++)
- pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
+ pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 889284a239..104874f2f8 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -697,7 +697,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
if (strcmp(nd_table[i].model, "ne2k_isa") == 0) {
isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
} else {
- pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
+ pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
}
}
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 504419458b..ea30816b32 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -219,7 +219,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
if (pci_bus) {
/* Register network interfaces. */
for (i = 0; i < nb_nics; i++) {
- pci_nic_init(&nd_table[i], "virtio", NULL);
+ pci_nic_init_nofail(&nd_table[i], "virtio", NULL);
}
}
diff --git a/hw/r2d.c b/hw/r2d.c
index ea19ff623d..f8a5968e7b 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -236,7 +236,7 @@ static void r2d_init(ram_addr_t ram_size,
/* NIC: rtl8139 on-board, and 2 slots. */
for (i = 0; i < nb_nics; i++)
- pci_nic_init(&nd_table[i], "rtl8139", i==0 ? "2" : NULL);
+ pci_nic_init_nofail(&nd_table[i], "rtl8139", i==0 ? "2" : NULL);
/* Todo: register on board registers */
if (kernel_filename) {
diff --git a/hw/realview.c b/hw/realview.c
index a18e7735ca..c494a20c88 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -125,7 +125,7 @@ static void realview_init(ram_addr_t ram_size,
smc91c111_init(nd, 0x4e000000, pic[28]);
done_smc = 1;
} else {
- pci_nic_init(nd, "rtl8139", NULL);
+ pci_nic_init_nofail(nd, "rtl8139", NULL);
}
}
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 37e3dda41b..58d708a72f 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -610,7 +610,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
}
for(i = 0; i < nb_nics; i++)
- pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
+ pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
fprintf(stderr, "qemu: too many IDE bus\n");
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 29b85ae7b8..e8ebdf1758 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -213,7 +213,7 @@ static void versatile_init(ram_addr_t ram_size,
smc91c111_init(nd, 0x10010000, sic[25]);
done_smc = 1;
} else {
- pci_nic_init(nd, "rtl8139", NULL);
+ pci_nic_init_nofail(nd, "rtl8139", NULL);
}
}
if (usb_enabled) {
diff --git a/net.c b/net.c
index 2feabbcf71..dc274c71d2 100644
--- a/net.c
+++ b/net.c
@@ -2348,6 +2348,19 @@ static int nic_get_free_idx(void)
return -1;
}
+int qemu_show_nic_models(const char *arg, const char *const *models)
+{
+ int i;
+
+ if (!arg || strcmp(arg, "?"))
+ return 0;
+
+ fprintf(stderr, "qemu: Supported NIC models: ");
+ for (i = 0 ; models[i]; i++)
+ fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n');
+ return 1;
+}
+
void qemu_check_nic_model(NICInfo *nd, const char *model)
{
const char *models[2];
@@ -2355,31 +2368,27 @@ void qemu_check_nic_model(NICInfo *nd, const char *model)
models[0] = model;
models[1] = NULL;
- qemu_check_nic_model_list(nd, models, model);
+ if (qemu_show_nic_models(nd->model, models))
+ exit(0);
+ if (qemu_find_nic_model(nd, models, model) < 0)
+ exit(1);
}
-int qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
- const char *default_model)
+int qemu_find_nic_model(NICInfo *nd, const char * const *models,
+ const char *default_model)
{
- int i, exit_status = 0;
+ int i;
if (!nd->model)
nd->model = strdup(default_model);
- if (strcmp(nd->model, "?") != 0) {
- for (i = 0 ; models[i]; i++)
- if (strcmp(nd->model, models[i]) == 0)
- return i;
-
- fprintf(stderr, "qemu: Unsupported NIC model: %s\n", nd->model);
- exit_status = 1;
+ for (i = 0 ; models[i]; i++) {
+ if (strcmp(nd->model, models[i]) == 0)
+ return i;
}
- fprintf(stderr, "qemu: Supported NIC models: ");
- for (i = 0 ; models[i]; i++)
- fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n');
-
- exit(exit_status);
+ qemu_error("qemu: Unsupported NIC model: %s\n", nd->model);
+ return -1;
}
static int net_handle_fd_param(Monitor *mon, const char *param)
diff --git a/net.h b/net.h
index c93cc99700..dfce8d6518 100644
--- a/net.h
+++ b/net.h
@@ -75,9 +75,10 @@ ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
void qemu_purge_queued_packets(VLANClientState *vc);
void qemu_flush_queued_packets(VLANClientState *vc);
void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]);
+int qemu_show_nic_models(const char *arg, const char *const *models);
void qemu_check_nic_model(NICInfo *nd, const char *model);
-int qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
- const char *default_model);
+int qemu_find_nic_model(NICInfo *nd, const char * const *models,
+ const char *default_model);
void qemu_handler_true(void *opaque);
void do_info_network(Monitor *mon);