host.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2012, Google Inc.
  4. */
  5. #include <common.h>
  6. #include <command.h>
  7. #include <dm.h>
  8. #include <fs.h>
  9. #include <part.h>
  10. #include <sandbox_host.h>
  11. #include <dm/device_compat.h>
  12. #include <dm/device-internal.h>
  13. #include <dm/uclass-internal.h>
  14. #include <linux/errno.h>
  15. static int do_host_load(struct cmd_tbl *cmdtp, int flag, int argc,
  16. char *const argv[])
  17. {
  18. return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
  19. }
  20. static int do_host_ls(struct cmd_tbl *cmdtp, int flag, int argc,
  21. char *const argv[])
  22. {
  23. return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
  24. }
  25. static int do_host_size(struct cmd_tbl *cmdtp, int flag, int argc,
  26. char *const argv[])
  27. {
  28. return do_size(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
  29. }
  30. static int do_host_save(struct cmd_tbl *cmdtp, int flag, int argc,
  31. char *const argv[])
  32. {
  33. return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
  34. }
  35. static int do_host_bind(struct cmd_tbl *cmdtp, int flag, int argc,
  36. char *const argv[])
  37. {
  38. bool removable = false;
  39. struct udevice *dev;
  40. const char *label;
  41. char *file;
  42. int ret;
  43. /* Skip 'bind' */
  44. argc--;
  45. argv++;
  46. if (argc < 2)
  47. return CMD_RET_USAGE;
  48. if (!strcmp(argv[0], "-r")) {
  49. removable = true;
  50. argc--;
  51. argv++;
  52. }
  53. if (argc > 2)
  54. return CMD_RET_USAGE;
  55. label = argv[0];
  56. file = argc > 1 ? argv[1] : NULL;
  57. ret = host_create_attach_file(label, file, removable, &dev);
  58. if (ret) {
  59. printf("Cannot create device / bind file\n");
  60. return CMD_RET_FAILURE;
  61. }
  62. return 0;
  63. }
  64. /**
  65. * parse_host_label() - Parse a device label or sequence number
  66. *
  67. * This shows an error if it returns NULL
  68. *
  69. * @label: String containing the label or sequence number
  70. * Returns: Associated device, or NULL if not found
  71. */
  72. static struct udevice *parse_host_label(const char *label)
  73. {
  74. struct udevice *dev;
  75. dev = host_find_by_label(label);
  76. if (!dev) {
  77. int devnum;
  78. char *ep;
  79. devnum = hextoul(label, &ep);
  80. if (*ep ||
  81. uclass_find_device_by_seq(UCLASS_HOST, devnum, &dev)) {
  82. printf("No such device '%s'\n", label);
  83. return NULL;
  84. }
  85. }
  86. return dev;
  87. }
  88. static int do_host_unbind(struct cmd_tbl *cmdtp, int flag, int argc,
  89. char *const argv[])
  90. {
  91. struct udevice *dev;
  92. const char *label;
  93. int ret;
  94. if (argc < 2)
  95. return CMD_RET_USAGE;
  96. label = argv[1];
  97. dev = parse_host_label(label);
  98. if (!dev)
  99. return CMD_RET_FAILURE;
  100. ret = host_detach_file(dev);
  101. if (ret) {
  102. printf("Cannot detach file (err=%d)\n", ret);
  103. return CMD_RET_FAILURE;
  104. }
  105. ret = device_unbind(dev);
  106. if (ret) {
  107. printf("Cannot attach file\n");
  108. ret = device_unbind(dev);
  109. if (ret)
  110. printf("Cannot unbind device '%s'\n", dev->name);
  111. return CMD_RET_FAILURE;
  112. }
  113. return 0;
  114. }
  115. static void show_host_dev(struct udevice *dev)
  116. {
  117. struct host_sb_plat *plat = dev_get_plat(dev);
  118. struct blk_desc *desc;
  119. struct udevice *blk;
  120. int ret;
  121. printf("%3d ", dev_seq(dev));
  122. if (!plat->fd) {
  123. printf("Not bound to a backing file\n");
  124. return;
  125. }
  126. ret = blk_get_from_parent(dev, &blk);
  127. if (ret) /* cannot happen */
  128. return;
  129. desc = dev_get_uclass_plat(blk);
  130. printf("%12lu %-15s %s\n", (unsigned long)desc->lba, plat->label,
  131. plat->filename);
  132. }
  133. static int do_host_info(struct cmd_tbl *cmdtp, int flag, int argc,
  134. char *const argv[])
  135. {
  136. struct udevice *dev;
  137. if (argc < 1)
  138. return CMD_RET_USAGE;
  139. dev = NULL;
  140. if (argc >= 2) {
  141. dev = parse_host_label(argv[1]);
  142. if (!dev)
  143. return CMD_RET_FAILURE;
  144. }
  145. printf("%3s %12s %-15s %s\n", "dev", "blocks", "label", "path");
  146. if (dev) {
  147. show_host_dev(dev);
  148. } else {
  149. struct uclass *uc;
  150. uclass_id_foreach_dev(UCLASS_HOST, dev, uc)
  151. show_host_dev(dev);
  152. }
  153. return 0;
  154. }
  155. static int do_host_dev(struct cmd_tbl *cmdtp, int flag, int argc,
  156. char *const argv[])
  157. {
  158. struct udevice *dev;
  159. const char *label;
  160. if (argc < 1 || argc > 3)
  161. return CMD_RET_USAGE;
  162. if (argc == 1) {
  163. struct host_sb_plat *plat;
  164. dev = host_get_cur_dev();
  165. if (!dev) {
  166. printf("No current host device\n");
  167. return CMD_RET_FAILURE;
  168. }
  169. plat = dev_get_plat(dev);
  170. printf("Current host device: %d: %s\n", dev_seq(dev),
  171. plat->label);
  172. return 0;
  173. }
  174. label = argv[1];
  175. dev = parse_host_label(argv[1]);
  176. if (!dev)
  177. return CMD_RET_FAILURE;
  178. host_set_cur_dev(dev);
  179. return 0;
  180. }
  181. static struct cmd_tbl cmd_host_sub[] = {
  182. U_BOOT_CMD_MKENT(load, 7, 0, do_host_load, "", ""),
  183. U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
  184. U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
  185. U_BOOT_CMD_MKENT(size, 3, 0, do_host_size, "", ""),
  186. U_BOOT_CMD_MKENT(bind, 4, 0, do_host_bind, "", ""),
  187. U_BOOT_CMD_MKENT(unbind, 4, 0, do_host_unbind, "", ""),
  188. U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
  189. U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
  190. };
  191. static int do_host(struct cmd_tbl *cmdtp, int flag, int argc,
  192. char *const argv[])
  193. {
  194. struct cmd_tbl *c;
  195. /* Skip past 'host' */
  196. argc--;
  197. argv++;
  198. c = find_cmd_tbl(argv[0], cmd_host_sub, ARRAY_SIZE(cmd_host_sub));
  199. if (c)
  200. return c->cmd(cmdtp, flag, argc, argv);
  201. else
  202. return CMD_RET_USAGE;
  203. }
  204. U_BOOT_CMD(
  205. host, 8, 1, do_host,
  206. "Miscellaneous host commands",
  207. "load hostfs - <addr> <filename> [<bytes> <offset>] - "
  208. "load a file from host\n"
  209. "host ls hostfs - <filename> - list files on host\n"
  210. "host save hostfs - <addr> <filename> <bytes> [<offset>] - "
  211. "save a file to host\n"
  212. "host size hostfs - <filename> - determine size of file on host\n"
  213. "host bind [-r] <label> [<filename>] - bind \"host\" device to file\n"
  214. " -r = mark as removable\n"
  215. "host unbind <label> - unbind file from \"host\" device\n"
  216. "host info [<label>] - show device binding & info\n"
  217. "host dev [<label>] - set or retrieve the current host device\n"
  218. "host commands use the \"hostfs\" device. The \"host\" device is used\n"
  219. "with standard IO commands such as fatls or ext2load"
  220. );