52df8f0a0efcbde5c3fe6bf38d7e33d61ac207b9
[lunaix-os.git] / lunaix-os / includes / lunaix / device.h
1 #ifndef __LUNAIX_DEVICE_H
2 #define __LUNAIX_DEVICE_H
3
4 #define DEVICE_NAME_SIZE 32
5
6 #include <lunaix/device_num.h>
7 #include <lunaix/ds/hashtable.h>
8 #include <lunaix/ds/hstr.h>
9 #include <lunaix/ds/ldga.h>
10 #include <lunaix/ds/llist.h>
11 #include <lunaix/ds/semaphore.h>
12 #include <lunaix/types.h>
13
14 /**
15  * @brief Export a device definition
16  *
17  */
18 #define EXPORT_DEVICE(id, devdef, load_order)                                  \
19     export_ldga_el(devdefs, id, ptr_t, devdef);                                \
20     export_ldga_el_sfx(devdefs, id##_ldorder, ptr_t, devdef, load_order);
21
22 #define load_on_demand ld_ondemand
23
24 /**
25  * @brief Mark the device definition should be loaded automatically as earlier
26  * as possible in the kernel bootstrapping stage (before initialization of file
27  * systems). Load here if your driver is standalone and require no other than
28  * basic memory allocation services
29  *
30  */
31 #define load_earlystage ld_early
32
33 /**
34  * @brief Mark the device definition should be loaded automatically after timer
35  * is ready. Load here if your driver require a basic timing service
36  *
37  */
38 #define load_timerstage ld_aftertimer
39
40 /**
41  * @brief Mark the device definition should be loaded automatically in
42  * the post boostrapping stage (i.e., the start up of proc0). Load here if your
43  * driver involves async mechanism
44  *
45  */
46 #define load_poststage ld_post
47
48 /**
49  * @brief Declare a device class
50  *
51  */
52 #define DEVCLASS(devif, devfn, devkind, devvar)                                \
53     (struct devclass)                                                          \
54     {                                                                          \
55         .meta = DEV_META(devif, devfn), .device = (devkind),                   \
56         .variant = (devvar)                                                    \
57     }
58
59 #define DEV_STRUCT_MAGIC 0x5645444c
60
61 #define DEV_MSKIF 0x00000003
62
63 #define DEV_IFVOL 0x0 // volumetric (block) device
64 #define DEV_IFSEQ 0x1 // sequential (character) device
65 #define DEV_IFCAT 0x2 // a device category (as device groupping)
66 #define DEV_IFSYS 0x3 // a system device
67
68 typedef unsigned int dev_t;
69
70 struct devclass
71 {
72     u32_t meta;
73     u32_t device;
74     u32_t variant;
75     u32_t hash;
76 };
77
78 struct device
79 {
80     u32_t magic;
81     struct llist_header siblings;
82     struct llist_header children;
83     struct device* parent;
84     // TODO investigate event polling
85
86     struct hstr name;
87     struct devclass class;
88     dev_t dev_id;
89     int dev_type;
90     char name_val[DEVICE_NAME_SIZE];
91     void* underlay;
92
93     struct
94     {
95         int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
96         int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
97         int (*read_page)(struct device* dev, void* buf, size_t offset);
98         int (*write_page)(struct device* dev, void* buf, size_t offset);
99         int (*exec_cmd)(struct device* dev, u32_t req, va_list args);
100     } ops;
101 };
102
103 struct device_def
104 {
105     struct llist_header dev_list;
106     struct hlist_node hlist;
107     struct hlist_node hlist_if;
108     char* name;
109
110     struct devclass class;
111
112     int (*init)(struct device_def*);
113     int (*init_for)(struct device_def*, struct device*);
114 };
115
116 static inline u32_t devclass_hash(struct devclass class)
117 {
118     return (((class.device & 0xffff) << 16) | (class.variant & 0xffff)) ^
119            ~class.meta;
120 }
121
122 void
123 device_register_all();
124
125 void
126 device_prepare(struct device* dev);
127
128 void
129 device_setname(struct device* dev, char* fmt, ...);
130
131 void
132 device_setname(struct device* dev, char* fmt, ...);
133
134 struct device*
135 device_add_vargs(struct device* parent,
136                  void* underlay,
137                  char* name_fmt,
138                  u32_t type,
139                  va_list args);
140
141 struct device*
142 device_add(struct device* parent,
143            void* underlay,
144            u32_t type,
145            char* name_fmt,
146            ...);
147
148 struct device*
149 device_addsys(struct device* parent, void* underlay, char* name_fmt, ...);
150
151 struct device*
152 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...);
153
154 struct device*
155 device_addvol(struct device* parent, void* underlay, char* name_fmt, ...);
156
157 struct device*
158 device_addcat(struct device* parent, char* name_fmt, ...);
159
160 void
161 device_remove(struct device* dev);
162
163 struct device*
164 device_getbyid(struct llist_header* devlist, dev_t id);
165
166 struct device*
167 device_getbyhname(struct device* root_dev, struct hstr* name);
168
169 struct device*
170 device_getbyname(struct device* root_dev, const char* name, size_t len);
171
172 struct device*
173 device_getbyoffset(struct device* root_dev, int pos);
174
175 struct device*
176 device_create_byclass(struct devclass* class,
177                       u32_t type,
178                       char* name,
179                       int* err_code);
180
181 struct hbucket*
182 device_definitions_byif(int if_type);
183
184 void
185 device_register_all();
186
187 /*------ Load hooks ------*/
188
189 void
190 device_earlystage();
191
192 void
193 device_poststage();
194
195 void
196 device_timerstage();
197
198 #endif /* __LUNAIX_DEVICE_H */