static int bpmp_populate_debugfs_inband()

in tegra/bpmp-debugfs.c [410:489]


static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
					struct dentry *parent,
					char *ppath)
{
	const size_t pathlen = SZ_256;
	const size_t bufsize = SZ_16K;
	uint32_t dsize, attrs = 0;
	struct dentry *dentry;
	struct seqbuf seqbuf;
	char *buf, *pathbuf;
	const char *name;
	int err = 0;

	if (!bpmp || !parent || !ppath)
		return -EINVAL;

	buf = kmalloc(bufsize, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	pathbuf = kzalloc(pathlen, GFP_KERNEL);
	if (!pathbuf) {
		kfree(buf);
		return -ENOMEM;
	}

	err = mrq_debug_read(bpmp, ppath, buf, bufsize, &dsize);
	if (err)
		goto out;

	seqbuf_init(&seqbuf, buf, dsize);

	while (!seqbuf_eof(&seqbuf)) {
		err = seqbuf_read_u32(&seqbuf, &attrs);
		if (err)
			goto out;

		err = seqbuf_read_str(&seqbuf, &name);
		if (err < 0)
			goto out;

		if (attrs & DEBUGFS_S_ISDIR) {
			size_t len;

			dentry = debugfs_create_dir(name, parent);
			if (IS_ERR(dentry)) {
				err = PTR_ERR(dentry);
				goto out;
			}

			len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name);
			if (len >= pathlen) {
				err = -EINVAL;
				goto out;
			}

			err = bpmp_populate_debugfs_inband(bpmp, dentry,
							   pathbuf);
			if (err < 0)
				goto out;
		} else {
			umode_t mode;

			mode = attrs & DEBUGFS_S_IRUSR ? 0400 : 0;
			mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0;
			dentry = debugfs_create_file(name, mode, parent, bpmp,
						     &bpmp_debug_fops);
			if (!dentry) {
				err = -ENOMEM;
				goto out;
			}
		}
	}

out:
	kfree(pathbuf);
	kfree(buf);

	return err;
}