page fault panic in device_get_softc/acpi_pcib_route_interrupt
Nate Lawson
nate at root.org
Wed Jan 5 15:02:57 PST 2005
John Baldwin wrote:
> On Sunday 02 January 2005 07:35 pm, Nate Lawson wrote:
>>We already associate handles and devices in
>>sys/dev/acpica/acpi.c:acpi_probe_child() before probing anything. See
>>the AcpiAttachData() step. I don't think that's the problem.
>
> I do because he passes a null device_t pointer in as an argument to a
> function. The calling code is:
>
> /*
> * We have to find the source device (PCI interrupt link device).
> */
> if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, prt->Source, &lnkdev))) {
> device_printf(pcib, "couldn't find PCI interrupt link device %s\n",
> prt->Source);
> interrupt = acpi_pci_link_route_interrupt(acpi_get_device(lnkdev),
> prt->SourceIndex);
>
> And Pawel's trace shows that the first argument to
> acpi_pci_link_route_interrupt() is NULL.
What's the value of prt->Source? If it's not a valid reference to a
link device (i.e. \_SB.PCIx.LNKx), then trying to get a device_t from it
would yield NULL. For instance, if it points to \_SB, you'll get a
valid handle from AcpiGetHandle but that handle obviously has no
associated device_t.
Additionally, I see you're using the root handle ACPI_ROOT_OBJECT as the
base for lookup. If the reference is relative (doesn't start with \),
this won't work. You should be using the handle of the parent of _PRT
(the PCI bus handle) as the root of the lookup. Commonly, this will be
something like a \_SB.PCI0 string.
This would fix this scenario:
\_SB.PCI0
_PRT (Source = LNKA)
LNKA
LNKB
Also, I'm not sure if you picked up the size issue with the _PRT struct
supplied by ACPI-CA. Since Source is a variable-length string, if you
copy the struct you get from AcpiGetRoutingTable (or whatever), you only
get the first 4 bytes, non-null terminated, of the string.
typedef struct acpi_pci_routing_table
{
UINT32 Length;
UINT32 Pin;
ACPI_INTEGER Address;
UINT32 SourceIndex;
char Source[4];
} ACPI_PCI_ROUTING_TABLE;
Note that Source above is not 4 bytes, it's variable-length. That's why
I copied it to a different field in the old acpi_pci_link PRT struct.
>
>>I do think the problem is that his link devices are not being probed
>>(and thus lack a softc) before the device that wants to route interrupts
>>via that link. The acpi_probe_order() hack would make sure that this
>>happens. Since all acpi devices are ordered by default based on the AML
>>tree hammered flat, dependencies have to be set by the bus drivers. PCI
>>does this correctly and I updated FDC to do this. ATA and others
>>currently do not but they don't use acpi yet.
>
>
> I already force-attach link devices when walking the _PRT during a pci bridge
> device's attach routine, meaning that any links mentioned in the _PRT for a
> given bridge are guaranteed to be attached before any child devices of that
> bridge (including the pci bus and all the pci devices on it).
>
--
Nate
More information about the freebsd-current
mailing list