]> git.hungrycats.org Git - linux/commitdiff
[PATCH] 2.5.3 ISDN work around buggy hw
authorKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Tue, 5 Feb 2002 09:50:12 +0000 (01:50 -0800)
committerKai Germaschewski <kai@chaos.tp1.ruhr-uni-bochum.de>
Tue, 5 Feb 2002 09:50:12 +0000 (01:50 -0800)
the appended patch works around a bug in the PLX9050 chip. This chip is
used in various PCI ISDN adapters (it's an PCI interface chip) and has
an erratum when the BAR 0/1 has bit 7 set (the size of the region is
0x80, so aligning it to 0x80 is legal and really happens for people).

This workaround has been tested by a user who hit this problem with a
Gazel card. Basically the same fix has been done for Elsa cards, but it's
untested.

drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/gazel.c
drivers/isdn/hisax/hisax.h

index 7fdeb01c955bee6c1c37c94aa760a81ea5f3a7cf..65043e636b5265dc01695407970e346f033f965a 100644 (file)
@@ -396,7 +396,8 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
        }
        if (cs->subtyp == ELSA_QS1000PCI || cs->subtyp == ELSA_QS3000PCI) {
                val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */
-               if (!(val & ELSA_PCI_IRQ_MASK))
+               if (!test_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags) && 
+                   !(val & ELSA_PCI_IRQ_MASK))
                        return;
        }
 #if ARCOFI_USE
@@ -868,7 +869,7 @@ setup_elsa(struct IsdnCard *card)
 {
        long flags;
        int bytecnt;
-       u_char val;
+       u_char val, pci_rev;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 
@@ -992,6 +993,7 @@ setup_elsa(struct IsdnCard *card)
                        cs->irq = dev_qs1000->irq;
                        cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
                        cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
+                       pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev);
                } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,
                        PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
                        if (pci_enable_device(dev_qs3000))
@@ -1000,6 +1002,7 @@ setup_elsa(struct IsdnCard *card)
                        cs->irq = dev_qs3000->irq;
                        cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
                        cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
+                       pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev);
                } else {
                        printk(KERN_WARNING "Elsa: No PCI card found\n");
                        return(0);
@@ -1013,15 +1016,9 @@ setup_elsa(struct IsdnCard *card)
                        printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n");
                        return(0);
                }
-               if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) {
-                       printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n");
-                       printk(KERN_WARNING "Elsa: If your system hangs now, read\n");
-                       printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n");
-                       printk(KERN_WARNING "Elsa: Waiting 5 sec to sync discs\n");
-                       save_flags(flags);
-                       sti();
-                       HZDELAY(500);   /* wait 500*10 ms */
-                       restore_flags(flags);
+               if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) {
+                       printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated");
+                       set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
                }
                cs->hw.elsa.ale  = cs->hw.elsa.base;
                cs->hw.elsa.isac = cs->hw.elsa.base +1;
index 0cdd30860b67224f348663ebc4da8c8b925a0e1a..a99fc45e16434d81d09d0010a74f972e6174df89 100644 (file)
@@ -382,12 +382,16 @@ reset_gazel(struct IsdnCardState *cs)
                        outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR);
                        break;
                case R753:
-                       plxcntrl = inl(addr + PLX_CNTRL);
+                       if (test_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags))
+                               /* we can't read, assume the default */
+                               plxcntrl = 0x18784db6;
+                       else
+                               plxcntrl = inl(addr + PLX_CNTRL);
                        plxcntrl |= (RESET_9050 + RESET_GAZEL);
                        outl(plxcntrl, addr + PLX_CNTRL);
-                       plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
                        WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
                        HZDELAY(4);
+                       plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
                        outl(plxcntrl, addr + PLX_CNTRL);
                        HZDELAY(10);
                        WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
@@ -549,6 +553,7 @@ setup_gazelpci(struct IsdnCardState *cs)
        u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0;
        u_char pci_irq = 0, found;
        u_int nbseek, seekcard;
+       u_char pci_rev;
 
        printk(KERN_WARNING "Gazel: PCI card automatic recognition\n");
 
@@ -623,6 +628,18 @@ setup_gazelpci(struct IsdnCardState *cs)
                        printk(KERN_INFO
                            "Gazel: config irq:%d ipac:0x%X  cfg:0x%X\n",
                        cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
+                       /* 
+                        * Erratum for PLX9050, revision 1:
+                        * If bit 7 of BAR 0/1 is set, local config registers
+                        * can not be read (write is okay)
+                        */
+                       if (cs->hw.gazel.cfg_reg & 0x80) {
+                               pci_read_config_byte(dev_tel, PCI_REVISION_ID, &pci_rev);
+                               if (pci_rev == 1) {
+                                       printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated");
+                                       set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
+                               }
+                       }
                        break;
        }
 
index 4915d01ade5e06222babe1091eeb2cc8c8e13585..646dbd3747374ebd3d4d806243b8ddb820f75a1b 100644 (file)
@@ -859,6 +859,7 @@ struct icc_chip {
 #define FLG_ARCOFI_TIMER       8
 #define FLG_ARCOFI_ERROR       9
 #define FLG_HW_L1_UINT         10
+#define FLG_BUGGY_PLX9050       11
 
 struct IsdnCardState {
        unsigned char typ;