Ejemplo n.º 1
0
int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
{
	struct ft_atom atom;
	void *node;
	char *p, *next;
	int size;

	node = ft_node_ph2node(cxt, phandle);
	if (node == NULL)
		return -1;

	p = node;
	while ((next = ft_next(cxt, p, &atom)) != NULL) {
		switch (atom.tag) {
		case OF_DT_BEGIN_NODE:
		case OF_DT_END_NODE:
			return -1;
		case OF_DT_PROP:
			if (strcmp(atom.name, propname))
				break;
			/* found the property, remove it */
			size = 12 + -_ALIGN(atom.size, 4);
			cxt->p = p;
			if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size))
				return -1;
			return 0;
		}
		p = next;
	}
	return -1;
}
Ejemplo n.º 2
0
int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
		void *buf, const unsigned int buflen)
{
	struct ft_atom atom;
	void *node;
	char *p;
	int depth;
	unsigned int size;

	node = ft_node_ph2node(cxt, phandle);
	if (node == NULL)
		return -1;

	depth = 0;
	p = (char *)node;

	while ((p = ft_next(cxt, p, &atom)) != NULL) {
		switch (atom.tag) {
		case OF_DT_BEGIN_NODE:
			++depth;
			break;
		case OF_DT_PROP:
			if ((depth != 1) || strcmp(atom.name, propname))
				break;
			size = min(atom.size, buflen);
			memcpy(buf, atom.data, size);
			return atom.size;
		case OF_DT_END_NODE:
			if (--depth <= 0)
				return -1;
		}
	}
	return -1;
}
Ejemplo n.º 3
0
void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
{
	void *node = ft_node_ph2node(cxt, phandle);
	if (node == NULL)
		return NULL;

	node = __ft_get_parent(cxt, node);
	return ft_get_phandle(cxt, node);
}
Ejemplo n.º 4
0
/* Returns the start of the path within the provided buffer, or NULL on
 * error.
 */
char *ft_get_path(struct ft_cxt *cxt, const void *phandle,
                  char *buf, int len)
{
	const char *path_comp[FT_MAX_DEPTH];
	struct ft_atom atom;
	char *p, *next, *pos;
	int depth = 0, i;
	void *node;

	node = ft_node_ph2node(cxt, phandle);
	if (node == NULL)
		return NULL;

	p = ft_root_node(cxt);

	while ((next = ft_next(cxt, p, &atom)) != NULL) {
		switch (atom.tag) {
		case OF_DT_BEGIN_NODE:
			path_comp[depth++] = atom.name;
			if (p == node)
				goto found;

			break;

		case OF_DT_END_NODE:
			if (--depth == 0)
				return NULL;
		}

		p = next;
	}

found:
	pos = buf;
	for (i = 1; i < depth; i++) {
		int this_len;

		if (len <= 1)
			return NULL;

		*pos++ = '/';
		len--;

		strncpy(pos, path_comp[i], len);

		if (pos[len - 1] != 0)
			return NULL;

		this_len = strlen(pos);
		len -= this_len;
		pos += this_len;
	}

	return buf;
}
Ejemplo n.º 5
0
void *ft_find_device(struct ft_cxt *cxt, const void *top, const char *srch_path)
{
	char *node;

	if (top) {
		node = ft_node_ph2node(cxt, top);
		if (node == NULL)
			return NULL;
	} else {
		node = ft_root_node(cxt);
	}

	node = ft_find_descendent(cxt, node, srch_path);
	return ft_get_phandle(cxt, node);
}
Ejemplo n.º 6
0
void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
                                 const char *propname, const char *propval,
                                 int proplen)
{
	void *node = NULL;

	if (prev) {
		node = ft_node_ph2node(cxt, prev);

		if (!node)
			return NULL;
	}

	node = __ft_find_node_by_prop_value(cxt, node, propname,
	                                    propval, proplen);
	return ft_get_phandle(cxt, node);
}
Ejemplo n.º 7
0
int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
		void *buf, const unsigned int buflen)
{
	const void *data;
	unsigned int size;

	void *node = ft_node_ph2node(cxt, phandle);
	if (!node)
		return -1;

	data = __ft_get_prop(cxt, node, propname, &size);
	if (data) {
		unsigned int clipped_size = min(size, buflen);
		memcpy(buf, data, clipped_size);
		return size;
	}

	return -1;
}
Ejemplo n.º 8
0
int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
		const void *buf, const unsigned int buflen)
{
	struct ft_atom atom;
	void *node;
	char *p, *next;
	int nextra, depth;

	node = ft_node_ph2node(cxt, phandle);
	if (node == NULL)
		return -1;

	depth = 0;
	p = node;

	while ((next = ft_next(cxt, p, &atom)) != NULL) {
		switch (atom.tag) {
		case OF_DT_BEGIN_NODE:
			++depth;
			break;
		case OF_DT_END_NODE:
			if (--depth > 0)
				break;
			/* haven't found the property, insert here */
			cxt->p = p;
			return ft_prop(cxt, propname, buf, buflen);
		case OF_DT_PROP:
			if ((depth != 1) || strcmp(atom.name, propname))
				break;
			/* found an existing property, overwrite it */
			nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4);
			cxt->p = atom.data;
			if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT,
						nextra))
				return -1;
			*(u32 *) (cxt->p - 8) = cpu_to_be32(buflen);
			ft_put_bin(cxt, buf, buflen);
			return 0;
		}
		p = next;
	}
	return -1;
}
Ejemplo n.º 9
0
void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name)
{
	struct ft_atom atom;
	char *p, *next, *ret;
	int depth = 0;

	if (parent) {
		p = ft_node_ph2node(cxt, parent);
		if (!p)
			return NULL;
	} else {
		p = ft_root_node(cxt);
	}

	while ((next = ft_next(cxt, p, &atom)) != NULL) {
		switch (atom.tag) {
		case OF_DT_BEGIN_NODE:
			++depth;
			if (depth == 1 && strcmp(atom.name, name) == 0)
				/* duplicate node name, return error */
				return NULL;
			break;
		case OF_DT_END_NODE:
			--depth;
			if (depth > 0)
				break;
			/* end of node, insert here */
			cxt->p = p;
			ret = ft_begin_node(cxt, name);
			ft_end_node(cxt);
			return ft_get_phandle(cxt, ret);
		}
		p = next;
	}
	return NULL;
}
Ejemplo n.º 10
0
void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
{
	void *node;
	int d;
	struct ft_atom atom;
	char *p;

	node = ft_node_ph2node(cxt, phandle);
	if (node == NULL)
		return NULL;

	for (d = 0; cxt->genealogy[d] != NULL; ++d)
		if (cxt->genealogy[d] == node)
			return cxt->genealogy[d > 0 ? d - 1 : 0];

	/* have to do it the hard way... */
	p = cxt->rgn[FT_STRUCT].start;
	d = 0;
	while ((p = ft_next(cxt, p, &atom)) != NULL) {
		switch (atom.tag) {
		case OF_DT_BEGIN_NODE:
			cxt->genealogy[d] = atom.data;
			if (node == atom.data) {
				/* found it */
				cxt->genealogy[d + 1] = NULL;
				return d > 0 ? cxt->genealogy[d - 1] : node;
			}
			++d;
			break;
		case OF_DT_END_NODE:
			--d;
			break;
		}
	}
	return NULL;
}