1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5library fuchsia.device.manager;
6
7// TODO(teisenbe): Move these interfaces to be internal to the devmgr codebase
8
9using zx;
10
11// This definition must be the same size as zx_device_prop_t and is checked by
12// static assert.  Once the bindings better handle vectors of structs (FIDL-323)
13// and we can move the binding struct definition into a more generate-able form,
14// we can make this reflect the actual structure.
15using DeviceProperty = uint64;
16
17/// This definition must match ZX_DEVICE_NAME_MAX and is checked by a static assert.
18const uint32 DEVICE_NAME_MAX = 31;
19
20/// Maximum number of bytes in a path
21const uint32 PATH_MAX = 1024;
22
23/// Maximum number of bytes in a device arguments string.
24const uint32 DEVICE_ARGS_MAX = 1024;
25
26/// Maximum number of bytes in a metadata payload
27const uint32 METADATA_MAX = 4096;
28
29/// Maximum number of bytes in a command string
30const uint32 COMMAND_MAX = 1024;
31
32/// Maxmimum number of properties that can be attached to a device
33const uint32 PROPERTIES_MAX = 256;
34
35// All functions in these interfaces have the most-significant-byte set to 0x01 to allow
36// multiplexing these interfaces and parts of the fuchsia.io interfaces.
37// TODO(ZX-2922): I believe this shouldn't be necessary anymore.
38
39/// Interface for controlling a device in a devhost process from the devcoordinator.
40[Layout = "Simple"]
41interface Controller {
42    // TODO(ZX-2921): These should probably return a status?
43
44    /// Create a device in the devhost that only implements the device protocol
45    /// and claims to support the given |protocol_id|.  This device will communicate
46    /// with the devcoordinator via |rpc|.
47    0x10000001: CreateDeviceStub(handle<channel> rpc, uint32 protocol_id);
48
49    /// Create a device in the devhost representing the shadowed half of device
50    /// in another devhost.  This new device will communicate with the devcoordinator
51    /// via |rpc|, and with its other half via |parent_proxy|.
52    ///
53    /// The new device will have the given driver responsible for running its half
54    /// of the driver's cross-process protocol.  It's create() method will be invoked,
55    /// giving it access to |parent_proxy| and |proxy_args|.
56    ///
57    /// parent_proxy, if present, will usually be a channel to the upper half of
58    /// a shadowed device.  The one exception is when this method is used
59    /// to create the Platform Bus, in which case it will be a VMO containing
60    /// the ZBI.
61    0x10000002: CreateDevice(handle<channel> rpc, string:PATH_MAX driver_path,
62                             handle<vmo> driver, handle? parent_proxy,
63                             string:DEVICE_ARGS_MAX? proxy_args);
64
65    /// Bind the requested driver to this device.  |driver_path| is informational,
66    /// but all calls to BindDriver/CreateDevice should use the same |driver_path|
67    /// each time they use a |driver| VMO with the same contents.
68    0x10000003: BindDriver(string:PATH_MAX driver_path, handle<vmo> driver)
69                    -> (zx.status status);
70
71    /// Give this device a channel to its shadow in another process.
72    0x10000004: ConnectProxy(handle<channel> shadow);
73
74    /// Ask this device to enter the suspend state indicated by |flags|.
75    0x10000005: Suspend(uint32 flags) -> (zx.status status);
76
77    /// Ask the devhost to remove this device.  On success, the remote end of
78    /// this interface channel will close instead of returning a result.
79    0x10000006: RemoveDevice();
80};
81
82/// Interface for the devices in devhosts to coordinate with the devcoordinator.
83[Layout = "Simple"]
84interface Coordinator {
85    /// Record the addition of a new device that can be communicated with via |rpc|.
86    /// For binding purposes, it is has properties |props|. |name| and |driver_path|
87    /// are informational and used for debugging.  The device will have |protocol_id|
88    /// as its primary protocol id.  |args| should only be used for shadowed devices,
89    /// and will be forwarded to the shadow device.
90    0x10000011: AddDevice(handle<channel> rpc,
91                          vector<DeviceProperty>:PROPERTIES_MAX props,
92                          string:DEVICE_NAME_MAX name, uint32 protocol_id,
93                          string:PATH_MAX? driver_path, string:DEVICE_ARGS_MAX? args)
94                    -> (zx.status status);
95
96    /// Behaves as AddDevice, but marks the device as initially invisible.  This means
97    /// that it will not be visible to other devices or the devfs until it is later marked
98    /// visible (via MakeVisible).
99    0x10000012: AddDeviceInvisible(handle<channel> rpc,
100                                   vector<DeviceProperty>:PROPERTIES_MAX props,
101                                   string:DEVICE_NAME_MAX name, uint32 protocol_id,
102                                   string:PATH_MAX? driver_path,
103                                   string:DEVICE_ARGS_MAX? args) -> (zx.status status);
104
105    /// Record the removal of this device.
106    0x10000013: RemoveDevice() -> (zx.status status);
107
108    /// Mark this device as visible.
109    0x10000014: MakeVisible() -> (zx.status status);
110
111    /// Attempt to bind a driver against this device.  If |driver_path| is null,
112    /// this will initiate the driver matching algorithm.
113    /// TODO(teisenbe): Specify the behavior of invoking this multiple times.  I believe
114    /// the current behavior is a bug.
115    0x10000015: BindDevice(string:PATH_MAX? driver_path) -> (zx.status status);
116
117    /// Returns the topological path of this device.
118    0x10000016: GetTopologicalPath() -> (zx.status status, string:PATH_MAX? path);
119
120    /// Requests that the firmware at the given path be loaded and returned.
121    0x10000017: LoadFirmware(string:PATH_MAX fw_path)
122                    -> (zx.status status, handle<vmo>? vmo, uint64 size);
123
124    /// Retrieve the metadata blob associated with this device and the given key.
125    0x10000018: GetMetadata(uint32 key)
126                    -> (zx.status status, vector<uint8>:METADATA_MAX? data);
127
128    /// Add metadata blob associated with this device and the given key.
129    /// TODO(teisenbe): Document the behavior of calling this twice with the same
130    /// key.  I believe the current behavior results in inaccessible data that is
131    /// kept around for the lifetime of the device.
132    0x10000019: AddMetadata(uint32 key, vector<uint8>:METADATA_MAX? data)
133                    -> (zx.status status);
134
135    /// Behaves like AddMetadata, but instead of associating it with the
136    /// requesting device, associates it with the device at |device_path|.  If
137    /// the device at |device_path| is not a child of the requesting device AND
138    /// the requesting device is not running in the sys devhost, then this will
139    /// fail.
140    0x1000001a: PublishMetadata(string:PATH_MAX device_path, uint32 key,
141                                vector<uint8>:METADATA_MAX? data) -> (zx.status status);
142
143    /// Special commands for implementing the dmctl device.
144    // TODO(teisenbe): We should revisit how these are carried over.
145
146    /// Execute the given string command.  This is mostly used for accessing debug
147    /// interfaces, but also as a backdoor for plumbing that has not been fully
148    /// solved.
149    0x10000020: DmCommand(handle<socket>? log_socket, string:COMMAND_MAX? command)
150                    -> (zx.status status);
151
152    /// Opens a new virtual console and transfers a handle to it over |vc_receiver|.
153    0x10000021: DmOpenVirtcon(handle<channel> vc_receiver);
154
155    /// Perform an mexec with the given kernel and bootdata.
156    /// See ZX-2069 for the thoughts on deprecating mexec.
157    0x10000023: DmMexec(handle<vmo> kernel, handle<vmo> bootdata);
158};
159