feat: fstat now handle symbolic link
[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 struct devclass
69 {
70     u32_t meta;
71     u32_t device;
72     u32_t variant;
73     u32_t hash;
74 };
75
76 struct device
77 {
78     u32_t magic;
79     struct llist_header siblings;
80     struct llist_header children;
81     struct device* parent;
82     // TODO investigate event polling
83
84     struct hstr name;
85     struct devclass* class;
86     u32_t dev_uid;
87     int dev_type;
88     char name_val[DEVICE_NAME_SIZE];
89     void* underlay;
90
91     struct
92     {
93         // TODO Think about where will they fit.
94         int (*acquire)(struct device* dev);
95         int (*release)(struct device* dev);
96
97         int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
98         int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
99         int (*read_page)(struct device* dev, void* buf, size_t offset);
100         int (*write_page)(struct device* dev, void* buf, size_t offset);
101         int (*exec_cmd)(struct device* dev, u32_t req, va_list args);
102     } ops;
103 };
104
105 struct device_def
106 {
107     struct llist_header dev_list;
108     struct hlist_node hlist;
109     struct hlist_node hlist_if;
110     char* name;
111
112     struct devclass class;
113
114     int (*init)(struct device_def*);
115     int (*init_for)(struct device_def*, struct device*);
116 };
117
118 static inline u32_t devclass_hash(struct devclass class)
119 {
120     return (((class.device & 0xffff) << 16) | (class.variant & 0xffff)) ^
121            ~class.meta;
122 }
123
124 static inline u32_t
125 device_id_from_class(struct devclass* class)
126 {
127     return ((class->device & 0xffff) << 16) | ((class->variant & 0xffff));
128 }
129
130 void
131 device_register_all();
132
133 void
134 device_prepare(struct device* dev, struct devclass* class);
135
136 void
137 device_setname(struct device* dev, char* fmt, ...);
138
139 void
140 device_setname(struct device* dev, char* fmt, ...);
141
142 struct device*
143 device_add_vargs(struct device* parent,
144                  void* underlay,
145                  char* name_fmt,
146                  u32_t type,
147                  struct devclass* class,
148                  va_list args);
149
150 struct device*
151 device_add(struct device* parent,
152            struct devclass* class,
153            void* underlay,
154            u32_t type,
155            char* name_fmt,
156            ...);
157
158 struct device*
159 device_addsys(struct device* parent,
160               struct devclass* class,
161               void* underlay,
162               char* name_fmt,
163               ...);
164
165 struct device*
166 device_addseq(struct device* parent,
167               struct devclass* class,
168               void* underlay,
169               char* name_fmt,
170               ...);
171
172 struct device*
173 device_addvol(struct device* parent,
174               struct devclass* class,
175               void* underlay,
176               char* name_fmt,
177               ...);
178
179 struct device*
180 device_addcat(struct device* parent, char* name_fmt, ...);
181
182 void
183 device_remove(struct device* dev);
184
185 struct device*
186 device_getbyid(struct llist_header* devlist, u32_t id);
187
188 struct device*
189 device_getbyhname(struct device* root_dev, struct hstr* name);
190
191 struct device*
192 device_getbyname(struct device* root_dev, const char* name, size_t len);
193
194 struct device*
195 device_getbyoffset(struct device* root_dev, int pos);
196
197 struct device*
198 device_create_byclass(struct devclass* class,
199                       u32_t type,
200                       char* name,
201                       int* err_code);
202
203 struct hbucket*
204 device_definitions_byif(int if_type);
205
206 struct device_def*
207 devdef_byclass(struct devclass* class);
208
209 void
210 device_register_all();
211
212 /*------ Load hooks ------*/
213
214 void
215 device_earlystage();
216
217 void
218 device_poststage();
219
220 void
221 device_timerstage();
222
223 #endif /* __LUNAIX_DEVICE_H */