> 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

Reply via email to