1 #ifndef __LUNAIX_DEVICE_H
2 #define __LUNAIX_DEVICE_H
4 #define DEVICE_NAME_SIZE 16
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/mutex.h>
12 #include <lunaix/iopoll.h>
13 #include <lunaix/types.h>
14 #include <lunaix/changeling.h>
16 #include <hal/devtreem.h>
18 #include <usr/lunaix/device.h>
21 * @brief Export a device definition (i.e., device driver metadata)
24 #define EXPORT_DEVICE(id, devdef, load_order) \
25 export_ldga_el(devdefs, id, ptr_t, devdef); \
26 export_ldga_el_sfx(devdefs, id##_ldorder, ptr_t, devdef, load_order);
29 * @brief Mark the device definition can be loaded on demand, all other loading
30 * options are extended from this
32 #define load_on_demand ld_ondemand
35 * @brief Mark the device definition to be loaded as system configuration
36 * device. These kind of devices are defined to be the devices that talk to the
37 * system firmware to do config, or collecting crucial information about the
38 * system. For instances, ACPI, SoC components, and other **interconnection**
39 * buese (not USB!). Such device driver must only rely on basic memory
40 * management service, and must not try accessing subsystems other than the mm
41 * unit, for example, timer, interrupt, file-system, must not assumed exist.
44 #define load_sysconf ld_sysconf
47 * @brief Mark the device definition should be loaded automatically during the
48 * bootstrapping stage. Most of the driver do load there.
51 #define load_onboot ld_kboot
54 * @brief Mark the device definition should be loaded automatically in
55 * the post boostrapping stage (i.e., the start up of proc0), where most of
56 * kernel sub-system are became ready to use. Do your load there if your driver
57 * depends on such condition
60 #define load_postboot ld_post
62 #define __foreach_exported_device_of(stage, index, pos) \
63 ldga_foreach(dev_##stage, struct device_def*, index, pos)
64 #define foreach_exported_device_of(stage, index, pos) \
65 __foreach_exported_device_of(stage, index, pos)
68 * @brief Declare a device class
71 #define DEVCLASS(vendor, devfn, dev) \
74 .fn_grp = DEV_FNGRP(dev_vn(vendor), dev_fn(devfn)), \
75 .device = dev_id(dev), .variant = 0 \
78 #define DEV_MSKIF 0x00000003
79 #define DEV_IFVOL 0x0 // volumetric (block) device
80 #define DEV_IFSEQ 0x1 // sequential (character) device
81 #define DEV_IFSYS 0x3 // a system device
83 #define dev_object_root \
84 ({ extern morph_t* device_mobj_root; device_mobj_root; })
87 * A potens is a capability of the device
88 * ("potens", means "capable" in latin)
90 * A device can have multiple capabilities
91 * (or "potentes", plural form of potens)
93 * A group of devices with same capability will forms
94 * a "globus potentis" or "capability group". The
95 * group is completely a logical formation, meaning
96 * that it is not explictly coded.
98 * The idea of potens is to provide a unified and yet
99 * opaque method to decouple the device provide raw
100 * functionalities with any higher abstraction, such
101 * as other subsystem, or standard-compilance wrapper
102 * (e.g., POSIX terminal)
106 struct device* owner;
108 struct llist_header potentes;
109 unsigned int pot_type;
112 #define POTENS_META \
115 struct potens_meta pot_meta; \
117 struct llist_header potentes; \
118 unsigned int pot_type; \
123 #define get_potens(cap, pot_struct) \
124 container_of((cap), pot_struct, pot_meta)
125 #define potens_meta(cap) (&(cap)->pot_meta)
126 #define potens_dev(cap) (potens_meta(cap)->owner)
128 #define potens(name) POTENS_##name
130 #define potens_check_unique(dev, pot_type) \
131 !device_get_potens(dev, pot_type)
133 enum device_potens_type
136 #include <listings/device_potens.lst>
140 * List of potentes of a device, pay attention to
141 * the spelling, "potentium", genitive plural of "potens".
143 typedef struct llist_header potentium_list_t;
146 #define DEVICE_META_FIELD \
149 char name_val[DEVICE_NAME_SIZE]; \
152 #define DEVICE_METADATA \
154 struct device_meta meta; \
158 #define devmeta_morpher morphable_attrs(device_meta, mobj)
159 #define devalias_morpher morphable_attrs(device_alias, mobj)
160 #define devcat_morpher morphable_attrs(device_cat, mobj)
161 #define device_morpher morphable_attrs(device, mobj)
163 #define dev_meta(dev) (&(dev)->meta)
164 #define dev_mobj(dev) (&(dev)->mobj)
165 #define dev_morph(dev) ({ likely(dev) ? &(dev)->mobj : dev_object_root; })
166 #define dev_uid(dev) (morpher_uid(&(dev)->mobj))
167 #define to_dev(dev) (container_of(dev,struct device, meta))
168 #define to_catdev(dev) (container_of(dev,struct device_cat, meta))
169 #define to_aliasdev(dev) (container_of(dev,struct device_alias, meta))
176 struct device_alias {
178 struct device_meta* alias;
187 /* -- device structing -- */
191 potentium_list_t potentium;
193 #ifdef CONFIG_USE_DEVICETREE
194 devtree_link_t devtree_node;
197 /* -- device state -- */
202 struct devident ident;
211 // TODO Think about where will they fit.
212 int (*acquire)(struct device* dev);
213 int (*release)(struct device* dev);
215 int (*read)(struct device*, void*, off_t, size_t);
216 int (*write)(struct device*, void*, off_t, size_t);
217 int (*read_async)(struct device*, void*, off_t, size_t);
218 int (*write_async)(struct device*, void*, off_t, size_t);
220 int (*read_page)(struct device*, void*, off_t);
221 int (*write_page)(struct device*, void*, off_t);
223 int (*exec_cmd)(struct device*, u32_t, va_list);
224 int (*poll)(struct device*);
229 typedef int (*devdef_ldfn)(struct device_def*);
231 struct device_ldfn_chain
233 struct device_ldfn_chain* chain;
239 struct llist_header dev_list;
240 struct hlist_node hlist;
241 struct hlist_node hlist_if;
247 bool no_default_realm : 1;
254 struct devclass class;
255 unsigned int class_hash;
258 struct device_ldfn_chain* load_chain;
262 * Called when driver is required to register itself to the system
263 * All registration code should put it here.
266 * "to the record" in latin. just in case anyone wonders.
267 * I am ran out of naming idea... have to improvise :)
270 devdef_ldfn ad_tabulam;
273 * @brief Called when the driver is loaded at it's desired load stage
279 * @brief Called when the driver is required to create device instance
280 * This is for device with their own preference of creation
281 * object that hold parameter for such creation is provided by second argument.
283 int (*create)(struct device_def*, morph_t*);
286 * @brief Called when a driver is requested to detach from the device and
287 * free up all it's resources
290 int (*free)(struct device_def*, void* instance);
293 #define def_device_name(dev_n) .name = dev_n
294 #define def_device_class(_if, fn, dev) .class = DEVCLASS(_if, fn, dev)
295 #define def_on_register(fn) .ad_tabulam = fn
296 #define def_on_load(fn) .load = fn
297 #define def_on_create(fn) .create = fn
298 #define def_on_free(fn) .free = fn
299 #define def_non_trivial .flags.no_default_realm = true
302 resolve_device_morph(void* maybe_dev);
304 #define mark_device_doing_write(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLOUT
305 #define mark_device_done_write(dev_ptr) (dev_ptr)->poll_evflags |= _POLLOUT
307 #define mark_device_doing_read(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLIN
308 #define mark_device_done_read(dev_ptr) (dev_ptr)->poll_evflags |= _POLLIN
310 #define mark_device_hanging(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLHUP
311 #define mark_device_grounded(dev_ptr) (dev_ptr)->poll_evflags |= _POLLHUP
314 device_id_from_class(struct devclass* class)
316 return ((class->device & 0xffff) << 16) | ((class->variant & 0xffff));
319 static inline struct device*
320 resolve_device(void* maybe_dev) {
321 morph_t* mobj = resolve_device_morph(maybe_dev);
322 return changeling_try_reveal(mobj, device_morpher);
326 device_scan_drivers();
329 device_setname_vargs(struct device_meta* dev, char* fmt, va_list args);
332 device_setname(struct device_meta* dev, char* fmt, ...);
335 device_register_generic(struct device_meta* dev, struct devclass* class,
338 #define register_device(dev, class, fmt, ...) \
339 device_register_generic(dev_meta(dev), class, fmt, ## __VA_ARGS__)
341 #define register_device_var(dev, class, fmt, ...) \
342 ({device_register_generic( \
343 dev_meta(dev), class, \
344 fmt "%d", ## __VA_ARGS__, (class)->variant); \
345 devclass_mkvar(class); })
348 device_create(struct device* dev,
349 struct device_meta* parent,
354 device_alloc(struct device_meta* parent, u32_t type, void* underlay);
356 #ifdef CONFIG_USE_DEVICETREE
358 device_set_devtree_node(struct device* dev, devtree_link_t node)
360 dev->devtree_node = node;
364 static inline struct device* must_inline
365 device_allocsys(struct device_meta* parent, void* underlay)
367 return device_alloc(parent, DEV_IFSYS, underlay);
370 static inline struct device* must_inline
371 device_allocseq(struct device_meta* parent, void* underlay)
373 return device_alloc(parent, DEV_IFSEQ, underlay);
376 static inline struct device* must_inline
377 device_allocvol(struct device_meta* parent, void* underlay)
379 return device_alloc(parent, DEV_IFVOL, underlay);
383 device_addalias(struct device_meta* parent, struct device_meta* aliased,
384 char* name_fmt, ...);
387 device_addcat(struct device_meta* parent, char* name_fmt, ...);
390 device_remove(struct device_meta* dev);
393 device_definitions_byif(int if_type);
396 devdef_byident(struct devident* class);
399 device_populate_info(struct device* dev, struct dev_info* devinfo);
402 device_scan_drivers();
404 /*------ Capability ------*/
407 alloc_potens(int cap, unsigned int size);
409 #define new_potens(pot_type, pot_struct)\
410 ((pot_struct*)alloc_potens((pot_type), sizeof(pot_struct)))
412 #define new_potens_marker(pot_type)\
413 (alloc_potens((pot_type), sizeof(struct potens_meta)))
416 device_grant_potens(struct device* dev, struct potens_meta* cap);
419 device_get_potens(struct device* dev, unsigned int pot_type);
421 /*------ Load hooks ------*/
424 device_onboot_load();
427 device_postboot_load();
430 device_sysconf_load();
433 * @brief Add the loader to the chain, used by device domain
434 * to inject their custom loading logic to the hook
437 device_chain_loader(struct device_def* def, devdef_ldfn fn);
440 * @brief Walk the chain and load in a use-and-burnt fashion.
441 * the chain will be deleted and freed after loading,
442 * regardless successful or not.
445 device_chain_load_once(struct device_def* def);
448 device_lock(struct device* dev)
450 mutex_lock(&dev->lock);
454 device_unlock(struct device* dev)
456 mutex_unlock(&dev->lock);
460 device_locked(struct device* dev)
462 return mutex_on_hold(&dev->lock);
465 #define devprintf_expand(devident) (devident)->fn_grp, (devident)->unique
470 * Device def hooks extern
475 default_onregister_hook(struct device_def* def)
481 default_onload_hook(struct device_def* def)
487 default_oncreate_hook(struct device_def* def, morph_t* morphed)
492 #define extern_hook_register(name) \
493 int weak_alias("default_onregister_hook") \
494 name(struct device_def* def)
496 #define extern_hook_load(name) \
497 int weak_alias("default_onload_hook") \
498 name(struct device_def* def)
500 #define extern_hook_create(name) \
501 int weak_alias("default_oncreate_hook") \
502 name(struct device_def* def, morph_t* morphed)
505 #endif /* __LUNAIX_DEVICE_H */