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