| From 5fa1659105fac63e0f3c199b476025c2e04111ce Mon Sep 17 00:00:00 2001 |
| From: Helge Deller <deller@gmx.de> |
| Date: Thu, 5 Sep 2019 16:44:17 +0200 |
| Subject: parisc: Disable HP HSC-PCI Cards to prevent kernel crash |
| |
| From: Helge Deller <deller@gmx.de> |
| |
| commit 5fa1659105fac63e0f3c199b476025c2e04111ce upstream. |
| |
| The HP Dino PCI controller chip can be used in two variants: as on-board |
| controller (e.g. in B160L), or on an Add-On card ("Card-Mode") to bridge |
| PCI components to systems without a PCI bus, e.g. to a HSC/GSC bus. One |
| such Add-On card is the HP HSC-PCI Card which has one or more DEC Tulip |
| PCI NIC chips connected to the on-card Dino PCI controller. |
| |
| Dino in Card-Mode has a big disadvantage: All PCI memory accesses need |
| to go through the DINO_MEM_DATA register, so Linux drivers will not be |
| able to use the ioremap() function. Without ioremap() many drivers will |
| not work, one example is the tulip driver which then simply crashes the |
| kernel if it tries to access the ports on the HP HSC card. |
| |
| This patch disables the HP HSC card if it finds one, and as such |
| fixes the kernel crash on a HP D350/2 machine. |
| |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| Noticed-by: Phil Scarr <phil.scarr@pm.me> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/parisc/dino.c | 24 ++++++++++++++++++++++++ |
| 1 file changed, 24 insertions(+) |
| |
| --- a/drivers/parisc/dino.c |
| +++ b/drivers/parisc/dino.c |
| @@ -160,6 +160,15 @@ struct dino_device |
| (struct dino_device *)__pdata; }) |
| |
| |
| +/* Check if PCI device is behind a Card-mode Dino. */ |
| +static int pci_dev_is_behind_card_dino(struct pci_dev *dev) |
| +{ |
| + struct dino_device *dino_dev; |
| + |
| + dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge)); |
| + return is_card_dino(&dino_dev->hba.dev->id); |
| +} |
| + |
| /* |
| * Dino Configuration Space Accessor Functions |
| */ |
| @@ -442,6 +451,21 @@ static void quirk_cirrus_cardbus(struct |
| } |
| DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus ); |
| |
| +#ifdef CONFIG_TULIP |
| +static void pci_fixup_tulip(struct pci_dev *dev) |
| +{ |
| + if (!pci_dev_is_behind_card_dino(dev)) |
| + return; |
| + if (!(pci_resource_flags(dev, 1) & IORESOURCE_MEM)) |
| + return; |
| + pr_warn("%s: HP HSC-PCI Cards with card-mode Dino not yet supported.\n", |
| + pci_name(dev)); |
| + /* Disable this card by zeroing the PCI resources */ |
| + memset(&dev->resource[0], 0, sizeof(dev->resource[0])); |
| + memset(&dev->resource[1], 0, sizeof(dev->resource[1])); |
| +} |
| +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_DEC, PCI_ANY_ID, pci_fixup_tulip); |
| +#endif /* CONFIG_TULIP */ |
| |
| static void __init |
| dino_bios_init(void) |