// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015 Google, Inc
 */

#include <common.h>
#include <dm.h>
#include <part.h>
#include <usb.h>
#include <asm/state.h>
#include <dm/test.h>
#include <test/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 *blk1, *blk3, *dev;

	/* 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, 2, &blk1));
	ut_assertok(blk_create_device(blk1, "sandbox_host_blk", "test",
				      IF_TYPE_HOST, 3, 512, 2, &blk3));

	/* 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(blk1, dev);
	ut_assertok(blk_get_device(IF_TYPE_HOST, 3, &dev));
	ut_asserteq_ptr(blk3, dev);

	/* Check we can iterate */
	ut_assertok(blk_first_device(IF_TYPE_HOST, &dev));
	ut_asserteq_ptr(blk1, dev);
	ut_assertok(blk_next_device(&dev));
	ut_asserteq_ptr(blk3, dev);

	return 0;
}
DM_TEST(dm_test_blk_base, UT_TESTF_SCAN_PDATA | UT_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(6, count_blk_devices());

	/* Now go around again, making sure the old devices were unbound */
	ut_assertok(usb_stop());
	ut_assertok(usb_init());
	ut_asserteq(6, count_blk_devices());
	ut_assertok(usb_stop());

	return 0;
}
DM_TEST(dm_test_blk_usb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

/* Test that we can find block devices without probing them */
static int dm_test_blk_find(struct unit_test_state *uts)
{
	struct udevice *blk, *dev;

	ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
				      IF_TYPE_HOST, 1, 512, 2, &blk));
	ut_asserteq(-ENODEV, blk_find_device(IF_TYPE_HOST, 0, &dev));
	ut_assertok(blk_find_device(IF_TYPE_HOST, 1, &dev));
	ut_asserteq_ptr(blk, dev);
	ut_asserteq(false, device_active(dev));

	/* Now activate it */
	ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev));
	ut_asserteq_ptr(blk, dev);
	ut_asserteq(true, device_active(dev));

	return 0;
}
DM_TEST(dm_test_blk_find, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

/* Test that block device numbering works as expected */
static int dm_test_blk_devnum(struct unit_test_state *uts)
{
	struct udevice *dev, *mmc_dev, *parent;
	int i;

	/*
	 * Probe the devices, with the first one being probed last. This is the
	 * one with no alias / sequence numnber.
	 */
	ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev));
	ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev));
	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
	for (i = 0; i < 3; i++) {
		struct blk_desc *desc;

		/* Check that the bblock device is attached */
		ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev));
		ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev));
		parent = dev_get_parent(dev);
		ut_asserteq_ptr(parent, mmc_dev);
		ut_asserteq(trailing_strtol(mmc_dev->name), i);

		/*
		 * Check that the block device devnum matches its parent's
		 * sequence number
		 */
		desc = dev_get_uclass_plat(dev);
		ut_asserteq(desc->devnum, i);
	}

	return 0;
}
DM_TEST(dm_test_blk_devnum, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

/* Test that we can get a block from its parent */
static int dm_test_blk_get_from_parent(struct unit_test_state *uts)
{
	struct udevice *dev, *blk;

	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
	ut_assertok(blk_get_from_parent(dev, &blk));

	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
	ut_asserteq(-ENOTBLK, blk_get_from_parent(dev, &blk));

	ut_assertok(uclass_get_device(UCLASS_GPIO, 0, &dev));
	ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));

	return 0;
}
DM_TEST(dm_test_blk_get_from_parent, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
