virtio: use qdev properties for configuration.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Gerd Hoffmann 2009-10-21 15:25:35 +02:00 committed by Anthony Liguori
parent 254111ecc8
commit 97b156213e
6 changed files with 71 additions and 36 deletions

View File

@ -390,6 +390,10 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
qdev_prop_set_vlan(dev, "vlan", nd->vlan); qdev_prop_set_vlan(dev, "vlan", nd->vlan);
if (nd->netdev) if (nd->netdev)
qdev_prop_set_netdev(dev, "netdev", nd->netdev); qdev_prop_set_netdev(dev, "netdev", nd->netdev);
if (nd->nvectors != NIC_NVECTORS_UNSPECIFIED &&
qdev_prop_exists(dev, "vectors")) {
qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
}
} }
static int next_block_unit[IF_COUNT]; static int next_block_unit[IF_COUNT];

View File

@ -77,13 +77,13 @@ static void syborg_init(ram_addr_t ram_size,
sysbus_create_simple("syborg,serial", 0xC0008000, pic[7]); sysbus_create_simple("syborg,serial", 0xC0008000, pic[7]);
sysbus_create_simple("syborg,serial", 0xC0009000, pic[8]); sysbus_create_simple("syborg,serial", 0xC0009000, pic[8]);
if (nd_table[0].vlan) { if (nd_table[0].vlan || nd_table[0].netdev) {
DeviceState *dev; DeviceState *dev;
SysBusDevice *s; SysBusDevice *s;
qemu_check_nic_model(&nd_table[0], "virtio"); qemu_check_nic_model(&nd_table[0], "virtio");
dev = qdev_create(NULL, "syborg,virtio-net"); dev = qdev_create(NULL, "syborg,virtio-net");
dev->nd = &nd_table[0]; qdev_set_nic_properties(dev, &nd_table[0]);
qdev_init_nofail(dev); qdev_init_nofail(dev);
s = sysbus_from_qdev(dev); s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0xc000c000); sysbus_mmio_map(s, 0, 0xc000c000);

View File

@ -65,6 +65,7 @@ typedef struct {
qemu_irq irq; qemu_irq irq;
uint32_t int_enable; uint32_t int_enable;
uint32_t id; uint32_t id;
NICConf nic;
} SyborgVirtIOProxy; } SyborgVirtIOProxy;
static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset) static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
@ -273,14 +274,23 @@ static int syborg_virtio_net_init(SysBusDevice *dev)
VirtIODevice *vdev; VirtIODevice *vdev;
SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev); SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev);
vdev = virtio_net_init(&dev->qdev); vdev = virtio_net_init(&dev->qdev, &proxy->nic);
return syborg_virtio_init(proxy, vdev); return syborg_virtio_init(proxy, vdev);
} }
static SysBusDeviceInfo syborg_virtio_net_info = {
.init = syborg_virtio_net_init,
.qdev.name = "syborg,virtio-net",
.qdev.size = sizeof(SyborgVirtIOProxy),
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic),
DEFINE_PROP_END_OF_LIST(),
}
};
static void syborg_virtio_register_devices(void) static void syborg_virtio_register_devices(void)
{ {
sysbus_register_dev("syborg,virtio-net", sizeof(SyborgVirtIOProxy), sysbus_register_withprop(&syborg_virtio_net_info);
syborg_virtio_net_init);
} }
device_init(syborg_virtio_register_devices) device_init(syborg_virtio_register_devices)

View File

@ -700,20 +700,10 @@ static void virtio_net_cleanup(VLANClientState *vc)
{ {
VirtIONet *n = vc->opaque; VirtIONet *n = vc->opaque;
qemu_purge_queued_packets(vc); n->vc = NULL;
unregister_savevm("virtio-net", n);
qemu_free(n->mac_table.macs);
qemu_free(n->vlans);
qemu_del_timer(n->tx_timer);
qemu_free_timer(n->tx_timer);
virtio_cleanup(&n->vdev);
} }
VirtIODevice *virtio_net_init(DeviceState *dev) VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
{ {
VirtIONet *n; VirtIONet *n;
static int virtio_net_id; static int virtio_net_id;
@ -731,15 +721,16 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx); n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl); n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl);
qdev_get_macaddr(dev, n->mac); qemu_macaddr_default_if_unset(&conf->macaddr);
n->status = VIRTIO_NET_S_LINK_UP; n->status = VIRTIO_NET_S_LINK_UP;
n->vc = qdev_get_vlan_client(dev, n->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC, conf->vlan, conf->peer,
dev->info->name, dev->id,
virtio_net_can_receive, virtio_net_can_receive,
virtio_net_receive, NULL, virtio_net_receive, NULL, NULL,
virtio_net_cleanup, n); virtio_net_cleanup, n);
n->vc->link_status_changed = virtio_net_set_link_status; n->vc->link_status_changed = virtio_net_set_link_status;
qemu_format_nic_info_str(n->vc, n->mac); qemu_format_nic_info_str(n->vc, conf->macaddr.a);
n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n); n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
n->tx_timer_active = 0; n->tx_timer_active = 0;
@ -749,13 +740,27 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN); n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
n->vlans = qemu_mallocz(MAX_VLAN >> 3); n->vlans = qemu_mallocz(MAX_VLAN >> 3);
if (dev->nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
n->vdev.nvectors = 3;
else
n->vdev.nvectors = dev->nd->nvectors;
register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION, register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
virtio_net_save, virtio_net_load, n); virtio_net_save, virtio_net_load, n);
return &n->vdev; return &n->vdev;
} }
void virtio_net_exit(VirtIODevice *vdev)
{
VirtIONet *n = DO_UPCAST(VirtIONet, vdev, vdev);
qemu_purge_queued_packets(n->vc);
unregister_savevm("virtio-net", n);
qemu_free(n->mac_table.macs);
qemu_free(n->vlans);
qemu_del_timer(n->tx_timer);
qemu_free_timer(n->tx_timer);
virtio_cleanup(&n->vdev);
qemu_del_vlan_client(n->vc);
}

View File

@ -20,6 +20,7 @@
#include "sysemu.h" #include "sysemu.h"
#include "msix.h" #include "msix.h"
#include "net.h" #include "net.h"
#include "loader.h"
/* from Linux's linux/virtio_pci.h */ /* from Linux's linux/virtio_pci.h */
@ -90,6 +91,7 @@ typedef struct {
uint32_t class_code; uint32_t class_code;
uint32_t nvectors; uint32_t nvectors;
DriveInfo *dinfo; DriveInfo *dinfo;
NICConf nic;
} VirtIOPCIProxy; } VirtIOPCIProxy;
/* virtio device */ /* virtio device */
@ -493,14 +495,9 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
VirtIODevice *vdev; VirtIODevice *vdev;
vdev = virtio_net_init(&pci_dev->qdev); vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic);
/* set nvectors from property, unless the user specified something
* via -net nic,model=virtio,vectors=n command line option */
if (pci_dev->qdev.nd->nvectors == NIC_NVECTORS_UNSPECIFIED)
if (proxy->nvectors != NIC_NVECTORS_UNSPECIFIED)
vdev->nvectors = proxy->nvectors;
vdev->nvectors = proxy->nvectors;
virtio_init_pci(proxy, vdev, virtio_init_pci(proxy, vdev,
PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_VENDOR_ID_REDHAT_QUMRANET,
PCI_DEVICE_ID_VIRTIO_NET, PCI_DEVICE_ID_VIRTIO_NET,
@ -509,9 +506,25 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
/* make the actual value visible */ /* make the actual value visible */
proxy->nvectors = vdev->nvectors; proxy->nvectors = vdev->nvectors;
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-virtio.bin");
loaded = 1;
}
}
return 0; return 0;
} }
static int virtio_net_exit_pci(PCIDevice *pci_dev)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
virtio_net_exit(proxy->vdev);
return virtio_exit_pci(pci_dev);
}
static int virtio_balloon_init_pci(PCIDevice *pci_dev) static int virtio_balloon_init_pci(PCIDevice *pci_dev)
{ {
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
@ -543,10 +556,10 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.name = "virtio-net-pci", .qdev.name = "virtio-net-pci",
.qdev.size = sizeof(VirtIOPCIProxy), .qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_net_init_pci, .init = virtio_net_init_pci,
.exit = virtio_exit_pci, .exit = virtio_net_exit_pci,
.qdev.props = (Property[]) { .qdev.props = (Property[]) {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
NIC_NVECTORS_UNSPECIFIED), DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}, },
.qdev.reset = virtio_pci_reset, .qdev.reset = virtio_pci_reset,

View File

@ -15,6 +15,7 @@
#define _QEMU_VIRTIO_H #define _QEMU_VIRTIO_H
#include "hw.h" #include "hw.h"
#include "net.h"
#include "qdev.h" #include "qdev.h"
#include "sysemu.h" #include "sysemu.h"
@ -163,8 +164,10 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
/* Base devices. */ /* Base devices. */
VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo); VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo);
VirtIODevice *virtio_net_init(DeviceState *dev); VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf);
VirtIODevice *virtio_console_init(DeviceState *dev); VirtIODevice *virtio_console_init(DeviceState *dev);
VirtIODevice *virtio_balloon_init(DeviceState *dev); VirtIODevice *virtio_balloon_init(DeviceState *dev);
void virtio_net_exit(VirtIODevice *vdev);
#endif #endif