add back NCR53c810 PCI quirk code from davej that was lost in the merge
[opensuse:kernel.git] / arch / i386 / kernel / pci / fixup.c
1 /*
2  * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
3  */
4
5 #include <linux/pci.h>
6 #include "pci.h"
7
8
9 static void __devinit pci_fixup_i450nx(struct pci_dev *d)
10 {
11         /*
12          * i450NX -- Find and scan all secondary buses on all PXB's.
13          */
14         int pxb, reg;
15         u8 busno, suba, subb;
16
17         printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", d->slot_name);
18         reg = 0xd0;
19         for(pxb=0; pxb<2; pxb++) {
20                 pci_read_config_byte(d, reg++, &busno);
21                 pci_read_config_byte(d, reg++, &suba);
22                 pci_read_config_byte(d, reg++, &subb);
23                 DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
24                 if (busno)
25                         pci_scan_bus(busno, pci_root_ops, NULL);        /* Bus A */
26                 if (suba < subb)
27                         pci_scan_bus(suba+1, pci_root_ops, NULL);       /* Bus B */
28         }
29         pcibios_last_bus = -1;
30 }
31
32 static void __devinit pci_fixup_i450gx(struct pci_dev *d)
33 {
34         /*
35          * i450GX and i450KX -- Find and scan all secondary buses.
36          * (called separately for each PCI bridge found)
37          */
38         u8 busno;
39         pci_read_config_byte(d, 0x4a, &busno);
40         printk(KERN_WARNING "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", d->slot_name, busno);
41         pci_scan_bus(busno, pci_root_ops, NULL);
42         pcibios_last_bus = -1;
43 }
44
45 static void __devinit  pci_fixup_umc_ide(struct pci_dev *d)
46 {
47         /*
48          * UM8886BF IDE controller sets region type bits incorrectly,
49          * therefore they look like memory despite of them being I/O.
50          */
51         int i;
52
53         printk(KERN_WARNING "PCI: Fixing base address flags for device %s\n", d->slot_name);
54         for(i=0; i<4; i++)
55                 d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
56 }
57
58 static void __devinit  pci_fixup_ncr53c810(struct pci_dev *d)
59 {
60         /*
61          * NCR 53C810 returns class code 0 (at least on some systems).
62          * Fix class to be PCI_CLASS_STORAGE_SCSI
63          */
64         if (!d->class) {
65                 printk(KERN_WARNING "PCI: fixing NCR 53C810 class code for %s\n", d->slot_name);
66                 d->class = PCI_CLASS_STORAGE_SCSI << 8;
67         }
68 }
69
70 static void __devinit pci_fixup_ide_bases(struct pci_dev *d)
71 {
72         int i;
73
74         /*
75          * PCI IDE controllers use non-standard I/O port decoding, respect it.
76          */
77         if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
78                 return;
79         DBG("PCI: IDE base address fixup for %s\n", d->slot_name);
80         for(i=0; i<4; i++) {
81                 struct resource *r = &d->resource[i];
82                 if ((r->start & ~0x80) == 0x374) {
83                         r->start |= 2;
84                         r->end = r->start;
85                 }
86         }
87 }
88
89 static void __devinit  pci_fixup_ide_trash(struct pci_dev *d)
90 {
91         int i;
92
93         /*
94          * There exist PCI IDE controllers which have utter garbage
95          * in first four base registers. Ignore that.
96          */
97         DBG("PCI: IDE base address trash cleared for %s\n", d->slot_name);
98         for(i=0; i<4; i++)
99                 d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
100 }
101
102 static void __devinit  pci_fixup_latency(struct pci_dev *d)
103 {
104         /*
105          *  SiS 5597 and 5598 chipsets require latency timer set to
106          *  at most 32 to avoid lockups.
107          */
108         DBG("PCI: Setting max latency to 32\n");
109         pcibios_max_latency = 32;
110 }
111
112 static void __devinit pci_fixup_piix4_acpi(struct pci_dev *d)
113 {
114         /*
115          * PIIX4 ACPI device: hardwired IRQ9
116          */
117         d->irq = 9;
118 }
119
120 /*
121  * Addresses issues with problems in the memory write queue timer in
122  * certain VIA Northbridges.  This bugfix is per VIA's specifications.
123  *
124  * VIA 8363,8622,8361 Northbridges:
125  *  - bits  5, 6, 7 at offset 0x55 need to be turned off
126  * VIA 8367 (KT266x) Northbridges:
127  *  - bits  5, 6, 7 at offset 0x95 need to be turned off
128  */
129 static void __init pci_fixup_via_northbridge_bug(struct pci_dev *d)
130 {
131         u8 v;
132         int where = 0x55;
133
134         if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
135                 where = 0x95; /* the memory write queue timer register is 
136                                  different for the kt266x's: 0x95 not 0x55 */
137         }
138
139         pci_read_config_byte(d, where, &v);
140         if (v & 0xe0) {
141                 printk(KERN_WARNING "Disabling broken memory write queue: [%02x] %02x->%02x\n",
142                         where, v, v & 0x1f);
143                 v &= 0x1f; /* clear bits 5, 6, 7 */
144                 pci_write_config_byte(d, where, v);
145         }
146 }
147
148 struct pci_fixup pcibios_fixups[] = {
149         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82451NX,    pci_fixup_i450nx },
150         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82454GX,    pci_fixup_i450gx },
151         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_UMC,      PCI_DEVICE_ID_UMC_UM8886BF,     pci_fixup_umc_ide },
152         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5513,          pci_fixup_ide_trash },
153         { PCI_FIXUP_HEADER,     PCI_ANY_ID,             PCI_ANY_ID,                     pci_fixup_ide_bases },
154         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5597,          pci_fixup_latency },
155         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5598,          pci_fixup_latency },
156         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371AB_3,  pci_fixup_piix4_acpi },
157         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8363_0,       pci_fixup_via_northbridge_bug },
158         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8622,         pci_fixup_via_northbridge_bug },
159         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8361,         pci_fixup_via_northbridge_bug },
160         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8367_0,       pci_fixup_via_northbridge_bug },
161         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_NCR,      PCI_DEVICE_ID_NCR_53C810,       pci_fixup_ncr53c810 },
162         { 0 }
163 };