aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorCasey Leedom <leedom@chelsio.com>2011-02-14 07:56:24 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-14 20:37:11 -0500
commit7e9c26295b2ae1be1285c7c9e593c19ce7ea7eba (patch)
treec8bb3d0decb24c44aca420faa0b0d88dbf1e82c2 /drivers
parent843635e0349be9e318be224d6241069a40e23320 (diff)
cxgb4vf: Quiesce Virtual Interfaces on shutdown ...
When a Virtual Machine is rebooted, KVM currently fails to issue a Function Level Reset against any "Attached PCI Devices" (AKA "PCI Passthrough"). In addition to leaving the attached device in a random state in the next booted kernel (which sort of violates the entire idea of a reboot reseting hardware state), this leaves our peer thinking that the link is still up. (Note that a bug has been filed with the KVM folks, #25332, but there's been no response on that as of yet.) So, we add a "->shutdown()" method for the Virtual Function PCI Device to handle administrative shutdowns like a reboot. Signed-off-by: Casey Leedom <leedom@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index 2be1088ff601..6aad64df4dcb 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -2862,6 +2862,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev)
2862} 2862}
2863 2863
2864/* 2864/*
2865 * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt
2866 * delivery.
2867 */
2868static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev)
2869{
2870 struct adapter *adapter;
2871 int pidx;
2872
2873 adapter = pci_get_drvdata(pdev);
2874 if (!adapter)
2875 return;
2876
2877 /*
2878 * Disable all Virtual Interfaces. This will shut down the
2879 * delivery of all ingress packets into the chip for these
2880 * Virtual Interfaces.
2881 */
2882 for_each_port(adapter, pidx) {
2883 struct net_device *netdev;
2884 struct port_info *pi;
2885
2886 if (!test_bit(pidx, &adapter->registered_device_map))
2887 continue;
2888
2889 netdev = adapter->port[pidx];
2890 if (!netdev)
2891 continue;
2892
2893 pi = netdev_priv(netdev);
2894 t4vf_enable_vi(adapter, pi->viid, false, false);
2895 }
2896
2897 /*
2898 * Free up all Queues which will prevent further DMA and
2899 * Interrupts allowing various internal pathways to drain.
2900 */
2901 t4vf_free_sge_resources(adapter);
2902}
2903
2904/*
2865 * PCI Device registration data structures. 2905 * PCI Device registration data structures.
2866 */ 2906 */
2867#define CH_DEVICE(devid, idx) \ 2907#define CH_DEVICE(devid, idx) \
@@ -2894,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = {
2894 .id_table = cxgb4vf_pci_tbl, 2934 .id_table = cxgb4vf_pci_tbl,
2895 .probe = cxgb4vf_pci_probe, 2935 .probe = cxgb4vf_pci_probe,
2896 .remove = __devexit_p(cxgb4vf_pci_remove), 2936 .remove = __devexit_p(cxgb4vf_pci_remove),
2937 .shutdown = __devexit_p(cxgb4vf_pci_shutdown),
2897}; 2938};
2898 2939
2899/* 2940/*