博客

Platform Devices and Drivers

Platform devices~~~~~~~~~~~~~~~~Platform devices are devices that typically appear as autonomousentities in the system. This includes legacy port-based devices andhost bridges to peripheral buses.

Platform drivers~~~~~~~~~~~~~~~~Drivers for platform devices are typically very simple andunstructured. Either the device was present at a particular I/O portand the driver was loaded, or it was not. There was no possibilityof hotplugging or alternative discovery besides probing at a specificI/O address and expecting a specific response.

Other Architectures, Modern Firmware, and new Platforms~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~These devices are not always at the legacy I/O ports. This is true onother architectures and on some modern architectures. In most cases,the drivers are modified to discover the devices at other well-knownports for the given platform. However, the firmware in these systemsdoes usually know where exactly these devices reside, and in somecases, it's the only way of discovering them.

The Platform Bus~~~~~~~~~~~~~~~~A platform bus has been created to deal with these issues. First andforemost, it groups all the legacy devices under a common bus, andgives them a common parent if they don't already have one.

Device Discovery~~~~~~~~~~~~~~~~The platform bus has no concept of probing for devices. Devicesdiscovery is left up to either the legacy drivers or thefirmware. These entities are expected to notify the platform ofdevices that it discovers via the bus's add() callback:

platform_bus.add(parent,bus_id).

Bus IDs~~~~~~~Bus IDs are the canonical names for the devices. There is no globallystandard addressing mechanism for legacy devices. In the IA-32 world,we have Pnp IDs to use, as well as the legacy I/O ports. However,neither tell what the device really is or have any meaning on otherplatforms.

Since both PnP IDs and the legacy I/O ports (and other standard I/Oports for specific devices) have a 1:1 mapping, we map theplatform-specific name or identifier to a generic name (at leastwithin the scope of the kernel).

For example, a serial driver might find a device at I/O 0x3f8. TheACPI firmware might also discover a device with PnP ID (_HID)PNP0501. Both correspond to the same device and should be mapped to thecanonical name 'serial'.

The bus_id field should be a concatenation of the canonical name andthe instance of that type of device. For example, the device at I/Oport 0x3f8 should have a bus_id of "serial0". This places theresponsibility of enumerating devices of a particular type up to thediscovery mechanism. But, they are the entity that should know best(as opposed to the platform bus driver).

Drivers ~~~~~~~Drivers for platform devices should have a name that is the same asthe canonical name of the devices they support. This allows theplatform bus driver to do simple matching with the basic datastructures to determine if a driver supports a certain device.

For example, a legacy serial driver should have a name of 'serial' andregister itself with the platform bus.

Driver Binding~~~~~~~~~~~~~~Legacy drivers assume they are bound to the device once they start upand probe an I/O port. Divorcing them from this will be a difficultprocess. However, that shouldn't prevent us from implementingfirmware-based enumeration.

The firmware should notify the platform bus about devices before thelegacy drivers have had a chance to load. Once the drivers are loaded,they driver model core will attempt to bind the driver to anypreviously-discovered devices. Once that has happened, it will be freeto discover any other devices it pleases.