sandbox: Provide a way to bind fixed/removeable devices

At present when a file is bound to a host device it is always marked as
removeable. Arguably the device is removeable, since it can be unbound at
will. However while it is bound, it is not considered removable by the
user. Also it is useful to be able to model both fixed and removeable
devices for code that distinguishes them.

Add a -r flag to the 'host bind' command and plumb it through to provide
this feature.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/cmd/host.c b/cmd/host.c
index 847bb1d..6aa3d91 100644
--- a/cmd/host.c
+++ b/cmd/host.c
@@ -41,6 +41,7 @@
 static int do_host_bind(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
+	bool removable = false;
 	const char *dev_str;
 	char *file;
 	char *ep;
@@ -49,7 +50,16 @@
 	/* Skip 'bind' */
 	argc--;
 	argv++;
-	if (argc < 1 || argv > 2)
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	if (!strcmp(argv[0], "-r")) {
+		removable = true;
+		argc--;
+		argv++;
+	}
+
+	if (argc > 2)
 		return CMD_RET_USAGE;
 	dev_str = argv[0];
 	dev = simple_strtoul(dev_str, &ep, 16);
@@ -59,7 +69,7 @@
 	}
 	file = argc > 1 ? argv[1] : NULL;
 
-	return !!host_dev_bind(dev, file);
+	return !!host_dev_bind(dev, file, removable);
 }
 
 static int do_host_info(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -154,7 +164,7 @@
 	U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
 	U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
 	U_BOOT_CMD_MKENT(size, 3, 0, do_host_size, "", ""),
-	U_BOOT_CMD_MKENT(bind, 3, 0, do_host_bind, "", ""),
+	U_BOOT_CMD_MKENT(bind, 4, 0, do_host_bind, "", ""),
 	U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
 	U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
 };
@@ -186,7 +196,8 @@
 	"host save hostfs - <addr> <filename> <bytes> [<offset>] - "
 		"save a file to host\n"
 	"host size hostfs - <filename> - determine size of file on host\n"
-	"host bind <dev> [<filename>] - bind \"host\" device to file\n"
+	"host bind [-r] <dev> [<filename>] - bind \"host\" device to file\n"
+	"     -r = mark as removable\n"
 	"host info [<dev>]            - show device binding & info\n"
 	"host dev [<dev>] - Set or retrieve the current host device\n"
 	"host commands use the \"hostfs\" device. The \"host\" device is used\n"
diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
index 8b18a22..e052b6b 100644
--- a/doc/arch/sandbox.rst
+++ b/doc/arch/sandbox.rst
@@ -389,6 +389,8 @@
    =>host bind 0 ./disk.raw
    =>ls host 0:2
 
+The device can be marked removeable with 'host bind -r'.
+
 A disk image can be created using the following commands::
 
    $> truncate -s 1200M ./disk.raw
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index e2f229b..1c2c3b4 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -89,7 +89,7 @@
 }
 
 #ifdef CONFIG_BLK
-int host_dev_bind(int devnum, char *filename)
+int host_dev_bind(int devnum, char *filename, bool removable)
 {
 	struct host_block_dev *host_dev;
 	struct udevice *dev;
@@ -146,7 +146,7 @@
 	}
 
 	desc = blk_get_devnum_by_type(IF_TYPE_HOST, devnum);
-	desc->removable = 1;
+	desc->removable = removable;
 	snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
 	snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
 	snprintf(desc->revision, BLK_REV_SIZE, "1.0");
@@ -160,7 +160,7 @@
 	return ret;
 }
 #else
-int host_dev_bind(int dev, char *filename)
+int host_dev_bind(int dev, char *filename, bool removable)
 {
 	struct host_block_dev *host_dev = find_host_device(dev);
 
@@ -195,7 +195,7 @@
 	blk_dev->block_write = host_block_write;
 	blk_dev->devnum = dev;
 	blk_dev->part_type = PART_TYPE_UNKNOWN;
-	blk_dev->removable = 1;
+	blk_dev->removable = removable;
 	snprintf(blk_dev->vendor, BLK_VEN_SIZE, "U-Boot");
 	snprintf(blk_dev->product, BLK_PRD_SIZE, "hostfile");
 	snprintf(blk_dev->revision, BLK_REV_SIZE, "1.0");
diff --git a/include/sandboxblockdev.h b/include/sandboxblockdev.h
index c1f0afb..4006e94 100644
--- a/include/sandboxblockdev.h
+++ b/include/sandboxblockdev.h
@@ -14,6 +14,13 @@
 	int fd;
 };
 
-int host_dev_bind(int dev, char *filename);
+/**
+ * host_dev_bind() - Bind or unbind a device
+ *
+ * @dev: Device number (0=first slot)
+ * @filename: Host filename to use, or NULL to unbind
+ * @removable: true if the block device should mark itself as removable
+ */
+int host_dev_bind(int dev, char *filename, bool removable);
 
 #endif