MPT Fusion SCSI drives no longer appear - suspect PCI bus scan bug
A message that is not in the archive (sent off-list or not yet received): [email protected]/
A message that is not in the archive (sent off-list or not yet received): [email protected]
Bjorn Helgaas
maintainerQuoted 1 line
I do still plan to work on bisecting this.
Can you also attach a dmesg log from a current kernel, e.g., 3.4 or newer? We now print a lot more information during PCI enumeration.
But I guess the problem is that 2.6.26 finds devices in domains 1 and 2, while 2.6.32 does not. I think MMCONFIG is the only config access method we have for domains other than 0. That suggests that MMCONFIG used to work but doesn't any more. The dmesg logs claim that we're not using MMCONFIG in either 2.6.26 or 2.6.32 though, so I don't know why we found anything in 2.6.26.
Quoted 11 lines · Bjorn Helgaas
Quoted 1 line
I do still plan to work on bisecting this.
Can you also attach a dmesg log from a current kernel, e.g., 3.4 or newer? We now print a lot more information during PCI enumeration.
But I guess the problem is that 2.6.26 finds devices in domains 1 and 2, while 2.6.32 does not. I think MMCONFIG is the only config access method we have for domains other than 0. That suggests that MMCONFIG used to work but doesn't any more. The dmesg logs claim that we're not using MMCONFIG in either 2.6.26 or 2.6.32 though, so I don't know why we found anything in 2.6.26.
in short: the bios is broken, it return wrong segment in DSDT.
in both case, only pci_conf1 is used. CPU is not new enough.
after comparing the code 2.6.26 and 2.6.32. 2.6.26 is not checking seg in pci_conf1_read. but 2.6.32 check that...
2.6.26:
static int pci_conf1_read(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 *value)
{
unsigned long flags;
if ((bus > 255) || (devfn > 255) || (reg > 255)) {
*value = -1;
return -EINVAL;
}2.6.32
20 static int pci_conf1_read(unsigned int seg, unsigned int bus,
21 unsigned int devfn, int reg, int len, u32 *value)
22 {
23 unsigned long flags;
24
25 if (seg || (bus > 255) || (devfn > 255) || (reg > 4095)) {
26 *value = -1;
27 return -EINVAL;28 }
so it happens to work on 2.6.26.
please get to get new BIOS from your vendor.
or you need to override your DSDT.
Thanks
Yinghai
Bjorn Helgaas
maintainerQuoted 1 line
in short: the bios is broken, it return wrong segment in DSDT.
I *think* what Yinghai is saying is:
- MMCONFIG is not used either in 2.6.26 or 2.6.32.
- BIOS reports these host bridges via DSDT PNP0A08 devices:
[PCI0] leading to segment 0000 bus 00
[PCI1] leading to segment 0001 bus 40
[PCI2] leading to segment 0002 bus 80
- Buses 40 and 80 are actually in segment 0, not segments 1 and 2.
- When we enumerate bus 40 and bus 80, we pass seg=1 and seg=2,
respectively, to pci_conf1_read(), but 2.6.26 ignores seg. For example, when we think we're reading 0001:40:01.0 config space, 2.6.26 actually reads 0000:40:01.0 config space instead.
- In 2.6.32, instead of ignoring seg, we return an error if it is
not zero. Therefore, we fail to find anything on bus 40 and bus 80.
Sean, what system and BIOS version is this? (The 3.4.x dmesg log or the "dmidecode" output will contain this information.) I don't expect HP to change the BIOS, and it wouldn't be reasonable to require users to debug this issue and upgrade their BIOS in any case.
But I would like to read the release notes or help text that mentions this issue. If all the buses were in fact in segment 0, the DSDT would typically not have any _SEG methods at all, because segment 0 is the default. Yinghai is assuming that HP went to the trouble to *add* _SEG methods that returned incorrect values. But the fact that HP was aware of the issue and provided the BIOS "disable ACPI bus segmentation" option makes it less likely that this is the case.
Also, the system was very likely tested with Windows, and the fact that the BIOS option is to *disable* segmentation suggests that the default is "segmentation enabled." So my guess is that segmentation does work with Windows. Sean, can you confirm or deny that? The AIDA64 tool (free trial version at http://www.aida64.com/) generates a report with useful information.
I agree with Jonathan's assertion here:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=543308#87 that the BIOS switch is not adequate. Neither is a patched DSDT.
I think it's likely that Windows works with segmentation, using MMCONFIG, and that Linux is a bit too quick to disable MMCONFIG in this case.