usb/hcd: irq 18: nobody cared
Subsystems (5)
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320 [ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18
Quoted 1 line
From earlier in the boot log:
[ 1.297020] uhci_hcd 0000:00:1d.2: setting latency timer to 64 [ 1.297032] uhci_hcd 0000:00:1d.2: UHCI Host Controller [ 1.297040] uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4 [ 1.297076] uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000ff40 [ 1.297213] hub 4-0:1.0: USB hub found [ 1.297221] hub 4-0:1.0: 2 ports detected
lsusb:
...
Bus 004 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS Bus 004 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
...
Didn't have this problem with -next-20120125. One of these commits, maybe? next/drivers/usb/core$ git log --oneline next-20130125..next-20130204 -- * 2c2e865 usb: forbid memory allocation with I/O during bus reset e9121a8 Merge remote-tracking branch 'usb/usb-next'
3b2ab2b Revert "usb: Register usb port's acpi power resources" da0aa71 USB: add usb_hcd_{start,end}_port_resume
192fef1 usb: enable usb port device's async suspend.
f6cced1 usb: expose usb port's pm qos flags to user space
ad493e5 usb: add usb port auto power off mechanism
971fcd4 usb: add runtime pm support for usb port device
88bb965 usb: Register usb port's acpi power resources
54a3ac0 usb: Using correct way to clear usb3.0 device's remote wakeup feature.
I didn't see any changes in the drivers/hid/hid-logitech-dj.c or usbhid but maybe it's doing something wrong anyway?
I'll open a bugzilla if a bunch more info is necessary.
Regards,
Peter Hurley
Quoted 37 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320 [ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18From earlier in the boot log:
[ 1.297020] uhci_hcd 0000:00:1d.2: setting latency timer to 64 [ 1.297032] uhci_hcd 0000:00:1d.2: UHCI Host Controller [ 1.297040] uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4 [ 1.297076] uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000ff40 [ 1.297213] hub 4-0:1.0: USB hub found [ 1.297221] hub 4-0:1.0: 2 ports detectedlsusb:
...
Bus 004 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS Bus 004 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
...
Quoted 12 lines
Didn't have this problem with -next-20120125. One of these commits, maybe? next/drivers/usb/core$ git log --oneline next-20130125..next-20130204 -- * 2c2e865 usb: forbid memory allocation with I/O during bus reset e9121a8 Merge remote-tracking branch 'usb/usb-next'
3b2ab2b Revert "usb: Register usb port's acpi power resources" da0aa71 USB: add usb_hcd_{start,end}_port_resume
192fef1 usb: enable usb port device's async suspend.
f6cced1 usb: expose usb port's pm qos flags to user space
ad493e5 usb: add usb port auto power off mechanism
971fcd4 usb: add runtime pm support for usb port device
88bb965 usb: Register usb port's acpi power resources
54a3ac0 usb: Using correct way to clear usb3.0 device's remote wakeup feature.
None of those commits seems likely to have caused the problem. The most likely is da0aa71, combined with one you didn't mention:
840008bb USB: UHCI: notify usbcore about port resumes
If you revert these two commits, does that make any difference? What if you revert all of these commits?
Quoted 4 lines
I didn't see any changes in the
drivers/hid/hid-logitech-dj.cor usbhid but maybe it's doing something wrong anyway?I'll open a bugzilla if a bunch more info is necessary.
If the suggestion above doesn't work out, bisection may be the best way to find the answer.
Alan Stern
Quoted 52 lines · Alan Stern
Quoted 37 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320 [ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18From earlier in the boot log:
[ 1.297020] uhci_hcd 0000:00:1d.2: setting latency timer to 64 [ 1.297032] uhci_hcd 0000:00:1d.2: UHCI Host Controller [ 1.297040] uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4 [ 1.297076] uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000ff40 [ 1.297213] hub 4-0:1.0: USB hub found [ 1.297221] hub 4-0:1.0: 2 ports detectedlsusb:
...
Bus 004 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS Bus 004 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
...Quoted 12 lines
Didn't have this problem with -next-20120125. One of these commits, maybe? next/drivers/usb/core$ git log --oneline next-20130125..next-20130204 -- * 2c2e865 usb: forbid memory allocation with I/O during bus reset e9121a8 Merge remote-tracking branch 'usb/usb-next'
3b2ab2b Revert "usb: Register usb port's acpi power resources" da0aa71 USB: add usb_hcd_{start,end}_port_resume
192fef1 usb: enable usb port device's async suspend.
f6cced1 usb: expose usb port's pm qos flags to user space
ad493e5 usb: add usb port auto power off mechanism
971fcd4 usb: add runtime pm support for usb port device
88bb965 usb: Register usb port's acpi power resources
54a3ac0 usb: Using correct way to clear usb3.0 device's remote wakeup feature.
Quoted 7 lines
None of those commits seems likely to have caused the problem. The most likely is da0aa71, combined with one you didn't mention:
840008bbUSB: UHCI: notify usbcore about port resumesIf you revert these two commits, does that make any difference? What if you revert all of these commits?
None of these commits are directly causing this. I tested Greg's usb master and usb-next and both run fine for me.
Quoted 7 lines
Quoted 4 lines
I didn't see any changes in the
drivers/hid/hid-logitech-dj.cor usbhid but maybe it's doing something wrong anyway?I'll open a bugzilla if a bunch more info is necessary.
If the suggestion above doesn't work out, bisection may be the best way to find the answer.
Any pointers on how to one of) build a linear history for -next, get bisect to work on an integration tree, or third option I haven't thought of?
Thanks,
Peter Hurley
Peter Hurley
Acked-by Rafael J. WysockiQuoted 37 lines · Alan Stern
Quoted 35 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320 [ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18From earlier in the boot log:
[ 1.297020] uhci_hcd 0000:00:1d.2: setting latency timer to 64 [ 1.297032] uhci_hcd 0000:00:1d.2: UHCI Host Controller [ 1.297040] uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4 [ 1.297076] uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000ff40 [ 1.297213] hub 4-0:1.0: USB hub found [ 1.297221] hub 4-0:1.0: 2 ports detectedlsusb:
...
Bus 004 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS Bus 004 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
[...]
Quoted 2 lines
If the suggestion above doesn't work out, bisection may be the best way to find the answer.
This bad irq bisected to:
4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4 is the first bad commit commit 4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
Author: Yinghai Lu <[email protected]> Date: Mon Jan 21 13:20:52 2013 -0800
PCI: Put pci_dev in device tree as early as possible
We want to put pci_dev structs in the device tree as soon as possible so for_each_pci_dev() iteration will not miss them, but driver attachment needs to be delayed until after pci_assign_unassigned_resources() to make sure all devices have resources assigned first.
This patch moves device registering from pci_bus_add_devices() to pci_device_add(), which happens earlier, leaving driver attachment in pci_bus_add_devices().
It also removes unattached child bus handling in pci_bus_add_devices(). That's not needed because child bus via pci_add_new_bus() is already in parent bus children list.
:040000 040000 0540c98d04d00de24b4e12fa750f6cd26c5addd2 2e24946cb7165a4028b7efb0a622271cc3990005 M drivers
All is fine if I revert these 2 commits:
40064ac PCI: Remove unused "rc" in virtfn_add_bus()
4f53509 (HEAD, refs/bisect/bad) PCI: Put pci_dev in device tree as early as possible
Any ideas how these are causing the USB HCD core / hid-logitech-dj driver to drop interrupts?
Regards,
Peter Hurley
Quoted 73 lines · Peter Hurley
Quoted 37 lines · Alan Stern
Quoted 35 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320 [ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18From earlier in the boot log:
[ 1.297020] uhci_hcd 0000:00:1d.2: setting latency timer to 64 [ 1.297032] uhci_hcd 0000:00:1d.2: UHCI Host Controller [ 1.297040] uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4 [ 1.297076] uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000ff40 [ 1.297213] hub 4-0:1.0: USB hub found [ 1.297221] hub 4-0:1.0: 2 ports detectedlsusb:
...
Bus 004 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS Bus 004 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver[...]
Quoted 2 lines
If the suggestion above doesn't work out, bisection may be the best way to find the answer.
This bad irq bisected to:
4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4is the first bad commit commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4Author: Yinghai Lu <[email protected]> Date: Mon Jan 21 13:20:52 2013 -0800PCI: Put
pci_devin device tree as early as possibleWe want to put
pci_devstructs in the device tree as soon as possible sofor_each_pci_dev()iteration will not miss them, but driver attachment needs to be delayed until afterpci_assign_unassigned_resources()to make sure all devices have resources assigned first.This patch moves device registering from
pci_bus_add_devices()topci_device_add(), which happens earlier, leaving driver attachment inpci_bus_add_devices().It also removes unattached child bus handling in
pci_bus_add_devices(). That's not needed because child bus viapci_add_new_bus()is already in parent bus children list.[bhelgaas: changelog]Signed-off-by Yinghai Lu <[email protected]>Signed-off-by Bjorn Helgaas <[email protected]>:040000 040000
0540c98d04d00de24b4e12fa750f6cd26c5addd22e24946cb7165a4028b7efb0a622271cc3990005M drivers
Quoted 7 lines
All is fine if I revert these 2 commits:
40064ac PCI: Remove unused "rc" in
virtfn_add_bus()
4f53509 (HEAD, refs/bisect/bad) PCI: Putpci_devin device tree as early as possibleAny ideas how these are causing the USB HCD core / hid-logitech-dj driver to drop interrupts?
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
peter@thor:~/src/kernels/next$ git log --oneline next-20130125..next-20130204 | grep -i acpi 65d6ce7 Merge remote-tracking branch 'acpi/next' 0d50e8c Merge branch 'acpi-pm-next' into linux-next be6d286 PCI: acpiphp: Remove dead code for PCI host bridge hotplug 4b794a0 Merge branch 'acpi-assorted' into linux-next bd3e4a3 Merge branch 'acpi-cleanup' into linux-next 02df734 ACPI / dock: Fix acpi_bus_get_device() check in drivers/acpi/dock.c 7217dac Merge branch 'acpi-lpss' into linux-next 4bede3f Merge branch 'acpi-pm' into linux-next cc0755b Merge branch 'acpica' into linux-next 308b10d Merge branch 'acpi-scan' into linux-next 2ca344e PCI: acpiphp: Create companion ACPI devices before creating PCI devices 741220e cpufreq: Make acpi-cpufreq link first c40a451 acpi-cpufreq: Do not load on K8 b378549 ACPI / PM: Do not power manage devices in unknown initial states cfc5755 PNPACPI: Fix acpi_bus_get_device() check in drivers/pnp/pnpacpi/core.c dde3bb4 ACPI / PM: Fix acpi_bus_get_device() check in drivers/acpi/device_pm.c 456de89 ACPI / scan: Clean up acpi_bus_get_parent() 0613e1f ACPI / scan: Fix acpi_bus_get_device() check in acpi_match_device() 141a297 ACPI / platform: Use struct acpi_scan_handler for creating devices 4daeaf6 ACPI / PCI: Make PCI IRQ link driver use struct acpi_scan_handler 00c43b9 ACPI / PCI: Make PCI root driver use struct acpi_scan_handler ca589f9 ACPI / scan: Introduce struct acpi_scan_handler 3b2ab2b Revert "usb: Register usb port's acpi power resources" 8b4e2fa Merge branch 'acpi-lpss' into acpi-cleanup 64e94e7 Merge branch 'acpi-scan' into acpi-cleanup 2c0d4fe ACPI / scan: Make scanning of fixed devices follow the general scheme 8a78cf7 Merge branch 'acpi-pm' into acpi-cleanup 0d1c28a gpiolib-acpi: Add ACPI5 event model support to gpio. 65ab96f ACPI / PM: Fix /proc/acpi/wakeup for devices w/o bus or parent c511cc1 ACPI / scan: Make namespace scanning and trimming mutually exclusive fb45579 Merge branch 'pci/acpi-scan2' into next 09212fd ACPI: Drop device start operation that is not used 51fac83 ACPI: Remove useless type argument of driver .remove() operation cc38e51 Merge branch 'acpi-scan' into acpi-cleanup 5baa1be ACPI: fix obsolete comment in custom_method.c ca4e713 ACPI / thermal: Use mode to enable/disable kernel thermal processing 7e3cf24 ACPI thermal: remove unnecessary newline from exception message c628423 ACPI sysfs: remove unnecessary newline from exception bf6787e ACPI video: remove unnecessary newline from error messages 208f6cc ACPI: SRAT: report non-volatile memory in debug 33f767d ACPI: Rework acpi_get_child() to be more efficient bfee26d ACPI / scan: Make it clear that acpi_bus_trim() cannot fail d59f53b PCI: acpiphp: Keep driver loaded even if no slots found 121b090 PCI/ACPI: Print info if host bridge notify handler installation fails 668192b PCI: acpiphp: Move host bridge hotplug to pci_root.c 92d8aff PCI/ACPI: acpiphp: Rename alloc_acpiphp_hp_work() to alloc_acpi_hp_work() 660b111 ACPI / PM: Fix consistency check for power resources during resume 18a3870 ACPI / PM: Expose lists of device power resources to user space 1f96a96 PCI: acpiphp: Add is_hotplug_bridge detection a276660 Merge branch 'acpi-scan' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm into pci/acpi-scan2 88bb965 usb: Register usb port's acpi power resources 2171953 ACPICA: Update version to 20130117 378bb8b ACPICA: Update predefined info table for _MLS method 5e30a96 ACPICA: Remove some extraneous newlines in ACPI_ERROR type calls d9652b4 ACPICA: iASL/Disassembler: Add option to ignore NOOP opcodes/operators 48ffb94 ACPICA: AcpiGetSleepTypeData: Allow \_Sx to return either 1 or 2 integers 25f044e ACPICA: Update ACPICA copyrights to 2013 586ce51 ACPICA: Update predefined info table afd51a0 x86/acpi: Use __pa_symbol instead of __pa on C visible symbols
Regards,
Peter Hurley
Quoted 79 lines · Peter Hurley
Quoted 78 lines · Peter Hurley
Quoted 37 lines · Alan Stern
Quoted 35 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320 [ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18From earlier in the boot log:
[ 1.297020] uhci_hcd 0000:00:1d.2: setting latency timer to 64 [ 1.297032] uhci_hcd 0000:00:1d.2: UHCI Host Controller [ 1.297040] uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4 [ 1.297076] uhci_hcd 0000:00:1d.2: irq 18, io base 0x0000ff40 [ 1.297213] hub 4-0:1.0: USB hub found [ 1.297221] hub 4-0:1.0: 2 ports detectedlsusb:
...
Bus 004 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS Bus 004 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver[...]
Quoted 2 lines
If the suggestion above doesn't work out, bisection may be the best way to find the answer.
This bad irq bisected to:
4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4is the first bad commit commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4Author: Yinghai Lu <[email protected]> Date: Mon Jan 21 13:20:52 2013 -0800PCI: Put
pci_devin device tree as early as possibleWe want to put
pci_devstructs in the device tree as soon as possible sofor_each_pci_dev()iteration will not miss them, but driver attachment needs to be delayed until afterpci_assign_unassigned_resources()to make sure all devices have resources assigned first.This patch moves device registering from
pci_bus_add_devices()topci_device_add(), which happens earlier, leaving driver attachment inpci_bus_add_devices().It also removes unattached child bus handling in
pci_bus_add_devices(). That's not needed because child bus viapci_add_new_bus()is already in parent bus children list.[bhelgaas: changelog]Signed-off-by Yinghai Lu <[email protected]>Signed-off-by Bjorn Helgaas <[email protected]>:040000 040000
0540c98d04d00de24b4e12fa750f6cd26c5addd22e24946cb7165a4028b7efb0a622271cc3990005M driversAll is fine if I revert these 2 commits:
40064ac PCI: Remove unused "rc" in
virtfn_add_bus()
4f53509 (HEAD, refs/bisect/bad) PCI: Putpci_devin device tree as early as possible
Quoted 7 lines
Quoted 2 lines
Any ideas how these are causing the USB HCD core / hid-logitech-dj driver to drop interrupts?
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 0
0 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4
v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4, snd_ctxfi
These messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5
...
acpi_pci_irq_add_prt() add wrong bus for that bridge, because that that bridge is not scanned.
Will check if I can produce one patch for it.
Thanks
Yinghai
Quoted 46 lines · Yinghai Lu
Quoted 27 lines · Peter Hurley
Quoted 18 lines · Peter Hurley
Quoted 17 lines · Alan Stern
Quoted 15 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
[ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18Quoted 4 lines
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 00 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4,snd_ctxfiThese messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.
Quoted 8 lines
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5...
acpi_pci_irq_add_prt()add wrong bus for that bridge, because that that bridge is not scanned.Will check if I can produce one patch for it.
Hi Peter,
Can you try attached debug patch?
Thanks
Yinghai
drivers/pci/bus.c +5 -0
@@ -160,6 +160,8 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,void __weak pcibios_resource_survey_bus (struct pci_bus *bus) { } +void __weak pcibios_irq_setup (struct device *dev) { } +/** * pci_bus_add_device - start driver for a single device * @dev: device to add
@@ -170,6 +172,9 @@ int pci_bus_add_device(struct pci_dev *dev) {int retval; +/* need to after bridge is scanned */ +pcibios_irq_setup (&dev->dev); +/* * Can not put in pci_device_add yet because resources * are not assigned yet for some devices.
drivers/pci/pci-acpi.c +11 -2
@@ -302,14 +302,16 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)return 0 ; } -static void pci_acpi_setup (struct device *dev) +void pcibios_irq_setup (struct device *dev) {struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev); -struct acpi_device *adev;acpi_status status;acpi_handle dummy; +if (acpi_disabled || acpi_pci_disabled) +return ; +/* * Evaluate and parse _PRT, if exists. This code allows parsing of * _PRT objects within the scope of non-bridge devices. Note that
@@ -326,6 +328,13 @@ static void pci_acpi_setup(struct device *dev) pci_dev->subordinate->number : pci_dev->bus->number;acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); } +} + +static void pci_acpi_setup (struct device *dev) +{ +struct pci_dev *pci_dev =to_pci_dev (dev); +acpi_handle handle =ACPI_HANDLE (dev); +struct acpi_device *adev;if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;
Quoted 1 line · Yinghai Lu
Can you try attached debug patch?
FWIW this fixes it for me. No more 'derived' or 'nobody' in dmesg.
thanks,
Signature · 2 lines
js suse labs
Quoted 51 lines · Yinghai Lu
Quoted 50 lines · Yinghai Lu
Quoted 27 lines · Peter Hurley
Quoted 18 lines · Peter Hurley
Quoted 17 lines · Alan Stern
Quoted 15 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
[ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18Quoted 4 lines
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 00 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4,snd_ctxfiThese messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5...
Quoted 8 lines
Quoted 4 lines
acpi_pci_irq_add_prt()add wrong bus for that bridge, because that that bridge is not scanned.Will check if I can produce one patch for it.
Hi Peter,
Can you try attached debug patch?
Fixed, thanks.
Regards,
Peter Hurley
Quoted 55 lines · Peter Hurley
Quoted 54 lines · Yinghai Lu
Quoted 53 lines · Yinghai Lu
Quoted 27 lines · Peter Hurley
Quoted 18 lines · Peter Hurley
Quoted 17 lines · Alan Stern
Quoted 15 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
[ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18Quoted 4 lines
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 00 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4,snd_ctxfiThese messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5...
acpi_pci_irq_add_prt()add wrong bus for that bridge, because that that bridge is not scanned.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Will check if I can produce one patch for it.
Hi Peter,
Can you try attached debug patch?
Fixed, thanks.
Bjorn, Rafael,
acpi_pci_irq_add_prt need to be called after pci bridge get scanned, so we can not call it from pci_acpi_setup, after we move dev_register for pci_dev early.
The attached debug patch move down that calling into pci_bus_add_devices and that will make prt works again.
Can acpi provide another hook after bridge get scanned?
Thanks
Yinghai
--- drivers/pci/bus.c | 5 +++++ drivers/pci/pci-acpi.c | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-)
drivers/pci/bus.c +5 -0
@@ -160,6 +160,8 @@ pci_bus_alloc_resource(struct pci_bus *bvoid __weak pcibios_resource_survey_bus (struct pci_bus *bus) { } +void __weak pcibios_irq_setup (struct device *dev) { } +/** * pci_bus_add_device - start driver for a single device * @dev: device to add
@@ -170,6 +172,9 @@ int pci_bus_add_device(struct pci_dev *d {int retval; +/* need to after bridge is scanned */ +pcibios_irq_setup (&dev->dev); +/* * Can not put in pci_device_add yet because resources * are not assigned yet for some devices.
drivers/pci/pci-acpi.c +11 -2
@@ -302,14 +302,16 @@ static int acpi_pci_find_device(struct dreturn 0 ; } -static void pci_acpi_setup (struct device *dev) +void pcibios_irq_setup (struct device *dev) {struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev); -struct acpi_device *adev;acpi_status status;acpi_handle dummy; +if (acpi_disabled || acpi_pci_disabled) +return ; +/* * Evaluate and parse _PRT, if exists. This code allows parsing of * _PRT objects within the scope of non-bridge devices. Note that
@@ -326,6 +328,13 @@ static void pci_acpi_setup(struct device pci_dev->subordinate->number : pci_dev->bus->number;acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); } +} + +static void pci_acpi_setup (struct device *dev) +{ +struct pci_dev *pci_dev =to_pci_dev (dev); +acpi_handle handle =ACPI_HANDLE (dev); +struct acpi_device *adev;if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;
Quoted 66 lines · Yinghai Lu
Quoted 55 lines · Peter Hurley
Quoted 54 lines · Yinghai Lu
Quoted 53 lines · Yinghai Lu
Quoted 27 lines · Peter Hurley
Quoted 18 lines · Peter Hurley
Quoted 17 lines · Alan Stern
Quoted 15 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
[ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18Quoted 4 lines
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 00 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4,snd_ctxfiThese messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5...
acpi_pci_irq_add_prt()add wrong bus for that bridge, because that that bridge is not scanned.Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Will check if I can produce one patch for it.
Hi Peter,
Can you try attached debug patch?
Fixed, thanks.
Bjorn, Rafael,
Quoted 9 lines
acpi_pci_irq_add_prtneed to be called after pci bridge get scanned, so we can not call it frompci_acpi_setup, after we movedev_registerforpci_devearly.The attached debug patch move down that calling into
pci_bus_add_devicesand that will make prt works again.Can acpi provide another hook after bridge get scanned?
23: + /* need to after bridge is scanned */
24: + pcibios_irq_setup(&dev->dev);
... need to *be called* after...
Even this is a temporary workaround, can you send a separate patch for this?
- Sedat -
P.S.: Still wonder why people use "linux-2.6" as prefix in their patches.
Quoted 3 lines
Thanks
Yinghai
Quoted 77 lines · Sedat Dilek
Quoted 66 lines · Yinghai Lu
Quoted 55 lines · Peter Hurley
Quoted 54 lines · Yinghai Lu
Quoted 53 lines · Yinghai Lu
Quoted 27 lines · Peter Hurley
Quoted 18 lines · Peter Hurley
Quoted 17 lines · Alan Stern
Quoted 15 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
[ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18Quoted 4 lines
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 00 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4,snd_ctxfiThese messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5...
acpi_pci_irq_add_prt()add wrong bus for that bridge, because that that bridge is not scanned.Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Will check if I can produce one patch for it.
Hi Peter,
Can you try attached debug patch?
Fixed, thanks.
Bjorn, Rafael,
Quoted 9 lines
acpi_pci_irq_add_prtneed to be called after pci bridge get scanned, so we can not call it frompci_acpi_setup, after we movedev_registerforpci_devearly.The attached debug patch move down that calling into
pci_bus_add_devicesand that will make prt works again.Can acpi provide another hook after bridge get scanned?
Quoted 6 lines
23: + /* need to after bridge is scanned */
24: +pcibios_irq_setup(&dev->dev);... need to *be called* after...
Even this is a temporary workaround, can you send a separate patch for this?
again, this is debug patch.
Thanks
Yinghai
Quoted 66 lines · Yinghai Lu
Quoted 55 lines · Peter Hurley
Quoted 54 lines · Yinghai Lu
Quoted 53 lines · Yinghai Lu
Quoted 27 lines · Peter Hurley
Quoted 18 lines · Peter Hurley
Quoted 17 lines · Alan Stern
Quoted 15 lines · Peter Hurley
With -next-20130204:
[ 33.855570] irq 18: nobody cared (try booting with the "irqpoll" option) [ 33.855580] Pid: 0, comm: swapper/4 Not tainted 3.8.0-next-20130204-xeon #20130204 [ 33.855582] Call Trace: [ 33.855585] <IRQ> [<ffffffff810f1076>] __report_bad_irq+0x36/0xe0 [ 33.855600] [<ffffffff810f152a>] note_interrupt+0x1aa/0x200 [ 33.855606] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855610] [<ffffffff810eed89>] handle_irq_event_percpu+0xc9/0x260 [ 33.855614] [<ffffffff810eef68>] handle_irq_event+0x48/0x70 [ 33.855618] [<ffffffff810f20ba>] handle_fasteoi_irq+0x5a/0x100 [ 33.855624] [<ffffffff810182f2>] handle_irq+0x22/0x40 [ 33.855630] [<ffffffff816e2a9a>] do_IRQ+0x5a/0xd0 [ 33.855636] [<ffffffff816d97ad>] common_interrupt+0x6d/0x6d [ 33.855638] <EOI> [<ffffffff810f8e2a>] ? rcu_eqs_enter_common+0x4a/0x320Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
[ 33.855646] [<ffffffff8101edf2>] ? mwait_idle+0x82/0x1b0 [ 33.855649] [<ffffffff8101ed99>] ? mwait_idle+0x29/0x1b0 [ 33.855653] [<ffffffff8101f8a6>] cpu_idle+0x116/0x130 [ 33.855658] [<ffffffff816c0c0f>] start_secondary+0x251/0x258 [ 33.855660] handlers: [ 33.855664] [<ffffffff814f98a0>] usb_hcd_irq [ 33.855667] Disabling IRQ #18Quoted 4 lines
https://bugzilla.kernel.org/show_bug.cgi?id=53561
Maybe this is some interaction with all the new ACPI code and fixes written in those 8 days.
interrupt routing seems get changed:
next:
5: 0 0 0 0 00 0 0 IO-APIC-fasteoi snd_ctxfi 18: 99970 13 16 20 99940 13 13 16 IO-APIC-fasteoi uhci_hcd:usb4v3.8-rc7:
18: 424 15 11 112 420
16 18 105 IO-APIC-fasteoi uhci_hcd:usb4,snd_ctxfiThese messages in the bad dmesg log are interesting since PCI INT A is routed on
irq 18 with the kernels that work.[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5...
acpi_pci_irq_add_prt()add wrong bus for that bridge, because that that bridge is not scanned.Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Will check if I can produce one patch for it.
Hi Peter,
Can you try attached debug patch?
Fixed, thanks.
Bjorn, Rafael,
Quoted 9 lines
acpi_pci_irq_add_prtneed to be called after pci bridge get scanned, so we can not call it frompci_acpi_setup, after we movedev_registerforpci_devearly.The attached debug patch move down that calling into
pci_bus_add_devicesand that will make prt works again.Can acpi provide another hook after bridge get scanned?
Can we extend platform_notify to beplatform_notify(struct device *dev, event) ?
and event could be _ADD, _SCAN, _REMOVE
Thanks
Yinghai
Quoted 7 lines · Yinghai Lu
Quoted 7 lines
Bjorn, Rafael,
acpi_pci_irq_add_prtneed to be called after pci bridge get scanned, so we can not call it frompci_acpi_setup, after we movedev_registerforpci_devearly.
Quoted 5 lines
Quoted 5 lines
The attached debug patch move down that calling into
pci_bus_add_devicesand that will make prt works again.Can acpi provide another hook after bridge get scanned?
Rafael, Bjorn,
Can you check attached patch?
Thanks
Yinghai
Subject: [PATCH] ACPI, PCI: add acpi_platform_notify_scan()
Peter Hurley found irq nobody cared, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5
bisect to
| commit 4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Put pci_dev in device tree as early as possible
It turns out we need to call acpi_pci_irq_add_prt() after the pci bridges are scanned.
Add acpi_platform_notify_scan() to call acpi_pci_irq_add_prt later.
--- drivers/acpi/glue.c | 12 ++++++++++++ drivers/base/core.c | 1 + drivers/pci/bus.c | 4 ++++ drivers/pci/pci-acpi.c | 27 +++++++++++++++++---------- include/acpi/acpi_bus.h | 1 + include/linux/device.h | 3 +-- 6 files changed, 36 insertions(+), 12 deletions(-)
drivers/acpi/glue.c +12 -0
@@ -312,6 +312,17 @@ static int acpi_platform_notify(struct dreturn ret; } +static int acpi_platform_notify_scan (struct device *dev) +{ +struct acpi_bus_type *type; + + type =acpi_get_bus_type (dev->bus); +if (type && type->setup_scan) + type->setup_scan (dev); + +return 0 ; +} +static int acpi_platform_notify_remove (struct device *dev) {struct acpi_bus_type *type;
@@ -331,6 +342,7 @@ int __init init_acpi_device_notify(void)return 0 ; } platform_notify = acpi_platform_notify; + platform_notify_scan = acpi_platform_notify_scan; platform_notify_remove = acpi_platform_notify_remove;return 0 ; }
drivers/base/core.c +1 -0
@@ -44,6 +44,7 @@ early_param("sysfs.deprecated", sysfs_de#endif int (*platform_notify)(struct device *dev) =NULL ; +int (*platform_notify_scan)(struct device *dev) =NULL ;int (*platform_notify_remove)(struct device *dev) =NULL ;static struct kobject *dev_kobj;struct kobject *sysfs_dev_char_kobj;
drivers/pci/bus.c +4 -0
@@ -170,6 +170,10 @@ int pci_bus_add_device(struct pci_dev *d {int retval; +/* need to be called after bridge is scanned */ +if (platform_notify_scan) +platform_notify_scan (&dev->dev); +/* * Can not put in pci_device_add yet because resources * are not assigned yet for some devices.
drivers/pci/pci-acpi.c +17 -10
@@ -307,6 +307,22 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; + +if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid) +return ; + +device_set_wakeup_capable (dev, true); +acpi_pci_sleep_wake (pci_dev, false); + +pci_acpi_add_pm_notifier (adev, pci_dev); +if (adev->wakeup.flags.run_wake) +device_set_run_wake (dev, true); +} + +static void pci_acpi_setup_scan (struct device *dev) +{ +struct pci_dev *pci_dev =to_pci_dev (dev); +acpi_handle handle =ACPI_HANDLE (dev);acpi_status status;acpi_handle dummy;
@@ -326,16 +342,6 @@ static void pci_acpi_setup(struct device pci_dev->subordinate->number : pci_dev->bus->number;acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); } - -if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid) -return ; - -device_set_wakeup_capable (dev, true); -acpi_pci_sleep_wake (pci_dev, false); - -pci_acpi_add_pm_notifier (adev, pci_dev); -if (adev->wakeup.flags.run_wake) -device_set_run_wake (dev, true); }static void pci_acpi_cleanup (struct device *dev)
@@ -359,6 +365,7 @@ static struct acpi_bus_type acpi_pci_bus .bus = &pci_bus_type, .find_device = acpi_pci_find_device, .setup = pci_acpi_setup, + .setup_scan = pci_acpi_setup_scan, .cleanup = pci_acpi_cleanup, };
include/acpi/acpi_bus.h +1 -0
@@ -440,6 +440,7 @@ struct acpi_bus_type {/* For bridges, such as PCI root bridge, IDE controller */ int (*find_bridge) (struct device *,acpi_handle *);void (*setup)(struct device *); +void (*setup_scan)(struct device *);void (*cleanup)(struct device *); };int register_acpi_bus_type (struct acpi_bus_type *);
include/linux/device.h +1 -2
@@ -897,10 +897,9 @@ extern void device_destroy(struct class*/ /* Notify platform of device discovery */ extern int (*platform_notify)(struct device *dev); - +extern int (*platform_notify_scan)(struct device *dev);extern int (*platform_notify_remove)(struct device *dev); -/* * get_device - atomically increment the reference count for the device. *
Bjorn Helgaas
maintainer[+cc linux-acpi, linux-pci]
Quoted 8 lines · Yinghai Lu
Quoted 7 lines · Yinghai Lu
Quoted 7 lines
Bjorn, Rafael,
acpi_pci_irq_add_prtneed to be called after pci bridge get scanned, so we can not call it frompci_acpi_setup, after we movedev_registerforpci_devearly.
Quoted 8 lines
Quoted 4 lines
Quoted 4 lines
The attached debug patch move down that calling into
pci_bus_add_devicesand that will make prt works again.Can acpi provide another hook after bridge get scanned?
Rafael, Bjorn,
Can you check attached patch?
[Yinghai's patch included below for ease of review]
Quoted 63 lines
Subject: [PATCH] ACPI, PCI: add
acpi_platform_notify_scan()Peter Hurley found irq nobody cared, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Add
acpi_platform_notify_scan()to callacpi_pci_irq_add_prtlater.Reported-and-tested-by Peter Hurley <[email protected]>Signed-off-by Yinghai Lu <[email protected]>--- drivers/acpi/glue.c | 12 ++++++++++++ drivers/base/core.c | 1 + drivers/pci/bus.c | 4 ++++ drivers/pci/pci-acpi.c | 27 +++++++++++++++++---------- include/acpi/acpi_bus.h | 1 + include/linux/device.h | 3 +-- 6 files changed, 36 insertions(+), 12 deletions(-)Index:
linux-2.6/drivers/acpi/glue.c
===================================================================drivers/acpi/glue.c +12
-0@@ -312,6 +312,17 @@ static int acpi_platform_notify(struct dreturn ret; } +static int acpi_platform_notify_scan (struct device *dev) +{ +struct acpi_bus_type *type; + + type =acpi_get_bus_type (dev->bus); +if (type && type->setup_scan) + type->setup_scan (dev); + +return 0 ; +} +static int acpi_platform_notify_remove (struct device *dev) {struct acpi_bus_type *type;@@ -331,6 +342,7 @@ int __init init_acpi_device_notify(void)return 0 ; } platform_notify = acpi_platform_notify; + platform_notify_scan = acpi_platform_notify_scan; platform_notify_remove = acpi_platform_notify_remove;return 0 ; }Index:
linux-2.6/drivers/base/core.c
===================================================================
drivers/base/core.c early_param("sysfs.deprecated", sysfs_de · line 47
Quoted 4 lines
drivers/base/core.c +1
-0@@ -44,6 +44,7 @@ early_param("sysfs.deprecated", sysfs_de#endif int (*platform_notify)(struct device *dev) =NULL ; +int (*platform_notify_scan)(struct device *dev) =NULL ;
I don't like the idea of adding another global function pointer just for this. That seems like overkill for a small, local, problem.
Quoted 46 lines
drivers/base/core.c +0
-0int (*platform_notify_remove)(struct device *dev) =NULL ;static struct kobject *dev_kobj;struct kobject *sysfs_dev_char_kobj;Index:
linux-2.6/drivers/pci/bus.c
===================================================================drivers/pci/bus.c +4
-0@@ -170,6 +170,10 @@ int pci_bus_add_device(struct pci_dev *d {int retval; +/* need to be called after bridge is scanned */ +if (platform_notify_scan) +platform_notify_scan (&dev->dev); +/* * Can not put in pci_device_add yet because resources * are not assigned yet for some devices. Index:
linux-2.6/drivers/pci/pci-acpi.c
===================================================================drivers/pci/pci-acpi.c +16
-0@@ -307,6 +307,22 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; + +if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid) +return ; + +device_set_wakeup_capable (dev, true); +acpi_pci_sleep_wake (pci_dev, false); + +pci_acpi_add_pm_notifier (adev, pci_dev); +if (adev->wakeup.flags.run_wake) +device_set_run_wake (dev, true); +} + +static void pci_acpi_setup_scan (struct device *dev) +{ +struct pci_dev *pci_dev =to_pci_dev (dev); +acpi_handle handle =ACPI_HANDLE (dev);acpi_status status;acpi_handle dummy;
drivers/pci/pci-acpi.c static void pci_acpi_setup(struct device · line 343
Quoted 2 lines
drivers/pci/pci-acpi.c +0
-0@@ -326,16 +342,6 @@ static void pci_acpi_setup(struct device pci_dev->subordinate->number : pci_dev->bus->number;acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus);
The _PRT describes motherboard interrupt wiring, which has nothing to do with PCI bus numbers. Our current drivers/acpi/pci_irq.c caches the PCI bus number along with the _PRT, and I think that's a mistake.
The bus number binding means acpi_pci_irq_add_prt() has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.
I think we should remove the bus numbers from the cached _PRT (or maybe even remove the _PRT caching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a _PRT associated with each node, and applying normal PCI bridge swizzling when we don't find a _PRT. I think this can be done without using PCI bus numbers at all.
Quoted 50 lines
drivers/pci/pci-acpi.c +1
-10} - -if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid) -return ; - -device_set_wakeup_capable (dev, true); -acpi_pci_sleep_wake (pci_dev, false); - -pci_acpi_add_pm_notifier (adev, pci_dev); -if (adev->wakeup.flags.run_wake) -device_set_run_wake (dev, true); }static void pci_acpi_cleanup (struct device *dev)@@ -359,6 +365,7 @@ static struct acpi_bus_type acpi_pci_bus .bus = &pci_bus_type, .find_device = acpi_pci_find_device, .setup = pci_acpi_setup, + .setup_scan = pci_acpi_setup_scan, .cleanup = pci_acpi_cleanup, };Index:
linux-2.6/include/acpi/acpi_bus.h
===================================================================include/acpi/acpi_bus.h +1
-0@@ -440,6 +440,7 @@ struct acpi_bus_type {/* For bridges, such as PCI root bridge, IDE controller */ int (*find_bridge) (struct device *,acpi_handle *);void (*setup)(struct device *); +void (*setup_scan)(struct device *);void (*cleanup)(struct device *); };int register_acpi_bus_type (struct acpi_bus_type *);Index:
linux-2.6/include/linux/device.h
===================================================================include/linux/device.h +1
-2@@ -897,10 +897,9 @@ extern void device_destroy(struct class*/ /* Notify platform of device discovery */ extern int (*platform_notify)(struct device *dev); - +extern int (*platform_notify_scan)(struct device *dev);extern int (*platform_notify_remove)(struct device *dev); -/* * get_device - atomically increment the reference count for the device. *
Quoted 10 lines · Bjorn Helgaas
[+cc linux-acpi, linux-pci]
The
_PRTdescribes motherboard interrupt wiring, which has nothing to do with PCI bus numbers. Our currentdrivers/acpi/pci_irq.ccaches the PCI bus number along with the_PRT, and I think that's a mistake.The bus number binding means
acpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.
Quoted 7 lines
I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.
Agreed, will give it try to remove the _PRT caching completely.
Thanks
Yinghai
Quoted 19 lines · Yinghai Lu
Quoted 10 lines · Bjorn Helgaas
[+cc linux-acpi, linux-pci]
The
_PRTdescribes motherboard interrupt wiring, which has nothing to do with PCI bus numbers. Our currentdrivers/acpi/pci_irq.ccaches the PCI bus number along with the_PRT, and I think that's a mistake.The bus number binding means
acpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.Quoted 7 lines
I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.
Quoted 2 lines
Agreed, will give it try to remove the
_PRTcaching completely.
Please check attached patch that removes _PRT caching.
Thanks
Yinghai
Subject: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Peter Hurley found irq nobody cared, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5
bisect to
| commit 4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Put pci_dev in device tree as early as possible
It turns out we need to call acpi_pci_irq_add_prt() after the pci bridges are scanned.
Bjorn said:
The bus number binding means acpi_pci_irq_add_prt() has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.
I think we should remove the bus numbers from the cached _PRT (or maybe even remove the _PRT caching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a _PRT associated with each node, and applying normal PCI bridge swizzling when we don't find a _PRT. I think this can be done without using PCI bus numbers at all.
So here we try to remove _PRT caching completely.
--- drivers/acpi/pci_irq.c | 97 ++++++++++++++++++-------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ---------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 40 insertions(+), 104 deletions(-)
drivers/acpi/pci_irq.c +40 -57
@@ -53,9 +53,6 @@ struct acpi_prt_entry {u32 index;/* GSI, or link _CRS index */ }; -static LIST_HEAD (acpi_prt_list); -static DEFINE_SPINLOCK (acpi_prt_lock); -static inline char pin_name (int pin) {return 'A' + pin -1 ;
@@ -65,28 +62,6 @@ static inline char pin_name(int pin)PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry (struct pci_dev *dev, -int pin) -{ -struct acpi_prt_entry *entry; -int segment =pci_domain_nr (dev->bus); -int bus = dev->bus->number; -int device =PCI_SLOT (dev->devfn); - -spin_lock (&acpi_prt_lock); -list_for_each_entry (entry, &acpi_prt_list, list) { -if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { -spin_unlock (&acpi_prt_lock); -return entry; - } - } -spin_unlock (&acpi_prt_lock); -return NULL ; -} -/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ static const struct dmi_system_id medion_md9580[] = { {
@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_pr } } -static int acpi_pci_irq_add_entry (acpi_handle handle,int segment,int bus, -struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_check_entry (acpi_handle handle,struct pci_dev *dev, +int pin,struct acpi_pci_routing_table *prt, +struct acpi_prt_entry **prt_entry) { +int segment =pci_domain_nr (dev->bus); +int bus = dev->bus->number; +int device =PCI_SLOT (dev->devfn);struct acpi_prt_entry *entry; +if (((prt->address >>16 ) &0xffff ) != device || + prt->pin +1 != pin) +return -ENODEV ; + entry =kzalloc (sizeof (struct acpi_prt_entry ),GFP_KERNEL );if (!entry)return -ENOMEM ;
@@ -237,26 +220,33 @@ static int acpi_pci_irq_add_entry(acpi_h entry->id.device,pin_name (entry->pin), prt->source, entry->index)); -spin_lock (&acpi_prt_lock); -list_add_tail (&entry->list, &acpi_prt_list); -spin_unlock (&acpi_prt_lock); + *prt_entry = entry;return 0 ; } -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus) +static int acpi_pci_irq_find_prt_entry (struct pci_dev *dev, +int pin,struct acpi_prt_entry **entry_ptr) {acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_pci_routing_table *entry; +acpi_handle handle; +struct acpi_prt_entry *prt_entry =NULL ; + +if (dev->bus->bridge) + handle =ACPI_HANDLE (dev->bus->bridge); +else +return -ENODEV ;/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ status =acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer);if (ACPI_FAILURE (status))return -ENODEV ; -printk (KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , - (char *) buffer.pointer); +dev_printk (KERN_DEBUG , &dev->dev, +"ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , + (char *) buffer.pointer);kfree (buffer.pointer);
@@ -273,7 +263,11 @@ int acpi_pci_irq_add_prt(acpi_handle han entry = buffer.pointer;while (entry && (entry->length >0 )) { -acpi_pci_irq_add_entry (handle, segment, bus, entry); +if (!acpi_pci_irq_check_entry (handle, dev, pin, + entry, &prt_entry)) { + *entry_ptr = prt_entry; +break ; + } entry = (struct acpi_pci_routing_table *) ((unsigned long )entry + entry->length); }
@@ -282,23 +276,6 @@ int acpi_pci_irq_add_prt(acpi_handle hanreturn 0 ; } -void acpi_pci_irq_del_prt (int segment,int bus) -{ -struct acpi_prt_entry *entry, *tmp; - -printk (KERN_DEBUG -"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n" , - segment, bus); -spin_lock (&acpi_prt_lock); -list_for_each_entry_safe (entry, tmp, &acpi_prt_list, list) { -if (segment == entry->id.segment && bus == entry->id.bus) { -list_del (&entry->list); -kfree (entry); - } - } -spin_unlock (&acpi_prt_lock); -} -/* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */
@@ -359,12 +336,13 @@ static int acpi_reroute_boot_interrupt(sstatic struct acpi_prt_entry *acpi_pci_irq_lookup (struct pci_dev *dev,int pin) { -struct acpi_prt_entry *entry; +struct acpi_prt_entry *entry =NULL ;struct pci_dev *bridge;u8 bridge_pin, orig_pin = pin; +int ret; - entry =acpi_pci_irq_find_prt_entry (dev, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (dev, pin, &entry); +if (!ret && entry) {#ifdef CONFIG_X86_IO_APIC acpi_reroute_boot_interrupt (dev, entry);#endif /* CONFIG_X86_IO_APIC */
@@ -373,7 +351,7 @@ static struct acpi_prt_entry *acpi_pci_ireturn entry; } -/* +/* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */
@@ -393,8 +371,8 @@ static struct acpi_prt_entry *acpi_pci_i pin = bridge_pin; } - entry =acpi_pci_irq_find_prt_entry (bridge, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (bridge, pin, &entry); +if (!ret && entry) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", pci_name(dev), pin_name(orig_pin),
@@ -470,6 +448,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev_warn (&dev->dev,"PCI INT %c: no GSI\n" ,pin_name (pin)); } +return 0 ; }
@@ -477,6 +456,7 @@ int acpi_pci_irq_enable(struct pci_dev *if (rc <0 ) {dev_warn (&dev->dev,"PCI INT %c: failed to register GSI\n" ,pin_name (pin)); +kfree (entry);return rc; } dev->irq = rc;
@@ -491,6 +471,7 @@ int acpi_pci_irq_enable(struct pci_dev * (triggering ==ACPI_LEVEL_SENSITIVE ) ?"level" :"edge" , (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); +kfree (entry);return 0 ; }
@@ -513,6 +494,8 @@ void acpi_pci_irq_disable(struct pci_develse gsi = entry->index; +kfree (entry); +/* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ).
drivers/acpi/pci_root.c +0 -18
@@ -413,7 +413,6 @@ static int acpi_pci_root_add(struct acpiacpi_status status;int result;struct acpi_pci_root *root; -acpi_handle handle;struct acpi_pci_driver *driver;u32 flags, base_flags;bool is_osc_granted = false;
@@ -468,16 +467,6 @@ static int acpi_pci_root_add(struct acpiacpi_device_name (device),acpi_device_bid (device), root->segment, &root->secondary); -/* -* PCI Routing Table -* ----------------- -* Evaluate and parse _PRT, if exists. -*/ - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) - result =acpi_pci_irq_add_prt (device->handle, root->segment, - root->secondary.start); - root->mcfg_addr =acpi_pci_root_get_mcfg_addr (device->handle);/*
@@ -602,7 +591,6 @@ out_del_root:list_del (&root->node);mutex_unlock (&acpi_pci_root_lock); -acpi_pci_irq_del_prt (root->segment, root->secondary.start); end:kfree (root);return result;
@@ -610,8 +598,6 @@ end:static void acpi_pci_root_remove (struct acpi_device *device) { -acpi_status status; -acpi_handle handle;struct acpi_pci_root *root =acpi_driver_data (device);struct acpi_pci_driver *driver;
@@ -626,10 +612,6 @@ static void acpi_pci_root_remove(structdevice_set_run_wake (root->bus->bridge, false);pci_acpi_remove_bus_pm_notifier (device); - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) -acpi_pci_irq_del_prt (root->segment, root->secondary.start); -pci_remove_root_bus (root->bus);mutex_lock (&acpi_pci_root_lock);
drivers/pci/pci-acpi.c +0 -24
@@ -307,25 +307,6 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; -acpi_status status; -acpi_handle dummy; - -/* -* Evaluate and parse _PRT, if exists. This code allows parsing of -* _PRT objects within the scope of non-bridge devices. Note that -* _PRTs within the scope of a PCI bridge assume the bridge's -* subordinate bus number. -* -* TBD: Can _PRTs exist within the scope of non-bridge PCI devices? -*/ - status =acpi_get_handle (handle,METHOD_NAME__PRT , &dummy); -if (ACPI_SUCCESS (status)) { -unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; -acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); - }if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;
@@ -340,7 +321,6 @@ static void pci_acpi_setup(struct devicestatic void pci_acpi_cleanup (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev;
@@ -349,10 +329,6 @@ static void pci_acpi_cleanup(struct devidevice_set_run_wake (dev, false);pci_acpi_remove_pm_notifier (adev); } - -if (pci_dev->subordinate) -acpi_pci_irq_del_prt (pci_domain_nr (pci_dev->bus), - pci_dev->subordinate->number); }static struct acpi_bus_type acpi_pci_bus = {
include/acpi/acpi_drivers.h +0 -5
@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_hand int *polarity, char **name);int acpi_pci_link_free_irq (acpi_handle handle); -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus); -void acpi_pci_irq_del_prt (int segment,int bus); -/* ACPI PCI Device Binding (pci_bind.c) */ struct pci_bus ;
PATCH 1/1 ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5
bisect to
| commit 4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Put pci_dev in device tree as early as possible
It turns out we need to call acpi_pci_irq_add_prt() after the pci bridges are scanned.
Bjorn said:
The bus number binding means acpi_pci_irq_add_prt() has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.
I think we should remove the bus numbers from the cached _PRT (or maybe even remove the _PRT caching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a _PRT associated with each node, and applying normal PCI bridge swizzling when we don't find a _PRT. I think this can be done without using PCI bus numbers at all.
So here we try to remove _PRT caching completely.
-v2: check !handle early.
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)
drivers/acpi/pci_irq.c +38 -57
@@ -53,9 +53,6 @@ struct acpi_prt_entry {u32 index;/* GSI, or link _CRS index */ }; -static LIST_HEAD (acpi_prt_list); -static DEFINE_SPINLOCK (acpi_prt_lock); -static inline char pin_name (int pin) {return 'A' + pin -1 ;
@@ -65,28 +62,6 @@ static inline char pin_name(int pin)PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry (struct pci_dev *dev, -int pin) -{ -struct acpi_prt_entry *entry; -int segment =pci_domain_nr (dev->bus); -int bus = dev->bus->number; -int device =PCI_SLOT (dev->devfn); - -spin_lock (&acpi_prt_lock); -list_for_each_entry (entry, &acpi_prt_list, list) { -if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { -spin_unlock (&acpi_prt_lock); -return entry; - } - } -spin_unlock (&acpi_prt_lock); -return NULL ; -} -/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ static const struct dmi_system_id medion_md9580[] = { {
@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_pr } } -static int acpi_pci_irq_add_entry (acpi_handle handle,int segment,int bus, -struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_check_entry (acpi_handle handle,struct pci_dev *dev, +int pin,struct acpi_pci_routing_table *prt, +struct acpi_prt_entry **entry_ptr) { +int segment =pci_domain_nr (dev->bus); +int bus = dev->bus->number; +int device =PCI_SLOT (dev->devfn);struct acpi_prt_entry *entry; +if (((prt->address >>16 ) &0xffff ) != device || + prt->pin +1 != pin) +return -ENODEV ; + entry =kzalloc (sizeof (struct acpi_prt_entry ),GFP_KERNEL );if (!entry)return -ENOMEM ;
@@ -237,26 +220,33 @@ static int acpi_pci_irq_add_entry(acpi_h entry->id.device,pin_name (entry->pin), prt->source, entry->index)); -spin_lock (&acpi_prt_lock); -list_add_tail (&entry->list, &acpi_prt_list); -spin_unlock (&acpi_prt_lock); + *entry_ptr = entry;return 0 ; } -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus) +static int acpi_pci_irq_find_prt_entry (struct pci_dev *dev, +int pin,struct acpi_prt_entry **entry_ptr) {acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_pci_routing_table *entry; +acpi_handle handle =NULL ; + +if (dev->bus->bridge) + handle =ACPI_HANDLE (dev->bus->bridge); + +if (!handle) +return -ENODEV ;/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ status =acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer);if (ACPI_FAILURE (status))return -ENODEV ; -printk (KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , - (char *) buffer.pointer); +dev_printk (KERN_DEBUG , &dev->dev, +"ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , + (char *) buffer.pointer);kfree (buffer.pointer);
@@ -273,7 +263,9 @@ int acpi_pci_irq_add_prt(acpi_handle han entry = buffer.pointer;while (entry && (entry->length >0 )) { -acpi_pci_irq_add_entry (handle, segment, bus, entry); +if (!acpi_pci_irq_check_entry (handle, dev, pin, + entry, entry_ptr)) +break ; entry = (struct acpi_pci_routing_table *) ((unsigned long )entry + entry->length); }
@@ -282,23 +274,6 @@ int acpi_pci_irq_add_prt(acpi_handle hanreturn 0 ; } -void acpi_pci_irq_del_prt (int segment,int bus) -{ -struct acpi_prt_entry *entry, *tmp; - -printk (KERN_DEBUG -"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n" , - segment, bus); -spin_lock (&acpi_prt_lock); -list_for_each_entry_safe (entry, tmp, &acpi_prt_list, list) { -if (segment == entry->id.segment && bus == entry->id.bus) { -list_del (&entry->list); -kfree (entry); - } - } -spin_unlock (&acpi_prt_lock); -} -/* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */
@@ -359,12 +334,13 @@ static int acpi_reroute_boot_interrupt(sstatic struct acpi_prt_entry *acpi_pci_irq_lookup (struct pci_dev *dev,int pin) { -struct acpi_prt_entry *entry; +struct acpi_prt_entry *entry =NULL ;struct pci_dev *bridge;u8 bridge_pin, orig_pin = pin; +int ret; - entry =acpi_pci_irq_find_prt_entry (dev, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (dev, pin, &entry); +if (!ret && entry) {#ifdef CONFIG_X86_IO_APIC acpi_reroute_boot_interrupt (dev, entry);#endif /* CONFIG_X86_IO_APIC */
@@ -373,7 +349,7 @@ static struct acpi_prt_entry *acpi_pci_ireturn entry; } -/* +/* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */
@@ -393,8 +369,8 @@ static struct acpi_prt_entry *acpi_pci_i pin = bridge_pin; } - entry =acpi_pci_irq_find_prt_entry (bridge, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (bridge, pin, &entry); +if (!ret && entry) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", pci_name(dev), pin_name(orig_pin),
@@ -470,6 +446,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev_warn (&dev->dev,"PCI INT %c: no GSI\n" ,pin_name (pin)); } +return 0 ; }
@@ -477,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev *if (rc <0 ) {dev_warn (&dev->dev,"PCI INT %c: failed to register GSI\n" ,pin_name (pin)); +kfree (entry);return rc; } dev->irq = rc;
@@ -491,6 +469,7 @@ int acpi_pci_irq_enable(struct pci_dev * (triggering ==ACPI_LEVEL_SENSITIVE ) ?"level" :"edge" , (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); +kfree (entry);return 0 ; }
@@ -513,6 +492,8 @@ void acpi_pci_irq_disable(struct pci_develse gsi = entry->index; +kfree (entry); +/* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ).
drivers/acpi/pci_root.c +0 -18
@@ -413,7 +413,6 @@ static int acpi_pci_root_add(struct acpiacpi_status status;int result;struct acpi_pci_root *root; -acpi_handle handle;struct acpi_pci_driver *driver;u32 flags, base_flags;bool is_osc_granted = false;
@@ -468,16 +467,6 @@ static int acpi_pci_root_add(struct acpiacpi_device_name (device),acpi_device_bid (device), root->segment, &root->secondary); -/* -* PCI Routing Table -* ----------------- -* Evaluate and parse _PRT, if exists. -*/ - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) - result =acpi_pci_irq_add_prt (device->handle, root->segment, - root->secondary.start); - root->mcfg_addr =acpi_pci_root_get_mcfg_addr (device->handle);/*
@@ -602,7 +591,6 @@ out_del_root:list_del (&root->node);mutex_unlock (&acpi_pci_root_lock); -acpi_pci_irq_del_prt (root->segment, root->secondary.start); end:kfree (root);return result;
@@ -610,8 +598,6 @@ end:static void acpi_pci_root_remove (struct acpi_device *device) { -acpi_status status; -acpi_handle handle;struct acpi_pci_root *root =acpi_driver_data (device);struct acpi_pci_driver *driver;
@@ -626,10 +612,6 @@ static void acpi_pci_root_remove(structdevice_set_run_wake (root->bus->bridge, false);pci_acpi_remove_bus_pm_notifier (device); - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) -acpi_pci_irq_del_prt (root->segment, root->secondary.start); -pci_remove_root_bus (root->bus);mutex_lock (&acpi_pci_root_lock);
drivers/pci/pci-acpi.c +0 -24
@@ -307,25 +307,6 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; -acpi_status status; -acpi_handle dummy; - -/* -* Evaluate and parse _PRT, if exists. This code allows parsing of -* _PRT objects within the scope of non-bridge devices. Note that -* _PRTs within the scope of a PCI bridge assume the bridge's -* subordinate bus number. -* -* TBD: Can _PRTs exist within the scope of non-bridge PCI devices? -*/ - status =acpi_get_handle (handle,METHOD_NAME__PRT , &dummy); -if (ACPI_SUCCESS (status)) { -unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; -acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); - }if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;
@@ -340,7 +321,6 @@ static void pci_acpi_setup(struct devicestatic void pci_acpi_cleanup (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev;
@@ -349,10 +329,6 @@ static void pci_acpi_cleanup(struct devidevice_set_run_wake (dev, false);pci_acpi_remove_pm_notifier (adev); } - -if (pci_dev->subordinate) -acpi_pci_irq_del_prt (pci_domain_nr (pci_dev->bus), - pci_dev->subordinate->number); }static struct acpi_bus_type acpi_pci_bus = {
include/acpi/acpi_drivers.h +0 -5
@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_hand int *polarity, char **name);int acpi_pci_link_free_irq (acpi_handle handle); -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus); -void acpi_pci_irq_del_prt (int segment,int bus); -/* ACPI PCI Device Binding (pci_bind.c) */ struct pci_bus ;
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 24 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.
Quoted 7 lines
So here we try to remove
_PRTcaching completely.-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Suggested-by Bjorn Helgaas <[email protected]>Signed-off-by Yinghai Lu <[email protected]>
Quoted 339 lines
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)Index:
linux-2.6/drivers/acpi/pci_irq.c
===================================================================drivers/acpi/pci_irq.c +38
-57@@ -53,9 +53,6 @@ struct acpi_prt_entry {u32 index;/* GSI, or link _CRS index */ }; -static LIST_HEAD (acpi_prt_list); -static DEFINE_SPINLOCK (acpi_prt_lock); -static inline char pin_name (int pin) {return 'A' + pin -1 ;@@ -65,28 +62,6 @@ static inline char pin_name(int pin)PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry (struct pci_dev *dev, -int pin) -{ -struct acpi_prt_entry *entry; -int segment =pci_domain_nr (dev->bus); -int bus = dev->bus->number; -int device =PCI_SLOT (dev->devfn); - -spin_lock (&acpi_prt_lock); -list_for_each_entry (entry, &acpi_prt_list, list) { -if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { -spin_unlock (&acpi_prt_lock); -return entry; - } - } -spin_unlock (&acpi_prt_lock); -return NULL ; -} -/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ static const struct dmi_system_id medion_md9580[] = { {@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_pr } } -static int acpi_pci_irq_add_entry (acpi_handle handle,int segment,int bus, -struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_check_entry (acpi_handle handle,struct pci_dev *dev, +int pin,struct acpi_pci_routing_table *prt, +struct acpi_prt_entry **entry_ptr) { +int segment =pci_domain_nr (dev->bus); +int bus = dev->bus->number; +int device =PCI_SLOT (dev->devfn);struct acpi_prt_entry *entry; +if (((prt->address >>16 ) &0xffff ) != device || + prt->pin +1 != pin) +return -ENODEV ; + entry =kzalloc (sizeof (struct acpi_prt_entry ),GFP_KERNEL );if (!entry)return -ENOMEM ;@@ -237,26 +220,33 @@ static int acpi_pci_irq_add_entry(acpi_h entry->id.device,pin_name (entry->pin), prt->source, entry->index)); -spin_lock (&acpi_prt_lock); -list_add_tail (&entry->list, &acpi_prt_list); -spin_unlock (&acpi_prt_lock); + *entry_ptr = entry;return 0 ; } -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus) +static int acpi_pci_irq_find_prt_entry (struct pci_dev *dev, +int pin,struct acpi_prt_entry **entry_ptr) {acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_pci_routing_table *entry; +acpi_handle handle =NULL ; + +if (dev->bus->bridge) + handle =ACPI_HANDLE (dev->bus->bridge); + +if (!handle) +return -ENODEV ;/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ status =acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer);if (ACPI_FAILURE (status))return -ENODEV ; -printk (KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , - (char *) buffer.pointer); +dev_printk (KERN_DEBUG , &dev->dev, +"ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , + (char *) buffer.pointer);kfree (buffer.pointer);@@ -273,7 +263,9 @@ int acpi_pci_irq_add_prt(acpi_handle han entry = buffer.pointer;while (entry && (entry->length >0 )) { -acpi_pci_irq_add_entry (handle, segment, bus, entry); +if (!acpi_pci_irq_check_entry (handle, dev, pin, + entry, entry_ptr)) +break ; entry = (struct acpi_pci_routing_table *) ((unsigned long )entry + entry->length); }@@ -282,23 +274,6 @@ int acpi_pci_irq_add_prt(acpi_handle hanreturn 0 ; } -void acpi_pci_irq_del_prt (int segment,int bus) -{ -struct acpi_prt_entry *entry, *tmp; - -printk (KERN_DEBUG -"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n" , - segment, bus); -spin_lock (&acpi_prt_lock); -list_for_each_entry_safe (entry, tmp, &acpi_prt_list, list) { -if (segment == entry->id.segment && bus == entry->id.bus) { -list_del (&entry->list); -kfree (entry); - } - } -spin_unlock (&acpi_prt_lock); -} -/* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */ @@ -359,12 +334,13 @@ static int acpi_reroute_boot_interrupt(sstatic struct acpi_prt_entry *acpi_pci_irq_lookup (struct pci_dev *dev,int pin) { -struct acpi_prt_entry *entry; +struct acpi_prt_entry *entry =NULL ;struct pci_dev *bridge;u8 bridge_pin, orig_pin = pin; +int ret; - entry =acpi_pci_irq_find_prt_entry (dev, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (dev, pin, &entry); +if (!ret && entry) {#ifdef CONFIG_X86_IO_APIC acpi_reroute_boot_interrupt (dev, entry);#endif /* CONFIG_X86_IO_APIC */ @@ -373,7 +349,7 @@ static struct acpi_prt_entry *acpi_pci_ireturn entry; } -/* +/* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */ @@ -393,8 +369,8 @@ static struct acpi_prt_entry *acpi_pci_i pin = bridge_pin; } - entry =acpi_pci_irq_find_prt_entry (bridge, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (bridge, pin, &entry); +if (!ret && entry) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", pci_name(dev), pin_name(orig_pin),@@ -470,6 +446,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev_warn (&dev->dev,"PCI INT %c: no GSI\n" ,pin_name (pin)); } +return 0 ; }@@ -477,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev *if (rc <0 ) {dev_warn (&dev->dev,"PCI INT %c: failed to register GSI\n" ,pin_name (pin)); +kfree (entry);return rc; } dev->irq = rc;@@ -491,6 +469,7 @@ int acpi_pci_irq_enable(struct pci_dev * (triggering ==ACPI_LEVEL_SENSITIVE ) ?"level" :"edge" , (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); +kfree (entry);return 0 ; }@@ -513,6 +492,8 @@ void acpi_pci_irq_disable(struct pci_develse gsi = entry->index; +kfree (entry); +/* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ). Index:
linux-2.6/drivers/acpi/pci_root.c
===================================================================drivers/acpi/pci_root.c +0
-18@@ -413,7 +413,6 @@ static int acpi_pci_root_add(struct acpiacpi_status status;int result;struct acpi_pci_root *root; -acpi_handle handle;struct acpi_pci_driver *driver;u32 flags, base_flags;bool is_osc_granted = false;@@ -468,16 +467,6 @@ static int acpi_pci_root_add(struct acpiacpi_device_name (device),acpi_device_bid (device), root->segment, &root->secondary); -/* -* PCI Routing Table -* ----------------- -* Evaluate and parse _PRT, if exists. -*/ - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) - result =acpi_pci_irq_add_prt (device->handle, root->segment, - root->secondary.start); - root->mcfg_addr =acpi_pci_root_get_mcfg_addr (device->handle);/* @@ -602,7 +591,6 @@ out_del_root:list_del (&root->node);mutex_unlock (&acpi_pci_root_lock); -acpi_pci_irq_del_prt (root->segment, root->secondary.start); end:kfree (root);return result;@@ -610,8 +598,6 @@ end:static void acpi_pci_root_remove (struct acpi_device *device) { -acpi_status status; -acpi_handle handle;struct acpi_pci_root *root =acpi_driver_data (device);struct acpi_pci_driver *driver;@@ -626,10 +612,6 @@ static void acpi_pci_root_remove(structdevice_set_run_wake (root->bus->bridge, false);pci_acpi_remove_bus_pm_notifier (device); - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) -acpi_pci_irq_del_prt (root->segment, root->secondary.start); -pci_remove_root_bus (root->bus);mutex_lock (&acpi_pci_root_lock);Index:
linux-2.6/drivers/pci/pci-acpi.c
===================================================================drivers/pci/pci-acpi.c +0
-24@@ -307,25 +307,6 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; -acpi_status status; -acpi_handle dummy; - -/* -* Evaluate and parse _PRT, if exists. This code allows parsing of -* _PRT objects within the scope of non-bridge devices. Note that -* _PRTs within the scope of a PCI bridge assume the bridge's -* subordinate bus number. -* -* TBD: Can _PRTs exist within the scope of non-bridge PCI devices? -*/ - status =acpi_get_handle (handle,METHOD_NAME__PRT , &dummy); -if (ACPI_SUCCESS (status)) { -unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; -acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); - }if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;@@ -340,7 +321,6 @@ static void pci_acpi_setup(struct devicestatic void pci_acpi_cleanup (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev;@@ -349,10 +329,6 @@ static void pci_acpi_cleanup(struct devidevice_set_run_wake (dev, false);pci_acpi_remove_pm_notifier (adev); } - -if (pci_dev->subordinate) -acpi_pci_irq_del_prt (pci_domain_nr (pci_dev->bus), - pci_dev->subordinate->number); }static struct acpi_bus_type acpi_pci_bus = {Index:
linux-2.6/include/acpi/acpi_drivers.h
===================================================================include/acpi/acpi_drivers.h +0
-5@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_hand int *polarity, char **name);int acpi_pci_link_free_irq (acpi_handle handle); -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus); -void acpi_pci_irq_del_prt (int segment,int bus); -/* ACPI PCI Device Binding (pci_bind.c) */ struct pci_bus ;
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 27 lines · Rafael J. Wysocki
Quoted 26 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.So here we try to remove
_PRTcaching completely.
Quoted 14 lines
Quoted 5 lines
-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Suggested-by Bjorn Helgaas <[email protected]>Signed-off-by Yinghai Lu <[email protected]>Quoted 6 lines
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)
Bjorn,
Can you put this one into pci/next?
Thanks
Yinghai
Quoted 340 lines
Quoted 323 lines
Index:
linux-2.6/drivers/acpi/pci_irq.c
===================================================================drivers/acpi/pci_irq.c +38
-57@@ -53,9 +53,6 @@ struct acpi_prt_entry {u32 index;/* GSI, or link _CRS index */ }; -static LIST_HEAD (acpi_prt_list); -static DEFINE_SPINLOCK (acpi_prt_lock); -static inline char pin_name (int pin) {return 'A' + pin -1 ;@@ -65,28 +62,6 @@ static inline char pin_name(int pin)PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry (struct pci_dev *dev, -int pin) -{ -struct acpi_prt_entry *entry; -int segment =pci_domain_nr (dev->bus); -int bus = dev->bus->number; -int device =PCI_SLOT (dev->devfn); - -spin_lock (&acpi_prt_lock); -list_for_each_entry (entry, &acpi_prt_list, list) { -if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { -spin_unlock (&acpi_prt_lock); -return entry; - } - } -spin_unlock (&acpi_prt_lock); -return NULL ; -} -/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ static const struct dmi_system_id medion_md9580[] = { {@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_pr } } -static int acpi_pci_irq_add_entry (acpi_handle handle,int segment,int bus, -struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_check_entry (acpi_handle handle,struct pci_dev *dev, +int pin,struct acpi_pci_routing_table *prt, +struct acpi_prt_entry **entry_ptr) { +int segment =pci_domain_nr (dev->bus); +int bus = dev->bus->number; +int device =PCI_SLOT (dev->devfn);struct acpi_prt_entry *entry; +if (((prt->address >>16 ) &0xffff ) != device || + prt->pin +1 != pin) +return -ENODEV ; + entry =kzalloc (sizeof (struct acpi_prt_entry ),GFP_KERNEL );if (!entry)return -ENOMEM ;@@ -237,26 +220,33 @@ static int acpi_pci_irq_add_entry(acpi_h entry->id.device,pin_name (entry->pin), prt->source, entry->index)); -spin_lock (&acpi_prt_lock); -list_add_tail (&entry->list, &acpi_prt_list); -spin_unlock (&acpi_prt_lock); + *entry_ptr = entry;return 0 ; } -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus) +static int acpi_pci_irq_find_prt_entry (struct pci_dev *dev, +int pin,struct acpi_prt_entry **entry_ptr) {acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_pci_routing_table *entry; +acpi_handle handle =NULL ; + +if (dev->bus->bridge) + handle =ACPI_HANDLE (dev->bus->bridge); + +if (!handle) +return -ENODEV ;/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ status =acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer);if (ACPI_FAILURE (status))return -ENODEV ; -printk (KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , - (char *) buffer.pointer); +dev_printk (KERN_DEBUG , &dev->dev, +"ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , + (char *) buffer.pointer);kfree (buffer.pointer);@@ -273,7 +263,9 @@ int acpi_pci_irq_add_prt(acpi_handle han entry = buffer.pointer;while (entry && (entry->length >0 )) { -acpi_pci_irq_add_entry (handle, segment, bus, entry); +if (!acpi_pci_irq_check_entry (handle, dev, pin, + entry, entry_ptr)) +break ; entry = (struct acpi_pci_routing_table *) ((unsigned long )entry + entry->length); }@@ -282,23 +274,6 @@ int acpi_pci_irq_add_prt(acpi_handle hanreturn 0 ; } -void acpi_pci_irq_del_prt (int segment,int bus) -{ -struct acpi_prt_entry *entry, *tmp; - -printk (KERN_DEBUG -"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n" , - segment, bus); -spin_lock (&acpi_prt_lock); -list_for_each_entry_safe (entry, tmp, &acpi_prt_list, list) { -if (segment == entry->id.segment && bus == entry->id.bus) { -list_del (&entry->list); -kfree (entry); - } - } -spin_unlock (&acpi_prt_lock); -} -/* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */ @@ -359,12 +334,13 @@ static int acpi_reroute_boot_interrupt(sstatic struct acpi_prt_entry *acpi_pci_irq_lookup (struct pci_dev *dev,int pin) { -struct acpi_prt_entry *entry; +struct acpi_prt_entry *entry =NULL ;struct pci_dev *bridge;u8 bridge_pin, orig_pin = pin; +int ret; - entry =acpi_pci_irq_find_prt_entry (dev, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (dev, pin, &entry); +if (!ret && entry) {#ifdef CONFIG_X86_IO_APIC acpi_reroute_boot_interrupt (dev, entry);#endif /* CONFIG_X86_IO_APIC */ @@ -373,7 +349,7 @@ static struct acpi_prt_entry *acpi_pci_ireturn entry; } -/* +/* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */ @@ -393,8 +369,8 @@ static struct acpi_prt_entry *acpi_pci_i pin = bridge_pin; } - entry =acpi_pci_irq_find_prt_entry (bridge, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (bridge, pin, &entry); +if (!ret && entry) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", pci_name(dev), pin_name(orig_pin),@@ -470,6 +446,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev_warn (&dev->dev,"PCI INT %c: no GSI\n" ,pin_name (pin)); } +return 0 ; }@@ -477,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev *if (rc <0 ) {dev_warn (&dev->dev,"PCI INT %c: failed to register GSI\n" ,pin_name (pin)); +kfree (entry);return rc; } dev->irq = rc;@@ -491,6 +469,7 @@ int acpi_pci_irq_enable(struct pci_dev * (triggering ==ACPI_LEVEL_SENSITIVE ) ?"level" :"edge" , (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); +kfree (entry);return 0 ; }@@ -513,6 +492,8 @@ void acpi_pci_irq_disable(struct pci_develse gsi = entry->index; +kfree (entry); +/* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ). Index:
linux-2.6/drivers/acpi/pci_root.c
===================================================================drivers/acpi/pci_root.c +0
-18@@ -413,7 +413,6 @@ static int acpi_pci_root_add(struct acpiacpi_status status;int result;struct acpi_pci_root *root; -acpi_handle handle;struct acpi_pci_driver *driver;u32 flags, base_flags;bool is_osc_granted = false;@@ -468,16 +467,6 @@ static int acpi_pci_root_add(struct acpiacpi_device_name (device),acpi_device_bid (device), root->segment, &root->secondary); -/* -* PCI Routing Table -* ----------------- -* Evaluate and parse _PRT, if exists. -*/ - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) - result =acpi_pci_irq_add_prt (device->handle, root->segment, - root->secondary.start); - root->mcfg_addr =acpi_pci_root_get_mcfg_addr (device->handle);/* @@ -602,7 +591,6 @@ out_del_root:list_del (&root->node);mutex_unlock (&acpi_pci_root_lock); -acpi_pci_irq_del_prt (root->segment, root->secondary.start); end:kfree (root);return result;@@ -610,8 +598,6 @@ end:static void acpi_pci_root_remove (struct acpi_device *device) { -acpi_status status; -acpi_handle handle;struct acpi_pci_root *root =acpi_driver_data (device);struct acpi_pci_driver *driver;@@ -626,10 +612,6 @@ static void acpi_pci_root_remove(structdevice_set_run_wake (root->bus->bridge, false);pci_acpi_remove_bus_pm_notifier (device); - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) -acpi_pci_irq_del_prt (root->segment, root->secondary.start); -pci_remove_root_bus (root->bus);mutex_lock (&acpi_pci_root_lock);Index:
linux-2.6/drivers/pci/pci-acpi.c
===================================================================drivers/pci/pci-acpi.c +0
-24@@ -307,25 +307,6 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; -acpi_status status; -acpi_handle dummy; - -/* -* Evaluate and parse _PRT, if exists. This code allows parsing of -* _PRT objects within the scope of non-bridge devices. Note that -* _PRTs within the scope of a PCI bridge assume the bridge's -* subordinate bus number. -* -* TBD: Can _PRTs exist within the scope of non-bridge PCI devices? -*/ - status =acpi_get_handle (handle,METHOD_NAME__PRT , &dummy); -if (ACPI_SUCCESS (status)) { -unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; -acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); - }if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;@@ -340,7 +321,6 @@ static void pci_acpi_setup(struct devicestatic void pci_acpi_cleanup (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev;@@ -349,10 +329,6 @@ static void pci_acpi_cleanup(struct devidevice_set_run_wake (dev, false);pci_acpi_remove_pm_notifier (adev); } - -if (pci_dev->subordinate) -acpi_pci_irq_del_prt (pci_domain_nr (pci_dev->bus), - pci_dev->subordinate->number); }static struct acpi_bus_type acpi_pci_bus = {Index:
linux-2.6/include/acpi/acpi_drivers.h
===================================================================include/acpi/acpi_drivers.h +0
-0@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_hand int *polarity, char **name);include/acpi/acpi_drivers.h int acpi_pci_link_allocate_irq(acpi_hand · line 95
Quoted 10 lines
include/acpi/acpi_drivers.h +0
-5int acpi_pci_link_free_irq (acpi_handle handle); -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus); -void acpi_pci_irq_del_prt (int segment,int bus); -/* ACPI PCI Device Binding (pci_bind.c) */ struct pci_bus ;--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas
maintainerRe: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 43 lines · Yinghai Lu
Quoted 27 lines · Rafael J. Wysocki
Quoted 26 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.So here we try to remove
_PRTcaching completely.Quoted 14 lines
Quoted 5 lines
-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Suggested-by Bjorn Helgaas <[email protected]>Signed-off-by Yinghai Lu <[email protected]>Quoted 6 lines
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)
Quoted 3 lines
Bjorn,
Can you put this one into pci/next?
I'm not sure what this patch is based on or what the best way to merge it is. It doesn't apply cleanly to my next or pci/yinghai-root-bus-hotplug branches.
I did apply it manually on top of pci/yinghai-root-bus-hotplug to try it out, but we need to tweak the messages a little bit.
Previously we printed "ACPI: PCI Interrupt Routing Table [%s._PRT]" once when loading it, which was fine. Now we print it every time we look at a _PRT, which is too much because it isn't really adding any information.
We also print "ACPI Exception: AE_NOT_FOUND, Evaluating _PRT [AE_NOT_FOUND] (20121018/pci_irq-259)" if we find ACPI nodes without _PRTs, which we shouldn't do, because that's a common and normal situation.
Bjorn
Quoted 339 lines
Quoted 339 lines
Quoted 322 lines
Index:
linux-2.6/drivers/acpi/pci_irq.c
===================================================================drivers/acpi/pci_irq.c +38
-57@@ -53,9 +53,6 @@ struct acpi_prt_entry {u32 index;/* GSI, or link _CRS index */ }; -static LIST_HEAD (acpi_prt_list); -static DEFINE_SPINLOCK (acpi_prt_lock); -static inline char pin_name (int pin) {return 'A' + pin -1 ;@@ -65,28 +62,6 @@ static inline char pin_name(int pin)PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry (struct pci_dev *dev, -int pin) -{ -struct acpi_prt_entry *entry; -int segment =pci_domain_nr (dev->bus); -int bus = dev->bus->number; -int device =PCI_SLOT (dev->devfn); - -spin_lock (&acpi_prt_lock); -list_for_each_entry (entry, &acpi_prt_list, list) { -if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { -spin_unlock (&acpi_prt_lock); -return entry; - } - } -spin_unlock (&acpi_prt_lock); -return NULL ; -} -/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ static const struct dmi_system_id medion_md9580[] = { {@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_pr } } -static int acpi_pci_irq_add_entry (acpi_handle handle,int segment,int bus, -struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_check_entry (acpi_handle handle,struct pci_dev *dev, +int pin,struct acpi_pci_routing_table *prt, +struct acpi_prt_entry **entry_ptr) { +int segment =pci_domain_nr (dev->bus); +int bus = dev->bus->number; +int device =PCI_SLOT (dev->devfn);struct acpi_prt_entry *entry; +if (((prt->address >>16 ) &0xffff ) != device || + prt->pin +1 != pin) +return -ENODEV ; + entry =kzalloc (sizeof (struct acpi_prt_entry ),GFP_KERNEL );if (!entry)return -ENOMEM ;@@ -237,26 +220,33 @@ static int acpi_pci_irq_add_entry(acpi_h entry->id.device,pin_name (entry->pin), prt->source, entry->index)); -spin_lock (&acpi_prt_lock); -list_add_tail (&entry->list, &acpi_prt_list); -spin_unlock (&acpi_prt_lock); + *entry_ptr = entry;return 0 ; } -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus) +static int acpi_pci_irq_find_prt_entry (struct pci_dev *dev, +int pin,struct acpi_prt_entry **entry_ptr) {acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_pci_routing_table *entry; +acpi_handle handle =NULL ; + +if (dev->bus->bridge) + handle =ACPI_HANDLE (dev->bus->bridge); + +if (!handle) +return -ENODEV ;/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ status =acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer);if (ACPI_FAILURE (status))return -ENODEV ; -printk (KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , - (char *) buffer.pointer); +dev_printk (KERN_DEBUG , &dev->dev, +"ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , + (char *) buffer.pointer);kfree (buffer.pointer);@@ -273,7 +263,9 @@ int acpi_pci_irq_add_prt(acpi_handle han entry = buffer.pointer;while (entry && (entry->length >0 )) { -acpi_pci_irq_add_entry (handle, segment, bus, entry); +if (!acpi_pci_irq_check_entry (handle, dev, pin, + entry, entry_ptr)) +break ; entry = (struct acpi_pci_routing_table *) ((unsigned long )entry + entry->length); }@@ -282,23 +274,6 @@ int acpi_pci_irq_add_prt(acpi_handle hanreturn 0 ; } -void acpi_pci_irq_del_prt (int segment,int bus) -{ -struct acpi_prt_entry *entry, *tmp; - -printk (KERN_DEBUG -"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n" , - segment, bus); -spin_lock (&acpi_prt_lock); -list_for_each_entry_safe (entry, tmp, &acpi_prt_list, list) { -if (segment == entry->id.segment && bus == entry->id.bus) { -list_del (&entry->list); -kfree (entry); - } - } -spin_unlock (&acpi_prt_lock); -} -/* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */ @@ -359,12 +334,13 @@ static int acpi_reroute_boot_interrupt(sstatic struct acpi_prt_entry *acpi_pci_irq_lookup (struct pci_dev *dev,int pin) { -struct acpi_prt_entry *entry; +struct acpi_prt_entry *entry =NULL ;struct pci_dev *bridge;u8 bridge_pin, orig_pin = pin; +int ret; - entry =acpi_pci_irq_find_prt_entry (dev, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (dev, pin, &entry); +if (!ret && entry) {#ifdef CONFIG_X86_IO_APIC acpi_reroute_boot_interrupt (dev, entry);#endif /* CONFIG_X86_IO_APIC */ @@ -373,7 +349,7 @@ static struct acpi_prt_entry *acpi_pci_ireturn entry; } -/* +/* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */ @@ -393,8 +369,8 @@ static struct acpi_prt_entry *acpi_pci_i pin = bridge_pin; } - entry =acpi_pci_irq_find_prt_entry (bridge, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (bridge, pin, &entry); +if (!ret && entry) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", pci_name(dev), pin_name(orig_pin),@@ -470,6 +446,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev_warn (&dev->dev,"PCI INT %c: no GSI\n" ,pin_name (pin)); } +return 0 ; }@@ -477,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev *if (rc <0 ) {dev_warn (&dev->dev,"PCI INT %c: failed to register GSI\n" ,pin_name (pin)); +kfree (entry);return rc; } dev->irq = rc;@@ -491,6 +469,7 @@ int acpi_pci_irq_enable(struct pci_dev * (triggering ==ACPI_LEVEL_SENSITIVE ) ?"level" :"edge" , (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); +kfree (entry);return 0 ; }@@ -513,6 +492,8 @@ void acpi_pci_irq_disable(struct pci_develse gsi = entry->index; +kfree (entry); +/* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ). Index:
linux-2.6/drivers/acpi/pci_root.c
===================================================================drivers/acpi/pci_root.c +0
-18@@ -413,7 +413,6 @@ static int acpi_pci_root_add(struct acpiacpi_status status;int result;struct acpi_pci_root *root; -acpi_handle handle;struct acpi_pci_driver *driver;u32 flags, base_flags;bool is_osc_granted = false;@@ -468,16 +467,6 @@ static int acpi_pci_root_add(struct acpiacpi_device_name (device),acpi_device_bid (device), root->segment, &root->secondary); -/* -* PCI Routing Table -* ----------------- -* Evaluate and parse _PRT, if exists. -*/ - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) - result =acpi_pci_irq_add_prt (device->handle, root->segment, - root->secondary.start); - root->mcfg_addr =acpi_pci_root_get_mcfg_addr (device->handle);/* @@ -602,7 +591,6 @@ out_del_root:list_del (&root->node);mutex_unlock (&acpi_pci_root_lock); -acpi_pci_irq_del_prt (root->segment, root->secondary.start); end:kfree (root);return result;@@ -610,8 +598,6 @@ end:static void acpi_pci_root_remove (struct acpi_device *device) { -acpi_status status; -acpi_handle handle;struct acpi_pci_root *root =acpi_driver_data (device);struct acpi_pci_driver *driver;@@ -626,10 +612,6 @@ static void acpi_pci_root_remove(structdevice_set_run_wake (root->bus->bridge, false);pci_acpi_remove_bus_pm_notifier (device); - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) -acpi_pci_irq_del_prt (root->segment, root->secondary.start); -pci_remove_root_bus (root->bus);mutex_lock (&acpi_pci_root_lock);Index:
linux-2.6/drivers/pci/pci-acpi.c
===================================================================drivers/pci/pci-acpi.c +0
-24@@ -307,25 +307,6 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; -acpi_status status; -acpi_handle dummy; - -/* -* Evaluate and parse _PRT, if exists. This code allows parsing of -* _PRT objects within the scope of non-bridge devices. Note that -* _PRTs within the scope of a PCI bridge assume the bridge's -* subordinate bus number. -* -* TBD: Can _PRTs exist within the scope of non-bridge PCI devices? -*/ - status =acpi_get_handle (handle,METHOD_NAME__PRT , &dummy); -if (ACPI_SUCCESS (status)) { -unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; -acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); - }if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)return ;@@ -340,7 +321,6 @@ static void pci_acpi_setup(struct devicestatic void pci_acpi_cleanup (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev;@@ -349,10 +329,6 @@ static void pci_acpi_cleanup(struct devidevice_set_run_wake (dev, false);pci_acpi_remove_pm_notifier (adev); } - -if (pci_dev->subordinate) -acpi_pci_irq_del_prt (pci_domain_nr (pci_dev->bus), - pci_dev->subordinate->number); }static struct acpi_bus_type acpi_pci_bus = {Index:
linux-2.6/include/acpi/acpi_drivers.h
===================================================================include/acpi/acpi_drivers.h +0
-0@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_hand int *polarity, char **name);include/acpi/acpi_drivers.h int acpi_pci_link_allocate_irq(acpi_hand · line 95
Quoted 10 lines
include/acpi/acpi_drivers.h +0
-5int acpi_pci_link_free_irq (acpi_handle handle); -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus); -void acpi_pci_irq_del_prt (int segment,int bus); -/* ACPI PCI Device Binding (pci_bind.c) */ struct pci_bus ;--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 44 lines · Bjorn Helgaas
Quoted 43 lines · Yinghai Lu
Quoted 41 lines · Rafael J. Wysocki
Quoted 24 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.Quoted 7 lines
So here we try to remove
_PRTcaching completely.-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Suggested-by Bjorn Helgaas <[email protected]>Signed-off-by Yinghai Lu <[email protected]>Quoted 6 lines
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)
Quoted 7 lines
Quoted 3 lines
Bjorn,
Can you put this one into pci/next?
I'm not sure what this patch is based on or what the best way to merge it is. It doesn't apply cleanly to my next or pci/yinghai-root-bus-hotplug branches.
My fault, that is based on pci/next + pm/linux-next
linux-next removed
acpi_power_resource_(un)register_device ...
Quoted 9 lines
I did apply it manually on top of pci/yinghai-root-bus-hotplug to try it out, but we need to tweak the messages a little bit.
Previously we printed "ACPI: PCI Interrupt Routing Table [%s._PRT]" once when loading it, which was fine. Now we print it every time we look at a
_PRT, which is too much because it isn't really adding any information.
Quoted 4 lines
We also print "ACPI Exception:
AE_NOT_FOUND, Evaluating_PRT[AE_NOT_FOUND] (20121018/pci_irq-259)" if we find ACPI nodes without_PRTs, which we shouldn't do, because that's a common and normal situation.
Sure. Can you have separated patch to do that ?
Or want me to resend the patch.
Thanks
Yinghai
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 67 lines · Yinghai Lu
Quoted 44 lines · Bjorn Helgaas
Quoted 43 lines · Yinghai Lu
Quoted 41 lines · Rafael J. Wysocki
Quoted 24 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.Quoted 7 lines
So here we try to remove
_PRTcaching completely.-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Suggested-by Bjorn Helgaas <[email protected]>Signed-off-by Yinghai Lu <[email protected]>Quoted 6 lines
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)Quoted 7 lines
Quoted 3 lines
Bjorn,
Can you put this one into pci/next?
I'm not sure what this patch is based on or what the best way to merge it is. It doesn't apply cleanly to my next or pci/yinghai-root-bus-hotplug branches.
My fault, that is based on pci/next + pm/linux-next
linux-next removed
acpi_power_resource_(un)register_device ...Quoted 9 lines
I did apply it manually on top of pci/yinghai-root-bus-hotplug to try it out, but we need to tweak the messages a little bit.
Previously we printed "ACPI: PCI Interrupt Routing Table [%s._PRT]" once when loading it, which was fine. Now we print it every time we look at a
_PRT, which is too much because it isn't really adding any information.
Quoted 8 lines
Quoted 4 lines
We also print "ACPI Exception:
AE_NOT_FOUND, Evaluating_PRT[AE_NOT_FOUND] (20121018/pci_irq-259)" if we find ACPI nodes without_PRTs, which we shouldn't do, because that's a common and normal situation.Sure. Can you have separated patch to do that ?
Or want me to resend the patch.
Please check attached updated version that remove print out ...
and it could be applied cleanly on top of pci/yinghai-root-bus-hotplug
Thanks
Yinghai
From: Yinghai Lu <[email protected]>
Subject: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5
bisect to
| commit 4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Put pci_dev in device tree as early as possible
It turns out we need to call acpi_pci_irq_add_prt() after the pci bridges are scanned.
Bjorn said:
The bus number binding means acpi_pci_irq_add_prt() has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.
I think we should remove the bus numbers from the cached _PRT (or maybe even remove the _PRT caching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a _PRT associated with each node, and applying normal PCI bridge swizzling when we don't find a _PRT. I think this can be done without using PCI bus numbers at all.
So here we try to remove _PRT caching completely.
-v2: check !handle early.
-v3: remove not needed print out according to Bjorn.
--- drivers/acpi/pci_irq.c | 102 ++++++++++++++------------------------------ drivers/acpi/pci_root.c | 18 ------- drivers/pci/pci-acpi.c | 24 ---------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 34 insertions(+), 115 deletions(-)
drivers/acpi/pci_irq.c +34 -68
@@ -53,9 +53,6 @@ struct acpi_prt_entry {u32 index;/* GSI, or link _CRS index */ }; -static LIST_HEAD (acpi_prt_list); -static DEFINE_SPINLOCK (acpi_prt_lock); -static inline char pin_name (int pin) {return 'A' + pin -1 ;
@@ -65,28 +62,6 @@ static inline char pin_name(int pin)PCI IRQ Routing Table (PRT) Support -------------------------------------------------------------------------- */ -static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry (struct pci_dev *dev, -int pin) -{ -struct acpi_prt_entry *entry; -int segment =pci_domain_nr (dev->bus); -int bus = dev->bus->number; -int device =PCI_SLOT (dev->devfn); - -spin_lock (&acpi_prt_lock); -list_for_each_entry (entry, &acpi_prt_list, list) { -if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { -spin_unlock (&acpi_prt_lock); -return entry; - } - } -spin_unlock (&acpi_prt_lock); -return NULL ; -} -/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ static const struct dmi_system_id medion_md9580[] = { {
@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_pr } } -static int acpi_pci_irq_add_entry (acpi_handle handle,int segment,int bus, -struct acpi_pci_routing_table *prt) +static int acpi_pci_irq_check_entry (acpi_handle handle,struct pci_dev *dev, +int pin,struct acpi_pci_routing_table *prt, +struct acpi_prt_entry **entry_ptr) { +int segment =pci_domain_nr (dev->bus); +int bus = dev->bus->number; +int device =PCI_SLOT (dev->devfn);struct acpi_prt_entry *entry; +if (((prt->address >>16 ) &0xffff ) != device || + prt->pin +1 != pin) +return -ENODEV ; + entry =kzalloc (sizeof (struct acpi_prt_entry ),GFP_KERNEL );if (!entry)return -ENOMEM ;
@@ -237,43 +220,37 @@ static int acpi_pci_irq_add_entry(acpi_h entry->id.device,pin_name (entry->pin), prt->source, entry->index)); -spin_lock (&acpi_prt_lock); -list_add_tail (&entry->list, &acpi_prt_list); -spin_unlock (&acpi_prt_lock); + *entry_ptr = entry;return 0 ; } -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus) +static int acpi_pci_irq_find_prt_entry (struct pci_dev *dev, +int pin,struct acpi_prt_entry **entry_ptr) {acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_pci_routing_table *entry; +acpi_handle handle =NULL ; -/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ - status =acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer); -if (ACPI_FAILURE (status)) -return -ENODEV ; - -printk (KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n" , - (char *) buffer.pointer); - -kfree (buffer.pointer); +if (dev->bus->bridge) + handle =ACPI_HANDLE (dev->bus->bridge); - buffer.length =ACPI_ALLOCATE_BUFFER ; - buffer.pointer =NULL ; +if (!handle) +return -ENODEV ; +/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ status =acpi_get_irq_routing_table (handle, &buffer);if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _PRT [%s]" , -acpi_format_exception (status)));kfree (buffer.pointer);return -ENODEV ; } entry = buffer.pointer;while (entry && (entry->length >0 )) { -acpi_pci_irq_add_entry (handle, segment, bus, entry); +if (!acpi_pci_irq_check_entry (handle, dev, pin, + entry, entry_ptr)) +break ; entry = (struct acpi_pci_routing_table *) ((unsigned long )entry + entry->length); }
@@ -282,23 +259,6 @@ int acpi_pci_irq_add_prt(acpi_handle hanreturn 0 ; } -void acpi_pci_irq_del_prt (int segment,int bus) -{ -struct acpi_prt_entry *entry, *tmp; - -printk (KERN_DEBUG -"ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n" , - segment, bus); -spin_lock (&acpi_prt_lock); -list_for_each_entry_safe (entry, tmp, &acpi_prt_list, list) { -if (segment == entry->id.segment && bus == entry->id.bus) { -list_del (&entry->list); -kfree (entry); - } - } -spin_unlock (&acpi_prt_lock); -} -/* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */
@@ -359,12 +319,13 @@ static int acpi_reroute_boot_interrupt(sstatic struct acpi_prt_entry *acpi_pci_irq_lookup (struct pci_dev *dev,int pin) { -struct acpi_prt_entry *entry; +struct acpi_prt_entry *entry =NULL ;struct pci_dev *bridge;u8 bridge_pin, orig_pin = pin; +int ret; - entry =acpi_pci_irq_find_prt_entry (dev, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (dev, pin, &entry); +if (!ret && entry) {#ifdef CONFIG_X86_IO_APIC acpi_reroute_boot_interrupt (dev, entry);#endif /* CONFIG_X86_IO_APIC */
@@ -373,7 +334,7 @@ static struct acpi_prt_entry *acpi_pci_ireturn entry; } -/* +/* * Attempt to derive an IRQ for this device from a parent bridge's * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). */
@@ -393,8 +354,8 @@ static struct acpi_prt_entry *acpi_pci_i pin = bridge_pin; } - entry =acpi_pci_irq_find_prt_entry (bridge, pin); -if (entry) { + ret =acpi_pci_irq_find_prt_entry (bridge, pin, &entry); +if (!ret && entry) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", pci_name(dev), pin_name(orig_pin),
@@ -470,6 +431,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev_warn (&dev->dev,"PCI INT %c: no GSI\n" ,pin_name (pin)); } +return 0 ; }
@@ -477,6 +439,7 @@ int acpi_pci_irq_enable(struct pci_dev *if (rc <0 ) {dev_warn (&dev->dev,"PCI INT %c: failed to register GSI\n" ,pin_name (pin)); +kfree (entry);return rc; } dev->irq = rc;
@@ -491,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev * (triggering ==ACPI_LEVEL_SENSITIVE ) ?"level" :"edge" , (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); +kfree (entry);return 0 ; }
@@ -513,6 +477,8 @@ void acpi_pci_irq_disable(struct pci_develse gsi = entry->index; +kfree (entry); +/* * TBD: It might be worth clearing dev->irq by magic constant * (e.g. PCI_UNDEFINED_IRQ).
drivers/acpi/pci_root.c +0 -18
@@ -434,7 +434,6 @@ static int acpi_pci_root_add(struct acpiacpi_status status;int result;struct acpi_pci_root *root; -acpi_handle handle;struct acpi_pci_driver *driver;u32 flags, base_flags;bool is_osc_granted = false;
@@ -489,16 +488,6 @@ static int acpi_pci_root_add(struct acpiacpi_device_name (device),acpi_device_bid (device), root->segment, &root->secondary); -/* -* PCI Routing Table -* ----------------- -* Evaluate and parse _PRT, if exists. -*/ - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) - result =acpi_pci_irq_add_prt (device->handle, root->segment, - root->secondary.start); - root->mcfg_addr =acpi_pci_root_get_mcfg_addr (device->handle);/*
@@ -623,7 +612,6 @@ out_del_root:list_del (&root->node);mutex_unlock (&acpi_pci_root_lock); -acpi_pci_irq_del_prt (root->segment, root->secondary.start); end:kfree (root);return result;
@@ -631,8 +619,6 @@ end:static int acpi_pci_root_remove (struct acpi_device *device,int type) { -acpi_status status; -acpi_handle handle;struct acpi_pci_root *root =acpi_driver_data (device);struct acpi_pci_driver *driver;
@@ -647,10 +633,6 @@ static int acpi_pci_root_remove(struct adevice_set_run_wake (root->bus->bridge, false);pci_acpi_remove_bus_pm_notifier (device); - status =acpi_get_handle (device->handle,METHOD_NAME__PRT , &handle); -if (ACPI_SUCCESS (status)) -acpi_pci_irq_del_prt (root->segment, root->secondary.start); -pci_remove_root_bus (root->bus);mutex_lock (&acpi_pci_root_lock);
drivers/pci/pci-acpi.c +0 -24
@@ -325,25 +325,6 @@ static void pci_acpi_setup(struct devicestruct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev; -acpi_status status; -acpi_handle dummy; - -/* -* Evaluate and parse _PRT, if exists. This code allows parsing of -* _PRT objects within the scope of non-bridge devices. Note that -* _PRTs within the scope of a PCI bridge assume the bridge's -* subordinate bus number. -* -* TBD: Can _PRTs exist within the scope of non-bridge PCI devices? -*/ - status =acpi_get_handle (handle,METHOD_NAME__PRT , &dummy); -if (ACPI_SUCCESS (status)) { -unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; -acpi_pci_irq_add_prt (handle,pci_domain_nr (pci_dev->bus), bus); - }acpi_power_resource_register_device (dev, handle);if (acpi_bus_get_device (handle, &adev) || !adev->wakeup.flags.valid)
@@ -359,7 +340,6 @@ static void pci_acpi_setup(struct devicestatic void pci_acpi_cleanup (struct device *dev) { -struct pci_dev *pci_dev =to_pci_dev (dev);acpi_handle handle =ACPI_HANDLE (dev);struct acpi_device *adev;
@@ -369,10 +349,6 @@ static void pci_acpi_cleanup(struct devipci_acpi_remove_pm_notifier (adev); }acpi_power_resource_unregister_device (dev, handle); - -if (pci_dev->subordinate) -acpi_pci_irq_del_prt (pci_domain_nr (pci_dev->bus), - pci_dev->subordinate->number); }static struct acpi_bus_type acpi_pci_bus = {
include/acpi/acpi_drivers.h +0 -5
@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_hand int *polarity, char **name);int acpi_pci_link_free_irq (acpi_handle handle); -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle,int segment,int bus); -void acpi_pci_irq_del_prt (int segment,int bus); -/* ACPI PCI Device Binding (pci_bind.c) */ struct pci_bus ;
Bjorn Helgaas
maintainerRe: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 73 lines · Yinghai Lu
Quoted 72 lines · Yinghai Lu
Quoted 44 lines · Bjorn Helgaas
Quoted 43 lines · Yinghai Lu
Quoted 41 lines · Rafael J. Wysocki
Quoted 24 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.Quoted 7 lines
So here we try to remove
_PRTcaching completely.-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Suggested-by Bjorn Helgaas <[email protected]>Signed-off-by Yinghai Lu <[email protected]>Quoted 6 lines
--- drivers/acpi/pci_irq.c | 95 +++++++++++++++++--------------------------- drivers/acpi/pci_root.c | 18 -------- drivers/pci/pci-acpi.c | 24 ----------- include/acpi/acpi_drivers.h | 5 -- 4 files changed, 38 insertions(+), 104 deletions(-)Quoted 7 lines
Quoted 3 lines
Bjorn,
Can you put this one into pci/next?
I'm not sure what this patch is based on or what the best way to merge it is. It doesn't apply cleanly to my next or pci/yinghai-root-bus-hotplug branches.
My fault, that is based on pci/next + pm/linux-next
linux-next removed
acpi_power_resource_(un)register_device ...Quoted 13 lines
I did apply it manually on top of pci/yinghai-root-bus-hotplug to try it out, but we need to tweak the messages a little bit.
Previously we printed "ACPI: PCI Interrupt Routing Table [%s._PRT]" once when loading it, which was fine. Now we print it every time we look at a
_PRT, which is too much because it isn't really adding any information.We also print "ACPI Exception:
AE_NOT_FOUND, Evaluating_PRT[AE_NOT_FOUND] (20121018/pci_irq-259)" if we find ACPI nodes without_PRTs, which we shouldn't do, because that's a common and normal situation.
Quoted 7 lines
Quoted 3 lines
Sure. Can you have separated patch to do that ?
Or want me to resend the patch.
Please check attached updated version that remove print out ...
and it could be applied cleanly on top of pci/yinghai-root-bus-hotplug
Thanks, I applied this to pci/yinghai-root-bus-hotplug and merged it into my next branch.
Bjorn
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
In reply to Yinghai LuQuoted 24 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.
Quoted 5 lines
So here we try to remove
_PRTcaching completely.-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>
Actually true now :)
Regards and thanks again,
Peter Hurley
PS - I just happened to see this version on the list. Would you please cc me on any future versions?
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 27 lines · Peter Hurley
Quoted 26 lines · Yinghai Lu
Peter Hurley found "irq 18 nobody cared" with pci-next, and dmesg has
[ 8.983246] pci 0000:00:1e.0: can't derive routing for PCI INT A [ 8.983600] snd_ctxfi 0000:09:02.0: PCI INT A: no GSI - using ISA IRQ 5bisect to
| commit4f535093cf8f6da8cfda7c36c2c1ecd2e9586ee4
| PCI: Putpci_devin device tree as early as possibleIt turns out we need to call
acpi_pci_irq_add_prt()after the pci bridges are scanned.Bjorn said:
The bus number binding meansacpi_pci_irq_add_prt()has to happen after enumerating everything below a bridge, and it will prevent us from doing any bus number reassignment for hotplug.I think we should remove the bus numbers from the cached
_PRT(or maybe even remove the_PRTcaching completely). When we enable a PCI device's IRQ, we should search up the PCI device tree looking for a_PRTassociated with each node, and applying normal PCI bridge swizzling when we don't find a_PRT. I think this can be done without using PCI bus numbers at all.So here we try to remove
_PRTcaching completely.
Quoted 7 lines
Quoted 3 lines
-v2: check !handle early.
Reported-and-tested-by Peter Hurley <[email protected]>Actually true now :)
Reported-and-tested-by Peter Hurley <[email protected]>
Thanks.
Quoted 2 lines
PS - I just happened to see this version on the list. Would you please cc me on any future versions?
oh, my fault. I take it for granted that "git send-email" will pick that email from
patch just like Cc.
Yinghai
Re: [PATCH] ACPI, PCI: Get PRT entry during acpi_pci_enable_irq()
Quoted 4 lines · Yinghai Lu
Quoted 2 lines · Peter Hurley
Reported-and-tested-by Peter Hurley <[email protected]>
Quoted 8 lines
Thanks.
Quoted 2 lines
PS - I just happened to see this version on the list. Would you please cc me on any future versions?
oh, my fault. I take it for granted that "git send-email" will pick that email from
patch just like Cc.
No problem. Actually, I'm sorry it took this long for me to test. I was stuck in an epic bisect that I eventually abandoned at the 41st test with it still in merge bases.