diff options
author | David Miller <davem@davemloft.net> | 2007-10-25 04:16:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-11-05 16:35:16 -0500 |
commit | ba698ad4b7e466cbb4a8bde6b9da8080ab06808d (patch) | |
tree | 31e0ebfbb91633da5f62e455d708328a0f9875ee /drivers | |
parent | 1d84b5424efbcce69a1c955ba181147d23d43a14 (diff) |
PCI: Add quirk for devices which disable MSI when INTX_DISABLE is set.
A reasonably common problem with some devices is that they will
disable MSI generation when the INTX_DISABLE bit is set in the
PCI_COMMAND register.
Quirk this explicitly, guarding the pci_intx() calls in msi.c with
this quirk indication.
The first entries for this quirk are for 5714 and 5780 Tigon3 chips,
and thus we can remove the workaround code from the tg3.c driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Michael Chan <mchan@broadcom.com>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/tg3.c | 9 | ||||
-rw-r--r-- | drivers/pci/msi.c | 18 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 24 |
3 files changed, 36 insertions, 15 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 09440d783e65..cad519910767 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -7365,10 +7365,6 @@ static int tg3_open(struct net_device *dev) | |||
7365 | } else if (pci_enable_msi(tp->pdev) == 0) { | 7365 | } else if (pci_enable_msi(tp->pdev) == 0) { |
7366 | u32 msi_mode; | 7366 | u32 msi_mode; |
7367 | 7367 | ||
7368 | /* Hardware bug - MSI won't work if INTX disabled. */ | ||
7369 | if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) | ||
7370 | pci_intx(tp->pdev, 1); | ||
7371 | |||
7372 | msi_mode = tr32(MSGINT_MODE); | 7368 | msi_mode = tr32(MSGINT_MODE); |
7373 | tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); | 7369 | tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); |
7374 | tp->tg3_flags2 |= TG3_FLG2_USING_MSI; | 7370 | tp->tg3_flags2 |= TG3_FLG2_USING_MSI; |
@@ -12681,11 +12677,6 @@ static int tg3_resume(struct pci_dev *pdev) | |||
12681 | if (err) | 12677 | if (err) |
12682 | return err; | 12678 | return err; |
12683 | 12679 | ||
12684 | /* Hardware bug - MSI won't work if INTX disabled. */ | ||
12685 | if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) && | ||
12686 | (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) | ||
12687 | pci_intx(tp->pdev, 1); | ||
12688 | |||
12689 | netif_device_attach(dev); | 12680 | netif_device_attach(dev); |
12690 | 12681 | ||
12691 | tg3_full_lock(tp, 0); | 12682 | tg3_full_lock(tp, 0); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 87e01615053d..07c9f09c856d 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -224,6 +224,12 @@ static struct msi_desc* alloc_msi_entry(void) | |||
224 | return entry; | 224 | return entry; |
225 | } | 225 | } |
226 | 226 | ||
227 | static void pci_intx_for_msi(struct pci_dev *dev, int enable) | ||
228 | { | ||
229 | if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG)) | ||
230 | pci_intx(dev, enable); | ||
231 | } | ||
232 | |||
227 | #ifdef CONFIG_PM | 233 | #ifdef CONFIG_PM |
228 | static void __pci_restore_msi_state(struct pci_dev *dev) | 234 | static void __pci_restore_msi_state(struct pci_dev *dev) |
229 | { | 235 | { |
@@ -237,7 +243,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
237 | entry = get_irq_msi(dev->irq); | 243 | entry = get_irq_msi(dev->irq); |
238 | pos = entry->msi_attrib.pos; | 244 | pos = entry->msi_attrib.pos; |
239 | 245 | ||
240 | pci_intx(dev, 0); /* disable intx */ | 246 | pci_intx_for_msi(dev, 0); |
241 | msi_set_enable(dev, 0); | 247 | msi_set_enable(dev, 0); |
242 | write_msi_msg(dev->irq, &entry->msg); | 248 | write_msi_msg(dev->irq, &entry->msg); |
243 | if (entry->msi_attrib.maskbit) | 249 | if (entry->msi_attrib.maskbit) |
@@ -260,7 +266,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
260 | return; | 266 | return; |
261 | 267 | ||
262 | /* route the table */ | 268 | /* route the table */ |
263 | pci_intx(dev, 0); /* disable intx */ | 269 | pci_intx_for_msi(dev, 0); |
264 | msix_set_enable(dev, 0); | 270 | msix_set_enable(dev, 0); |
265 | 271 | ||
266 | list_for_each_entry(entry, &dev->msi_list, list) { | 272 | list_for_each_entry(entry, &dev->msi_list, list) { |
@@ -343,7 +349,7 @@ static int msi_capability_init(struct pci_dev *dev) | |||
343 | } | 349 | } |
344 | 350 | ||
345 | /* Set MSI enabled bits */ | 351 | /* Set MSI enabled bits */ |
346 | pci_intx(dev, 0); /* disable intx */ | 352 | pci_intx_for_msi(dev, 0); |
347 | msi_set_enable(dev, 1); | 353 | msi_set_enable(dev, 1); |
348 | dev->msi_enabled = 1; | 354 | dev->msi_enabled = 1; |
349 | 355 | ||
@@ -433,7 +439,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
433 | i++; | 439 | i++; |
434 | } | 440 | } |
435 | /* Set MSI-X enabled bits */ | 441 | /* Set MSI-X enabled bits */ |
436 | pci_intx(dev, 0); /* disable intx */ | 442 | pci_intx_for_msi(dev, 0); |
437 | msix_set_enable(dev, 1); | 443 | msix_set_enable(dev, 1); |
438 | dev->msix_enabled = 1; | 444 | dev->msix_enabled = 1; |
439 | 445 | ||
@@ -528,7 +534,7 @@ void pci_disable_msi(struct pci_dev* dev) | |||
528 | return; | 534 | return; |
529 | 535 | ||
530 | msi_set_enable(dev, 0); | 536 | msi_set_enable(dev, 0); |
531 | pci_intx(dev, 1); /* enable intx */ | 537 | pci_intx_for_msi(dev, 1); |
532 | dev->msi_enabled = 0; | 538 | dev->msi_enabled = 0; |
533 | 539 | ||
534 | BUG_ON(list_empty(&dev->msi_list)); | 540 | BUG_ON(list_empty(&dev->msi_list)); |
@@ -640,7 +646,7 @@ void pci_disable_msix(struct pci_dev* dev) | |||
640 | return; | 646 | return; |
641 | 647 | ||
642 | msix_set_enable(dev, 0); | 648 | msix_set_enable(dev, 0); |
643 | pci_intx(dev, 1); /* enable intx */ | 649 | pci_intx_for_msi(dev, 1); |
644 | dev->msix_enabled = 0; | 650 | dev->msix_enabled = 0; |
645 | 651 | ||
646 | msix_free_all_irqs(dev); | 652 | msix_free_all_irqs(dev); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f975f7fccb1d..9e8c7af0cc16 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1707,4 +1707,28 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1707 | } | 1707 | } |
1708 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1708 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1709 | quirk_nvidia_ck804_msi_ht_cap); | 1709 | quirk_nvidia_ck804_msi_ht_cap); |
1710 | |||
1711 | static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) | ||
1712 | { | ||
1713 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | ||
1714 | } | ||
1715 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | ||
1716 | PCI_DEVICE_ID_TIGON3_5780, | ||
1717 | quirk_msi_intx_disable_bug); | ||
1718 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | ||
1719 | PCI_DEVICE_ID_TIGON3_5780S, | ||
1720 | quirk_msi_intx_disable_bug); | ||
1721 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | ||
1722 | PCI_DEVICE_ID_TIGON3_5714, | ||
1723 | quirk_msi_intx_disable_bug); | ||
1724 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | ||
1725 | PCI_DEVICE_ID_TIGON3_5714S, | ||
1726 | quirk_msi_intx_disable_bug); | ||
1727 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | ||
1728 | PCI_DEVICE_ID_TIGON3_5715, | ||
1729 | quirk_msi_intx_disable_bug); | ||
1730 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | ||
1731 | PCI_DEVICE_ID_TIGON3_5715S, | ||
1732 | quirk_msi_intx_disable_bug); | ||
1733 | |||
1710 | #endif /* CONFIG_PCI_MSI */ | 1734 | #endif /* CONFIG_PCI_MSI */ |