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