aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/myri10ge
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2006-12-18 05:50:40 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-26 16:28:20 -0500
commitdf30a740e4647b035e44a94e6977ad42a94cb850 (patch)
treee3805821b02b350f0d25710119647ef94a5d7d4b /drivers/net/myri10ge
parent7adda30c82f403c948b016a40fc68a1ef427dbca (diff)
myri10ge: move request_irq to myri10ge_open
Request IRQ in myri10ge_open() and free in close() instead of probe() and remove() to eliminate potential race between the watchdog and the interrupt handler. Additionaly, the interrupt handler won't get called on shared irq anymore when the interface is down. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r--drivers/net/myri10ge/myri10ge.c98
1 files changed, 54 insertions, 44 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 28540265240c..53325ba0a6ae 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -721,12 +721,10 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
721 status |= 721 status |=
722 myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); 722 myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
723 mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); 723 mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
724 if (!mgp->msi_enabled) { 724 status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
725 status |= myri10ge_send_cmd 725 &cmd, 0);
726 (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); 726 mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
727 mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
728 727
729 }
730 status |= myri10ge_send_cmd 728 status |= myri10ge_send_cmd
731 (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); 729 (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0);
732 mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0); 730 mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0);
@@ -1619,6 +1617,41 @@ static void myri10ge_free_rings(struct net_device *dev)
1619 mgp->tx.req_list = NULL; 1617 mgp->tx.req_list = NULL;
1620} 1618}
1621 1619
1620static int myri10ge_request_irq(struct myri10ge_priv *mgp)
1621{
1622 struct pci_dev *pdev = mgp->pdev;
1623 int status;
1624
1625 if (myri10ge_msi) {
1626 status = pci_enable_msi(pdev);
1627 if (status != 0)
1628 dev_err(&pdev->dev,
1629 "Error %d setting up MSI; falling back to xPIC\n",
1630 status);
1631 else
1632 mgp->msi_enabled = 1;
1633 } else {
1634 mgp->msi_enabled = 0;
1635 }
1636 status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
1637 mgp->dev->name, mgp);
1638 if (status != 0) {
1639 dev_err(&pdev->dev, "failed to allocate IRQ\n");
1640 if (mgp->msi_enabled)
1641 pci_disable_msi(pdev);
1642 }
1643 return status;
1644}
1645
1646static void myri10ge_free_irq(struct myri10ge_priv *mgp)
1647{
1648 struct pci_dev *pdev = mgp->pdev;
1649
1650 free_irq(pdev->irq, mgp);
1651 if (mgp->msi_enabled)
1652 pci_disable_msi(pdev);
1653}
1654
1622static int myri10ge_open(struct net_device *dev) 1655static int myri10ge_open(struct net_device *dev)
1623{ 1656{
1624 struct myri10ge_priv *mgp; 1657 struct myri10ge_priv *mgp;
@@ -1634,10 +1667,13 @@ static int myri10ge_open(struct net_device *dev)
1634 status = myri10ge_reset(mgp); 1667 status = myri10ge_reset(mgp);
1635 if (status != 0) { 1668 if (status != 0) {
1636 printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name); 1669 printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name);
1637 mgp->running = MYRI10GE_ETH_STOPPED; 1670 goto abort_with_nothing;
1638 return -ENXIO;
1639 } 1671 }
1640 1672
1673 status = myri10ge_request_irq(mgp);
1674 if (status != 0)
1675 goto abort_with_nothing;
1676
1641 /* decide what small buffer size to use. For good TCP rx 1677 /* decide what small buffer size to use. For good TCP rx
1642 * performance, it is important to not receive 1514 byte 1678 * performance, it is important to not receive 1514 byte
1643 * frames into jumbo buffers, as it confuses the socket buffer 1679 * frames into jumbo buffers, as it confuses the socket buffer
@@ -1677,7 +1713,7 @@ static int myri10ge_open(struct net_device *dev)
1677 "myri10ge: %s: failed to get ring sizes or locations\n", 1713 "myri10ge: %s: failed to get ring sizes or locations\n",
1678 dev->name); 1714 dev->name);
1679 mgp->running = MYRI10GE_ETH_STOPPED; 1715 mgp->running = MYRI10GE_ETH_STOPPED;
1680 return -ENXIO; 1716 goto abort_with_irq;
1681 } 1717 }
1682 1718
1683 if (mgp->mtrr >= 0) { 1719 if (mgp->mtrr >= 0) {
@@ -1708,7 +1744,7 @@ static int myri10ge_open(struct net_device *dev)
1708 1744
1709 status = myri10ge_allocate_rings(dev); 1745 status = myri10ge_allocate_rings(dev);
1710 if (status != 0) 1746 if (status != 0)
1711 goto abort_with_nothing; 1747 goto abort_with_irq;
1712 1748
1713 /* now give firmware buffers sizes, and MTU */ 1749 /* now give firmware buffers sizes, and MTU */
1714 cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; 1750 cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN;
@@ -1771,6 +1807,9 @@ static int myri10ge_open(struct net_device *dev)
1771abort_with_rings: 1807abort_with_rings:
1772 myri10ge_free_rings(dev); 1808 myri10ge_free_rings(dev);
1773 1809
1810abort_with_irq:
1811 myri10ge_free_irq(mgp);
1812
1774abort_with_nothing: 1813abort_with_nothing:
1775 mgp->running = MYRI10GE_ETH_STOPPED; 1814 mgp->running = MYRI10GE_ETH_STOPPED;
1776 return -ENOMEM; 1815 return -ENOMEM;
@@ -1807,7 +1846,7 @@ static int myri10ge_close(struct net_device *dev)
1807 printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name); 1846 printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name);
1808 1847
1809 netif_tx_disable(dev); 1848 netif_tx_disable(dev);
1810 1849 myri10ge_free_irq(mgp);
1811 myri10ge_free_rings(dev); 1850 myri10ge_free_rings(dev);
1812 1851
1813 mgp->running = MYRI10GE_ETH_STOPPED; 1852 mgp->running = MYRI10GE_ETH_STOPPED;
@@ -2529,7 +2568,6 @@ static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
2529 rtnl_unlock(); 2568 rtnl_unlock();
2530 } 2569 }
2531 myri10ge_dummy_rdma(mgp, 0); 2570 myri10ge_dummy_rdma(mgp, 0);
2532 free_irq(pdev->irq, mgp);
2533 myri10ge_save_state(mgp); 2571 myri10ge_save_state(mgp);
2534 pci_disable_device(pdev); 2572 pci_disable_device(pdev);
2535 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 2573 pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -2565,13 +2603,6 @@ static int myri10ge_resume(struct pci_dev *pdev)
2565 2603
2566 pci_set_master(pdev); 2604 pci_set_master(pdev);
2567 2605
2568 status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
2569 netdev->name, mgp);
2570 if (status != 0) {
2571 dev_err(&pdev->dev, "failed to allocate IRQ\n");
2572 goto abort_with_enabled;
2573 }
2574
2575 myri10ge_reset(mgp); 2606 myri10ge_reset(mgp);
2576 myri10ge_dummy_rdma(mgp, 1); 2607 myri10ge_dummy_rdma(mgp, 1);
2577 2608
@@ -2581,8 +2612,11 @@ static int myri10ge_resume(struct pci_dev *pdev)
2581 2612
2582 if (netif_running(netdev)) { 2613 if (netif_running(netdev)) {
2583 rtnl_lock(); 2614 rtnl_lock();
2584 myri10ge_open(netdev); 2615 status = myri10ge_open(netdev);
2585 rtnl_unlock(); 2616 rtnl_unlock();
2617 if (status != 0)
2618 goto abort_with_enabled;
2619
2586 } 2620 }
2587 netif_device_attach(netdev); 2621 netif_device_attach(netdev);
2588 2622
@@ -2860,23 +2894,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2860 goto abort_with_firmware; 2894 goto abort_with_firmware;
2861 } 2895 }
2862 2896
2863 if (myri10ge_msi) {
2864 status = pci_enable_msi(pdev);
2865 if (status != 0)
2866 dev_err(&pdev->dev,
2867 "Error %d setting up MSI; falling back to xPIC\n",
2868 status);
2869 else
2870 mgp->msi_enabled = 1;
2871 }
2872
2873 status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
2874 netdev->name, mgp);
2875 if (status != 0) {
2876 dev_err(&pdev->dev, "failed to allocate IRQ\n");
2877 goto abort_with_firmware;
2878 }
2879
2880 pci_set_drvdata(pdev, mgp); 2897 pci_set_drvdata(pdev, mgp);
2881 if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) 2898 if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU)
2882 myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; 2899 myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
@@ -2913,8 +2930,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2913 dev_err(&pdev->dev, "register_netdev failed: %d\n", status); 2930 dev_err(&pdev->dev, "register_netdev failed: %d\n", status);
2914 goto abort_with_state; 2931 goto abort_with_state;
2915 } 2932 }
2916 dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", 2933 dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n",
2917 (mgp->msi_enabled ? "MSI" : "xPIC"),
2918 pdev->irq, mgp->tx.boundary, mgp->fw_name, 2934 pdev->irq, mgp->tx.boundary, mgp->fw_name,
2919 (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); 2935 (mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
2920 2936
@@ -2922,9 +2938,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2922 2938
2923abort_with_state: 2939abort_with_state:
2924 myri10ge_restore_state(mgp); 2940 myri10ge_restore_state(mgp);
2925 free_irq(pdev->irq, mgp);
2926 if (mgp->msi_enabled)
2927 pci_disable_msi(pdev);
2928 2941
2929abort_with_firmware: 2942abort_with_firmware:
2930 myri10ge_dummy_rdma(mgp, 0); 2943 myri10ge_dummy_rdma(mgp, 0);
@@ -2975,9 +2988,6 @@ static void myri10ge_remove(struct pci_dev *pdev)
2975 flush_scheduled_work(); 2988 flush_scheduled_work();
2976 netdev = mgp->dev; 2989 netdev = mgp->dev;
2977 unregister_netdev(netdev); 2990 unregister_netdev(netdev);
2978 free_irq(pdev->irq, mgp);
2979 if (mgp->msi_enabled)
2980 pci_disable_msi(pdev);
2981 2991
2982 myri10ge_dummy_rdma(mgp, 0); 2992 myri10ge_dummy_rdma(mgp, 0);
2983 2993