1 // Copyright 2016 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
5 #pragma once
6
7 #include <zircon/compiler.h>
8 #include <zircon/device/device.h>
9 #include <zircon/syscalls.h>
10 #include <zircon/types.h>
11 #include <zircon/listnode.h>
12
13 __BEGIN_CDECLS;
14
15 typedef struct zx_device zx_device_t;
16 typedef struct zx_driver zx_driver_t;
17 typedef struct zx_device_prop zx_device_prop_t;
18
19 typedef struct zx_protocol_device zx_protocol_device_t;
20
21 typedef struct fidl_msg fidl_msg_t;
22 typedef struct fidl_txn fidl_txn_t;
23
24 // Max device name length, not including a null-terminator
25 #define ZX_DEVICE_NAME_MAX 31
26
27 // echo -n "mx_device_ops_v0.5" | sha256sum | cut -c1-16
28 #define DEVICE_OPS_VERSION_0_50 0xc9410d2a24f57424
29
30 // echo -n "zx_device_ops_v0.51" | sha256sum | cut -c1-16
31 #define DEVICE_OPS_VERSION_0_51 0xc4640f7115d2ee49
32
33 // Current Version
34 #define DEVICE_OPS_VERSION DEVICE_OPS_VERSION_0_51
35
36
37 // TODO: temporary flags used by devcoord to communicate
38 // with the system bus device.
39 #define DEVICE_SUSPEND_FLAG_REBOOT 0xdcdc0100
40 #define DEVICE_SUSPEND_FLAG_POWEROFF 0xdcdc0200
41 #define DEVICE_SUSPEND_FLAG_MEXEC 0xdcdc0300
42 #define DEVICE_SUSPEND_FLAG_SUSPEND_RAM 0xdcdc0400
43 #define DEVICE_SUSPEND_REASON_MASK 0xffffff00
44
45 // reboot modifiers
46 #define DEVICE_SUSPEND_FLAG_REBOOT_BOOTLOADER (DEVICE_SUSPEND_FLAG_REBOOT | 0x01)
47 #define DEVICE_SUSPEND_FLAG_REBOOT_RECOVERY (DEVICE_SUSPEND_FLAG_REBOOT | 0x02)
48
49 //@doc(docs/ddk/device-ops.md)
50
51 //@ # The Device Protocol
52 //
53 // Device drivers implement a set of hooks (methods) to support the
54 // operations that may be done on the devices that they publish.
55 //
56 // These are described below, including the action that is taken
57 // by the default implementation that is used for each hook if the
58 // driver does not provide its own implementation.
59
60 typedef struct zx_protocol_device {
61 //@ ## version
62 // This field must be set to `DEVICE_OPS_VERSION`
63 uint64_t version;
64
65 zx_status_t (*get_protocol)(void* ctx, uint32_t proto_id, void* protocol);
66
67 //@ ## open
68 //
69 // The open hook is called when a device is opened via the device filesystem,
70 // or when an existing open connection to a device is cloned (for example,
71 // when a device fd is shared with another process). The default open hook,
72 // if a driver does not implement one, simply returns **ZX_OK**.
73 //
74 // Drivers may want to implement open to disallow simultaneous access (by
75 // failing if the device is already open), or to return a new **device instance**
76 // instead.
77 //
78 // The optional *dev_out* parameter allows a device to create and return a
79 // **device instance** child device, which can be used to manage per-instance
80 // state instead of all client connections interacting with the device itself.
81 // A child created for return as an instance **must** be created with the
82 // **DEVICE_ADD_INSTANCE** flag set in the arguments to **device_add()**.
83 //
84 zx_status_t (*open)(void* ctx, zx_device_t** dev_out, uint32_t flags);
85
86 //@ ## open_at
87 // The open_at hook is called in the event that the open path to the device
88 // contains segments after the device name itself. For example, if a device
89 // exists as `/dev/misc/foo` and an attempt is made to `open("/dev/misc/foo/bar",...)`,
90 // the open_at hook would be invoked with a *path* of `"bar"`.
91 //
92 // The default open_at implementation returns **ZX_ERR_NOT_SUPPORTED**
93 //
94 zx_status_t (*open_at)(void* ctx, zx_device_t** dev_out, const char* path, uint32_t flags);
95
96 //@ ## close
97 // The close hook is called when a connection to a device is closed. These
98 // calls will balance the calls to open or open_at.
99 //
100 // **Note:** If open or open_at return a **device instance**, the balancing close
101 // hook that is called is the close hook on the **instance**, not the parent.
102 //
103 // The default close implementation returns **ZX_OK**.
104 zx_status_t (*close)(void* ctx, uint32_t flags);
105
106 //@ ## unbind
107 // The unbind hook is called when the parent of this device is being removed (due
108 // to hot unplug, fatal error, etc). At the point unbind is called, it is not
109 // possible for further open or open_at calls to occur, but io operations, etc
110 // may continue until those client connections are closed.
111 //
112 // The driver should avoid further method calls to its parent device or any
113 // protocols obtained from that device, and expect that any further such calls
114 // will return with an error.
115 //
116 // The driver should adjust its state to encourage its client connections to close
117 // (cause IO to error out, etc), and call **device_remove()** on itself when ready.
118 //
119 // The driver must continue to handle all device hooks until the **release** hook
120 // is invoked.
121 //
122 void (*unbind)(void* ctx);
123
124 //@ ## release
125 // The release hook is called after this device has been removed by **device_remove()**
126 // and all open client connections have been closed, and all child devices have been
127 // removed and released.
128 //
129 // At the point release is invoked, the driver will not receive any further calls
130 // and absolutely must not use the underlying **zx_device_t** or any protocols obtained
131 // from that device once this method returns.
132 //
133 // The driver must free all memory and release all resources related to this device
134 // before returning.
135 void (*release)(void* ctx);
136
137 //@ ## read
138 // The read hook is an attempt to do a non-blocking read operation.
139 //
140 // On success *actual* must be set to the number of bytes read (which may be less
141 // than the number requested in *count*), and return **ZX_OK**.
142 //
143 // A successful read of 0 bytes is generally treated as an End Of File notification
144 // by clients.
145 //
146 // If no data is available now, **ZX_ERR_SHOULD_WAIT** must be returned and when
147 // data becomes available `device_state_set(DEVICE_STATE_READABLE)` may be used to
148 // signal waiting clients.
149 //
150 // This hook **must not block**.
151 //
152 // The default read implementation returns **ZX_ERR_NOT_SUPPORTED**.
153 //
154 zx_status_t (*read)(void* ctx, void* buf, size_t count,
155 zx_off_t off, size_t* actual);
156
157 //@ ## write
158 // The write hook is an attempt to do a non-blocking write operation.
159 //
160 // On success *actual* must be set to the number of bytes written (which may be
161 // less than the number requested in *count*), and **ZX_OK** should be returned.
162 //
163 // If it is not possible to write data at present **ZX_ERR_SHOULD_WAIT** must
164 // be returned and when it is again possible to write,
165 // `device_state_set(DEVICE_STATE_WRITABLE)` may be used to signal waiting clients.
166 //
167 // This hook **must not block**.
168 //
169 // The default write implementation returns **ZX_ERR_NOT_SUPPORTED**.
170 //
171 zx_status_t (*write)(void* ctx, const void* buf, size_t count,
172 zx_off_t off, size_t* actual);
173
174 //@ ## get_size
175 // If the device is seekable, the get_size hook should return the size of the device.
176 //
177 // This is the offset at which no more reads or writes are possible.
178 //
179 // The default implementation returns 0.
180 zx_off_t (*get_size)(void* ctx);
181
182 //@ ## ioctl
183 // The ioctl hook allows support for device-specific operations.
184 //
185 // These, like read and write, must not block.
186 //
187 // On success, **ZX_OK** must be returned and *out_actual* must be set
188 // to the number of output bytes provided (0 if none).
189 //
190 // The default ioctl implementation returns **ZX_ERR_NOT_SUPPORTED**.
191 zx_status_t (*ioctl)(void* ctx, uint32_t op,
192 const void* in_buf, size_t in_len,
193 void* out_buf, size_t out_len, size_t* out_actual);
194
195 // Stops the device and puts it in a low power mode
196 zx_status_t (*suspend)(void* ctx, uint32_t flags);
197
198 // Restarts the device after being suspended
199 zx_status_t (*resume)(void* ctx, uint32_t flags);
200
201 //@ ## rxrpc
202 // Only called for bus devices.
203 // When the "shadow" of a busdev sends an rpc message, the
204 // device that is shadowing is notified by the rxrpc op and
205 // should attempt to read and respond to a single message on
206 // the provided channel.
207 //
208 // Any error return from this method will result in the channel
209 // being closed and the remote "shadow" losing its connection.
210 //
211 // This method is called with ZX_HANDLE_INVALID for the channel
212 // when a new client connects -- at which point any state from
213 // the previous client should be torn down.
214 zx_status_t (*rxrpc)(void* ctx, zx_handle_t channel);
215
216 //@ ## message
217 // Process a FIDL rpc message. This is used to handle class or
218 // device specific messaging. fuchsia.io.{Node,File,Device} are
219 // handles by the devhost itself.
220 //
221 // The entire message becomes the responsibility of the driver,
222 // including the handles.
223 //
224 // The txn provided to respond to the message is only valid for
225 // the duration of the message() call. It must not be cached
226 // and used later.
227 zx_status_t (*message)(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn);
228 } zx_protocol_device_t;
229
230
231 // Device Accessors
232 const char* device_get_name(zx_device_t* dev);
233
234 zx_device_t* device_get_parent(zx_device_t* dev);
235
236 // protocols look like:
237 // typedef struct {
238 // protocol_xyz_ops_t* ops;
239 // void* ctx;
240 // } protocol_xyz_t;
241 zx_status_t device_get_protocol(const zx_device_t* dev, uint32_t proto_id, void* protocol);
242
243
244 // Direct Device Ops Functions
245 zx_status_t device_read(zx_device_t* dev, void* buf, size_t count,
246 zx_off_t off, size_t* actual);
247
248 zx_status_t device_write(zx_device_t* dev, const void* buf, size_t count,
249 zx_off_t off, size_t* actual);
250
251 zx_off_t device_get_size(zx_device_t* dev);
252
253 zx_status_t device_ioctl(zx_device_t* dev, uint32_t op,
254 const void* in_buf, size_t in_len,
255 void* out_buf, size_t out_len, size_t* out_actual);
256
257 // Device Metadata Support
258
259 // retrieves metadata for a specific device
260 // searches parent devices to find a match
261 zx_status_t device_get_metadata(zx_device_t* dev, uint32_t type, void* buf, size_t buflen,
262 size_t* actual);
263
264 // Adds metadata to a specific device.
265 zx_status_t device_add_metadata(zx_device_t* dev, uint32_t type, const void* data, size_t length);
266
267
268 // Adds metadata to be provided to future devices matching the specified topo path.
269 // Drivers may use this to publish metadata to a driver with a topo path that matches
270 // itself or one of its children. Only drivers running in the "sys" devhost may publish
271 // metadata to arbitrary topo paths.
272 zx_status_t device_publish_metadata(zx_device_t* dev, const char* path, uint32_t type,
273 const void* data, size_t length);
274
275 // Device State Change Functions
276 //@ #### Device State Bits
277 //{
278 #define DEV_STATE_READABLE DEVICE_SIGNAL_READABLE
279 #define DEV_STATE_WRITABLE DEVICE_SIGNAL_WRITABLE
280 #define DEV_STATE_ERROR DEVICE_SIGNAL_ERROR
281 #define DEV_STATE_HANGUP DEVICE_SIGNAL_HANGUP
282 #define DEV_STATE_OOB DEVICE_SIGNAL_OOB
283 //}
284
285 void device_state_clr_set(zx_device_t* dev, zx_signals_t clearflag, zx_signals_t setflag);
286
287 //@ #### device_state_set
device_state_set(zx_device_t * dev,zx_signals_t stateflag)288 static inline void device_state_set(zx_device_t* dev, zx_signals_t stateflag) {
289 device_state_clr_set(dev, 0, stateflag);
290 }
device_state_clr(zx_device_t * dev,zx_signals_t stateflag)291 static inline void device_state_clr(zx_device_t* dev, zx_signals_t stateflag) {
292 device_state_clr_set(dev, stateflag, 0);
293 }
294
295 __END_CDECLS;
296