blob: 54db64732dcf7332a173e77c198478e1d012f9fa [file] [log] [blame] [view] [edit]
# Driver communication
Important: This page contains information that is specific to the new
version of the driver framework (DFv2).
In Fuchsia, all communication occurs over FIDL calls, for both drivers and
non-drivers. What differs is how drivers' services are discovered and how
connection is established.
For driver-to-driver communication, Fuchsia uses the
[node topology][node-topology] to place parent nodes' capabilities in a child
node's incoming FIDL namespace (that is, under `/svc` as directories and files).
This setup enables a driver (once bound to the child node) to access FIDL
services inherited from the parent nodes.
However, communication from a non-driver component to a driver takes place in
two phases:
1. [Service discovery (using devfs)](#service_discovery_using_devfs)
1. [FIDL communication](#fidl_communication)
For non-driver components, the first task is to discover which drivers' services
are available in the system. These services are provided by the drivers that are
currently bound to nodes representing hardware or virtual devices in the system.
A filesystem known as `devfs` provides a mechanism for discovering these services.
The following events take place for non-driver to driver communication:
1. To discover driver services in the system, a non-driver component scans the
directories and files in `devfs`.
2. The non-driver component finds a file in `devfs` that represents a service
provided by the target driver.
3. The non-driver component opens this file and contacts the target driver.
4. After the initial contact, a FIDL connection is established between the
non-driver component and the driver.
5. From this point, all communication takes place over the FIDL channels.
Note: Fuchsia's expectation is that non-drivers will also discover
driver services using FIDL in the near future. Meanwhile, Fuchsia will continue
to support `devfs`. However, it will be deprecated at some point.
## Service discovery (using devfs)
The [driver manager][driver-manager] hosts a virtual filesystem named `devfs`
(as in "device filesystem"). This virtual filesystem provides uniform access to
all driver services in a Fuchsia system to Fuchsia’s user-space services
(that is, components external to the drivers). These non-driver components
establish initial contacts with drivers by discovering the services of the
target drivers in `devfs`.
Strictly speaking, `devfs` is a directory capability exposed by the driver
manager. Therefore, by convention, components that wish to access drivers mount
`devfs` under the `/dev` directory in their namespace (although it’s not
mandated that `devfs` to be always mounted under `/dev`).
`devfs` hosts virtual files that enable Fuchsia components to route messages to
the interfaces implemented by the drivers running in a Fuchsia system.
In other words, when a client (that is, a non-driver component) opens a file
under the `/dev` directory, it receives a channel that can be used to make
FIDL calls directly to the driver mapped to the file. For example,
a Fuchsia component can connect to an input device by opening and writing to
a file that looks like `/dev/class/input-report/000`. In this case,
the client may receive a channel that speaks the `fuchsia.input.report` FIDL.
Drivers can use the [`DevfsAddArgs`][devfs-add-args] table to export
themselves into `devfs` when they add a new node.
## FIDL communication
Once an initial contact is made between non-driver and driver components
using `devfs`, the components can exchange FIDL handles. From this point,
these components make use of FIDL calls for communication, just like any
other components in Fuchsia.
Drivers, as [Fuchsia components][components], have an incoming FIDL namespace
filled with capabilities the drivers can use. Some of these capabilities may be
inherited from their parent driver (for example, a PCI device will have
a `fuchsia.hardware.PCI` capability from its parent node). Drivers can use
these capabilities to make FIDL calls to their parent drivers. Similarly,
their clients (that is, non-driver components) can also use the capabilities
received from the drivers to make FIDL calls to the drivers.
These FIDL calls, by default, get routed through the Zircon kernel. However,
if the target driver is in the same process (therefore, in the same
driver host), the [driver runtime][driver-runtime] can route
the FIDL calls to remain in process, without going in and out of
the Zircon kernel.
<!-- Reference links -->
[driver-manager]: driver_framework.md#driver_manager
[driver-runtime]: driver_framework.md#driver_runtime
[node-topology]: drivers_and_nodes.md#node_topology
[devfs-add-args]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.driver.framwork/topology.fidl
[components]: /docs/concepts/components/v2/README.md