1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <virtio_types.h> 9 #include <virtio.h> 10 #include <virtio_ring.h> 11 #include <dm/device-internal.h> 12 #include <dm/uclass-internal.h> 13 #include <dm/root.h> 14 #include <dm/test.h> 15 #include <test/ut.h> 16 17 /* Basic test of the virtio uclass */ 18 static int dm_test_virtio_base(struct unit_test_state *uts) 19 { 20 struct udevice *bus, *dev; 21 u8 status; 22 23 /* check probe success */ 24 ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus)); 25 26 /* check the child virtio-blk device is bound */ 27 ut_assertok(device_find_first_child(bus, &dev)); 28 ut_assertok(strcmp(dev->name, "virtio-blk#0")); 29 30 /* check driver status */ 31 ut_assertok(virtio_get_status(dev, &status)); 32 ut_asserteq(VIRTIO_CONFIG_S_ACKNOWLEDGE, status); 33 34 return 0; 35 } 36 DM_TEST(dm_test_virtio_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 37 38 /* Test all of the virtio uclass ops */ 39 static int dm_test_virtio_all_ops(struct unit_test_state *uts) 40 { 41 struct udevice *bus, *dev; 42 struct virtio_dev_priv *uc_priv; 43 uint offset = 0, len = 0, nvqs = 1; 44 void *buffer = NULL; 45 u8 status; 46 u32 counter; 47 u64 features; 48 struct virtqueue *vqs[2]; 49 50 /* check probe success */ 51 ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus)); 52 53 /* check the child virtio-blk device is bound */ 54 ut_assertok(device_find_first_child(bus, &dev)); 55 56 /* 57 * fake the virtio device probe by filling in uc_priv->vdev 58 * which is used by virtio_find_vqs/virtio_del_vqs. 59 */ 60 uc_priv = dev_get_uclass_priv(bus); 61 uc_priv->vdev = dev; 62 63 /* test virtio_xxx APIs */ 64 ut_assertok(virtio_get_config(dev, offset, buffer, len)); 65 ut_assertok(virtio_set_config(dev, offset, buffer, len)); 66 ut_asserteq(-ENOSYS, virtio_generation(dev, &counter)); 67 ut_assertok(virtio_set_status(dev, VIRTIO_CONFIG_S_DRIVER_OK)); 68 ut_assertok(virtio_get_status(dev, &status)); 69 ut_asserteq(VIRTIO_CONFIG_S_DRIVER_OK, status); 70 ut_assertok(virtio_reset(dev)); 71 ut_assertok(virtio_get_status(dev, &status)); 72 ut_asserteq(0, status); 73 ut_assertok(virtio_get_features(dev, &features)); 74 ut_asserteq(VIRTIO_F_VERSION_1, features); 75 ut_assertok(virtio_set_features(dev)); 76 ut_assertok(virtio_find_vqs(dev, nvqs, vqs)); 77 ut_assertok(virtio_del_vqs(dev)); 78 ut_assertok(virtio_notify(dev, vqs[0])); 79 80 return 0; 81 } 82 DM_TEST(dm_test_virtio_all_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 83 84 /* Test of the virtio driver that does not have required driver ops */ 85 static int dm_test_virtio_missing_ops(struct unit_test_state *uts) 86 { 87 struct udevice *bus; 88 89 /* find the virtio device */ 90 ut_assertok(uclass_find_device(UCLASS_VIRTIO, 1, &bus)); 91 92 /* 93 * Probe the device should fail with error -ENOENT. 94 * See ops check in virtio_uclass_pre_probe(). 95 */ 96 ut_asserteq(-ENOENT, device_probe(bus)); 97 98 return 0; 99 } 100 DM_TEST(dm_test_virtio_missing_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 101 102 /* Test removal of virtio device driver */ 103 static int dm_test_virtio_remove(struct unit_test_state *uts) 104 { 105 struct udevice *bus, *dev; 106 107 /* check probe success */ 108 ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus)); 109 110 /* check the child virtio-blk device is bound */ 111 ut_assertok(device_find_first_child(bus, &dev)); 112 113 /* set driver status to VIRTIO_CONFIG_S_DRIVER_OK */ 114 ut_assertok(virtio_set_status(dev, VIRTIO_CONFIG_S_DRIVER_OK)); 115 116 /* check the device can be successfully removed */ 117 dev->flags |= DM_FLAG_ACTIVATED; 118 ut_assertok(device_remove(bus, DM_REMOVE_ACTIVE_ALL)); 119 120 return 0; 121 } 122 DM_TEST(dm_test_virtio_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); 123