diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2018-03-02 10:30:50 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-03-12 16:12:45 +0100 |
commit | 52310c3fa7dc854dd2376ae8a518141abcdb78f3 (patch) | |
tree | 29b2447b2f36061d43c4b6b6d3a57193b1e6bce6 /hw/pci | |
parent | 47c66009ab793241e8210b3018c77a9ce9506aa8 (diff) |
net: allow using any PCI NICs in -net or -nic
Remove the hard-coded list of PCI NIC names; instead, fill an array
using all PCI devices listed under DEVICE_CATEGORY_NETWORK. Keep
the old shortcut "virtio" for virtio-net-pci.
Suggested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r-- | hw/pci/pci.c | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2174c254eb..67a3f72bd6 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1815,49 +1815,48 @@ PciInfoList *qmp_query_pci(Error **errp) return head; } -static const char * const pci_nic_models[] = { - "ne2k_pci", - "i82551", - "i82557b", - "i82559er", - "rtl8139", - "e1000", - "pcnet", - "virtio", - "sungem", - NULL -}; - -static const char * const pci_nic_names[] = { - "ne2k_pci", - "i82551", - "i82557b", - "i82559er", - "rtl8139", - "e1000", - "pcnet", - "virtio-net-pci", - "sungem", - NULL -}; - /* Initialize a PCI NIC. */ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, const char *default_model, const char *default_devaddr) { const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr; + GSList *list; + GPtrArray *pci_nic_models; PCIBus *bus; PCIDevice *pci_dev; DeviceState *dev; int devfn; int i; - if (qemu_show_nic_models(nd->model, pci_nic_models)) { + if (nd->model && !strcmp(nd->model, "virtio")) { + g_free(nd->model); + nd->model = g_strdup("virtio-net-pci"); + } + + list = object_class_get_list_sorted(TYPE_PCI_DEVICE, false); + pci_nic_models = g_ptr_array_new(); + while (list) { + DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, list->data, + TYPE_DEVICE); + GSList *next; + if (test_bit(DEVICE_CATEGORY_NETWORK, dc->categories) && + dc->user_creatable) { + const char *name = object_class_get_name(list->data); + g_ptr_array_add(pci_nic_models, (gpointer)name); + } + next = list->next; + g_slist_free_1(list); + list = next; + } + g_ptr_array_add(pci_nic_models, NULL); + + if (qemu_show_nic_models(nd->model, (const char **)pci_nic_models->pdata)) { exit(0); } - i = qemu_find_nic_model(nd, pci_nic_models, default_model); + i = qemu_find_nic_model(nd, (const char **)pci_nic_models->pdata, + default_model); if (i < 0) { exit(1); } @@ -1865,15 +1864,15 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, bus = pci_get_bus_devfn(&devfn, rootbus, devaddr); if (!bus) { error_report("Invalid PCI device address %s for device %s", - devaddr, pci_nic_names[i]); + devaddr, nd->model); exit(1); } - pci_dev = pci_create(bus, devfn, pci_nic_names[i]); + pci_dev = pci_create(bus, devfn, nd->model); dev = &pci_dev->qdev; qdev_set_nic_properties(dev, nd); qdev_init_nofail(dev); - + g_ptr_array_free(pci_nic_models, true); return pci_dev; } |