X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/f044ca812256b421e793c4335ce1ffed74710a70..7b8a1bcad75628f9add4590db2bb9b8e418ee8eb:/lunaix-os/kernel/device/devdb.c diff --git a/lunaix-os/kernel/device/devdb.c b/lunaix-os/kernel/device/devdb.c index cf58a9d..eb9e612 100644 --- a/lunaix-os/kernel/device/devdb.c +++ b/lunaix-os/kernel/device/devdb.c @@ -2,16 +2,24 @@ #include #include -#include +#include + +#include static DECLARE_HASHTABLE(dev_registry, 32); static DECLARE_HASHTABLE(dev_byif, 8); static DEFINE_LLIST(dev_registry_flat); -static struct device* adhoc_devcat; +static struct device_cat* adhoc_devcat; + +static inline u32_t +hash_dev(u32_t fngrp, u32_t dev) +{ + return (hash_32(fngrp, 16) << 16) | (hash_32(dev, 16)); +} void -device_register_all() +device_scan_drivers() { adhoc_devcat = device_addcat(NULL, "adhoc"); @@ -22,12 +30,16 @@ device_register_all() struct device_def* devdef; ldga_foreach(devdefs, struct device_def*, idx, devdef) { - u32_t hash = devclass_hash(devdef->class); - devdef->class.hash = hash; + struct devclass* devc = &devdef->class; + u32_t hash = hash_dev(devc->fn_grp, devc->device); + devc->hash = hash; + + if (!devdef->name) { + devdef->name = ""; + } hashtable_hash_in(dev_registry, &devdef->hlist, hash); - hashtable_hash_in( - dev_byif, &devdef->hlist_if, DEV_IF(devdef->class.meta)); + hashtable_hash_in(dev_byif, &devdef->hlist_if, DEV_IF(devc->fn_grp)); llist_append(&dev_registry_flat, &devdef->dev_list); } @@ -36,14 +48,13 @@ device_register_all() static int devclass_eq(struct devclass* c1, struct devclass* c2) { - return c1->meta == c2->meta && c1->variant == c2->variant && - c1->device == c2->device; + return c1->fn_grp == c2->fn_grp && c1->device == c2->device; } struct device_def* -devdef_byclass(struct devclass* class) +devdef_byclass(struct devclass* devc) { - u32_t hash = devclass_hash(*class); + u32_t hash = hash_dev(devc->fn_grp, devc->device); int errno; struct device_def *pos, *n; @@ -52,7 +63,7 @@ devdef_byclass(struct devclass* class) if (pos->class.hash != hash) { continue; } - if (devclass_eq(class, &pos->class)) { + if (devclass_eq(devc, &pos->class)) { break; } } @@ -60,45 +71,12 @@ devdef_byclass(struct devclass* class) return pos; } -struct device* -device_create_byclass(struct devclass* class, - u32_t type, - char* name, - int* err_code) +struct device_def* +devdef_byident(struct devident* ident) { - int errno; - struct device_def* devdef = devdef_byclass(class); - - if (!devdef) { - *err_code = ENOENT; - return NULL; - } - - if (!devdef->init_for) { - if (err_code) { - *err_code = ENOTSUP; - } - return NULL; - } - - struct device* dev = device_add(adhoc_devcat, NULL, type, NULL); - - errno = devdef->init_for(devdef, dev); - if (err_code && !errno) { - *err_code = errno; - device_remove(dev); - return NULL; - } - - device_setname(dev, - "%s_%d:%d:%d_%d", - name, - class->meta, - class->device, - class->device, - dev->dev_id); - - return dev; + struct devclass derived = { .device = DEV_KIND_FROM(ident->unique), + .fn_grp = ident->fn_grp }; + return devdef_byclass(&derived); } struct hbucket* @@ -107,32 +85,33 @@ device_definitions_byif(int if_type) return &dev_byif[__hashkey(dev_byif, if_type)]; } -#define device_load_on_stage(stage) \ +#define __device_load_on_stage(stage) \ ({ \ int idx = 0; \ struct device_def* devdef; \ - ldga_foreach(dev_ld_##stage, struct device_def*, idx, devdef) \ + ldga_foreach(dev_##stage, struct device_def*, idx, devdef) \ { \ devdef->init(devdef); \ } \ }) +#define device_load_on_stage(stage) __device_load_on_stage(stage) void -device_earlystage() +device_onboot_load() { - device_load_on_stage(early); + device_load_on_stage(load_onboot); } void -device_timerstage() +device_postboot_load() { - device_load_on_stage(aftertimer); + device_load_on_stage(load_postboot); } void -device_poststage() +device_sysconf_load() { - device_load_on_stage(post); + device_load_on_stage(load_sysconf); } static int @@ -150,25 +129,32 @@ __devdb_db_gonext(struct twimap* mapping) static void __devdb_twifs_lsdb(struct twimap* mapping) { - char flags[32]; + char flags[64]; struct device_def* def = twimap_index(mapping, struct device_def*); - int meta = def->class.meta; - ksnprintf(flags, 32, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta)); + int meta = def->class.fn_grp; + ksnprintf(flags, 64, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta)); twimap_printf(mapping, - "%d:%d:%d %s (%s)\n", - def->class.meta, + "%08xh:%04d \"%s\" %s\n", + def->class.fn_grp, def->class.device, - def->class.variant, def->name, flags); } +void +__devdb_reset(struct twimap* map) +{ + map->index = + container_of(dev_registry_flat.next, struct device_def, dev_list); +} + static void devdb_twifs_plugin() { struct twimap* map = twifs_mapping(NULL, NULL, "devtab"); + map->reset = __devdb_reset; map->read = __devdb_twifs_lsdb; map->go_next = __devdb_db_gonext; }