1 #include <lunaix/device.h>
2 #include <lunaix/fs/twifs.h>
3 #include <lunaix/status.h>
4 #include <lunaix/syslog.h>
6 #include <klibc/hash.h>
8 #include <klibc/strfmt.h>
12 static DECLARE_HASHTABLE(dev_registry, 32);
13 static DECLARE_HASHTABLE(dev_byif, 8);
14 static DEFINE_LLIST(dev_registry_flat);
16 static struct device_cat* adhoc_devcat;
19 hash_dev(u32_t fngrp, u32_t dev)
21 return (hash_32(fngrp, 16) << 16) | (hash_32(dev, 16));
27 adhoc_devcat = device_addcat(NULL, "adhoc");
29 hashtable_init(dev_registry);
30 hashtable_init(dev_byif);
33 struct device_def* devdef;
34 ldga_foreach(devdefs, struct device_def*, idx, devdef)
36 struct devclass* devc = &devdef->class;
37 u32_t hash = hash_dev(devc->fn_grp, devc->device);
38 devdef->class_hash = hash;
41 devdef->name = "<unspecified>";
45 if (devdef->ad_tabulam) {
46 errno = devdef->ad_tabulam(devdef);
50 ERROR("driver unable to register %xh:%xh.%d (err=%d)",
53 devdef->class.variant, errno);
57 hashtable_hash_in(dev_registry, &devdef->hlist, hash);
58 hashtable_hash_in(dev_byif, &devdef->hlist_if, DEV_VN(devc->fn_grp));
60 llist_append(&dev_registry_flat, &devdef->dev_list);
65 devclass_eq(struct devclass* c1, struct devclass* c2)
67 return c1->fn_grp == c2->fn_grp && c1->device == c2->device;
71 devdef_byclass(struct devclass* devc)
73 u32_t hash = hash_dev(devc->fn_grp, devc->device);
76 struct device_def *pos, *n;
77 hashtable_hash_foreach(dev_registry, hash, pos, n, hlist)
79 if (pos->class_hash != hash) {
82 if (devclass_eq(devc, &pos->class)) {
91 devdef_byident(struct devident* ident)
93 struct devclass derived = { .device = DEV_KIND_FROM(ident->unique),
94 .fn_grp = ident->fn_grp };
95 return devdef_byclass(&derived);
99 device_definitions_byif(int if_type)
101 return &dev_byif[__hashkey(dev_byif, if_type)];
104 #define __device_load_on_stage(stage) \
107 struct device_def* devdef; \
108 ldga_foreach(dev_##stage, struct device_def*, idx, devdef) \
110 device_chain_load_once(devdef); \
113 #define device_load_on_stage(stage) __device_load_on_stage(stage)
118 device_load_on_stage(load_onboot);
122 device_postboot_load()
124 device_load_on_stage(load_postboot);
128 device_sysconf_load()
130 device_load_on_stage(load_sysconf);
134 __devdb_db_gonext(struct twimap* mapping)
136 struct device_def* current = twimap_index(mapping, struct device_def*);
137 if (current->dev_list.next == &dev_registry_flat) {
141 list_entry(current->dev_list.next, struct device_def, dev_list);
146 __devdb_twifs_lsdb(struct twimap* mapping)
149 struct device_def* def = twimap_index(mapping, struct device_def*);
151 int meta = def->class.fn_grp;
152 ksnprintf(flags, 64, "vn=%x, fn=%x", DEV_VN(meta), DEV_FN(meta));
154 twimap_printf(mapping,
155 "%08xh:%04d \"%s\" %s\n",
163 __devdb_reset(struct twimap* map)
166 container_of(dev_registry_flat.next, struct device_def, dev_list);
172 struct twimap* map = twifs_mapping(NULL, NULL, "devtab");
173 map->reset = __devdb_reset;
174 map->read = __devdb_twifs_lsdb;
175 map->go_next = __devdb_db_gonext;
177 EXPORT_TWIFS_PLUGIN(devdb, devdb_twifs_plugin);