[PATCH] sky2: msi enhancements.
Stephen Hemminger [Fri, 1 Dec 2006 22:29:37 +0000 (14:29 -0800)]
If using Message Signaled Interrupts (MSI) then the IRQ will never
be shared. Don't call pci_disable_msi() unless using MSI.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

drivers/net/sky2.c
drivers/net/sky2.h

index b95b9b7..0ef1848 100644 (file)
@@ -3311,7 +3311,7 @@ static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id)
                return IRQ_NONE;
 
        if (status & Y2_IS_IRQ_SW) {
-               hw->msi_detected = 1;
+               hw->msi = 1;
                wake_up(&hw->msi_wait);
                sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
        }
@@ -3330,7 +3330,7 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
 
        sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
 
-       err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw);
+       err = request_irq(pdev->irq, sky2_test_intr, 0, DRV_NAME, hw);
        if (err) {
                printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
                       pci_name(pdev), pdev->irq);
@@ -3340,9 +3340,9 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
        sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
        sky2_read8(hw, B0_CTST);
 
-       wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
+       wait_event_timeout(hw->msi_wait, hw->msi, HZ/10);
 
-       if (!hw->msi_detected) {
+       if (!hw->msi) {
                /* MSI test failed, go back to INTx mode */
                printk(KERN_INFO PFX "%s: No interrupt generated using MSI, "
                       "switching to INTx mode.\n",
@@ -3475,7 +3475,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                goto err_out_free_netdev;
        }
 
-       err = request_irq(pdev->irq,  sky2_intr, IRQF_SHARED, dev->name, hw);
+       err = request_irq(pdev->irq,  sky2_intr, hw->msi ? 0 : IRQF_SHARED,
+                         dev->name, hw);
        if (err) {
                printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
                       pci_name(pdev), pdev->irq);
@@ -3505,7 +3506,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
        return 0;
 
 err_out_unregister:
-       pci_disable_msi(pdev);
+       if (hw->msi)
+               pci_disable_msi(pdev);
        unregister_netdev(dev);
 err_out_free_netdev:
        free_netdev(dev);
@@ -3548,7 +3550,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
        sky2_read8(hw, B0_CTST);
 
        free_irq(pdev->irq, hw);
-       pci_disable_msi(pdev);
+       if (hw->msi)
+               pci_disable_msi(pdev);
        pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
index c551ec3..7760545 100644 (file)
@@ -1900,7 +1900,7 @@ struct sky2_hw {
        dma_addr_t           st_dma;
 
        struct timer_list    idle_timer;
-       int                  msi_detected;
+       int                  msi;
        wait_queue_head_t    msi_wait;
 };