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