xref: /rk3399_rockchip-uboot/test/dm/blk.c (revision e48eeb9ea3aed67e4bda94c65a7f13e8672a3501)
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 */
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 
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 */
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 */
86*e48eeb9eSSimon 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());
91*e48eeb9eSSimon 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 */
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);
118*e48eeb9eSSimon Glass 
119*e48eeb9eSSimon Glass /* Test that block device numbering works as expected */
120*e48eeb9eSSimon Glass static int dm_test_blk_devnum(struct unit_test_state *uts)
121*e48eeb9eSSimon Glass {
122*e48eeb9eSSimon Glass 	struct udevice *dev, *mmc_dev, *parent;
123*e48eeb9eSSimon Glass 	int i;
124*e48eeb9eSSimon Glass 
125*e48eeb9eSSimon Glass 	/*
126*e48eeb9eSSimon Glass 	 * Probe the devices, with the first one being probed last. This is the
127*e48eeb9eSSimon Glass 	 * one with no alias / sequence numnber.
128*e48eeb9eSSimon Glass 	 */
129*e48eeb9eSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev));
130*e48eeb9eSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev));
131*e48eeb9eSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
132*e48eeb9eSSimon Glass 	for (i = 0; i < 3; i++) {
133*e48eeb9eSSimon Glass 		struct blk_desc *desc;
134*e48eeb9eSSimon Glass 
135*e48eeb9eSSimon Glass 		/* Check that the bblock device is attached */
136*e48eeb9eSSimon Glass 		ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev));
137*e48eeb9eSSimon Glass 		ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev));
138*e48eeb9eSSimon Glass 		parent = dev_get_parent(dev);
139*e48eeb9eSSimon Glass 		ut_asserteq_ptr(parent, mmc_dev);
140*e48eeb9eSSimon Glass 		ut_asserteq(trailing_strtol(mmc_dev->name), i);
141*e48eeb9eSSimon Glass 
142*e48eeb9eSSimon Glass 		/*
143*e48eeb9eSSimon Glass 		 * Check that the block device devnum matches its parent's
144*e48eeb9eSSimon Glass 		 * sequence number
145*e48eeb9eSSimon Glass 		 */
146*e48eeb9eSSimon Glass 		desc = dev_get_uclass_platdata(dev);
147*e48eeb9eSSimon Glass 		ut_asserteq(desc->devnum, i);
148*e48eeb9eSSimon Glass 	}
149*e48eeb9eSSimon Glass 
150*e48eeb9eSSimon Glass 	return 0;
151*e48eeb9eSSimon Glass }
152*e48eeb9eSSimon Glass DM_TEST(dm_test_blk_devnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
153