X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_pci_ethdev.c;h=4083853c4887bf1711c1f421868eb37f7f1dc5fe;hb=b37ed6def36798342172f298516c5fc6d0d8e070;hp=6427e57290e30b9885fe567aee63f238f82d8614;hpb=36a7a2e7a53fd269725429eec2d2354d8ca17f3e;p=dpdk.git diff --git a/drivers/net/virtio/virtio_pci_ethdev.c b/drivers/net/virtio/virtio_pci_ethdev.c index 6427e57290..4083853c48 100644 --- a/drivers/net/virtio/virtio_pci_ethdev.c +++ b/drivers/net/virtio/virtio_pci_ethdev.c @@ -19,6 +19,7 @@ #include #include +#include "virtio.h" #include "virtio_ethdev.h" #include "virtio_pci.h" #include "virtio_logs.h" @@ -32,10 +33,89 @@ static const struct rte_pci_id pci_id_virtio_map[] = { { .vendor_id = 0, /* sentinel */ }, }; + +/* + * Remap the PCI device again (IO port map for legacy device and + * memory map for modern device), so that the secondary process + * could have the PCI initiated correctly. + */ +static int +virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_pci_dev *dev) +{ + struct virtio_hw *hw = &dev->hw; + + if (dev->modern) { + /* + * We don't have to re-parse the PCI config space, since + * rte_pci_map_device() makes sure the mapped address + * in secondary process would equal to the one mapped in + * the primary process: error will be returned if that + * requirement is not met. + * + * That said, we could simply reuse all cap pointers + * (such as dev_cfg, common_cfg, etc.) parsed from the + * primary process, which is stored in shared memory. + */ + if (rte_pci_map_device(pci_dev)) { + PMD_INIT_LOG(DEBUG, "failed to map pci device!"); + return -1; + } + } else { + if (vtpci_legacy_ioport_map(hw) < 0) + return -1; + } + + return 0; +} + static int eth_virtio_pci_init(struct rte_eth_dev *eth_dev) { - return eth_virtio_dev_init(eth_dev); + struct virtio_pci_dev *dev = eth_dev->data->dev_private; + struct virtio_hw *hw = &dev->hw; + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + int ret; + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + hw->port_id = eth_dev->data->port_id; + VTPCI_DEV(hw) = pci_dev; + ret = vtpci_init(RTE_ETH_DEV_TO_PCI(eth_dev), dev); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to init PCI device\n"); + return -1; + } + } else { + VTPCI_DEV(hw) = pci_dev; + if (dev->modern) + VIRTIO_OPS(hw) = &modern_ops; + else + VIRTIO_OPS(hw) = &legacy_ops; + + ret = virtio_remap_pci(RTE_ETH_DEV_TO_PCI(eth_dev), dev); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to remap PCI device\n"); + return -1; + } + } + + ret = eth_virtio_dev_init(eth_dev); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to init virtio device\n"); + goto err_unmap; + } + + PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x", + eth_dev->data->port_id, pci_dev->id.vendor_id, + pci_dev->id.device_id); + + return 0; + +err_unmap: + rte_pci_unmap_device(RTE_ETH_DEV_TO_PCI(eth_dev)); + if (!dev->modern) + vtpci_legacy_ioport_unmap(hw); + + return ret; } static int