From patchwork Wed Oct 21 13:25:35 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 36567 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 058F6B7B9C for ; Thu, 22 Oct 2009 01:17:30 +1100 (EST) Received: from localhost ([127.0.0.1]:44359 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N0c0F-0001L5-1s for incoming@patchwork.ozlabs.org; Wed, 21 Oct 2009 10:17:27 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N0bCZ-000818-7d for qemu-devel@nongnu.org; Wed, 21 Oct 2009 09:26:07 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N0bCU-0007sX-A3 for qemu-devel@nongnu.org; Wed, 21 Oct 2009 09:26:06 -0400 Received: from [199.232.76.173] (port=55728 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N0bCT-0007s8-IM for qemu-devel@nongnu.org; Wed, 21 Oct 2009 09:26:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:24025) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N0bCS-0007RS-UP for qemu-devel@nongnu.org; Wed, 21 Oct 2009 09:26:01 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9LDQ0j8004234 for ; Wed, 21 Oct 2009 09:26:00 -0400 Received: from zweiblum.home.kraxel.org (vpn2-9-113.ams2.redhat.com [10.36.9.113]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id n9LDPpfV030897; Wed, 21 Oct 2009 09:25:52 -0400 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id 0A7F970114; Wed, 21 Oct 2009 15:25:44 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 21 Oct 2009 15:25:35 +0200 Message-Id: <1256131543-28416-15-git-send-email-kraxel@redhat.com> In-Reply-To: <1256131543-28416-1-git-send-email-kraxel@redhat.com> References: <1256131543-28416-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 14/22] virtio: use qdev properties for configuration. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Gerd Hoffmann --- hw/qdev.c | 4 ++++ hw/syborg.c | 4 ++-- hw/syborg_virtio.c | 16 +++++++++++++--- hw/virtio-net.c | 43 ++++++++++++++++++++++++------------------- hw/virtio-pci.c | 33 +++++++++++++++++++++++---------- hw/virtio.h | 5 ++++- 6 files changed, 70 insertions(+), 35 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index b32dbfc..e81d662 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -390,6 +390,10 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) qdev_prop_set_vlan(dev, "vlan", nd->vlan); if (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]; diff --git a/hw/syborg.c b/hw/syborg.c index 2aec769..2d08cb2 100644 --- a/hw/syborg.c +++ b/hw/syborg.c @@ -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", 0xC0009000, pic[8]); - if (nd_table[0].vlan) { + if (nd_table[0].vlan || nd_table[0].netdev) { DeviceState *dev; SysBusDevice *s; qemu_check_nic_model(&nd_table[0], "virtio"); dev = qdev_create(NULL, "syborg,virtio-net"); - dev->nd = &nd_table[0]; + qdev_set_nic_properties(dev, &nd_table[0]); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xc000c000); diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c index c1faf3d..6cf5a15 100644 --- a/hw/syborg_virtio.c +++ b/hw/syborg_virtio.c @@ -65,6 +65,7 @@ typedef struct { qemu_irq irq; uint32_t int_enable; uint32_t id; + NICConf nic; } SyborgVirtIOProxy; 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; 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); } +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) { - sysbus_register_dev("syborg,virtio-net", sizeof(SyborgVirtIOProxy), - syborg_virtio_net_init); + sysbus_register_withprop(&syborg_virtio_net_info); } device_init(syborg_virtio_register_devices) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 218f985..f187461 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -700,20 +700,10 @@ static void virtio_net_cleanup(VLANClientState *vc) { VirtIONet *n = vc->opaque; - qemu_purge_queued_packets(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); + n->vc = NULL; } -VirtIODevice *virtio_net_init(DeviceState *dev) +VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf) { VirtIONet *n; 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->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); - qdev_get_macaddr(dev, n->mac); + qemu_macaddr_default_if_unset(&conf->macaddr); n->status = VIRTIO_NET_S_LINK_UP; - n->vc = qdev_get_vlan_client(dev, + n->vc = qemu_new_vlan_client(conf->vlan, conf->peer, + dev->info->name, dev->id, virtio_net_can_receive, virtio_net_receive, NULL, virtio_net_cleanup, n); 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_active = 0; @@ -749,13 +740,27 @@ VirtIODevice *virtio_net_init(DeviceState *dev) n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN); 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, virtio_net_save, virtio_net_load, n); 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); +} diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index e07a2a7..1665b59 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -20,6 +20,7 @@ #include "sysemu.h" #include "msix.h" #include "net.h" +#include "loader.h" /* from Linux's linux/virtio_pci.h */ @@ -90,6 +91,7 @@ typedef struct { uint32_t class_code; uint32_t nvectors; DriveInfo *dinfo; + NICConf nic; } VirtIOPCIProxy; /* virtio device */ @@ -493,14 +495,9 @@ static int virtio_net_init_pci(PCIDevice *pci_dev) VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIODevice *vdev; - vdev = virtio_net_init(&pci_dev->qdev); - - /* 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 = virtio_net_init(&pci_dev->qdev, &proxy->nic); + vdev->nvectors = proxy->nvectors; virtio_init_pci(proxy, vdev, PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_NET, @@ -509,9 +506,25 @@ static int virtio_net_init_pci(PCIDevice *pci_dev) /* make the actual value visible */ 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; } +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) { VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); @@ -543,10 +556,10 @@ static PCIDeviceInfo virtio_info[] = { .qdev.name = "virtio-net-pci", .qdev.size = sizeof(VirtIOPCIProxy), .init = virtio_net_init_pci, - .exit = virtio_exit_pci, + .exit = virtio_net_exit_pci, .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, - NIC_NVECTORS_UNSPECIFIED), + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3), + DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic), DEFINE_PROP_END_OF_LIST(), }, .qdev.reset = virtio_pci_reset, diff --git a/hw/virtio.h b/hw/virtio.h index 0f9be7d..15ad910 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -15,6 +15,7 @@ #define _QEMU_VIRTIO_H #include "hw.h" +#include "net.h" #include "qdev.h" #include "sysemu.h" @@ -163,8 +164,10 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding, /* Base devices. */ 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_balloon_init(DeviceState *dev); +void virtio_net_exit(VirtIODevice *vdev); + #endif