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 */ 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 */ 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 */ 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 */ 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