x86: early_quirk check all bus/dev/func in domain 0
PATCH 1/1 x86: early_quirk check all bus/dev/func in domain 0
When we have 00:1a.0, 00:1a.1, 00:1a.2, 00:1a.7
Found only 00:1a.0, and 00:1a.1 get processed. and 00:1a.2 and 00:1a.7 get skipped.
We should only check header type on func0.
Also should not bail out when have gap.
At last try to process bus 00 - 0xff instead of only bus 00.
-v2: check with VENDOR_ID instead of CLASS_DEVICE for invalid device.
--- arch/x86/kernel/early-quirks.c | 44 +++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-)
arch/x86/kernel/early-quirks.c +25 -19
@@ -234,20 +234,22 @@ static struct chipset early_qrk[] __init*/ static int __init check_dev_quirk (int num,int slot,int func) { +u32 l;u16 class;u16 vendor;u16 device;u8 type;int i; - class =read_pci_config_16 (num, slot, func,PCI_CLASS_DEVICE ); - -if (class ==0xffff ) -return -1 ;/* no class, treat as single function */ - - vendor =read_pci_config_16 (num, slot, func,PCI_VENDOR_ID ); + l =read_pci_config (num, slot, func,PCI_VENDOR_ID ); +/* some broken boards return 0 or ~0 if a slot is empty: */ +if (l ==0xffffffff || l ==0x00000000 || + l ==0x0000ffff || l ==0xffff0000 ) +return 0 ; - device =read_pci_config_16 (num, slot, func,PCI_DEVICE_ID ); + class =read_pci_config_16 (num, slot, func,PCI_CLASS_DEVICE ); + vendor = l &0xffff ; + device = l >>16 ;for (i =0 ; early_qrk[i].f !=NULL ; i++) { if (((early_qrk[i].vendor == PCI_ANY_ID) ||
@@ -263,27 +265,31 @@ static int __init check_dev_quirk(int nu } } - type =read_pci_config_byte (num, slot, func, -PCI_HEADER_TYPE ); -if (!(type &0x80 )) -return -1 ; +/* only check header type on func 0 */ +if (func ==0 ) { + type =read_pci_config_byte (num, slot, func, +PCI_HEADER_TYPE ); +if (!(type &0x80 )) +return -1 ; + }return 0 ; }void __init early_quirks (void ) { -int slot, func; +int num, slot, func;if (!early_pci_allowed ())return ;/* Poor man's PCI discovery */ -/* Only scan the root bus */ -for (slot =0 ; slot <32 ; slot++) -for (func =0 ; func <8 ; func++) { -/* Only probe function 0 on single fn devices */ -if (check_dev_quirk (0 , slot, func)) -break ; - } +/* Only can scan first domain */ +for (num =0 ; num <256 ; num++) +for (slot =0 ; slot <32 ; slot++) +for (func =0 ; func <8 ; func++) { +/* Only probe func 0 on single fn devices */ +if (check_dev_quirk (num, slot, func)) +break ; + } }
Quoted 4 lines · On Mon, 07 Feb 2011 14:14:52 -0800 Yinghai Lu <[email protected]> wrote:
When we have 00:1a.0, 00:1a.1, 00:1a.2, 00:1a.7
Found only 00:1a.0, and 00:1a.1 get processed. and 00:1a.2 and 00:1a.7 get skipped.
Quoted 8 lines
We should only check header type on func0.
Also should not bail out when have gap.At last try to process bus 00 -
0xffinstead of only bus 00.-v2: check with
VENDOR_IDinstead ofCLASS_DEVICEfor invalid device.Signed-off-by Yinghai Lu <[email protected]>
I need a much better changelog here. It sounds (and looks) like the patch is doing several things:
- processing more than the first two functions on a device
- processing the full set of busses in the first domain
- checking for nonexistent devices
Why are you making these changes? Do you have a system that needs early quirks but violates the existing assumptions? Can you apply a standard quirk instead?
Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center