~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/pci/quirks.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * $Id: quirks.c,v 1.5 1998/05/02 19:24:14 mj Exp $
  3  *
  4  *  This file contains work-arounds for many known PCI hardware
  5  *  bugs.  Devices present only on certain architectures (host
  6  *  bridges et cetera) should be handled in arch-specific code.
  7  *
  8  *  Copyright (c) 1999 Martin Mares <mj@suse.cz>
  9  *
 10  *  The bridge optimization stuff has been removed. If you really
 11  *  have a silly BIOS which is unable to set your host bridge right,
 12  *  use the PowerTweak utility (see http://powertweak.sourceforge.net).
 13  */
 14 
 15 #include <linux/types.h>
 16 #include <linux/kernel.h>
 17 #include <linux/pci.h>
 18 #include <linux/init.h>
 19 
 20 #undef DEBUG
 21 
 22 /* Deal with broken BIOS'es that neglect to enable passive release,
 23    which can cause problems in combination with the 82441FX/PPro MTRRs */
 24 static void __init quirk_passive_release(struct pci_dev *dev)
 25 {
 26         struct pci_dev *d = NULL;
 27         unsigned char dlc;
 28 
 29         /* We have to make sure a particular bit is set in the PIIX3
 30            ISA bridge, so we have to go out and find it. */
 31         while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
 32                 pci_read_config_byte(d, 0x82, &dlc);
 33                 if (!(dlc & 1<<1)) {
 34                         printk("PCI: PIIX3: Enabling Passive Release on %s\n", d->slot_name);
 35                         dlc |= 1<<1;
 36                         pci_write_config_byte(d, 0x82, dlc);
 37                 }
 38         }
 39 }
 40 
 41 /*  The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
 42     but VIA don't answer queries. If you happen to have good contacts at VIA
 43     ask them for me please -- Alan 
 44     
 45     This appears to be BIOS not version dependent. So presumably there is a 
 46     chipset level fix */
 47     
 48 
 49 int isa_dma_bridge_buggy;               /* Exported */
 50     
 51 static void __init quirk_isa_dma_hangs(struct pci_dev *dev)
 52 {
 53         if (!isa_dma_bridge_buggy) {
 54                 isa_dma_bridge_buggy=1;
 55                 printk(KERN_INFO "Activating ISA DMA hang workarounds.\n");
 56         }
 57 }
 58 
 59 int pci_pci_problems;
 60 
 61 /*
 62  *      Chipsets where PCI->PCI transfers vanish or hang
 63  */
 64 
 65 static void __init quirk_nopcipci(struct pci_dev *dev)
 66 {
 67         if((pci_pci_problems&PCIPCI_FAIL)==0)
 68         {
 69                 printk(KERN_INFO "Disabling direct PCI/PCI transfers.\n");
 70                 pci_pci_problems|=PCIPCI_FAIL;
 71         }
 72 }
 73 
 74 /*
 75  *      Triton requires workarounds to be used by the drivers
 76  */
 77  
 78 static void __init quirk_triton(struct pci_dev *dev)
 79 {
 80         if((pci_pci_problems&PCIPCI_TRITON)==0)
 81         {
 82                 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
 83                 pci_pci_problems|=PCIPCI_TRITON;
 84         }
 85 }
 86 
 87 /*
 88  *      VIA Apollo VP3 needs ETBF on BT848/878
 89  */
 90  
 91 static void __init quirk_viaetbf(struct pci_dev *dev)
 92 {
 93         if((pci_pci_problems&PCIPCI_VIAETBF)==0)
 94         {
 95                 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
 96                 pci_pci_problems|=PCIPCI_VIAETBF;
 97         }
 98 }
 99 
100 /*
101  *      Natoma has some interesting boundary conditions with Zoran stuff
102  *      at least
103  */
104  
105 static void __init quirk_natoma(struct pci_dev *dev)
106 {
107         if((pci_pci_problems&PCIPCI_NATOMA)==0)
108         {
109                 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
110                 pci_pci_problems|=PCIPCI_NATOMA;
111         }
112 }
113 
114 /*
115  *  S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
116  *  If it's needed, re-allocate the region.
117  */
118 
119 static void __init quirk_s3_64M(struct pci_dev *dev)
120 {
121         struct resource *r = &dev->resource[0];
122 
123         if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) {
124                 r->start = 0;
125                 r->end = 0x3ffffff;
126         }
127 }
128 
129 static void __init quirk_io_region(struct pci_dev *dev, unsigned region, unsigned size, int nr)
130 {
131         region &= ~(size-1);
132         if (region) {
133                 struct resource *res = dev->resource + nr;
134 
135                 res->name = dev->name;
136                 res->start = region;
137                 res->end = region + size - 1;
138                 res->flags = IORESOURCE_IO;
139                 pci_claim_resource(dev, nr);
140         }
141 }       
142 
143 /*
144  * Let's make the southbridge information explicit instead
145  * of having to worry about people probing the ACPI areas,
146  * for example.. (Yes, it happens, and if you read the wrong
147  * ACPI register it will put the machine to sleep with no
148  * way of waking it up again. Bummer).
149  *
150  * ALI M7101: Two IO regions pointed to by words at
151  *      0xE0 (64 bytes of ACPI registers)
152  *      0xE2 (32 bytes of SMB registers)
153  */
154 static void __init quirk_ali7101_acpi(struct pci_dev *dev)
155 {
156         u16 region;
157 
158         pci_read_config_word(dev, 0xE0, &region);
159         quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES);
160         pci_read_config_word(dev, 0xE2, &region);
161         quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1);
162 }
163 
164 /*
165  * PIIX4 ACPI: Two IO regions pointed to by longwords at
166  *      0x40 (64 bytes of ACPI registers)
167  *      0x90 (32 bytes of SMB registers)
168  */
169 static void __init quirk_piix4_acpi(struct pci_dev *dev)
170 {
171         u32 region;
172 
173         pci_read_config_dword(dev, 0x40, &region);
174         quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES);
175         pci_read_config_dword(dev, 0x90, &region);
176         quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1);
177 }
178 
179 /*
180  * VIA ACPI: One IO region pointed to by longword at
181  *      0x48 or 0x20 (256 bytes of ACPI registers)
182  */
183 static void __init quirk_vt82c586_acpi(struct pci_dev *dev)
184 {
185         u8 rev;
186         u32 region;
187 
188         pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
189         if (rev & 0x10) {
190                 pci_read_config_dword(dev, 0x48, &region);
191                 region &= PCI_BASE_ADDRESS_IO_MASK;
192                 quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES);
193         }
194 }
195 
196 /*
197  * VIA VT82C686 ACPI: Three IO region pointed to by (long)words at
198  *      0x48 (256 bytes of ACPI registers)
199  *      0x70 (128 bytes of hardware monitoring register)
200  *      0x90 (16 bytes of SMB registers)
201  */
202 static void __init quirk_vt82c686_acpi(struct pci_dev *dev)
203 {
204         u16 hm;
205         u32 smb;
206 
207         quirk_vt82c586_acpi(dev);
208 
209         pci_read_config_word(dev, 0x70, &hm);
210         hm &= PCI_BASE_ADDRESS_IO_MASK;
211         quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1);
212 
213         pci_read_config_dword(dev, 0x90, &smb);
214         smb &= PCI_BASE_ADDRESS_IO_MASK;
215         quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2);
216 }
217 
218 /*
219  * PIIX3 USB: We have to disable USB interrupts that are
220  * hardwired to PIRQD# and may be shared with an
221  * external device.
222  *
223  * Legacy Support Register (LEGSUP):
224  *     bit13:  USB PIRQ Enable (USBPIRQDEN),
225  *     bit4:   Trap/SMI On IRQ Enable (USBSMIEN).
226  *
227  * We mask out all r/wc bits, too.
228  */
229 static void __init quirk_piix3_usb(struct pci_dev *dev)
230 {
231         u16 legsup;
232 
233         pci_read_config_word(dev, 0xc0, &legsup);
234         legsup &= 0x50ef;
235         pci_write_config_word(dev, 0xc0, legsup);
236 }
237 
238 /*
239  * VIA VT82C598 has its device ID settable and many BIOSes
240  * set it to the ID of VT82C597 for backward compatibility.
241  * We need to switch it off to be able to recognize the real
242  * type of the chip.
243  */
244 static void __init quirk_vt82c598_id(struct pci_dev *dev)
245 {
246         pci_write_config_byte(dev, 0xfc, 0);
247         pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
248 }
249 
250 /*
251  *  The main table of quirks.
252  */
253 
254 static struct pci_fixup pci_fixups[] __initdata = {
255         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82441,      quirk_passive_release },
256         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82441,      quirk_passive_release },
257         /*
258          * Its not totally clear which chipsets are the problematic ones
259          * We know 82C586 and 82C596 variants are affected.
260          */
261         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C586_0,     quirk_isa_dma_hangs },
262         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C596,       quirk_isa_dma_hangs },
263         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371SB_0,  quirk_isa_dma_hangs },
264         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_S3,       PCI_DEVICE_ID_S3_868,           quirk_s3_64M },
265         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_S3,       PCI_DEVICE_ID_S3_968,           quirk_s3_64M },
266         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82437,      quirk_triton }, 
267         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82437VX,    quirk_triton }, 
268         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82439,      quirk_triton }, 
269         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82439TX,    quirk_triton }, 
270         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82441,      quirk_natoma }, 
271         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82443LX_0,  quirk_natoma }, 
272         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82443LX_1,  quirk_natoma }, 
273         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82443BX_0,  quirk_natoma }, 
274         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82443BX_1,  quirk_natoma }, 
275         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82443BX_2,  quirk_natoma },
276         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5597,          quirk_nopcipci },
277         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_496,           quirk_nopcipci },
278         { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C597_0,     quirk_viaetbf },
279         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C597_0,     quirk_vt82c598_id },
280         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C586_3,     quirk_vt82c586_acpi },
281         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C686_4,     quirk_vt82c686_acpi },
282         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371AB_3,  quirk_piix4_acpi },
283         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_AL,       PCI_DEVICE_ID_AL_M7101,         quirk_ali7101_acpi },
284         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371SB_2,  quirk_piix3_usb },
285         { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371AB_2,  quirk_piix3_usb },
286         { 0 }
287 };
288 
289 
290 static void pci_do_fixups(struct pci_dev *dev, int pass, struct pci_fixup *f)
291 {
292         while (f->pass) {
293                 if (f->pass == pass &&
294                     (f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
295                     (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
296 #ifdef DEBUG
297                         printk("PCI: Calling quirk %p for %s\n", f->hook, dev->slot_name);
298 #endif
299                         f->hook(dev);
300                 }
301                 f++;
302         }
303 }
304 
305 void pci_fixup_device(int pass, struct pci_dev *dev)
306 {
307         pci_do_fixups(dev, pass, pcibios_fixups);
308         pci_do_fixups(dev, pass, pci_fixups);
309 }
310 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.