⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 of-devtree.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* get the component length */        sz = ofd_pathsplit_right(s, '/', 0);        /* check for an alias */        asz = ofd_pathsplit_right(s, ':', sz);        if ( s[asz] == ':' ) {            /*             * s points to an alias and &s[sz] points to the alias             * args.             */            assert(0); /* aliases no supported */            return 0;        }    } else if ( s[1] == '\0' ) {        return n;    }    n = ofd_node_child(m, n);    if ( n == 0 ) {        return 0;    }    return ofd_node_walk(m, n, s);}static struct ofd_prop *ofd_prop_get(struct ofd_mem *m, ofdn_t p){    if ( p < m->om_next ) {        struct ofd_prop *r;        r = (struct ofd_prop *)&m->om_mem[p];        if ( r->op_ima == PROP_PAT ) {            return r;        }        assert(r->op_ima == PROP_PAT); /* bad object */    }    return NULL;}static ofdn_t ofd_prop_create(    struct ofd_mem *m,    ofdn_t node,    const char *name,    const void *src,    size_t sz){    struct ofd_node *n;    struct ofd_prop *p;    size_t len = strlen(name) + 1;    size_t sum = sizeof (*p) + sz + len;    ofdn_t cells;    char *dst;    ofdn_t pos;    cells = (sum + sizeof (m->om_mem[0]) - 1) / sizeof (m->om_mem[0]);    if ( m->om_next + cells >= m->om_num ) {        return 0;    }    /* actual data structure */    pos = m->om_next;    assert(ofd_check(&m->om_mem[pos], cells)); /* non-zero */    p = (struct ofd_prop *)&m->om_mem[pos];    m->om_next += cells;    assert(p->op_ima == 0); /* new node not empty */    p->op_ima = PROP_PAT;    p->op_next = 0;    p->op_objsz = sz;    p->op_namesz = len;    /* the rest of the data */    dst = p->op_data;    /* zero what will be the pad, cheap and cannot hurt */    m->om_mem[m->om_next - 1] = 0;    if ( sz > 0 ) {        /* some props have no data, just a name */        memcpy(dst, src, sz);        dst += sz;    }    memcpy(dst, name, len);    /* now place it in the tree */    n = ofd_node_get(m, node);    assert(n != NULL);    if ( n->on_prop == 0 ) {        n->on_prop = pos;    } else {        ofdn_t pn = n->on_prop;        struct ofd_prop *nxt;        for (;;) {            nxt = ofd_prop_get(m, pn);            if (nxt->op_next == 0) {                nxt->op_next = pos;                break;            }            pn = nxt->op_next;        }    }    return pos;}void ofd_prop_remove(void *mem, ofdn_t node, ofdn_t prop){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_node *n = ofd_node_get(m, node);    struct ofd_prop *p = ofd_prop_get(m, prop);    if (n == NULL) return;    if (p == NULL) return;    if ( n->on_prop == prop ) {        n->on_prop = p->op_next;    } else {        ofdn_t pn = n->on_prop;        struct ofd_prop *nxt;        for ( ; ; ) {            nxt = ofd_prop_get(m, pn);            if ( nxt->op_next == prop ) {                nxt->op_next = p->op_next;                break;            }            pn = nxt->op_next;        }    }    return;}ofdn_t ofd_prop_find(void *mem, ofdn_t n, const char *name){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t p = ofd_node_prop(m, n);    struct ofd_prop *r;    char *s;    size_t len;    if ( name == NULL || *name == '\0' ) {        return OFD_ROOT;    }    len = strlen(name) + 1;        while ( p != 0 ) {        r = ofd_prop_get(m, p);        s = &r->op_data[r->op_objsz];        if ( len == r->op_namesz ) {            if ( strncmp(name, s, r->op_namesz) == 0 ) {                break;            }        }        p = r->op_next;    }    return p;}static ofdn_t ofd_prop_next(struct ofd_mem *m, ofdn_t n, const char *prev){    ofdn_t p;    if ( prev == NULL || *prev == '\0' ) {        /* give the first */        p = ofd_node_prop(m, n);    } else {        struct ofd_prop *r;        /* look for the name */        p = ofd_prop_find(m, n, prev);        if ( p != 0 ) {            /* get the data for prev */            r = ofd_prop_get(m, p);            /* now get next */            p = r->op_next;        } else {            p = -1;        }    }    return p;}ofdn_t ofd_nextprop(void *mem, ofdn_t n, const char *prev, char *name){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t p = ofd_prop_next(m, n, prev);    struct ofd_prop *r;    char *s;    if ( p > 0 ) {        r = ofd_prop_get(m, p);        s = &r->op_data[r->op_objsz];        memcpy(name, s, r->op_namesz);    }    return p;}/* * It is valid to call with NULL pointers, in case you want only one * cell size. */int ofd_getcells(void* mem, ofdn_t n, u32* addr_cells, u32* size_cells){    if ( addr_cells != NULL ) *addr_cells = 0;    if ( size_cells != NULL ) *size_cells = 0;retry:    if ( addr_cells  != NULL && *addr_cells == 0 ) {        ofd_getprop(mem, n, "#address-cells",                addr_cells, sizeof(u32));    }    if ( size_cells != NULL && *size_cells == 0 ) {        ofd_getprop(mem, n, "#size-cells", size_cells, sizeof(u32));    }    if ( ( size_cells != NULL && *size_cells == 0 )            || ( addr_cells != NULL && *addr_cells == 0 ) ) {        if ( n != OFD_ROOT ) {            n = ofd_node_parent(mem, n);            goto retry;        }        return -1;    }    return 1;}int ofd_getprop(void *mem, ofdn_t n, const char *name, void *buf, size_t sz){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t p = ofd_prop_find(m, n, name);    struct ofd_prop *r;    if ( p == 0 ) {        return -1;    }    r = ofd_prop_get(m, p);    if ( sz > r->op_objsz ) {        sz = r->op_objsz;    }    memcpy(buf, r->op_data, sz);    return r->op_objsz;}int ofd_getproplen(void *mem, ofdn_t n, const char *name){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t p = ofd_prop_find(m, n, name);    struct ofd_prop *r;    if ( p == 0 ) {        return -1;    }    r = ofd_prop_get(m, p);    return r->op_objsz;}static ofdn_t ofd_prop_set(    void *mem, ofdn_t n, const char *name, const void *src, size_t sz){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t p = ofd_prop_find(m, n, name);    struct ofd_prop *r;    char *dst;    r = ofd_prop_get(m, p);    if ( sz <= r->op_objsz ) {        /* we can reuse */        memcpy(r->op_data, src, sz);        if ( sz < r->op_objsz ) {            /* need to move name */            dst = r->op_data + sz;            /*             * use the name arg size we may have overlap with the             * original             */            memcpy(dst, name, r->op_namesz);            r->op_objsz = sz;        }    } else {        /*         * Sadly, we remove from the list, wasting the space and then         * we can creat a new one         */        ofd_prop_remove(m, n, p);        p = ofd_prop_create(mem, n, name, src, sz);    }    return p;}int ofd_setprop(    void *mem, ofdn_t n, const char *name, const void *buf, size_t sz){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t r;    r = ofd_prop_find(m, n, name);    if ( r == 0 ) {        r = ofd_prop_create(mem, n, name, buf, sz);    } else {        r = ofd_prop_set(mem, n, name, buf, sz);    }    if ( r > 0 ) {        struct ofd_prop *pp = ofd_prop_get(m, r);        return pp->op_objsz;    }    return OF_FAILURE;}static ofdn_t ofd_find_by_prop(    struct ofd_mem *m,    ofdn_t head,    ofdn_t *prev_p,    ofdn_t n,    const char *name,    const void *val,    size_t sz){    struct ofd_node *np;    struct ofd_prop *pp;    ofdn_t p;retry:    p = ofd_prop_find(m, n, name);    if ( p > 0 ) {        int match = 0;        /* a property exists by that name */        if ( val == NULL ) {            match = 1;        } else {            /* need to compare values */            pp = ofd_prop_get(m, p);            if ( sz == pp->op_objsz                 && memcmp(pp->op_data, val, sz) == 0 ) {                match = 1;            }        }        if ( match == 1 ) {            if ( *prev_p >= 0 ) {                np = ofd_node_get(m, *prev_p);                np->on_next = n;            } else {                head = n;            }            np = ofd_node_get(m, n);            np->on_prev = *prev_p;            np->on_next = -1;            *prev_p = n;        }    }    p = ofd_node_child(m, n);    if ( p > 0 ) {        head = ofd_find_by_prop(m, head, prev_p, p, name, val, sz);    }    p = ofd_node_peer(m, n);    if ( p > 0 ) {        n = p;        goto retry;    }    return head;}ofdn_t ofd_node_find_by_prop(    void *mem,    ofdn_t n,    const char *name,    const void *val,    size_t sz){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t prev = -1;    if ( n <= 0 ) {        n = OFD_ROOT;    }    return ofd_find_by_prop(m, -1, &prev, n, name, val, sz);}ofdn_t ofd_node_find_next(void *mem, ofdn_t n){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_node *np;    np = ofd_node_get(m, n);    if (np == NULL) return 0;    return np->on_next;}ofdn_t ofd_node_find_prev(void *mem, ofdn_t n){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_node *np;    np = ofd_node_get(m, n);    if (np == NULL) return 0;    return np->on_prev;}ofdn_t ofd_io_create(void *mem, ofdn_t node, u64 open){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_node *n;    struct ofd_io *i;    ofdn_t pos;    ofdn_t cells;    cells = (sizeof (*i) + sizeof (m->om_mem[0]) - 1) / sizeof(m->om_mem[0]);    n = ofd_node_get(m, node);    if ( n == NULL ) return 0;    if ( m->om_next + cells >= m->om_num ) {        return 0;    }    pos = m->om_next;    assert(ofd_check(&m->om_mem[pos], cells)); /* non-zero */    m->om_next += cells;        i = (struct ofd_io *)&m->om_mem[pos];    assert(i->oi_ima == 0); /* new node not empty */    i->oi_ima = IO_PAT;    i->oi_node = node;    i->oi_open = open;    n->on_io = pos;    return pos;}static struct ofd_io *ofd_io_get(struct ofd_mem *m, ofdn_t i){    if ( i < m->om_next ) {        struct ofd_io *r;        r = (struct ofd_io *)&m->om_mem[i];        if ( r->oi_ima == IO_PAT ) {            return r;        }        assert(r->oi_ima == IO_PAT); /* bad object */    }    return NULL;}ofdn_t ofd_node_io(void *mem, ofdn_t n){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_node *r = ofd_node_get(m, n);    if (r == NULL) return 0;    return r->on_io;}uint ofd_io_open(void *mem, ofdn_t n){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_io *r = ofd_io_get(m, n);    if (r == NULL) return 0;    return r->oi_open;}void ofd_io_close(void *mem, ofdn_t n){    struct ofd_mem *m = (struct ofd_mem *)mem;    struct ofd_io *o = ofd_io_get(m, n);    struct ofd_node *r = ofd_node_get(m, o->oi_node);    assert(o != NULL);    assert(r != NULL);    o->oi_open = 0;    r->on_io = 0;}ofdn_t ofd_node_add(void *m, ofdn_t p, const char *path, size_t sz){    ofdn_t n;    n = ofd_node_child(m, p);    if ( n > 0 ) {        n = ofd_node_peer_last(m, n);        if ( n > 0 ) {            n = ofd_node_peer_create(m, n, path, sz);        }    } else {        n = ofd_node_child_create(m, p, path, sz);    }    return n;}ofdn_t ofd_prop_add(    void *mem,    ofdn_t n,    const char *name,    const void *buf,    size_t sz){    struct ofd_mem *m = (struct ofd_mem *)mem;    ofdn_t r;    r = ofd_prop_find(m, n, name);    if ( r == 0 ) {        r = ofd_prop_create(mem, n, name, buf, sz);    } else {        r = ofd_prop_set(mem, n, name, buf, sz);    }    return r;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -