Exemplo n.º 1
0
static int do_ubiformat(int argc, char *argv[])
{
	int err, fd;
	struct ubiformat_args args;
	char *node = NULL;
	struct mtd_info_user mtd_user;

	err = parse_opt(argc, argv, &args, &node);
	if (err)
		return err;

	fd = open(node, O_RDWR);
	if (fd < 0)
		return sys_errmsg("cannot open \"%s\"", node);

	err = ioctl(fd, MEMGETINFO, &mtd_user);
	if (err) {
		sys_errmsg("MEMGETINFO ioctl request failed");
		goto out_close;
	}

	err = ubiformat(mtd_user.mtd, &args);

out_close:
	close(fd);

	return err;
}
Exemplo n.º 2
0
static int open_file(off_t *sz)
{
	int fd;

	if (!strcmp(args.image, "-")) {
		if (args.image_sz == 0)
			return errmsg("must use '-S' with non-zero value when reading from stdin");

		*sz = args.image_sz;
		fd  = dup(STDIN_FILENO);
		if (fd < 0)
			return sys_errmsg("failed to dup stdin");
	} else {
		struct stat st;

		if (stat(args.image, &st))
			return sys_errmsg("cannot open \"%s\"", args.image);

		*sz = st.st_size;
		fd  = open(args.image, O_RDONLY);
		if (fd == -1)
			return sys_errmsg("cannot open \"%s\"", args.image);
	}

	return fd;
}
Exemplo n.º 3
0
int legacy_get_mtd_oobavail(const char *node)
{
	struct stat st;
	struct nand_ecclayout_user usrlay;
	int fd, ret;

	if (stat(node, &st))
		return sys_errmsg("cannot open \"%s\"", node);

	if (!S_ISCHR(st.st_mode)) {
		errno = EINVAL;
		return errmsg("\"%s\" is not a character device", node);
	}

	fd = open(node, O_RDONLY);
	if (fd == -1)
		return sys_errmsg("cannot open \"%s\"", node);

	ret = ioctl(fd, ECCGETLAYOUT, &usrlay);
	if (ret < 0) {
		if (errno == EOPNOTSUPP)
			goto out_close;
		sys_errmsg("ECCGETLAYOUT ioctl request failed");
		goto out_close;
	}

	ret = usrlay.oobavail;

out_close:
	close(fd);

	return ret;
}
Exemplo n.º 4
0
int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
	     void *buf, int len)
{
	int ret, rd = 0;
	off_t seek;

	if (eb < 0 || eb >= mtd->eb_cnt) {
		errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks",
		       eb, mtd->dev_num, mtd->eb_cnt);
		errno = EINVAL;
		return -1;
	}
	if (offs < 0 || offs + len > mtd->eb_size) {
		errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d",
		       offs, len, mtd->dev_num, mtd->eb_size);
		errno = EINVAL;
		return -1;
	}

	/* Seek to the beginning of the eraseblock */
	seek = (off_t)eb * mtd->eb_size + offs;
	if (lseek(fd, seek, SEEK_SET) != seek)
		return sys_errmsg("cannot seek mtd%d to offset %llu",
				  mtd->dev_num, (unsigned long long)seek);

	while (rd < len) {
		ret = read(fd, buf, len);
		if (ret < 0)
			return sys_errmsg("cannot read %d bytes from mtd%d (eraseblock %d, offset %d)",
					  len, mtd->dev_num, eb, offs);
		rd += ret;
	}

	return 0;
}
Exemplo n.º 5
0
static void print_region_map(const struct mtd_dev_info *mtd, int fd,
			     const region_info_t *reginfo)
{
	unsigned long start;
	int i, width;
	int ret_locked, errno_locked, ret_bad, errno_bad;

	printf("Eraseblock map:\n");

	/* Figure out the number of spaces to pad w/out libm */
	for (i = 1, width = 0; i < reginfo->numblocks; i *= 10, ++width)
		continue;

	/* If we don't have a fd to query, just show the bare map */
	if (fd == -1) {
		ret_locked = ret_bad = -1;
		errno_locked = errno_bad = ENODEV;
	} else
		ret_locked = ret_bad = errno_locked = errno_bad = 0;

	for (i = 0; i < reginfo->numblocks; ++i) {
		start = reginfo->offset + i * reginfo->erasesize;
		printf(" %*i: %08lx ", width, i, start);

		if (ret_locked != -1) {
			ret_locked = mtd_is_locked(mtd, fd, i);
			if (ret_locked == 1)
				printf("RO ");
			else
				errno_locked = errno;
		}
		if (ret_locked != 1)
			printf("   ");

		if (ret_bad != -1) {
			ret_bad = mtd_is_bad(mtd, fd, i);
			if (ret_bad == 1)
				printf("BAD ");
			else
				errno_bad = errno;
		}
		if (ret_bad != 1)
			printf("    ");

		if (((i + 1) % 4) == 0)
			printf("\n");
	}
	if (i % 4)
		printf("\n");

	if (ret_locked == -1 && errno_locked != EOPNOTSUPP) {
		errno = errno_locked;
		sys_errmsg("could not read locked block info");
	}

	if (mtd->bb_allowed && ret_bad == -1 && errno_bad != EOPNOTSUPP) {
		errno = errno_bad;
		sys_errmsg("could not read bad block info");
	}
}
Exemplo n.º 6
0
/**
 * refill_wl_pool - refills all the fastmap pool used by the
 * WL sub-system and ubi_wl_get_peb.
 * @ubi: UBI device description object
 */
static void ubi_refill_pools(struct ubigen_info *ui, int fd)
{
        struct ubi_fm_pool *pool = &ui->fm_wl_pool;
	int start = ui->used_peb;
	off_t seek;
	char *outbuf;

	outbuf = malloc(ui->peb_size);
	memset(outbuf, 0xFF, ui->peb_size);
	ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ui->ec);

        printf("Start PEB %d for wl pool size %d\n", start, pool->max_size);
        for (pool->size = 0; pool->size < pool->max_size; pool->size++) {
                if (ui->peb_count - start < 5)
                        break;

		seek = start * ui->peb_size;
		if (lseek(fd, seek, SEEK_SET) != seek) {
			sys_errmsg("cannot seek output file");
			break;
		}
		if (write(fd, outbuf, ui->peb_size) != ui->peb_size) {
			sys_errmsg("cannot write %d bytes to the output file", ui->peb_size);
			break;
		}

                pool->pebs[pool->size] = start;
		start++;
        }
        printf( "End PEB %d for wl pool\n", start-1);
        printf( "found %d PEB for wl pool\n", pool->size);
        pool->used = 0;

        pool = &ui->fm_pool;

        printf( "Start PEB %d for user wl pool size %d\n", start, pool->max_size);
        for (pool->size = 0; pool->size < pool->max_size; pool->size++) {
                if (ui->peb_count - start < 1)
                        break;

		seek = start * ui->peb_size;
		if (lseek(fd, seek, SEEK_SET) != seek) {
			sys_errmsg("cannot seek output file");
			break;
		}
		if (write(fd, outbuf, ui->peb_size) != ui->peb_size) {
			sys_errmsg("cannot write %d bytes to the output file", ui->peb_size);
			break;
		}

                pool->pebs[pool->size] = start;
		start++;
        }
        printf( "End PEB %d for user wl pool\n", start-1);
        printf( "found %d PEB for wl pool\n", pool->size);
        pool->used = 0;
}
/**
 * ubigen_write_volume - write UBI volume.
 * @ui: libubigen information
 * @vi: volume information
 * @ec: erase coutner value to put to EC headers
 * @bytes: volume size in bytes
 * @in: input file descriptor (has to be properly seeked)
 * @out: output file descriptor
 *
 * This function reads the contents of the volume from the input file @in and
 * writes the UBI volume to the output file @out. Returns zero on success and
 * %-1 on failure.
 */
int ubigen_write_volume(const struct ubigen_info *ui,
			const struct ubigen_vol_info *vi, long long ec,
			long long bytes, int in, int out)
{
	int len = vi->usable_leb_size, rd, lnum = 0;
	char inbuf[ui->leb_size], outbuf[ui->peb_size];

	if (vi->id >= ui->max_volumes)
		return errmsg("too high volume id %d, max. volumes is %d",
			      vi->id, ui->max_volumes);

	if (vi->alignment >= ui->leb_size)
		return errmsg("too large alignment %d, max is %d (LEB size)",
			      vi->alignment, ui->leb_size);

	memset(outbuf, 0xFF, ui->data_offs);
	ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec);

	while (bytes) {
		int l;
		struct ubi_vid_hdr *vid_hdr;

		if (bytes < len)
			len = bytes;
		bytes -= len;

		l = len;
		do {
			rd = read(in, inbuf + len - l, l);
			if (rd != l)
				return sys_errmsg("cannot read %d bytes from the input file", l);

			l -= rd;
		} while (l);

		vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]);
		init_vid_hdr(ui, vi, vid_hdr, lnum, inbuf, len);

		memcpy(outbuf + ui->data_offs, inbuf, len);
		memset(outbuf + ui->data_offs + len, 0xFF,
		       ui->peb_size - ui->data_offs - len);

		if (write(out, outbuf, ui->peb_size) != ui->peb_size)
			return sys_errmsg("cannot write %d bytes to the output file", ui->peb_size);

		lnum += 1;
	}

	return 0;
}
Exemplo n.º 8
0
static int open_file(off_t *sz)
{
	int fd;
	struct stat st;

	if (stat(args.image, &st))
		return sys_errmsg("cannot open \"%s\"", args.image);

	*sz = st.st_size;
	fd  = open(args.image, O_RDONLY);
	if (fd < 0)
		return sys_errmsg("cannot open \"%s\"", args.image);

	return fd;
}
Exemplo n.º 9
0
/**
 * vol_node2nums - find UBI device number and volume ID by volume device node
 *                 file.
 * @lib: UBI library descriptor
 * @node: UBI character device node name
 * @dev_num: UBI device number is returned here
 * @vol_id: volume ID is returned hers
 *
 * This function returns zero in case of succes and %-1 in case of failure.
 */
static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num,
			 int *vol_id)
{
	struct stat st;
	struct ubi_info info;
	int i, fd, major, minor;
	char file[strlen(lib->ubi_vol) + 100];

	if (stat(node, &st))
		return sys_errmsg("cannot get information about \"%s\"",
				  node);

	if (!S_ISCHR(st.st_mode)) {
		errno = EINVAL;
		return errmsg("\"%s\" is not a character device", node);
	}

	major = major(st.st_rdev);
	minor = minor(st.st_rdev);

	if (minor == 0) {
		errno = EINVAL;
		return errmsg("\"%s\" is not a volume character device", node);
	}

	if (ubi_get_info((libubi_t *)lib, &info))
		return -1;

	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
		int major1, minor1, ret;

		ret = dev_get_major(lib, i, &major1, &minor1);
		if (ret) {
			if (errno == ENOENT)
				continue;
			return -1;
		}

		if (major1 == major)
			break;
	}

	if (i > info.highest_dev_num) {
		errno = ENODEV;
		return -1;
	}

	/* Make sure this UBI volume exists */
	sprintf(file, lib->ubi_vol, i, minor - 1);
	fd = open(file, O_RDONLY);
	if (fd == -1) {
		errno = ENODEV;
		return -1;
	}

	*dev_num = i;
	*vol_id = minor - 1;
	errno = 0;
	return 0;
}
Exemplo n.º 10
0
int ubi_rmvol(libubi_t desc, const char *node, int vol_id)
{
	int fd, ret;

	desc = desc;
	fd = open(node, O_RDONLY);
	if (fd == -1)
		return sys_errmsg("cannot open \"%s\"", node);

	ret = ioctl(fd, UBI_IOCRMVOL, &vol_id);
	if (ret == -1) {
		close(fd);
		return ret;
	}

	close(fd);

#ifdef UDEV_SETTLE_HACK
//	if (system("udevsettle") == -1)
//		return -1;
	usleep(100000);
#endif

	return 0;
}
Exemplo n.º 11
0
int ubi_attach_mtd(libubi_t desc, const char *node,
		   struct ubi_attach_request *req)
{
	int fd, ret;
	struct ubi_attach_req r;

	memset(&r, sizeof(struct ubi_attach_req), '\0');

	desc = desc;
	r.ubi_num = req->dev_num;
	r.mtd_num = req->mtd_num;
	r.vid_hdr_offset = req->vid_hdr_offset;

	fd = open(node, O_RDONLY);
	if (fd == -1)
		return sys_errmsg("cannot open \"%s\"", node);

	ret = ioctl(fd, UBI_IOCATT, &r);
	close(fd);
	if (ret == -1)
		return -1;

	req->dev_num = r.ubi_num;

#ifdef UDEV_SETTLE_HACK
	if (system("udevsettle") == -1)
		return -1;
#endif

	return ret;
}
Exemplo n.º 12
0
static int proc_parse_start(struct proc_parse_info *pi)
{
	int fd, ret;

	fd = open(MTD_PROC_FILE, O_RDONLY);
	if (fd == -1)
		return -1;

	pi->buf = xmalloc(PROC_MTD_MAX_LEN);

	ret = read(fd, pi->buf, PROC_MTD_MAX_LEN);
	if (ret == -1) {
		sys_errmsg("cannot read \"%s\"", MTD_PROC_FILE);
		goto out_free;
	}

	if (ret < PROC_MTD_FIRST_LEN ||
	    memcmp(pi->buf, PROC_MTD_FIRST, PROC_MTD_FIRST_LEN)) {
		errmsg("\"%s\" does not start with \"%s\"", MTD_PROC_FILE,
		       PROC_MTD_FIRST);
		goto out_free;
	}

	pi->data_size = ret;
	pi->next = pi->buf + PROC_MTD_FIRST_LEN;

	close(fd);
	return 0;

out_free:
	free(pi->buf);
	close(fd);
	return -1;
}
Exemplo n.º 13
0
int main(int argc, char * const argv[])
{
	int err;
	libmtd_t libmtd;
	struct mtd_info mtd_info;

	err = parse_opt(argc, argv);
	if (err)
		return -1;

	libmtd = libmtd_open();
	if (libmtd == NULL) {
		if (errno == 0)
			return errmsg("MTD is not present in the system");
		return sys_errmsg("cannot open libmtd");
	}

	err = mtd_get_info(libmtd, &mtd_info);
	if (err) {
		if (errno == ENODEV)
			return errmsg("MTD is not present");
		return sys_errmsg("cannot get MTD information");
	}

	if (!args.all && args.node) {
		int mtdn;

		/*
		 * A character device was specified, translate this to MTD
		 * device number.
		 */
		mtdn = translate_dev(libmtd, args.node);
		if (mtdn < 0)
			goto out_libmtd;
		err = print_dev_info(libmtd, &mtd_info, mtdn);
	} else
		err = print_general_info(libmtd, &mtd_info, args.all);
	if (err)
		goto out_libmtd;

	libmtd_close(libmtd);
	return 0;

out_libmtd:
	libmtd_close(libmtd);
	return -1;
}
Exemplo n.º 14
0
int ubi_probe_node(libubi_t desc, const char *node)
{
	struct stat st;
	struct ubi_info info;
	int i, fd, major, minor;
	struct libubi *lib = (struct libubi *)desc;
	char file[strlen(lib->ubi_vol) + 100];

	if (stat(node, &st))
		return sys_errmsg("cannot get information about \"%s\"", node);

	if (!S_ISCHR(st.st_mode)) {
		errmsg("\"%s\" is not a character device", node);
		errno = EINVAL;
		return -1;
	}

	major = major(st.st_rdev);
	minor = minor(st.st_rdev);

	if (ubi_get_info((libubi_t *)lib, &info))
		return -1;

	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
		int major1, minor1, ret;

		ret = dev_get_major(lib, i, &major1, &minor1);
		if (ret) {
			if (errno == ENOENT)
				continue;
			if (!errno)
				goto out_not_ubi;
			return -1;
		}

		if (major1 == major)
			break;
	}

	if (i > info.highest_dev_num)
		goto out_not_ubi;

	if (minor == 0)
		return 1;

	/* This is supposdely an UBI volume device node */
	sprintf(file, lib->ubi_vol, i, minor - 1);
	fd = open(file, O_RDONLY);
	if (fd == -1)
		goto out_not_ubi;

	return 2;

out_not_ubi:
	errmsg("\"%s\" has major:minor %d:%d, but this does not correspond to "
	       "any existing UBI device or volume", node, major, minor);
	errno = ENODEV;
	return -1;
}
Exemplo n.º 15
0
/**
 * read_data - read data from a file.
 * @file: the file to read from
 * @buf: the buffer to read to
 * @buf_len: buffer length
 *
 * This function returns number of read bytes in case of success and %-1 in
 * case of failure. Note, if the file contains more then @buf_len bytes of
 * date, this function fails with %EINVAL error code.
 */
static int read_data(const char *file, void *buf, int buf_len)
{
	int fd, rd, tmp, tmp1;

	fd = open(file, O_RDONLY);
	if (fd == -1)
		return -1;

	rd = read(fd, buf, buf_len);
	if (rd == -1) {
		sys_errmsg("cannot read \"%s\"", file);
		goto out_error;
	}

	if (rd == buf_len) {
		errmsg("contents of \"%s\" is too long", file);
		errno = EINVAL;
		goto out_error;
	}

	((char *)buf)[rd] = '\0';

	/* Make sure all data is read */
	tmp1 = read(fd, &tmp, 1);
	if (tmp1 == 1) {
		sys_errmsg("cannot read \"%s\"", file);
		goto out_error;
	}
	if (tmp1) {
		errmsg("file \"%s\" contains too much data (> %d bytes)",
		       file, buf_len);
		errno = EINVAL;
		goto out_error;
	}

	if (close(fd)) {
		sys_errmsg("close failed on \"%s\"", file);
		return -1;
	}

	return rd;

out_error:
	close(fd);
	return -1;
}
Exemplo n.º 16
0
int mtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
	      void *buf, int len)
{
	int ret;
	off_t seek;

	if (eb < 0 || eb >= mtd->eb_cnt) {
		errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks",
		       eb, mtd->dev_num, mtd->eb_cnt);
		errno = EINVAL;
		return -1;
	}
	if (offs < 0 || offs + len > mtd->eb_size) {
		errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d",
		       offs, len, mtd->dev_num, mtd->eb_size);
		errno = EINVAL;
		return -1;
	}

	if (offs % mtd->subpage_size) {
		errmsg("write offset %d is not aligned to mtd%d min. I/O size %d",
		       offs, mtd->dev_num, mtd->subpage_size);
		errno = EINVAL;
		return -1;
	}
	if (len % mtd->subpage_size) {
		errmsg("write length %d is not aligned to mtd%d min. I/O size %d",
		       len, mtd->dev_num, mtd->subpage_size);
		errno = EINVAL;
		return -1;
	}

	/* Seek to the beginning of the eraseblock */
	seek = (off_t)eb * mtd->eb_size + offs;
	if (lseek(fd, seek, SEEK_SET) != seek)
		return sys_errmsg("cannot seek mtd%d to offset %llu",
				  mtd->dev_num, (unsigned long long)seek);

	ret = write(fd, buf, len);
	if (ret != len)
		return sys_errmsg("cannot write %d bytes to mtd%d (eraseblock %d, offset %d)",
				  len, mtd->dev_num, eb, offs);

	return 0;
}
Exemplo n.º 17
0
/**
 * read_hex_ll - read a hex 'long long' value from a file.
 * @file: the file to read from
 * @value: the result is stored here
 *
 * This function reads file @file and interprets its contents as hexadecimal
 * 'long long' integer. If this is not true, it fails with %EINVAL error code.
 * Returns %0 in case of success and %-1 in case of failure.
 */
static int read_hex_ll(const char *file, long long *value)
{
	int fd, rd;
	char buf[50];

	fd = open(file, O_RDONLY);
	if (fd == -1)
		return -1;

	rd = read(fd, buf, sizeof(buf));
	if (rd == -1) {
		sys_errmsg("cannot read \"%s\"", file);
		goto out_error;
	}
	if (rd == sizeof(buf)) {
		errmsg("contents of \"%s\" is too long", file);
		errno = EINVAL;
		goto out_error;
	}
	buf[rd] = '\0';

	if (sscanf(buf, "%llx\n", value) != 1) {
		errmsg("cannot read integer from \"%s\"\n", file);
		errno = EINVAL;
		goto out_error;
	}

	if (*value < 0) {
		errmsg("negative value %lld in \"%s\"", *value, file);
		errno = EINVAL;
		goto out_error;
	}

	if (close(fd))
		return sys_errmsg("close failed on \"%s\"", file);

	return 0;

out_error:
	close(fd);
	return -1;
}
Exemplo n.º 18
0
/**
 * read_positive_ll - read a positive 'long long' value from a file.
 * @file: the file to read from
 * @value: the result is stored here
 *
 * This function reads file @file and interprets its contents as a positive
 * 'long long' integer. If this is not true, it fails with %EINVAL error code.
 * Returns %0 in case of success and %-1 in case of failure.
 */
static int read_positive_ll(const char *file, long long *value)
{
	int fd, rd;
	char buf[50];

	fd = open(file, O_RDONLY);
	if (fd == -1)
		return -1;

	rd = read(fd, buf, 50);
	if (rd == -1) {
		sys_errmsg("cannot read \"%s\"", file);
		goto out_error;
	}
	if (rd == 50) {
		errmsg("contents of \"%s\" is too long", file);
		errno = EINVAL;
		goto out_error;
	}

	if (sscanf(buf, "%lld\n", value) != 1) {
		/* This must be a UBI bug */
		errmsg("cannot read integer from \"%s\"\n", file);
		errno = EINVAL;
		goto out_error;
	}

	if (*value < 0) {
		errmsg("negative value %lld in \"%s\"", *value, file);
		errno = EINVAL;
		goto out_error;
	}

	if (close(fd))
		return sys_errmsg("close failed on \"%s\"", file);

	return 0;

out_error:
	close(fd);
	return -1;
}
Exemplo n.º 19
0
static int print_dev_info(libmtd_t libmtd, const struct mtd_info *mtd_info, int mtdn)
{
	int err;
	struct mtd_dev_info mtd;

	err = mtd_get_dev_info1(libmtd, mtdn, &mtd);
	if (err) {
		if (errno == ENODEV)
			return errmsg("mtd%d does not correspond to any "
				      "existing MTD device", mtdn);
		return sys_errmsg("cannot get information about MTD device %d",
				  mtdn);
	}

	printf("mtd%d\n", mtd.mtd_num);
	printf("Name:                           %s\n", mtd.name);
	printf("Type:                           %s\n", mtd.type_str);
	printf("Eraseblock size:                ");
	ubiutils_print_bytes(mtd.eb_size, 0);
	printf("\n");
	printf("Amount of eraseblocks:          %d (", mtd.eb_cnt);
	ubiutils_print_bytes(mtd.size, 0);
	printf(")\n");
	printf("Minimum input/output unit size: %d %s\n",
	       mtd.min_io_size, mtd.min_io_size > 1 ? "bytes" : "byte");
	if (mtd_info->sysfs_supported)
		printf("Sub-page size:                  %d %s\n",
		       mtd.subpage_size,
		       mtd.subpage_size > 1 ? "bytes" : "byte");
	else if (mtd.type == MTD_NANDFLASH || mtd.type == MTD_MLCNANDFLASH)
		printf("Sub-page size:                  unknown\n");

	if (mtd.oob_size > 0)
		printf("OOB size:                       %d bytes\n",
		       mtd.oob_size);
	if (mtd.region_cnt > 0)
		printf("Additional erase regions:       %d\n", mtd.oob_size);
	if (mtd_info->sysfs_supported)
		printf("Character device major/minor:   %d:%d\n",
		       mtd.major, mtd.minor);
	printf("Bad blocks are allowed:         %s\n",
	       mtd.bb_allowed ? "true" : "false");
	printf("Device is writable:             %s\n",
	      mtd.writable ? "true" : "false");

	if (args.ubinfo)
		print_ubi_info(mtd_info, &mtd);

	print_region_info(&mtd);

	printf("\n");
	return 0;
}
Exemplo n.º 20
0
/**
 * legacy_procfs_is_supported - legacy version of 'sysfs_is_supported()'.
 *
 * Check if we can access the procfs files for the MTD subsystem.
 */
int legacy_procfs_is_supported(void)
{
	if (access(MTD_PROC_FILE, R_OK) != 0) {
		if (errno == ENOENT) {
			errno = 0;
		} else {
			sys_errmsg("cannot read \"%s\"", MTD_PROC_FILE);
		}
		return 0;
	}
	return 1;
}
Exemplo n.º 21
0
/**
 * dev_node2num - find UBI device number by its character device node.
 * @lib: UBI library descriptor
 * @node: UBI character device node name
 *
 * This function returns positive UBI device number in case of success and %-1
 * in case of failure.
 */
static int dev_node2num(struct libubi *lib, const char *node, int *dev_num)
{
	struct stat st;
	struct ubi_info info;
	int i, major, minor;

	if (stat(node, &st))
		return sys_errmsg("cannot get information about \"%s\"",
				  node);

	if (!S_ISCHR(st.st_mode)) {
		errno = EINVAL;
		return errmsg("\"%s\" is not a character device", node);
	}

	major = major(st.st_rdev);
	minor = minor(st.st_rdev);

	if (minor != 0) {
		errno = EINVAL;
		return errmsg("\"%s\" is not an UBI character device", node);
	}

	if (ubi_get_info((libubi_t *)lib, &info))
		return -1;

	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
		int major1, minor1, ret;

		ret = dev_get_major(lib, i, &major1, &minor1);
		if (ret) {
			if (errno == ENOENT)
				continue;
			return -1;
		}

		if (major1 == major) {
			if (minor1 != 0) {
				errmsg("UBI character device minor number is "
				       "%d, but must be 0", minor1);
				errno = EINVAL;
				return -1;
			}
			errno = 0;
			*dev_num = i;
			return 0;
		}
	}

	errno = ENODEV;
	return -1;
}
Exemplo n.º 22
0
int main(int argc, char * const argv[])
{
	int err = 0;
	uint32_t crc = UBI_CRC32_INIT;
	char buf[BUFSIZE];
	FILE *fp;

	if (argc > 1) {
		fp = fopen(argv[1], "r");
		if (!fp)
			return sys_errmsg("cannot open \"%s\"", argv[1]);
	} else
		fp = stdin;

	err = parse_opt(argc, argv);
	if (err)
		return err;

	while (!feof(fp)) {
		size_t read;

		read = fread(buf, 1, BUFSIZE, fp);
		if (ferror(fp)) {
			sys_errmsg("cannot read input file");
			err = -1;
			goto out_close;
		}
		crc = crc32(crc, buf, read);
	}

	printf("0x%08x\n", crc);

out_close:
	if (fp != stdin)
		fclose(fp);
	return err;
}
Exemplo n.º 23
0
/**
 * mtd_node_to_num - converts device node to MTD number.
 * @mtd_dev_node: path to device node to convert
 *
 * This function converts given @mtd_dev_node to MTD device number.
 * @mtd_dev_node should contain path to the MTD device node. Returns MTD device
 * number in case of success and %-1 in case of failure (errno is set).
 */
static int mtd_node_to_num(const char *mtd_dev_node)
{
	int major_dev, minor_dev;
	struct stat sb;

	if (stat(mtd_dev_node, &sb) < 0)
		return sys_errmsg("cannot stat \"%s\"", mtd_dev_node);

	if (!S_ISCHR(sb.st_mode)) {
		errno = EINVAL;
		return sys_errmsg("\"%s\" is not a character device",
				  mtd_dev_node);
	}

	major_dev = major(sb.st_rdev);
	minor_dev = minor(sb.st_rdev);

	if (major != MTD_CHAR_MAJOR) {
		errno = EINVAL;
		return sys_errmsg("\"%s\" is not an MTD device", mtd_dev_node);
	}

	return minor_dev / 2;
}
Exemplo n.º 24
0
static int answer_is_yes(void)
{
	char buf[4];

	while (1) {
		if (scanf("%3s", buf) == EOF) {
			sys_errmsg("scanf returned unexpected EOF, assume \"no\"");
			return 0;
		}
		if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1))
			return 1;
		if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1))
			return 0;
	}
}
Exemplo n.º 25
0
static int translate_dev(libmtd_t libmtd, const char *node)
{
	int err;
	struct mtd_dev_info mtd;

	err = mtd_get_dev_info(libmtd, node, &mtd);
	if (err) {
		if (errno == ENODEV)
			return errmsg("\"%s\" does not correspond to any "
				      "existing MTD device", node);
		return sys_errmsg("cannot get information about MTD "
				  "device \"%s\"", node);
	}

	return mtd.mtd_num;
}
Exemplo n.º 26
0
static int want_exit(void)
{
	char buf[4];

	while (1) {
		normsg_cont("continue? (yes/no)  ");
		if (scanf("%3s", buf) == EOF) {
			sys_errmsg("scanf returned unexpected EOF, assume \"yes\"");
			return 1;
		}
		if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1))
			return 0;
		if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1))
			return 1;
	}
}
Exemplo n.º 27
0
static int print_general_info(libmtd_t libmtd, const struct mtd_info *mtd_info,
			      int all)
{
	int i, err, first = 1;
	struct mtd_dev_info mtd;

	printf("Count of MTD devices:           %d\n", mtd_info->mtd_dev_cnt);
	if (mtd_info->mtd_dev_cnt == 0)
		return 0;

	for (i = mtd_info->lowest_mtd_num;
	     i <= mtd_info->highest_mtd_num; i++) {
		err = mtd_get_dev_info1(libmtd, i, &mtd);
		if (err == -1) {
			if (errno == ENODEV)
				continue;
			return sys_errmsg("libmtd failed to get MTD device %d "
					  "information", i);
		}

		if (!first)
			printf(", mtd%d", i);
		else {
			printf("Present MTD devices:            mtd%d", i);
			first = 0;
		}
	}
	printf("\n");
	printf("Sysfs interface supported:      %s\n",
	       mtd_info->sysfs_supported ? "yes" : "no");

	if (!all)
		return 0;

	printf("\n");

	for (i = mtd_info->lowest_mtd_num;
	     i <= mtd_info->highest_mtd_num; i++) {
		if (!mtd_dev_present(libmtd, i))
			continue;
		err = print_dev_info(libmtd, mtd_info, i);
		if (err)
			return err;
	}

	return 0;
}
Exemplo n.º 28
0
static void print_region_info(const struct mtd_dev_info *mtd)
{
	region_info_t reginfo;
	int r, fd;

	/*
	 * If we don't have any region info, just return
	 *
	 * FIXME: We can't get region_info (via ioctl) without having the MTD
	 *        node path. This is a problem for `mtdinfo -a', for example,
	 *        since it doesn't provide any filepath information.
	 */
	if (!args.node || (!args.map && mtd->region_cnt == 0))
		return;

	/* First open the device so we can query it */
	fd = open(args.node, O_RDONLY | O_CLOEXEC);
	if (fd == -1) {
		sys_errmsg("couldn't open MTD dev: %s", args.node);
		if (mtd->region_cnt)
			return;
	}

	/* Walk all the regions and show the map for them */
	if (mtd->region_cnt) {
		for (r = 0; r < mtd->region_cnt; ++r) {
			printf("Eraseblock region %i: ", r);
			if (mtd_regioninfo(fd, r, &reginfo) == 0) {
				printf(" offset: %#x size: %#x numblocks: %#x\n",
					reginfo.offset, reginfo.erasesize,
					reginfo.numblocks);
				if (args.map)
					print_region_map(mtd, fd, &reginfo);
			} else
				printf(" info is unavailable\n");
		}
	} else {
		reginfo.offset = 0;
		reginfo.erasesize = mtd->eb_size;
		reginfo.numblocks = mtd->eb_cnt;
		reginfo.regionindex = 0;
		print_region_map(mtd, fd, &reginfo);
	}

	if (fd != -1)
		close(fd);
}
Exemplo n.º 29
0
int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes)
{
	int fd, ret;
	struct ubi_rsvol_req req;

	desc = desc;
	fd = open(node, O_RDONLY);
	if (fd == -1)
		return sys_errmsg("cannot open \"%s\"", node);

	req.bytes = bytes;
	req.vol_id = vol_id;

	ret = ioctl(fd, UBI_IOCRSVOL, &req);
	close(fd);
	return ret;
}
Exemplo n.º 30
0
static int read_all(int fd, void *buf, size_t len)
{
	while (len > 0) {
		ssize_t l = read(fd, buf, len);
		if (l == 0)
			return errmsg("eof reached; %zu bytes remaining", len);
		else if (l > 0) {
			buf += l;
			len -= l;
		} else if (errno == EINTR || errno == EAGAIN)
			continue;
		else
			return sys_errmsg("reading failed; %zu bytes remaining", len);
	}

	return 0;
}