blk.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Google, Inc
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <part.h>
  8. #include <sandbox_host.h>
  9. #include <usb.h>
  10. #include <asm/global_data.h>
  11. #include <asm/state.h>
  12. #include <dm/test.h>
  13. #include <test/test.h>
  14. #include <test/ut.h>
  15. DECLARE_GLOBAL_DATA_PTR;
  16. /* Test that block devices can be created */
  17. static int dm_test_blk_base(struct unit_test_state *uts)
  18. {
  19. struct udevice *blk0, *blk1, *dev0, *dev1, *dev, *chk0, *chk1;
  20. /* Create two, one the parent of the other */
  21. ut_assertok(host_create_device("test0", false, &dev0));
  22. ut_assertok(host_create_device("test1", false, &dev1));
  23. /* Check we can find them */
  24. ut_assertok(blk_get_device(UCLASS_HOST, 0, &blk0));
  25. ut_assertok(blk_get_from_parent(dev0, &chk0));
  26. ut_asserteq_ptr(blk0, chk0);
  27. ut_assertok(blk_get_device(UCLASS_HOST, 1, &blk1));
  28. ut_assertok(blk_get_from_parent(dev1, &chk1));
  29. ut_asserteq_ptr(blk1, chk1);
  30. ut_asserteq(-ENODEV, blk_get_device(UCLASS_HOST, 2, &dev0));
  31. /* Check we can iterate */
  32. ut_assertok(blk_first_device(UCLASS_HOST, &dev));
  33. ut_asserteq_ptr(blk0, dev);
  34. ut_assertok(blk_next_device(&dev));
  35. ut_asserteq_ptr(blk1, dev);
  36. return 0;
  37. }
  38. DM_TEST(dm_test_blk_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  39. static int count_blk_devices(void)
  40. {
  41. struct udevice *blk;
  42. struct uclass *uc;
  43. int count = 0;
  44. int ret;
  45. ret = uclass_get(UCLASS_BLK, &uc);
  46. if (ret)
  47. return ret;
  48. uclass_foreach_dev(blk, uc)
  49. count++;
  50. return count;
  51. }
  52. /* Test that block devices work correctly with USB */
  53. static int dm_test_blk_usb(struct unit_test_state *uts)
  54. {
  55. struct udevice *usb_dev, *dev;
  56. struct blk_desc *dev_desc;
  57. usb_started = false;
  58. /* Get a flash device */
  59. state_set_skip_delays(true);
  60. ut_assertok(usb_stop());
  61. ut_assertok(usb_init());
  62. ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev));
  63. ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
  64. /* The parent should be a block device */
  65. ut_assertok(blk_get_device(UCLASS_USB, 0, &dev));
  66. ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
  67. /* Check we have one block device for each mass storage device */
  68. ut_asserteq(6, count_blk_devices());
  69. /* Now go around again, making sure the old devices were unbound */
  70. ut_assertok(usb_stop());
  71. ut_assertok(usb_init());
  72. ut_asserteq(6, count_blk_devices());
  73. ut_assertok(usb_stop());
  74. return 0;
  75. }
  76. DM_TEST(dm_test_blk_usb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  77. /* Test that we can find block devices without probing them */
  78. static int dm_test_blk_find(struct unit_test_state *uts)
  79. {
  80. struct udevice *blk, *chk, *dev;
  81. ut_assertok(host_create_device("test0", false, &dev));
  82. ut_assertok(blk_find_device(UCLASS_HOST, 0, &chk));
  83. ut_assertok(device_find_first_child_by_uclass(dev, UCLASS_BLK, &blk));
  84. ut_asserteq_ptr(chk, blk);
  85. ut_asserteq(false, device_active(dev));
  86. ut_asserteq(-ENODEV, blk_find_device(UCLASS_HOST, 1, &dev));
  87. /* Now activate it */
  88. ut_assertok(blk_get_device(UCLASS_HOST, 0, &blk));
  89. ut_asserteq_ptr(chk, blk);
  90. ut_asserteq(true, device_active(blk));
  91. return 0;
  92. }
  93. DM_TEST(dm_test_blk_find, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  94. /* Test that block device numbering works as expected */
  95. static int dm_test_blk_devnum(struct unit_test_state *uts)
  96. {
  97. struct udevice *dev, *mmc_dev, *parent;
  98. int i;
  99. /*
  100. * Probe the devices, with the first one being probed last. This is the
  101. * one with no alias / sequence number.
  102. */
  103. ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev));
  104. ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev));
  105. ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
  106. for (i = 0; i < 3; i++) {
  107. struct blk_desc *desc;
  108. /* Check that the bblock device is attached */
  109. ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev));
  110. ut_assertok(blk_find_device(UCLASS_MMC, i, &dev));
  111. parent = dev_get_parent(dev);
  112. ut_asserteq_ptr(parent, mmc_dev);
  113. ut_asserteq(trailing_strtol(mmc_dev->name), i);
  114. /*
  115. * Check that the block device devnum matches its parent's
  116. * sequence number
  117. */
  118. desc = dev_get_uclass_plat(dev);
  119. ut_asserteq(desc->devnum, i);
  120. }
  121. return 0;
  122. }
  123. DM_TEST(dm_test_blk_devnum, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  124. /* Test that we can get a block from its parent */
  125. static int dm_test_blk_get_from_parent(struct unit_test_state *uts)
  126. {
  127. struct udevice *dev, *blk;
  128. ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
  129. ut_assertok(blk_get_from_parent(dev, &blk));
  130. ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
  131. ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
  132. ut_assertok(uclass_get_device(UCLASS_GPIO, 0, &dev));
  133. ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
  134. return 0;
  135. }
  136. DM_TEST(dm_test_blk_get_from_parent, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  137. /* Test iteration through block devices */
  138. static int dm_test_blk_iter(struct unit_test_state *uts)
  139. {
  140. struct udevice *dev;
  141. int i;
  142. /*
  143. * See sandbox test.dts - it has:
  144. *
  145. * mmc0 - removable
  146. * mmc1 - removable
  147. * mmc2 - fixed
  148. */
  149. ut_assertok(blk_first_device_err(BLKF_FIXED, &dev));
  150. ut_asserteq_str("mmc2.blk", dev->name);
  151. ut_asserteq(-ENODEV, blk_next_device_err(BLKF_FIXED, &dev));
  152. ut_assertok(blk_first_device_err(BLKF_REMOVABLE, &dev));
  153. ut_asserteq_str("mmc1.blk", dev->name);
  154. ut_assertok(blk_next_device_err(BLKF_REMOVABLE, &dev));
  155. ut_asserteq_str("mmc0.blk", dev->name);
  156. ut_asserteq(-ENODEV, blk_next_device_err(BLKF_REMOVABLE, &dev));
  157. ut_assertok(blk_first_device_err(BLKF_BOTH, &dev));
  158. ut_asserteq_str("mmc2.blk", dev->name);
  159. ut_assertok(blk_next_device_err(BLKF_BOTH, &dev));
  160. ut_asserteq_str("mmc1.blk", dev->name);
  161. ut_assertok(blk_next_device_err(BLKF_BOTH, &dev));
  162. ut_asserteq_str("mmc0.blk", dev->name);
  163. ut_asserteq(-ENODEV, blk_next_device_err(BLKF_FIXED, &dev));
  164. ut_asserteq(1, blk_count_devices(BLKF_FIXED));
  165. ut_asserteq(2, blk_count_devices(BLKF_REMOVABLE));
  166. ut_asserteq(3, blk_count_devices(BLKF_BOTH));
  167. i = 0;
  168. blk_foreach_probe(BLKF_FIXED, dev)
  169. ut_asserteq_str((i++, "mmc2.blk"), dev->name);
  170. ut_asserteq(1, i);
  171. i = 0;
  172. blk_foreach_probe(BLKF_REMOVABLE, dev)
  173. ut_asserteq_str(i++ ? "mmc0.blk" : "mmc1.blk", dev->name);
  174. ut_asserteq(2, i);
  175. i = 0;
  176. blk_foreach_probe(BLKF_BOTH, dev)
  177. ut_asserteq_str((++i == 1 ? "mmc2.blk" : i == 2 ?
  178. "mmc1.blk" : "mmc0.blk"), dev->name);
  179. ut_asserteq(3, i);
  180. return 0;
  181. }
  182. DM_TEST(dm_test_blk_iter, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  183. /* Test finding fixed/removable block devices */
  184. static int dm_test_blk_flags(struct unit_test_state *uts)
  185. {
  186. struct udevice *dev;
  187. /* Iterate through devices without probing them */
  188. ut_assertok(blk_find_first(BLKF_BOTH, &dev));
  189. ut_assertnonnull(dev);
  190. ut_asserteq_str("mmc2.blk", dev->name);
  191. ut_assertok(blk_find_next(BLKF_BOTH, &dev));
  192. ut_assertnonnull(dev);
  193. ut_asserteq_str("mmc1.blk", dev->name);
  194. ut_assertok(blk_find_next(BLKF_BOTH, &dev));
  195. ut_assertnonnull(dev);
  196. ut_asserteq_str("mmc0.blk", dev->name);
  197. ut_asserteq(-ENODEV, blk_find_next(BLKF_BOTH, &dev));
  198. ut_assertnull(dev);
  199. /* All devices are removable until probed */
  200. ut_asserteq(-ENODEV, blk_find_first(BLKF_FIXED, &dev));
  201. ut_assertok(blk_find_first(BLKF_REMOVABLE, &dev));
  202. ut_assertnonnull(dev);
  203. ut_asserteq_str("mmc2.blk", dev->name);
  204. /* Now probe them and iterate again */
  205. ut_assertok(blk_first_device_err(BLKF_BOTH, &dev));
  206. ut_assertnonnull(dev);
  207. ut_asserteq_str("mmc2.blk", dev->name);
  208. ut_assertok(blk_next_device_err(BLKF_BOTH, &dev));
  209. ut_assertnonnull(dev);
  210. ut_asserteq_str("mmc1.blk", dev->name);
  211. ut_assertok(blk_next_device_err(BLKF_BOTH, &dev));
  212. ut_assertnonnull(dev);
  213. ut_asserteq_str("mmc0.blk", dev->name);
  214. ut_asserteq(-ENODEV, blk_next_device_err(BLKF_BOTH, &dev));
  215. /* Look only for fixed devices */
  216. ut_assertok(blk_first_device_err(BLKF_FIXED, &dev));
  217. ut_assertnonnull(dev);
  218. ut_asserteq_str("mmc2.blk", dev->name);
  219. ut_asserteq(-ENODEV, blk_next_device_err(BLKF_FIXED, &dev));
  220. /* Look only for removable devices */
  221. ut_assertok(blk_first_device_err(BLKF_REMOVABLE, &dev));
  222. ut_assertnonnull(dev);
  223. ut_asserteq_str("mmc1.blk", dev->name);
  224. ut_assertok(blk_next_device_err(BLKF_REMOVABLE, &dev));
  225. ut_assertnonnull(dev);
  226. ut_asserteq_str("mmc0.blk", dev->name);
  227. ut_asserteq(-ENODEV, blk_next_device_err(BLKF_REMOVABLE, &dev));
  228. return 0;
  229. }
  230. DM_TEST(dm_test_blk_flags, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  231. /* Test blk_foreach() and friend */
  232. static int dm_test_blk_foreach(struct unit_test_state *uts)
  233. {
  234. struct udevice *dev;
  235. int found;
  236. /* Test blk_foreach() - use the 3rd bytes of the name (0/1/2) */
  237. found = 0;
  238. blk_foreach(BLKF_BOTH, dev)
  239. found |= 1 << dectoul(&dev->name[3], NULL);
  240. ut_asserteq(7, found);
  241. /* All devices are removable until probed */
  242. found = 0;
  243. blk_foreach(BLKF_FIXED, dev)
  244. found |= 1 << dectoul(&dev->name[3], NULL);
  245. ut_asserteq(0, found);
  246. found = 0;
  247. blk_foreach(BLKF_REMOVABLE, dev)
  248. found |= 1 << dectoul(&dev->name[3], NULL);
  249. ut_asserteq(7, found);
  250. /* Now try again with the probing functions */
  251. found = 0;
  252. blk_foreach_probe(BLKF_BOTH, dev)
  253. found |= 1 << dectoul(&dev->name[3], NULL);
  254. ut_asserteq(7, found);
  255. ut_asserteq(3, blk_count_devices(BLKF_BOTH));
  256. found = 0;
  257. blk_foreach_probe(BLKF_FIXED, dev)
  258. found |= 1 << dectoul(&dev->name[3], NULL);
  259. ut_asserteq(4, found);
  260. ut_asserteq(1, blk_count_devices(BLKF_FIXED));
  261. found = 0;
  262. blk_foreach_probe(BLKF_REMOVABLE, dev)
  263. found |= 1 << dectoul(&dev->name[3], NULL);
  264. ut_asserteq(3, found);
  265. ut_asserteq(2, blk_count_devices(BLKF_REMOVABLE));
  266. return 0;
  267. }
  268. DM_TEST(dm_test_blk_foreach, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);