On 5/22/15, 08:00, "Mark Salter" msalter@redhat.com wrote:
On Fri, 2015-05-22 at 19:09 +0800, Hanjun Guo wrote:
On 2015年05月22日 01:12, Suravee Suthikulanit wrote:
On 5/21/2015 8:57 AM, Hanjun Guo wrote:
On 2015年05月21日 21:01, Mark Salter wrote:
On Wed, 2015-05-20 at 17:19 -0500, Suravee Suthikulpanit wrote:
Current logic does not parse the _PRT object inside the DSDT of PCI host bridge, and result in failing to route PCI legacy interrupt. This patch
adds
the logic to do so.
In what way is it not parsed already? This is all code used by other architectures isn't it? I think the code expects firmware to set up the _PRT for each device/slot. That seems to be the intent in acpi_pci_irq_check_entry() where device id is checked:
if (((prt->address >> 16) & 0xffff) != device || prt->pin + 1 != pin) return -ENODEV;
Yes, I doubt it too, may be the handle of the bridge is NULL?
Could you please try the debug info below and see if I'm right?
So, here is the PCI topology:
# lspci -tv -[0000:00]-+-00.0 Host bridge +-02.0 .... -02.1- PCI-PCI bridge - [01]----00.0 End-point Device
Here is the _PRT from the ACPI table: // // PCIe Root bus // Device (PCI0) { Name (_HID, "PNP0A08") // PCI Express Root Bridge Name (_CID, "PNP0A03") // Compatible PCI Root Bridge Name(_SEG, 0) // Segment of this Root complex Name(_BBN, 0) // Base Bus Number Name (_CCA, 1) // Cache-coherent bus
Name(_PRT, Package(4) { // PCI Routing Table Package(4) {0x000000FFFF, 0, 0, 320}, // A Package(4) {0x000000FFFF, 1, 0, 321}, // B Package(4) {0x000000FFFF, 2, 0, 322}, // C Package(4) {0x000000FFFF, 3, 0, 323} // D })
Here is the debug trace:
[ 7.295381] DEBUG0: acpi_pci_irq_lookup: CHECK DEV : 0000:01:00.0 [ 7.300160] DEBUG: acpi_pci_irq_find_prt_entry: pci=0000:01:00.0: bus=1, bridge=0000:00:02.1, handle=( (null)) [ 7.309716] DEBUG1: acpi_pci_irq_lookup: CHECK BRIDGE :
0000:00:02.1
[ 7.314759] DEBUG: acpi_pci_irq_find_prt_entry: pci=0000:00:02.1: bus=0, bridge=pci0000:00, handle=_SB_.PCI0(fffffe03f3140c80) [ 7.324938] pci 0000:00:02.1: can't derive routing for PCI INT A [ 7.329629] tg3 0000:01:00.0: PCI INT A: no GSI
When the code is calling acpi_pci_irq_find_prt_entry(), we are passing the bridge device (i.e. Device 0:2.1) into the acpi_pci_irq_find_prt_entry(). Here, the logic is trying to match deviceID (2) and pin in the PRT entries above, and it failed to match.
However, the patch I submitted tries to match for device 0 (i.e. the host bridge itself), which now that I think more about it, the _PRT table might not be programmed properly. I am also trying to
cross-check
if this is how the _PRT is supposed to be programmed. The alternative table would probably be:
Name(_PRT, Package(4) { // PCI Routing Table Package(4) {0x000002FFFF, 0, 0, 320}, // A Package(4) {0x000002FFFF, 1, 0, 321}, // B Package(4) {0x000002FFFF, 2, 0, 322}, // C Package(4) {0x000002FFFF, 3, 0, 323} // D })
Thanks for debugging this, so that's because of the bridge device (parent of endpoint) ID (02) is not match the device ID of host bridge (00), I think the PRT is wrong, not the kernel code itself.
And just FYI, on my x86 desktop, the _PRT has entries for every individual PCI device, not just bridges.