1e4fb863fSSimon Glass /*
2e4fb863fSSimon Glass * Copyright (C) 2015 Google, Inc
3e4fb863fSSimon Glass *
4e4fb863fSSimon Glass * SPDX-License-Identifier: GPL-2.0+
5e4fb863fSSimon Glass */
6e4fb863fSSimon Glass
7e4fb863fSSimon Glass #include <common.h>
8e4fb863fSSimon Glass #include <dm.h>
9e4fb863fSSimon Glass #include <usb.h>
10e4fb863fSSimon Glass #include <asm/state.h>
11e4fb863fSSimon Glass #include <dm/test.h>
12e4fb863fSSimon Glass #include <test/ut.h>
13e4fb863fSSimon Glass
14e4fb863fSSimon Glass DECLARE_GLOBAL_DATA_PTR;
15e4fb863fSSimon Glass
16e4fb863fSSimon Glass /* Test that block devices can be created */
dm_test_blk_base(struct unit_test_state * uts)17e4fb863fSSimon Glass static int dm_test_blk_base(struct unit_test_state *uts)
18e4fb863fSSimon Glass {
19e4fb863fSSimon Glass struct udevice *blk, *usb_blk, *dev;
20e4fb863fSSimon Glass
21e4fb863fSSimon Glass /* Make sure there are no block devices */
22e4fb863fSSimon Glass ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_BLK, 0, &blk));
23e4fb863fSSimon Glass
24e4fb863fSSimon Glass /* Create two, one the parent of the other */
25e4fb863fSSimon Glass ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
26e4fb863fSSimon Glass IF_TYPE_HOST, 1, 512, 1024, &blk));
27e4fb863fSSimon Glass ut_assertok(blk_create_device(blk, "usb_storage_blk", "test",
28e4fb863fSSimon Glass IF_TYPE_USB, 3, 512, 1024, &usb_blk));
29e4fb863fSSimon Glass
30e4fb863fSSimon Glass /* Check we can find them */
31e4fb863fSSimon Glass ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev));
32e4fb863fSSimon Glass ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev));
33e4fb863fSSimon Glass ut_asserteq_ptr(blk, dev);
34e4fb863fSSimon Glass
35e4fb863fSSimon Glass ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_USB, 0, &dev));
36e4fb863fSSimon Glass ut_assertok(blk_get_device(IF_TYPE_USB, 3, &dev));
37e4fb863fSSimon Glass ut_asserteq_ptr(usb_blk, dev);
38e4fb863fSSimon Glass
39e4fb863fSSimon Glass /* Check we can iterate */
40e4fb863fSSimon Glass ut_assertok(blk_first_device(IF_TYPE_HOST, &dev));
41e4fb863fSSimon Glass ut_asserteq_ptr(blk, dev);
42e4fb863fSSimon Glass ut_asserteq(-ENODEV, blk_next_device(&dev));
43e4fb863fSSimon Glass
44e4fb863fSSimon Glass ut_assertok(blk_first_device(IF_TYPE_USB, &dev));
45e4fb863fSSimon Glass ut_asserteq_ptr(usb_blk, dev);
46e4fb863fSSimon Glass ut_asserteq(-ENODEV, blk_next_device(&dev));
47e4fb863fSSimon Glass
48e4fb863fSSimon Glass return 0;
49e4fb863fSSimon Glass }
50e4fb863fSSimon Glass DM_TEST(dm_test_blk_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
51e4fb863fSSimon Glass
count_blk_devices(void)52e4fb863fSSimon Glass static int count_blk_devices(void)
53e4fb863fSSimon Glass {
54e4fb863fSSimon Glass struct udevice *blk;
55e4fb863fSSimon Glass struct uclass *uc;
56e4fb863fSSimon Glass int count = 0;
57e4fb863fSSimon Glass int ret;
58e4fb863fSSimon Glass
59e4fb863fSSimon Glass ret = uclass_get(UCLASS_BLK, &uc);
60e4fb863fSSimon Glass if (ret)
61e4fb863fSSimon Glass return ret;
62e4fb863fSSimon Glass
63e4fb863fSSimon Glass uclass_foreach_dev(blk, uc)
64e4fb863fSSimon Glass count++;
65e4fb863fSSimon Glass
66e4fb863fSSimon Glass return count;
67e4fb863fSSimon Glass }
68e4fb863fSSimon Glass
69e4fb863fSSimon Glass /* Test that block devices work correctly with USB */
dm_test_blk_usb(struct unit_test_state * uts)70e4fb863fSSimon Glass static int dm_test_blk_usb(struct unit_test_state *uts)
71e4fb863fSSimon Glass {
72e4fb863fSSimon Glass struct udevice *usb_dev, *dev;
73e4fb863fSSimon Glass struct blk_desc *dev_desc;
74e4fb863fSSimon Glass
75e4fb863fSSimon Glass /* Get a flash device */
76e4fb863fSSimon Glass state_set_skip_delays(true);
77e4fb863fSSimon Glass ut_assertok(usb_init());
78e4fb863fSSimon Glass ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev));
79e4fb863fSSimon Glass ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
80e4fb863fSSimon Glass
81e4fb863fSSimon Glass /* The parent should be a block device */
82e4fb863fSSimon Glass ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev));
83e4fb863fSSimon Glass ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
84e4fb863fSSimon Glass
85e4fb863fSSimon Glass /* Check we have one block device for each mass storage device */
86e48eeb9eSSimon Glass ut_asserteq(6, count_blk_devices());
87e4fb863fSSimon Glass
88e4fb863fSSimon Glass /* Now go around again, making sure the old devices were unbound */
89e4fb863fSSimon Glass ut_assertok(usb_stop());
90e4fb863fSSimon Glass ut_assertok(usb_init());
91e48eeb9eSSimon Glass ut_asserteq(6, count_blk_devices());
92e4fb863fSSimon Glass ut_assertok(usb_stop());
93e4fb863fSSimon Glass
94e4fb863fSSimon Glass return 0;
95e4fb863fSSimon Glass }
96e4fb863fSSimon Glass DM_TEST(dm_test_blk_usb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
976139281aSSimon Glass
986139281aSSimon Glass /* Test that we can find block devices without probing them */
dm_test_blk_find(struct unit_test_state * uts)996139281aSSimon Glass static int dm_test_blk_find(struct unit_test_state *uts)
1006139281aSSimon Glass {
1016139281aSSimon Glass struct udevice *blk, *dev;
1026139281aSSimon Glass
1036139281aSSimon Glass ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test",
1046139281aSSimon Glass IF_TYPE_HOST, 1, 512, 1024, &blk));
1056139281aSSimon Glass ut_asserteq(-ENODEV, blk_find_device(IF_TYPE_HOST, 0, &dev));
1066139281aSSimon Glass ut_assertok(blk_find_device(IF_TYPE_HOST, 1, &dev));
1076139281aSSimon Glass ut_asserteq_ptr(blk, dev);
1086139281aSSimon Glass ut_asserteq(false, device_active(dev));
1096139281aSSimon Glass
1106139281aSSimon Glass /* Now activate it */
1116139281aSSimon Glass ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev));
1126139281aSSimon Glass ut_asserteq_ptr(blk, dev);
1136139281aSSimon Glass ut_asserteq(true, device_active(dev));
1146139281aSSimon Glass
1156139281aSSimon Glass return 0;
1166139281aSSimon Glass }
1176139281aSSimon Glass DM_TEST(dm_test_blk_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
118e48eeb9eSSimon Glass
119e48eeb9eSSimon Glass /* Test that block device numbering works as expected */
dm_test_blk_devnum(struct unit_test_state * uts)120e48eeb9eSSimon Glass static int dm_test_blk_devnum(struct unit_test_state *uts)
121e48eeb9eSSimon Glass {
122e48eeb9eSSimon Glass struct udevice *dev, *mmc_dev, *parent;
123e48eeb9eSSimon Glass int i;
124e48eeb9eSSimon Glass
125e48eeb9eSSimon Glass /*
126e48eeb9eSSimon Glass * Probe the devices, with the first one being probed last. This is the
127e48eeb9eSSimon Glass * one with no alias / sequence numnber.
128e48eeb9eSSimon Glass */
129e48eeb9eSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev));
130e48eeb9eSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev));
131e48eeb9eSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
132e48eeb9eSSimon Glass for (i = 0; i < 3; i++) {
133e48eeb9eSSimon Glass struct blk_desc *desc;
134e48eeb9eSSimon Glass
135e48eeb9eSSimon Glass /* Check that the bblock device is attached */
136e48eeb9eSSimon Glass ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev));
137e48eeb9eSSimon Glass ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev));
138e48eeb9eSSimon Glass parent = dev_get_parent(dev);
139e48eeb9eSSimon Glass ut_asserteq_ptr(parent, mmc_dev);
140e48eeb9eSSimon Glass ut_asserteq(trailing_strtol(mmc_dev->name), i);
141e48eeb9eSSimon Glass
142e48eeb9eSSimon Glass /*
143e48eeb9eSSimon Glass * Check that the block device devnum matches its parent's
144e48eeb9eSSimon Glass * sequence number
145e48eeb9eSSimon Glass */
146e48eeb9eSSimon Glass desc = dev_get_uclass_platdata(dev);
147e48eeb9eSSimon Glass ut_asserteq(desc->devnum, i);
148e48eeb9eSSimon Glass }
149e48eeb9eSSimon Glass
150e48eeb9eSSimon Glass return 0;
151e48eeb9eSSimon Glass }
152e48eeb9eSSimon Glass DM_TEST(dm_test_blk_devnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
153*9f103b9cSSimon Glass
154*9f103b9cSSimon Glass /* Test that we can get a block from its parent */
dm_test_blk_get_from_parent(struct unit_test_state * uts)155*9f103b9cSSimon Glass static int dm_test_blk_get_from_parent(struct unit_test_state *uts)
156*9f103b9cSSimon Glass {
157*9f103b9cSSimon Glass struct udevice *dev, *blk;
158*9f103b9cSSimon Glass
159*9f103b9cSSimon Glass ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
160*9f103b9cSSimon Glass ut_assertok(blk_get_from_parent(dev, &blk));
161*9f103b9cSSimon Glass
162*9f103b9cSSimon Glass ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
163*9f103b9cSSimon Glass ut_asserteq(-ENOTBLK, blk_get_from_parent(dev, &blk));
164*9f103b9cSSimon Glass
165*9f103b9cSSimon Glass ut_assertok(uclass_get_device(UCLASS_GPIO, 0, &dev));
166*9f103b9cSSimon Glass ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
167*9f103b9cSSimon Glass
168*9f103b9cSSimon Glass return 0;
169*9f103b9cSSimon Glass }
170*9f103b9cSSimon Glass DM_TEST(dm_test_blk_get_from_parent, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
171