[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/busybox/src/util-linux/blockdev.c b/ap/app/busybox/src/util-linux/blockdev.c
new file mode 100644
index 0000000..e25e529
--- /dev/null
+++ b/ap/app/busybox/src/util-linux/blockdev.c
@@ -0,0 +1,206 @@
+/*
+ * blockdev implementation for busybox
+ *
+ * Copyright (C) 2010 Sergey Naumov <sknaumov@gmail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+
+//applet:IF_BLOCKDEV(APPLET(blockdev, BB_DIR_SBIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_BLOCKDEV) += blockdev.o
+
+//config:config BLOCKDEV
+//config:	bool "blockdev"
+//config:	default y
+//config:	help
+//config:	  Performs some ioctls with block devices.
+
+//usage:#define blockdev_trivial_usage
+//usage:	"OPTION BLOCKDEV"
+//usage:#define blockdev_full_usage "\n\n"
+//usage:       "	--setro		Set ro"
+//usage:     "\n	--setrw		Set rw"
+//usage:     "\n	--getro		Get ro"
+//usage:     "\n	--getss		Get sector size"
+//usage:     "\n	--getbsz	Get block size"
+//usage:     "\n	--setbsz BYTES	Set block size"
+//usage:     "\n	--getsz		Get device size in 512-byte sectors"
+/*//usage:     "\n	--getsize	Get device size in sectors (deprecated)"*/
+//usage:     "\n	--getsize64	Get device size in bytes"
+//usage:     "\n	--flushbufs	Flush buffers"
+//usage:     "\n	--rereadpt	Reread partition table"
+
+
+#include "libbb.h"
+#include <linux/fs.h>
+
+enum {
+	ARG_NONE   = 0,
+	ARG_INT    = 1,
+	ARG_ULONG  = 2,
+	/* Yes, BLKGETSIZE64 takes pointer to uint64_t, not ullong! */
+	ARG_U64    = 3,
+	ARG_MASK   = 3,
+
+	FL_USRARG   = 4, /* argument is provided by user */
+	FL_NORESULT = 8,
+	FL_SCALE512 = 16,
+};
+
+struct bdc {
+	uint32_t   ioc;                       /* ioctl code */
+	const char name[sizeof("flushbufs")]; /* "--setfoo" wothout "--" */
+	uint8_t    flags;
+	int8_t     argval;                    /* default argument value */
+};
+
+static const struct bdc bdcommands[] = {
+	{
+		.ioc = BLKROSET,
+		.name = "setro",
+		.flags = ARG_INT + FL_NORESULT,
+		.argval = 1,
+	},{
+		.ioc = BLKROSET,
+		.name = "setrw",
+		.flags = ARG_INT + FL_NORESULT,
+		.argval = 0,
+	},{
+		.ioc = BLKROGET,
+		.name = "getro",
+		.flags = ARG_INT,
+		.argval = -1,
+	},{
+		.ioc = BLKSSZGET,
+		.name = "getss",
+		.flags = ARG_INT,
+		.argval = -1,
+	},{
+		.ioc = BLKBSZGET,
+		.name = "getbsz",
+		.flags = ARG_INT,
+		.argval = -1,
+	},{
+		.ioc = BLKBSZSET,
+		.name = "setbsz",
+		.flags = ARG_INT + FL_NORESULT + FL_USRARG,
+		.argval = 0,
+	},{
+		.ioc = BLKGETSIZE64,
+		.name = "getsz",
+		.flags = ARG_U64 + FL_SCALE512,
+		.argval = -1,
+	},{
+		.ioc = BLKGETSIZE,
+		.name = "getsize",
+		.flags = ARG_ULONG,
+		.argval = -1,
+	},{
+		.ioc = BLKGETSIZE64,
+		.name = "getsize64",
+		.flags = ARG_U64,
+		.argval = -1,
+	},{
+		.ioc = BLKFLSBUF,
+		.name = "flushbufs",
+		.flags = ARG_NONE + FL_NORESULT,
+		.argval = 0,
+	},{
+		.ioc = BLKRRPART,
+		.name = "rereadpt",
+		.flags = ARG_NONE + FL_NORESULT,
+		.argval = 0,
+	}
+};
+
+static const struct bdc *find_cmd(const char *s)
+{
+	const struct bdc *bdcmd = bdcommands;
+	if (s[0] == '-' && s[1] == '-') {
+		s += 2;
+		do {
+			if (strcmp(s, bdcmd->name) == 0)
+				return bdcmd;
+			bdcmd++;
+		} while (bdcmd != bdcommands + ARRAY_SIZE(bdcommands));
+	}
+	bb_show_usage();
+}
+
+int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int blockdev_main(int argc UNUSED_PARAM, char **argv)
+{
+	const struct bdc *bdcmd;
+	int fd;
+	uint64_t u64;
+	union {
+		int i;
+		unsigned long lu;
+		uint64_t u64;
+	} ioctl_val_on_stack;
+
+	argv++;
+	if (!argv[0] || !argv[1]) /* must have at least 2 args */
+		bb_show_usage();
+
+	bdcmd = find_cmd(*argv);
+
+	u64 = (int)bdcmd->argval;
+	if (bdcmd->flags & FL_USRARG)
+		u64 = xatoi_positive(*++argv);
+
+	argv++;
+	if (!argv[0] || argv[1])
+		bb_show_usage();
+	fd = xopen(argv[0], O_RDONLY);
+
+	ioctl_val_on_stack.u64 = u64;
+#if BB_BIG_ENDIAN
+	/* Store data properly wrt data size.
+	 * (1) It's no-op for little-endian.
+	 * (2) it's no-op for 0 and -1. Only --setro uses arg != 0 and != -1,
+	 * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT.
+	 * Thus, we don't need to handle ARG_ULONG.
+	 */
+	switch (bdcmd->flags & ARG_MASK) {
+	case ARG_INT:
+		ioctl_val_on_stack.i = (int)u64;
+		break;
+# if 0 /* unused */
+	case ARG_ULONG:
+		ioctl_val_on_stack.lu = (unsigned long)u64;
+		break;
+# endif
+	}
+#endif
+
+	if (ioctl(fd, bdcmd->ioc, &ioctl_val_on_stack.u64) == -1)
+		bb_simple_perror_msg_and_die(*argv);
+
+	/* Fetch it into register(s) */
+	u64 = ioctl_val_on_stack.u64;
+
+	if (bdcmd->flags & FL_SCALE512)
+		u64 >>= 9;
+
+	/* Zero- or one-extend the value if needed, then print */
+	switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) {
+	case ARG_INT:
+		/* Smaller code when we use long long
+		 * (gcc tail-merges printf call)
+		 */
+		printf("%lld\n", (long long)(int)u64);
+		break;
+	case ARG_ULONG:
+		u64 = (unsigned long)u64;
+		/* FALLTHROUGH */
+	case ARG_U64:
+		printf("%llu\n", (unsigned long long)u64);
+		break;
+	}
+
+	if (ENABLE_FEATURE_CLEAN_UP)
+		close(fd);
+	return EXIT_SUCCESS;
+}