Re: page fault panic in device_get_softc/acpi_pcib_route_interrupt

From: Nate Lawson <nate_at_root.org>
Date: Wed, 05 Jan 2005 15:02:40 -0800
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
Received on Wed Jan 05 2005 - 22:02:57 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:25 UTC