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