blob: e5081d9c419e834058eda59518c118e667280095 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.driver.framework;
using fuchsia.device.fs;
using fuchsia.component;
using fuchsia.component.decl;
using zx;
alias NodePropertyKeyString = string:256;
alias NodePropertyKeyUint = uint32;
alias NodePropertyValueUint = uint32;
alias NodePropertyValueString = string:256;
alias NodePropertyValueBool = bool;
alias NodePropertyValueEnum = string:256;
const MAX_OFFER_COUNT uint32 = fuchsia.component.MAX_DYNAMIC_OFFER_COUNT;
const MAX_SYMBOL_COUNT uint8 = 64;
const MAX_PROPERTY_COUNT uint8 = 64;
const MAX_NODE_NAME_LENGTH uint8 = 128;
const MAX_SYMBOL_NAME_LENGTH uint8 = 128;
alias NodePropertyVector = vector<NodeProperty>:MAX_PROPERTY_COUNT;
alias NodeName = string:MAX_NODE_NAME_LENGTH;
/// Definition of a symbol provided by a driver for a node. A symbol is local to
/// a driver host.
type NodeSymbol = table {
/// Name of the symbol.
1: name string:MAX_SYMBOL_NAME_LENGTH;
/// Virtual address of the symbol, within a driver host's process.
2: address zx.vaddr;
type NodePropertyKey = strict union {
1: int_value NodePropertyKeyUint;
2: string_value NodePropertyKeyString;
type NodePropertyValue = flexible union {
1: int_value NodePropertyValueUint;
2: string_value NodePropertyValueString;
3: bool_value NodePropertyValueBool;
4: enum_value NodePropertyValueEnum;
/// Definition of a property for a node. A property is commonly used to match a
/// node to a driver for driver binding.
type NodeProperty = struct {
/// Key for the property.
key NodePropertyKey;
/// Value for the property.
value NodePropertyValue;
// Arguments for adding a node to the devfs filesystem.
type DevfsAddArgs = resource table {
/// This is the connector to be installed in devfs.
/// `Connect()` will be called when a client connects to this node in the filesystem.
/// Optional: If this is not provided then an empty node will appear in devfs.
1: connector client_end:fuchsia.device.fs.Connector;
/// This is the class name for installing this node in devfs.
/// The node will be placed within /dev/class/{class_name}.
/// If `class_name` does not exist under /dev/class/ it will be created.
/// Optional: If this is not provided then the node will only be added via topological path.
2: class_name;
/// Arguments for adding a node.
type NodeAddArgs = resource table {
/// Name of the node.
1: name NodeName;
/// Capabilities to offer to the driver that is bound to this node.
/// The driver must ensure these capabilities are added to its outgoing directory
/// before adding the child node.
2: offers vector<fuchsia.component.decl.Offer>:MAX_OFFER_COUNT;
/// Functions to provide to the driver that is bound to this node.
3: symbols vector<NodeSymbol>:MAX_SYMBOL_COUNT;
/// Properties of the node.
4: properties NodePropertyVector;
/// The arguments for how this node should be added to devfs.
5: devfs_args DevfsAddArgs;
/// Protocol through which a parent node controls one of its children.
protocol NodeController {
/// Removes the node and all of its children.
/// Request that the framework attempts to bind a driver to this node.
/// This is an *additional* request for binding as the framework attempts to bind a node once
/// when the node is created.
/// * error `ZX_ERR_ALREADY_BOUND` if the node is already bound and `force_rebind` is false.
RequestBind(table {
/// If this is true, then the node unbinds from its matched driver before it attempts to
/// bind through the normal bind process.
1: force_rebind bool;
/// If this is set, then only drivers matching this URL suffix will be considered in
/// binding.
/// E.g: "", "meta/", "fuchsia-boot:///#meta/".
2: driver_url_suffix string:MAX;
}) -> () error zx.status;
/// Event that is triggered when the associated `Node` is bound to a driver.
-> OnBind();
/// Error codes for the Node protocol.
type NodeError = strict enum {
// An internal error occurred.
// The Node was removed from the topology.
// The Node's name is missing.
/// The Node's name is invalid. Specifically, it must not contain a period
/// in its name.
/// A sibling Node exists with the same name.
/// An offer for this Node is missing a source name.
/// An offer for this Node should not have a source or target.
/// A symbol for this Node is missing a name.
/// A symbol for this Node is missing an address.
/// There is another symbol for this Node with the same name.
/// Protocol through which a driver manages a node that it is bound to.
protocol Node {
/// Adds a child node to this node.
/// If `node` is present, this driver takes responsibility for binding to
/// the newly created child. Otherwise, the driver framework will locate an
/// appropriate driver to bind the child to.
AddChild(resource struct {
args NodeAddArgs;
controller server_end:NodeController;
node server_end:<Node, optional>;
}) -> () error NodeError;