183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2e4fb863fSSimon Glass /*
3e4fb863fSSimon Glass * Copyright (C) 2015 Google, Inc
4e4fb863fSSimon Glass */
5e4fb863fSSimon Glass
6e4fb863fSSimon Glass #include <common.h>
7e4fb863fSSimon Glass #include <dm.h>
8e4fb863fSSimon Glass #include <usb.h>
9e4fb863fSSimon Glass #include <asm/state.h>
10e4fb863fSSimon Glass #include <dm/test.h>
11e4fb863fSSimon Glass #include <test/ut.h>
12e4fb863fSSimon Glass
13e4fb863fSSimon Glass DECLARE_GLOBAL_DATA_PTR;
14e4fb863fSSimon Glass
15e4fb863fSSimon Glass /* Test that block devices can be created */
dm_test_blk_base(struct unit_test_state * uts)16e4fb863fSSimon Glass static int dm_test_blk_base(struct unit_test_state *uts)
17e4fb863fSSimon Glass {
18*fa583f86SBin Meng struct udevice *blk1, *blk3, *dev;
19e4fb863fSSimon Glass
20e4fb863fSSimon Glass /* Make sure there are no block devices */
21*fa583f86SBin Meng ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &dev));
22e4fb863fSSimon Glass
23e4fb863fSSimon Glass /* Create two, one the parent of the other */
24e4fb863fSSimon Glass ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
25*fa583f86SBin Meng IF_TYPE_HOST, 1, 512, 2, &blk1));
26*fa583f86SBin Meng ut_assertok(blk_create_device(blk1, "sandbox_host_blk", "test",
27*fa583f86SBin Meng IF_TYPE_HOST, 3, 512, 2, &blk3));
28e4fb863fSSimon Glass
29e4fb863fSSimon Glass /* Check we can find them */
30e4fb863fSSimon Glass ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev));
31e4fb863fSSimon Glass ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev));
32*fa583f86SBin Meng ut_asserteq_ptr(blk1, dev);
33*fa583f86SBin Meng ut_assertok(blk_get_device(IF_TYPE_HOST, 3, &dev));
34*fa583f86SBin Meng ut_asserteq_ptr(blk3, dev);
35e4fb863fSSimon Glass
36e4fb863fSSimon Glass /* Check we can iterate */
37e4fb863fSSimon Glass ut_assertok(blk_first_device(IF_TYPE_HOST, &dev));
38*fa583f86SBin Meng ut_asserteq_ptr(blk1, dev);
39*fa583f86SBin Meng ut_assertok(blk_next_device(&dev));
40*fa583f86SBin Meng ut_asserteq_ptr(blk3, dev);
41e4fb863fSSimon Glass
42e4fb863fSSimon Glass return 0;
43e4fb863fSSimon Glass }
44e4fb863fSSimon Glass DM_TEST(dm_test_blk_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
45e4fb863fSSimon Glass
count_blk_devices(void)46e4fb863fSSimon Glass static int count_blk_devices(void)
47e4fb863fSSimon Glass {
48e4fb863fSSimon Glass struct udevice *blk;
49e4fb863fSSimon Glass struct uclass *uc;
50e4fb863fSSimon Glass int count = 0;
51e4fb863fSSimon Glass int ret;
52e4fb863fSSimon Glass
53e4fb863fSSimon Glass ret = uclass_get(UCLASS_BLK, &uc);
54e4fb863fSSimon Glass if (ret)
55e4fb863fSSimon Glass return ret;
56e4fb863fSSimon Glass
57e4fb863fSSimon Glass uclass_foreach_dev(blk, uc)
58e4fb863fSSimon Glass count++;
59e4fb863fSSimon Glass
60e4fb863fSSimon Glass return count;
61e4fb863fSSimon Glass }
62e4fb863fSSimon Glass
63e4fb863fSSimon Glass /* Test that block devices work correctly with USB */
dm_test_blk_usb(struct unit_test_state * uts)64e4fb863fSSimon Glass static int dm_test_blk_usb(struct unit_test_state *uts)
65e4fb863fSSimon Glass {
66e4fb863fSSimon Glass struct udevice *usb_dev, *dev;
67e4fb863fSSimon Glass struct blk_desc *dev_desc;
68e4fb863fSSimon Glass
69e4fb863fSSimon Glass /* Get a flash device */
70e4fb863fSSimon Glass state_set_skip_delays(true);
71e4fb863fSSimon Glass ut_assertok(usb_init());
72e4fb863fSSimon Glass ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev));
73e4fb863fSSimon Glass ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
74e4fb863fSSimon Glass
75e4fb863fSSimon Glass /* The parent should be a block device */
76e4fb863fSSimon Glass ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev));
77e4fb863fSSimon Glass ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
78e4fb863fSSimon Glass
79e4fb863fSSimon Glass /* Check we have one block device for each mass storage device */
80e48eeb9eSSimon Glass ut_asserteq(6, count_blk_devices());
81e4fb863fSSimon Glass
82e4fb863fSSimon Glass /* Now go around again, making sure the old devices were unbound */
83e4fb863fSSimon Glass ut_assertok(usb_stop());
84e4fb863fSSimon Glass ut_assertok(usb_init());
85e48eeb9eSSimon Glass ut_asserteq(6, count_blk_devices());
86e4fb863fSSimon Glass ut_assertok(usb_stop());
87e4fb863fSSimon Glass
88e4fb863fSSimon Glass return 0;
89e4fb863fSSimon Glass }
90e4fb863fSSimon Glass DM_TEST(dm_test_blk_usb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
916139281aSSimon Glass
926139281aSSimon Glass /* Test that we can find block devices without probing them */
dm_test_blk_find(struct unit_test_state * uts)936139281aSSimon Glass static int dm_test_blk_find(struct unit_test_state *uts)
946139281aSSimon Glass {
956139281aSSimon Glass struct udevice *blk, *dev;
966139281aSSimon Glass
976139281aSSimon Glass ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
985fe7702eSJean-Jacques Hiblot IF_TYPE_HOST, 1, 512, 2, &blk));
996139281aSSimon Glass ut_asserteq(-ENODEV, blk_find_device(IF_TYPE_HOST, 0, &dev));
1006139281aSSimon Glass ut_assertok(blk_find_device(IF_TYPE_HOST, 1, &dev));
1016139281aSSimon Glass ut_asserteq_ptr(blk, dev);
1026139281aSSimon Glass ut_asserteq(false, device_active(dev));
1036139281aSSimon Glass
1046139281aSSimon Glass /* Now activate it */
1056139281aSSimon Glass ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev));
1066139281aSSimon Glass ut_asserteq_ptr(blk, dev);
1076139281aSSimon Glass ut_asserteq(true, device_active(dev));
1086139281aSSimon Glass
1096139281aSSimon Glass return 0;
1106139281aSSimon Glass }
1116139281aSSimon Glass DM_TEST(dm_test_blk_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
112e48eeb9eSSimon Glass
113e48eeb9eSSimon Glass /* Test that block device numbering works as expected */
dm_test_blk_devnum(struct unit_test_state * uts)114e48eeb9eSSimon Glass static int dm_test_blk_devnum(struct unit_test_state *uts)
115e48eeb9eSSimon Glass {
116e48eeb9eSSimon Glass struct udevice *dev, *mmc_dev, *parent;
117e48eeb9eSSimon Glass int i;
118e48eeb9eSSimon Glass
119e48eeb9eSSimon Glass /*
120e48eeb9eSSimon Glass * Probe the devices, with the first one being probed last. This is the
121e48eeb9eSSimon Glass * one with no alias / sequence numnber.
122e48eeb9eSSimon Glass */
123e48eeb9eSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev));
124e48eeb9eSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev));
125e48eeb9eSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
126e48eeb9eSSimon Glass for (i = 0; i < 3; i++) {
127e48eeb9eSSimon Glass struct blk_desc *desc;
128e48eeb9eSSimon Glass
129e48eeb9eSSimon Glass /* Check that the bblock device is attached */
130e48eeb9eSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev));
131e48eeb9eSSimon Glass ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev));
132e48eeb9eSSimon Glass parent = dev_get_parent(dev);
133e48eeb9eSSimon Glass ut_asserteq_ptr(parent, mmc_dev);
134e48eeb9eSSimon Glass ut_asserteq(trailing_strtol(mmc_dev->name), i);
135e48eeb9eSSimon Glass
136e48eeb9eSSimon Glass /*
137e48eeb9eSSimon Glass * Check that the block device devnum matches its parent's
138e48eeb9eSSimon Glass * sequence number
139e48eeb9eSSimon Glass */
140e48eeb9eSSimon Glass desc = dev_get_uclass_platdata(dev);
141e48eeb9eSSimon Glass ut_asserteq(desc->devnum, i);
142e48eeb9eSSimon Glass }
143e48eeb9eSSimon Glass
144e48eeb9eSSimon Glass return 0;
145e48eeb9eSSimon Glass }
146e48eeb9eSSimon Glass DM_TEST(dm_test_blk_devnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
1479f103b9cSSimon Glass
1489f103b9cSSimon Glass /* Test that we can get a block from its parent */
dm_test_blk_get_from_parent(struct unit_test_state * uts)1499f103b9cSSimon Glass static int dm_test_blk_get_from_parent(struct unit_test_state *uts)
1509f103b9cSSimon Glass {
1519f103b9cSSimon Glass struct udevice *dev, *blk;
1529f103b9cSSimon Glass
1539f103b9cSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
1549f103b9cSSimon Glass ut_assertok(blk_get_from_parent(dev, &blk));
1559f103b9cSSimon Glass
1569f103b9cSSimon Glass ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
1579f103b9cSSimon Glass ut_asserteq(-ENOTBLK, blk_get_from_parent(dev, &blk));
1589f103b9cSSimon Glass
1599f103b9cSSimon Glass ut_assertok(uclass_get_device(UCLASS_GPIO, 0, &dev));
1609f103b9cSSimon Glass ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
1619f103b9cSSimon Glass
1629f103b9cSSimon Glass return 0;
1639f103b9cSSimon Glass }
1649f103b9cSSimon Glass DM_TEST(dm_test_blk_get_from_parent, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
165