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 <ddk/device.h>
8#include <zircon/compiler.h>
9
10typedef struct proxy_iostate proxy_iostate_t;
11
12struct zx_device {
13    zx_device() = default;
14    ~zx_device() = default;
15
16    zx_device(const zx_device&) = delete;
17    zx_device& operator=(const zx_device&) = delete;
18
19    zx_device(zx_device&&) = default;
20    zx_device& operator=(zx_device&&) = default;
21
22    zx_status_t Open(zx_device_t** dev_out, uint32_t flags) {
23        return ops->open(ctx, dev_out, flags);
24    }
25
26    zx_status_t OpenAt(zx_device_t** dev_out, const char* path, uint32_t flags) {
27        return ops->open_at(ctx, dev_out, path, flags);
28    }
29
30    zx_status_t Close(uint32_t flags) {
31        return ops->close(ctx, flags);
32    }
33
34    void Unbind() {
35        ops->unbind(ctx);
36    }
37
38    void Release() {
39        ops->release(ctx);
40    }
41
42    zx_status_t Suspend(uint32_t flags) {
43        return ops->suspend(ctx, flags);
44    }
45
46    zx_status_t Resume(uint32_t flags) {
47        return ops->resume(ctx, flags);
48    }
49
50    zx_status_t Read(void* buf, size_t count, zx_off_t off,
51                     size_t* actual) {
52        return ops->read(ctx, buf, count, off, actual);
53    }
54
55    zx_status_t Write(const void* buf, size_t count,
56                      zx_off_t off, size_t* actual) {
57        return ops->write(ctx, buf, count, off, actual);
58    }
59
60    zx_off_t GetSize() {
61        return ops->get_size(ctx);
62    }
63
64    zx_status_t Ioctl(uint32_t op, const void* in_buf, size_t in_len,
65                      void* out_buf, size_t out_len, size_t* out_actual) {
66        return ops->ioctl(ctx, op, in_buf, in_len, out_buf, out_len, out_actual);
67    }
68
69    zx_status_t Message(fidl_msg_t* msg, fidl_txn_t* txn) {
70        return ops->message(ctx, msg, txn);
71    }
72
73    uintptr_t magic;
74
75    zx_protocol_device_t* ops;
76
77    // reserved for driver use; will not be touched by devmgr
78    void* ctx;
79
80    uint32_t flags;
81    uint32_t refcount;
82
83    zx_handle_t event;
84    zx_handle_t local_event;
85    zx_handle_t rpc;
86
87    // most devices implement a single
88    // protocol beyond the base device protocol
89    uint32_t protocol_id;
90    void* protocol_ops;
91
92    // driver that has published this device
93    zx_driver_t* driver;
94
95    // parent in the device tree
96    zx_device_t* parent;
97
98    // for the parent's device_list
99    struct list_node node;
100
101    // list of this device's children in the device tree
102    struct list_node children;
103
104    // list node for the defer_device_list
105    struct list_node defer;
106
107    // iostate
108    void* ios;
109    proxy_iostate_t* proxy_ios;
110
111    char name[ZX_DEVICE_NAME_MAX + 1];
112};
113
114// zx_device_t objects must be created or initialized by the driver manager's
115// device_create() function.  Drivers MAY NOT touch any
116// fields in the zx_device_t, except for the protocol_id and protocol_ops
117// fields which it may fill out after init and before device_add() is called,
118// and the ctx field which may be used to store driver-specific data.
119
120#define DEV_FLAG_DEAD           0x00000001  // being deleted
121#define DEV_FLAG_VERY_DEAD      0x00000002  // safe for ref0 and release()
122#define DEV_FLAG_UNBINDABLE     0x00000004  // nobody may bind to this device
123#define DEV_FLAG_BUSY           0x00000010  // device being created
124#define DEV_FLAG_INSTANCE       0x00000020  // this device was created-on-open
125#define DEV_FLAG_MULTI_BIND     0x00000080  // this device accepts many children
126#define DEV_FLAG_ADDED          0x00000100  // device_add() has been called for this device
127#define DEV_FLAG_INVISIBLE      0x00000200  // device not visible via devfs
128#define DEV_FLAG_UNBOUND        0x00000400  // informed that it should self-delete asap
129#define DEV_FLAG_WANTS_REBIND   0x00000800  // when last child goes, rebind this device
130
131#define DEV_MAGIC 'MDEV'
132
133zx_status_t device_bind(zx_device_t* dev, const char* drv_libname);
134zx_status_t device_open_at(zx_device_t* dev, zx_device_t** out, const char* path, uint32_t flags);
135zx_status_t device_close(zx_device_t* dev, uint32_t flags);
136