sim-card
/
qemu
Archived
10
0
Fork 0

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>
This commit is contained in:
Markus Armbruster 2009-09-25 03:53:51 +02:00 committed by Anthony Liguori
parent 9ee05825d9
commit 07caea315a
15 changed files with 71 additions and 32 deletions

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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");

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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");

View File

@ -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) {

41
net.c
View File

@ -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)

5
net.h
View File

@ -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);