From 72da42085924f65c78e6ec478373f51a9e49e48d Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 11 Feb 2009 15:19:52 +0000 Subject: [PATCH] qemu: return PCIDevice on net device init and record devfn (Marcelo Tosatti) Change the PCI network drivers init functions to return the PCIDev, to inform which slot has been hot-plugged. Also record PCIDevice structure on NICInfo to locate for release on hot-removal. Signed-off-by: Marcelo Tosatti Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6593 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/e1000.c | 4 +++- hw/eepro100.c | 15 ++++++++------- hw/ne2000.c | 4 +++- hw/pci.c | 15 +++++++++++---- hw/pci.h | 16 ++++++++-------- hw/pcnet.c | 3 ++- hw/rtl8139.c | 3 ++- hw/virtio-net.c | 9 +++++---- hw/virtio-net.h | 2 +- net.h | 1 + 10 files changed, 44 insertions(+), 28 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index 6f841d6..14c8297 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -1034,7 +1034,7 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num, excluded_regs[i] - 4); } -void +PCIDevice * pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn) { E1000State *d; @@ -1092,4 +1092,6 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn) qemu_format_nic_info_str(d->vc, d->nd->macaddr); register_savevm(info_str, -1, 2, nic_save, nic_load, d); + + return (PCIDevice *)d; } diff --git a/hw/eepro100.c b/hw/eepro100.c index b8709b0..790192a 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -1735,7 +1735,7 @@ static void nic_save(QEMUFile * f, void *opaque) qemu_put_buffer(f, s->configuration, sizeof(s->configuration)); } -static void nic_init(PCIBus * bus, NICInfo * nd, +static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, const char *name, uint32_t device) { PCIEEPRO100State *d; @@ -1783,22 +1783,23 @@ static void nic_init(PCIBus * bus, NICInfo * nd, qemu_register_reset(nic_reset, s); register_savevm(name, -1, 3, nic_save, nic_load, s); + return (PCIDevice *)d; } -void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn) +PCIDevice *pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn) { - nic_init(bus, nd, "i82551", i82551); + return nic_init(bus, nd, "i82551", i82551); //~ uint8_t *pci_conf = d->dev.config; } -void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn) +PCIDevice *pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn) { - nic_init(bus, nd, "i82557b", i82557B); + return nic_init(bus, nd, "i82557b", i82557B); } -void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn) +PCIDevice *pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn) { - nic_init(bus, nd, "i82559er", i82559ER); + return nic_init(bus, nd, "i82559er", i82559ER); } /* eof */ diff --git a/hw/ne2000.c b/hw/ne2000.c index bd7ac10..1f8d957 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -777,7 +777,7 @@ static void ne2000_map(PCIDevice *pci_dev, int region_num, register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s); } -void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn) +PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn) { PCINE2000State *d; NE2000State *s; @@ -807,4 +807,6 @@ void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn) qemu_format_nic_info_str(s->vc, s->macaddr); register_savevm("ne2000", -1, 3, ne2000_save, ne2000_load, s); + + return (PCIDevice *)d; } diff --git a/hw/pci.c b/hw/pci.c index d0e16fe..b88ed35 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -662,7 +662,7 @@ static const char * const pci_nic_models[] = { NULL }; -typedef void (*PCINICInitFn)(PCIBus *, NICInfo *, int); +typedef PCIDevice *(*PCINICInitFn)(PCIBus *, NICInfo *, int); static PCINICInitFn pci_nic_init_fns[] = { pci_ne2000_init, @@ -677,16 +677,23 @@ static PCINICInitFn pci_nic_init_fns[] = { }; /* Initialize a PCI NIC. */ -void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, +PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, const char *default_model) { + PCIDevice *pci_dev; int i; qemu_check_nic_model_list(nd, pci_nic_models, default_model); for (i = 0; pci_nic_models[i]; i++) - if (strcmp(nd->model, pci_nic_models[i]) == 0) - pci_nic_init_fns[i](bus, nd, devfn); + if (strcmp(nd->model, pci_nic_models[i]) == 0) { + pci_dev = pci_nic_init_fns[i](bus, nd, devfn); + if (pci_dev) + nd->private = pci_dev; + return pci_dev; + } + + return NULL; } typedef struct { diff --git a/hw/pci.h b/hw/pci.h index 255ba30..d827d12 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -220,7 +220,7 @@ typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, qemu_irq *pic, int devfn_min, int nirq); -void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, +PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, const char *default_model); 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); @@ -269,23 +269,23 @@ void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn); /* eepro100.c */ -void pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn); -void pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn); -void pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn); /* ne2000.c */ -void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn); /* rtl8139.c */ -void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn); /* e1000.c */ -void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn); /* pcnet.c */ -void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn); /* prep_pci.c */ PCIBus *pci_prep_init(qemu_irq *pic); diff --git a/hw/pcnet.c b/hw/pcnet.c index 5642099..15167ac 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -1985,7 +1985,7 @@ static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr, cpu_physical_memory_read(addr, buf, len); } -void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn) +PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn) { PCNetState *d; uint8_t *pci_conf; @@ -2032,6 +2032,7 @@ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn) d->pci_dev = &d->dev; pcnet_common_init(d, nd); + return (PCIDevice *)d; } /* SPARC32 interface */ diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 59b0cc7..9fa69db 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -3414,7 +3414,7 @@ static void rtl8139_timer(void *opaque) } #endif /* RTL8139_ONBOARD_TIMER */ -void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn) +PCIDevice *pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn) { PCIRTL8139State *d; RTL8139State *s; @@ -3466,4 +3466,5 @@ void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn) qemu_mod_timer(s->timer, rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock))); #endif /* RTL8139_ONBOARD_TIMER */ + return (PCIDevice *)d; } diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 62153e9..dcfab66 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -560,7 +560,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) return 0; } -void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) +PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) { VirtIONet *n; static int virtio_net_id; @@ -574,7 +574,7 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) sizeof(struct virtio_net_config), sizeof(VirtIONet)); if (!n) - return; + return NULL; n->vdev.get_config = virtio_net_get_config; n->vdev.set_config = virtio_net_set_config; @@ -599,12 +599,13 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN); if (!n->mac_table.macs) - return; + return NULL; n->vlans = qemu_mallocz(MAX_VLAN >> 3); if (!n->vlans) - return; + return NULL; register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION, virtio_net_save, virtio_net_load, n); + return (PCIDevice *)n; } diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 95587f7..4e20349 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -85,7 +85,7 @@ struct virtio_net_hdr_mrg_rxbuf uint16_t num_buffers; /* Number of merged rx buffers */ }; -void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn); +PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn); /* * Control virtqueue data structures diff --git a/net.h b/net.h index 291807a..84c3454 100644 --- a/net.h +++ b/net.h @@ -64,6 +64,7 @@ struct NICInfo { const char *model; const char *name; VLANState *vlan; + void *private; }; extern int nb_nics; -- 1.7.9.5