polarity. Some machines route PCI IRQs to an ISA IRQ but fail to include
an interrupt override entry to set the polarity and trigger of the given
ISA IRQ in their MADT table.
PR: usb/74989
Reported by: Julien Gabel jpeg at thilelli dot net
MFC after: 1 week
entry that is not zero, assume that it is really a hard-wired IRQ (commonly
used for APIC routing) and not a source index. In practice, we've only
ever seen source indices of 0 for legitimate non-hard-wired _PRT entries.
Reviewed by: njl
Tested by: Alex Lyashkov shadow at psoft dot net
MFC after: 2 weeks
- Fix a bug in the same condition where we forgot to drop the ACPI pcib
lock. This fixes hangs after the pcib0 attach on some machines.
Tested by: sos (2)
object (/) rather than the pci bus object when walking the _PRT to force
attach devices. We already look up relative to the root object when doing
interrupt routing.
Suggested by: njl
- Use a new-bus device driver for the ACPI PCI link devices. The devices
are called pci_linkX. The driver includes suspend/resume support so that
the ACPI bridge drivers no longer have to poke the links to get them
to handle suspend/resume. Also, the code to handle which IRQs a link is
routed to and choosing an IRQ when a link is not already routed is all
contained in the link driver. The PCI bridge drivers now ask the link
driver which IRQ to use once they determine that a _PRT entry does not
use a hardwired interrupt number.
- The new link driver includes support for multiple IRQ resources per
link device as well as preserving any non-IRQ resources when adjusting
the IRQ that a link is routed to.
- The entire approach to routing when using a link device is now
link-centric rather than pci bus/device/pin specific. Thus, when
using a tunable to override the default IRQ settings, one now uses
a single tunable to route an entire link rather than routing a single
device that uses the link (which has great foot-shooting potential if
the user tries to route the same link to two different IRQs using two
different pci bus/device/pin hints). For example, to adjust the IRQ
that \_SB_.LNKA uses, one would set 'hw.pci.link.LNKA.irq=10' from the
loader.
- As a side effect of having the link driver, unused link devices will now
be disabled when they are probed.
- The algorithm for choosing an IRQ for a link that doesn't already have an
IRQ assigned is now much closer to the one used in $PIR routing. When a
link is routed via an ISA IRQ, only known-good IRQs that the BIOS has
already used are used for routing instead of using probabilities to
guess at which IRQs are probably not used by an ISA device. One change
from $PIR is that the SCI is always considered a viable ISA IRQ, so that
if the BIOS does not setup any IRQs the kernel will degenerate to routing
all interrupts over the SCI. For non ISA IRQs, interrupts are picked
from the possible pool using a simplistic weighting algorithm.
Tested by: ru, scottl, others on acpi@
Reviewed by: njl
a bridge without a _PRT were a _PRT was needed. Instead, the warning in
dmesg is a false warning and only serves to cause unnecessary concern.
MFC after: 1 week
there is no irq link. Since we now use the stored copy of PRT, not the
one that used to be passed into acpi_pcib_route_interrupt(), we need it in
the list. [1]
Fix a bug in acpi_pci_find_prt() where we weren't checking the bus, thus
choosing the wrong PRT entry to use for routing the link. Also, add a
printf for the case where the PRT entry is not found as this should not
happen.
Tested by: marcel [1]
incomplete in that the PRT routing was not aware of link programming.
Fix this by doing all routing through the link devices. The new algorithm
for setting up links is:
1. Read _CRS to get current setting. If invalid (not in _PRS), then set
to 0.
2. Attempt to call _DIS on the link. If successful, mark the link as not
routed. Otherwise, assume it still is.
Then when a routing request occurs:
3. Update weights for all IRQs
4. Attempt to route the initial IRQ if valid
5. If that fails, walk through the sorted list, attempting to route IRQs.
6. Configure the trigger/polarity based on _PRS.
Other changes:
* Add acpi_pci_find_prt() to look up the PRT entry for a given device and
acpi_pci_link_route() to select/route the best IRQ for it.
* Remove duplicated code in acpi_pcib_route_interrupt() that picked the
first IRQ from _PRS.
* Remove unneeded arguments from acpi_pcib_resume() and friends.
* Ignore _STA on link devices but report if it seems strange.
* Add a prt_source handle to the PRT structure since the ACPI struct
ACPI_PCI_ROUTING_TABLE uses a fixed-size entry for it. We'll need to
dynamically size this object if we want to use it the same way ACPI-CA
does. Null-terminate the source.
Tested by: Luo Hong <luohong99_at_mails.tsinghua.edu.cn>,
Jeffrey Katcher <jmkatcher_at_yahoo.com>
Info from: jhb, Len Brown (Intel)
actually used. For most ACPI devices this means deferring the call
until bus_alloc_resource().
- Add a function acpi_config_intr() to call BUS_CONFIG_INTR() for an
ACPI IRQ resource using the trigger mode and polarity information
stored in the ACPI resource object.
- Add a function acpi_lookup_irq_resource() to lookup the ACPI IRQ
resource that corresponds to a specified rid and new-bus resource.
- Have the ACPI PCI bridge driver call BUS_CONFIG_INTR() on interrupts
that it routes through link devices.
- Remove needactivate variable from acpi_alloc_resource() by changing the
function not modify the flags variable but just mask off RF_ACTIVE when
calling rman_reserve_resource().
Reviewed by: njl (1, an earlier version)
a NULL crsbuf pointer. This shouldn't happen if it returns AE_OK. We'll
figure out why this is happening later.
Submitted by: Bruno Ducrot <ducrot@poupinou.org>
This completes the effort to handle dependent functions, which are used
in some machines for irq link resources. Also, clean up some nearby
comments while I'm at it.
Implement this in acpi_MatchHid() and acpi_isa_get_compatid(). This
should fix mouse support for some users.
Move all users of AcpiGetObjectInfo() to use dynamic storage instead of
a devinfo on the stack. This is necessary since ACPI-CA needs to
allocate different sized arrays for the CompatList.
- For acpi_pci_link_entry_dump(), add a few helper functions to display
the trigger mode, polarity, and sharemode of an individual IRQ resource.
These functions are then called for both regular and extended IRQ
resources.
- In acpi_pci_link_set_irq(), use the same type of IRQ resource
(regular vs. extended) for the new current resource as the type of
the resources from _PRS.
- When routing an interrupt don't ignore extended IRQ resources. Also,
use the same type of IRQ resource (regular vs. extended) for the new
current resource when as the type of the resource from _PRS.
Tested by: peter
* Use ACPI_BUFFER as the type for AcpiGetObjectInfo
* Remove AcpiEnableEvent/AcpiClearEvent for ACPI_EVENT_FIXED (power/sleep
buttons) as they are no longer needed
* Change calls to use the new GPE functions
* Add AcpiOs*Lock functions
This allocate the best IRQ to boot-disable devices (have IRQ 0).
Allocated IRQ will be used for PCI interrupt routing when ACPI is
enabled.
Note that verbose messaging enabled for the time being so that
people can easily notice the strange behavior if it happened.
- Add an ACPI PCI-PCI bridge driver (the previous driver just handled
Host-PCI bridges) that is a PCI driver that is a subclass of the generic
PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and
pci_route_interrupt.
- The probe routine only succeeds if our parent is an ACPI PCI bus which
we test for by seeing if we can read our ACPI_HANDLE as an ivar.
- The attach routine saves a copy of our handle and calls the new
acpi_pcib_attach_common() function described below.
- The read_ivar routine handles normal PCI-PCI bridge ivars and adds an
ivar to return the ACPI_HANDLE of the bus this bridge represents.
- The route_interrupt routine fetches the _PRT (PCI Interrupt Routing
Table) from the bridge device's softc and passes it off to
acpi_pcib_route_interrupt() to route the interrupt.
- Split the old ACPI Host-PCI bridge driver into two pieces. Part of
the attach routine and most of the route_interrupt routine remain in
acpi_pcib.c and are shared by both ACPI PCI bridge drivers.
- The attach routine verifies the PCI bridge is present, reads in
the _PRT for the bridge, and attaches the child PCI bus.
- The route_interrupt routine uses the passed in _PRT to route a PCI
interrupt.
The rest of the driver is the ACPI Host-PCI bridge specific bits that
live in acpi_pcib_acpi.c.
- We no longer duplicate pcib_maxslots but use it directly.
- The driver now uses the pcib devclass instead of its own devclass.
This means that PCI busses are now only children of pcib devices.
- Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar
of the child bus.
- Fetch the _PRT for routing PCI interrupts directly from our softc
instead of walking the devclass to find ourself and then fetch our
own softc.
With this change and the new ACPI PCI bus driver, ACPI can now properly
route interrupts for devices behind PCI-PCI bridges. That is, the
Itanium2 with like 10 PCI busses can now boot ok and route all the PCI
interrupts. Hopefully this will also fix problems people are having with
CardBus bridges behind PCI-PCI bridges not properly routing interrupts
when ACPI is used.
Tested on: i386, ia64
LNK device (interrupt source provider sort of) is present before using it,
but the code actually tested the status (_STA) of the PCI bridge device
doing the routing, not the actual LNK device. Fix it to check the status
of the LNK device.
Use ACPI_SUCCESS/ACPI_FAILURE consistently.
The AcpiGetInto* interfaces are obsoleted by ACPI_ALLOCATE_BUFFER.
Use _ADR as well as _BBN to get our bus number.
Fix acpi_DeviceIsPresent to check for valid _STA data and to check
the "present" and "functioning" bits.
Use acpi_DeviceIsPresent in acpi_pcib rather than rolling our own
(also broken) version.
in the case where there are no interrupts routed for it does not
contain enough space to use it to route an interrupt. In the case
where we need to route an interrupt, throw away the returned buffer
and create a new one containing the interrupt we want.