1 #include <lunaix/device.h>
2 #include <lunaix/fs/twifs.h>
3 #include <lunaix/status.h>
5 #include <klibc/hash.h>
7 #include <klibc/strfmt.h>
9 static DECLARE_HASHTABLE(dev_registry, 32);
10 static DECLARE_HASHTABLE(dev_byif, 8);
11 static DEFINE_LLIST(dev_registry_flat);
13 static struct device_cat* adhoc_devcat;
16 hash_dev(u32_t fngrp, u32_t dev)
18 return (hash_32(fngrp, 16) << 16) | (hash_32(dev, 16));
24 adhoc_devcat = device_addcat(NULL, "adhoc");
26 hashtable_init(dev_registry);
27 hashtable_init(dev_byif);
30 struct device_def* devdef;
31 ldga_foreach(devdefs, struct device_def*, idx, devdef)
33 struct devclass* devc = &devdef->class;
34 u32_t hash = hash_dev(devc->fn_grp, devc->device);
38 devdef->name = "<unspecified>";
41 hashtable_hash_in(dev_registry, &devdef->hlist, hash);
42 hashtable_hash_in(dev_byif, &devdef->hlist_if, DEV_IF(devc->fn_grp));
44 llist_append(&dev_registry_flat, &devdef->dev_list);
49 devclass_eq(struct devclass* c1, struct devclass* c2)
51 return c1->fn_grp == c2->fn_grp && c1->device == c2->device;
55 devdef_byclass(struct devclass* devc)
57 u32_t hash = hash_dev(devc->fn_grp, devc->device);
60 struct device_def *pos, *n;
61 hashtable_hash_foreach(dev_registry, hash, pos, n, hlist)
63 if (pos->class.hash != hash) {
66 if (devclass_eq(devc, &pos->class)) {
75 devdef_byident(struct devident* ident)
77 struct devclass derived = { .device = DEV_KIND_FROM(ident->unique),
78 .fn_grp = ident->fn_grp };
79 return devdef_byclass(&derived);
83 device_definitions_byif(int if_type)
85 return &dev_byif[__hashkey(dev_byif, if_type)];
88 #define __device_load_on_stage(stage) \
91 struct device_def* devdef; \
92 ldga_foreach(dev_##stage, struct device_def*, idx, devdef) \
94 devdef->init(devdef); \
97 #define device_load_on_stage(stage) __device_load_on_stage(stage)
102 device_load_on_stage(load_onboot);
106 device_postboot_load()
108 device_load_on_stage(load_postboot);
112 device_sysconf_load()
114 device_load_on_stage(load_sysconf);
118 __devdb_db_gonext(struct twimap* mapping)
120 struct device_def* current = twimap_index(mapping, struct device_def*);
121 if (current->dev_list.next == &dev_registry_flat) {
125 list_entry(current->dev_list.next, struct device_def, dev_list);
130 __devdb_twifs_lsdb(struct twimap* mapping)
133 struct device_def* def = twimap_index(mapping, struct device_def*);
135 int meta = def->class.fn_grp;
136 ksnprintf(flags, 64, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta));
138 twimap_printf(mapping,
139 "%08xh:%04d \"%s\" %s\n",
147 __devdb_reset(struct twimap* map)
150 container_of(dev_registry_flat.next, struct device_def, dev_list);
156 struct twimap* map = twifs_mapping(NULL, NULL, "devtab");
157 map->reset = __devdb_reset;
158 map->read = __devdb_twifs_lsdb;
159 map->go_next = __devdb_db_gonext;
161 EXPORT_TWIFS_PLUGIN(devdb, devdb_twifs_plugin);