> On Mar 24, 2021, at 8:09 AM, Paul Goyette <p...@whooppee.com> wrote:
>
> I think you got it!
>
> Now, we just need to record this critical info somewhere, so we can
> find it again in the future!
I’ll at least add some comments, certainly.
I think some of the confusion stems from the differences between “direct
configuration” and “indirect configuration”. I’ve considered writing up a
short treatise on how all this works, but a quick primer will have to do :-)
Direct configuration: Used in the cases where the interface attribute has
built-in enumeration support, and where the things that attach to it are
self-describing. Examples: PCI, EISA, or simple busses backed by a platform
description mechanism like ACPI, OpenFirmware, or FDT.
Indirect configuration: Used in cases where the interface attribute has no
built-in support for enumeration and there is no platform description to fall
back on. Examples: ISA, VME, SPI, I2C, memory-mapped device space on e.g.
sun3, and other simple busses.
In direct configuration, what drives driver matching is enumeration of the
devices; identifying information is retrieved, the location of the device
recorded, and the kernel’s configuration data is searched for a driver that
matches the description (and maybe the location, if the kernel configuration
wires down specific instances to specific locations). The driver that reports
the best match is then asked to attach an instance of itself to the found
device (which is why we use a routine called “config_found()” for this, at
least in the common cases…)
In indirect configuration, what drives driver matching is the kernel
configuration file; the kernel configuration data is searched for config
directives that are eligible to attach to a specific parent, and the driver
associated with that config directive is asked to probe for a device it
recognizes. The location to probe comes from the config directive.
config_search() is the routine used for this, and it’s provided a “submatch”
routine that is responsible for extracting the config directive data (from a
cfdata_t) into the appropriate “attach args” structure for that interface
attribute and calling the “match” routine. If the match routine returns
non-zero, it immediately calls the “attach” routine.
In direct configuration, the locators are a filter whose main usefulness is to
wire specific physical device locations to specific driver instances. In this
instance, the locators passed to “rescan” narrow the scope of enumeration, but
should not be passed through to config_found() / config_search() as locators
where the device was found because 99.99999999999% of the time they’ll just be
wildcards.
In indirect configuration, the locators are everything, and these must, by
their nature, be passed by “rescan” to config_search() because it’s what
defines where to probe for something.
>
> Maybe an "implementation detail" section added to autoconfig(8) man
> page?
>
>
> On Wed, 24 Mar 2021, Jason Thorpe wrote:
>
>> There appears to be come inconsistency and/or confusion regarding the usage
>> of the “locators” argument passed to the (*ca_rescan)() functions.
>>
>> Background: drochner@ added this rescan mechanism back in 2004 to support
>> driver modules providing cfdata, to facilitate correct device->driver
>> matching when driver modules are loaded.
>>
>> It appears as though sys/dev/pci/pci.c uses it as intended:
>>
>> - pci_attach() creates “wildcard” locators and passes them to pcirescan().
>>
>> - Takes passes these “wildcard” locators on to pci_enumerate_bus(), which
>> uses them to filter which PCI device locations to enumerate. Eventually,
>> pci_probe_device() is called. Note, the “locators” array is no longer
>> passed through .. it was meant only to filter where on the bus to look.
>>
>> - pci_probe_device() looks for a device at the requested location, and if it
>> finds one, it constructs a *new* locators array that indicates the actual
>> location, and passes *that* to config_found() (in mainline,
>> config_found_sm_loc()). The sub match routine pci uses is
>> config_stdsubmatch().
>>
>> - config_stdsubmatch() uses the locators in the cfdata it receives to check
>> if that spec (i.e. the user-specified location) matches the data in the
>> locators array passed by pci_probe_device().
>>
>> This appears to be the original intended use. However, a bunch of the
>> (*ca_rescan)() routines do not use it properly. “Since I’m here already
>> (for other reasons), …” I’ll go ahead and audit these routines and fix them
>> up. But I wanted to confirm that my understanding of “how it’s supposed to
>> work” is correct.
>>
>> (It’s really amazing how fast copy-paste can propagate an anti-pattern…)
>>
>> Thx.
>>
>> -- thorpej
>>
>>
>> !DSPAM:605b5578133582098537439!
>>
>>
>
> +--------------------+--------------------------+-----------------------+
> | Paul Goyette | PGP Key fingerprint: | E-mail addresses: |
> | (Retired) | FA29 0E3B 35AF E8AE 6651 | p...@whooppee.com |
> | Software Developer | 0786 F758 55DE 53BA 7731 | pgoye...@netbsd.org |
> +--------------------+--------------------------+-----------------------+
-- thorpej