All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 0/4] dm: Add driver-model support for block drivers
@ 2016-03-13 14:22 Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB Simon Glass
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Simon Glass @ 2016-03-13 14:22 UTC (permalink / raw)
  To: u-boot

Recent additions of the MMC and DISK uclasses have indicated that it is time
to look at adding a uclass for block devices. This series does this and
includes a few clean-ups to the partition code also.

A block device is typically a child device of its storage parent. For
example an MMC device will have a block-device child. A USB storage device
may have multiple block-device children, one for each LUN.

With this series only USB storage and 'host' are converted over to use the
new support. Several more remain, including SCSI, IDE and MMC. Each of these
should get its own uclass.

The uclass implements only a few basic features. A few tests are added to
check that things work as expected.

The code size impact of switching to driver model for block devices is
small. One benefit is that it becomes possible to enumerate all block
devices, regardless of their type.

Changes in v3:
- Expand the commit message
- Drop patches already applied

Changes in v2:
- Rename to blk_get_device_by_str()

Simon Glass (4):
  dm: usb: Unbind old block devices when shutting down USB
  dm: sandbox: Switch over to use DM for block devices
  dm: sandbox: Drop the pre-DM host implementation
  dm: blk: Add tests for block devices

 configs/sandbox_defconfig     |  1 +
 drivers/block/sandbox.c       | 90 ----------------------------------------
 drivers/usb/host/usb-uclass.c |  6 ++-
 test/dm/Makefile              |  1 +
 test/dm/blk.c                 | 96 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 103 insertions(+), 91 deletions(-)
 create mode 100644 test/dm/blk.c

-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB
  2016-03-13 14:22 [U-Boot] [PATCH v3 0/4] dm: Add driver-model support for block drivers Simon Glass
@ 2016-03-13 14:22 ` Simon Glass
  2016-03-20  0:26   ` Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 2/4] dm: sandbox: Switch over to use DM for block devices Simon Glass
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2016-03-13 14:22 UTC (permalink / raw)
  To: u-boot

When 'usb start' is used, block devices are created for any USB flash sticks
and disks, etc. When 'usb stop' is used, these block devices are currently
not removed.

We don't want old block devices hanging around since they can still be
visible to U-Boot. Therefore, when USB is shut down, remove and unbind all
the block devices created by the USB subsystem.

Possibly we should unbind all devices which don't cause problems by being
unbound. Most likely we can remove everything except USB controllers, hubs
and emulators. We can consider that later.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Stephen Warren <swarren@nvidia.com>
---

Changes in v3:
- Expand the commit message

Changes in v2: None

 drivers/usb/host/usb-uclass.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 50538e0..69c9a50 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -159,7 +159,11 @@ int usb_stop(void)
 		if (ret && !err)
 			err = ret;
 	}
-
+#ifdef CONFIG_BLK
+	ret = blk_unbind_all(IF_TYPE_USB);
+	if (ret && !err)
+		err = ret;
+#endif
 #ifdef CONFIG_SANDBOX
 	struct udevice *dev;
 
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 2/4] dm: sandbox: Switch over to use DM for block devices
  2016-03-13 14:22 [U-Boot] [PATCH v3 0/4] dm: Add driver-model support for block drivers Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB Simon Glass
@ 2016-03-13 14:22 ` Simon Glass
  2016-03-20  0:26   ` Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 3/4] dm: sandbox: Drop the pre-DM host implementation Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 4/4] dm: blk: Add tests for block devices Simon Glass
  3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2016-03-13 14:22 UTC (permalink / raw)
  To: u-boot

Now that the drivers used by sandbox support CONFIG_BLK, we can switch
sandbox over to use driver model for block devices.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Stephen Warren <swarren@nvidia.com>
---

Changes in v3: None
Changes in v2: None

 configs/sandbox_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 02534bf..d69c9fc 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -28,6 +28,7 @@ CONFIG_SPL_SYSCON=y
 CONFIG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+CONFIG_BLK=y
 CONFIG_CLK=y
 CONFIG_SANDBOX_GPIO=y
 CONFIG_SYS_I2C_SANDBOX=y
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 3/4] dm: sandbox: Drop the pre-DM host implementation
  2016-03-13 14:22 [U-Boot] [PATCH v3 0/4] dm: Add driver-model support for block drivers Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 2/4] dm: sandbox: Switch over to use DM for block devices Simon Glass
@ 2016-03-13 14:22 ` Simon Glass
  2016-03-20  0:26   ` Simon Glass
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 4/4] dm: blk: Add tests for block devices Simon Glass
  3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2016-03-13 14:22 UTC (permalink / raw)
  To: u-boot

Driver model is used for host device block devices now, so we don't need the
old code. Remove it.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Stephen Warren <swarren@nvidia.com>
---

Changes in v3: None
Changes in v2: None

 drivers/block/sandbox.c | 90 -------------------------------------------------
 1 file changed, 90 deletions(-)

diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 6d41508..2d340ef 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -17,19 +17,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifndef CONFIG_BLK
-static struct host_block_dev host_devices[CONFIG_HOST_MAX_DEVICES];
-
-static struct host_block_dev *find_host_device(int dev)
-{
-	if (dev >= 0 && dev < CONFIG_HOST_MAX_DEVICES)
-		return &host_devices[dev];
-
-	return NULL;
-}
-#endif
-
-#ifdef CONFIG_BLK
 static unsigned long host_block_read(struct udevice *dev,
 				     unsigned long start, lbaint_t blkcnt,
 				     void *buffer)
@@ -37,18 +24,6 @@ static unsigned long host_block_read(struct udevice *dev,
 	struct host_block_dev *host_dev = dev_get_priv(dev);
 	struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
 
-#else
-static unsigned long host_block_read(struct blk_desc *block_dev,
-				     unsigned long start, lbaint_t blkcnt,
-				     void *buffer)
-{
-	int dev = block_dev->devnum;
-	struct host_block_dev *host_dev = find_host_device(dev);
-
-	if (!host_dev)
-		return -1;
-#endif
-
 	if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
 			-1) {
 		printf("ERROR: Invalid block %lx\n", start);
@@ -60,21 +35,12 @@ static unsigned long host_block_read(struct blk_desc *block_dev,
 	return -1;
 }
 
-#ifdef CONFIG_BLK
 static unsigned long host_block_write(struct udevice *dev,
 				      unsigned long start, lbaint_t blkcnt,
 				      const void *buffer)
 {
 	struct host_block_dev *host_dev = dev_get_priv(dev);
 	struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
-#else
-static unsigned long host_block_write(struct blk_desc *block_dev,
-				      unsigned long start, lbaint_t blkcnt,
-				      const void *buffer)
-{
-	int dev = block_dev->devnum;
-	struct host_block_dev *host_dev = find_host_device(dev);
-#endif
 
 	if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
 			-1) {
@@ -87,7 +53,6 @@ static unsigned long host_block_write(struct blk_desc *block_dev,
 	return -1;
 }
 
-#ifdef CONFIG_BLK
 int host_dev_bind(int devnum, char *filename)
 {
 	struct host_block_dev *host_dev;
@@ -150,51 +115,9 @@ err:
 	free(str);
 	return ret;
 }
-#else
-int host_dev_bind(int dev, char *filename)
-{
-	struct host_block_dev *host_dev = find_host_device(dev);
-
-	if (!host_dev)
-		return -1;
-	if (host_dev->blk_dev.priv) {
-		os_close(host_dev->fd);
-		host_dev->blk_dev.priv = NULL;
-	}
-	if (host_dev->filename)
-		free(host_dev->filename);
-	if (filename && *filename) {
-		host_dev->filename = strdup(filename);
-	} else {
-		host_dev->filename = NULL;
-		return 0;
-	}
-
-	host_dev->fd = os_open(host_dev->filename, OS_O_RDWR);
-	if (host_dev->fd == -1) {
-		printf("Failed to access host backing file '%s'\n",
-		       host_dev->filename);
-		return 1;
-	}
-
-	struct blk_desc *blk_dev = &host_dev->blk_dev;
-	blk_dev->if_type = IF_TYPE_HOST;
-	blk_dev->priv = host_dev;
-	blk_dev->blksz = 512;
-	blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz;
-	blk_dev->block_read = host_block_read;
-	blk_dev->block_write = host_block_write;
-	blk_dev->devnum = dev;
-	blk_dev->part_type = PART_TYPE_UNKNOWN;
-	part_init(blk_dev);
-
-	return 0;
-}
-#endif
 
 int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
 {
-#ifdef CONFIG_BLK
 	struct udevice *dev;
 	int ret;
 
@@ -202,17 +125,6 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
 	if (ret)
 		return ret;
 	*blk_devp = dev_get_uclass_platdata(dev);
-#else
-	struct host_block_dev *host_dev = find_host_device(devnum);
-
-	if (!host_dev)
-		return -ENODEV;
-
-	if (!host_dev->blk_dev.priv)
-		return -ENOENT;
-
-	*blk_devp = &host_dev->blk_dev;
-#endif
 
 	return 0;
 }
@@ -227,7 +139,6 @@ struct blk_desc *host_get_dev(int dev)
 	return blk_dev;
 }
 
-#ifdef CONFIG_BLK
 static const struct blk_ops sandbox_host_blk_ops = {
 	.read	= host_block_read,
 	.write	= host_block_write,
@@ -239,4 +150,3 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
 	.ops		= &sandbox_host_blk_ops,
 	.priv_auto_alloc_size	= sizeof(struct host_block_dev),
 };
-#endif
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 4/4] dm: blk: Add tests for block devices
  2016-03-13 14:22 [U-Boot] [PATCH v3 0/4] dm: Add driver-model support for block drivers Simon Glass
                   ` (2 preceding siblings ...)
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 3/4] dm: sandbox: Drop the pre-DM host implementation Simon Glass
@ 2016-03-13 14:22 ` Simon Glass
  2016-03-20  0:26   ` Simon Glass
  3 siblings, 1 reply; 9+ messages in thread
From: Simon Glass @ 2016-03-13 14:22 UTC (permalink / raw)
  To: u-boot

Add some tests to check that block devices work as expected.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Stephen Warren <swarren@nvidia.com>
---

Changes in v3:
- Drop patches already applied

Changes in v2:
- Rename to blk_get_device_by_str()

 test/dm/Makefile |  1 +
 test/dm/blk.c    | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)
 create mode 100644 test/dm/blk.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index fd0198f..df2d71f 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_UT_DM) += test-uclass.o
 # subsystem you must add sandbox tests here.
 obj-$(CONFIG_UT_DM) += core.o
 ifneq ($(CONFIG_SANDBOX),)
+obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_CLK) += clk.o
 obj-$(CONFIG_DM_ETH) += eth.o
 obj-$(CONFIG_DM_GPIO) += gpio.o
diff --git a/test/dm/blk.c b/test/dm/blk.c
new file mode 100644
index 0000000..f4ea32e
--- /dev/null
+++ b/test/dm/blk.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <asm/state.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Test that block devices can be created */
+static int dm_test_blk_base(struct unit_test_state *uts)
+{
+	struct udevice *blk, *usb_blk, *dev;
+
+	/* Make sure there are no block devices */
+	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &blk));
+
+	/* Create two, one the parent of the other */
+	ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
+				      IF_TYPE_HOST, 1, 512, 1024, &blk));
+	ut_assertok(blk_create_device(blk, "usb_storage_blk", "test",
+				      IF_TYPE_USB, 3, 512, 1024, &usb_blk));
+
+	/* Check we can find them */
+	ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev));
+	ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev));
+	ut_asserteq_ptr(blk, dev);
+
+	ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_USB, 0, &dev));
+	ut_assertok(blk_get_device(IF_TYPE_USB, 3, &dev));
+	ut_asserteq_ptr(usb_blk, dev);
+
+	/* Check we can iterate */
+	ut_assertok(blk_first_device(IF_TYPE_HOST, &dev));
+	ut_asserteq_ptr(blk, dev);
+	ut_asserteq(-ENODEV, blk_next_device(&dev));
+
+	ut_assertok(blk_first_device(IF_TYPE_USB, &dev));
+	ut_asserteq_ptr(usb_blk, dev);
+	ut_asserteq(-ENODEV, blk_next_device(&dev));
+
+	return 0;
+}
+DM_TEST(dm_test_blk_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int count_blk_devices(void)
+{
+	struct udevice *blk;
+	struct uclass *uc;
+	int count = 0;
+	int ret;
+
+	ret = uclass_get(UCLASS_BLK, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(blk, uc)
+		count++;
+
+	return count;
+}
+
+/* Test that block devices work correctly with USB */
+static int dm_test_blk_usb(struct unit_test_state *uts)
+{
+	struct udevice *usb_dev, *dev;
+	struct blk_desc *dev_desc;
+
+	/* Get a flash device */
+	state_set_skip_delays(true);
+	ut_assertok(usb_init());
+	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev));
+	ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
+
+	/* The parent should be a block device */
+	ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev));
+	ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
+
+	/* Check we have one block device for each mass storage device */
+	ut_asserteq(3, count_blk_devices());
+
+	/* Now go around again, making sure the old devices were unbound */
+	ut_assertok(usb_stop());
+	ut_assertok(usb_init());
+	ut_asserteq(3, count_blk_devices());
+	ut_assertok(usb_stop());
+
+	return 0;
+}
+DM_TEST(dm_test_blk_usb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB Simon Glass
@ 2016-03-20  0:26   ` Simon Glass
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Glass @ 2016-03-20  0:26 UTC (permalink / raw)
  To: u-boot

On 13 March 2016 at 08:22, Simon Glass <sjg@chromium.org> wrote:
> When 'usb start' is used, block devices are created for any USB flash sticks
> and disks, etc. When 'usb stop' is used, these block devices are currently
> not removed.
>
> We don't want old block devices hanging around since they can still be
> visible to U-Boot. Therefore, when USB is shut down, remove and unbind all
> the block devices created by the USB subsystem.
>
> Possibly we should unbind all devices which don't cause problems by being
> unbound. Most likely we can remove everything except USB controllers, hubs
> and emulators. We can consider that later.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Tested-by: Stephen Warren <swarren@nvidia.com>
> ---
>
> Changes in v3:
> - Expand the commit message
>
> Changes in v2: None
>
>  drivers/usb/host/usb-uclass.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 2/4] dm: sandbox: Switch over to use DM for block devices
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 2/4] dm: sandbox: Switch over to use DM for block devices Simon Glass
@ 2016-03-20  0:26   ` Simon Glass
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Glass @ 2016-03-20  0:26 UTC (permalink / raw)
  To: u-boot

On 13 March 2016 at 08:22, Simon Glass <sjg@chromium.org> wrote:
> Now that the drivers used by sandbox support CONFIG_BLK, we can switch
> sandbox over to use driver model for block devices.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Tested-by: Stephen Warren <swarren@nvidia.com>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  configs/sandbox_defconfig | 1 +
>  1 file changed, 1 insertion(+)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 3/4] dm: sandbox: Drop the pre-DM host implementation
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 3/4] dm: sandbox: Drop the pre-DM host implementation Simon Glass
@ 2016-03-20  0:26   ` Simon Glass
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Glass @ 2016-03-20  0:26 UTC (permalink / raw)
  To: u-boot

On 13 March 2016 at 08:22, Simon Glass <sjg@chromium.org> wrote:
> Driver model is used for host device block devices now, so we don't need the
> old code. Remove it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Tested-by: Stephen Warren <swarren@nvidia.com>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/block/sandbox.c | 90 -------------------------------------------------
>  1 file changed, 90 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [U-Boot] [PATCH v3 4/4] dm: blk: Add tests for block devices
  2016-03-13 14:22 ` [U-Boot] [PATCH v3 4/4] dm: blk: Add tests for block devices Simon Glass
@ 2016-03-20  0:26   ` Simon Glass
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Glass @ 2016-03-20  0:26 UTC (permalink / raw)
  To: u-boot

On 13 March 2016 at 08:22, Simon Glass <sjg@chromium.org> wrote:
> Add some tests to check that block devices work as expected.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Tested-by: Stephen Warren <swarren@nvidia.com>
> ---
>
> Changes in v3:
> - Drop patches already applied
>
> Changes in v2:
> - Rename to blk_get_device_by_str()
>
>  test/dm/Makefile |  1 +
>  test/dm/blk.c    | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 97 insertions(+)
>  create mode 100644 test/dm/blk.c

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-03-20  0:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-13 14:22 [U-Boot] [PATCH v3 0/4] dm: Add driver-model support for block drivers Simon Glass
2016-03-13 14:22 ` [U-Boot] [PATCH v3 1/4] dm: usb: Unbind old block devices when shutting down USB Simon Glass
2016-03-20  0:26   ` Simon Glass
2016-03-13 14:22 ` [U-Boot] [PATCH v3 2/4] dm: sandbox: Switch over to use DM for block devices Simon Glass
2016-03-20  0:26   ` Simon Glass
2016-03-13 14:22 ` [U-Boot] [PATCH v3 3/4] dm: sandbox: Drop the pre-DM host implementation Simon Glass
2016-03-20  0:26   ` Simon Glass
2016-03-13 14:22 ` [U-Boot] [PATCH v3 4/4] dm: blk: Add tests for block devices Simon Glass
2016-03-20  0:26   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.