1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2020 John Chau <john@harmon.hk>
14 #define BUFSIZE (1 * 1024 * 1024)
15 static int do_clone(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
18 struct blk_desc *srcdesc, *destdesc;
19 int srcbz, destbz, ret;
21 unsigned long wrcnt, rdcnt, requested, srcblk, destblk;
23 const unsigned long buffersize = 1024 * 1024;
28 srcdev = blk_get_device_by_str(argv[1], argv[2], &srcdesc);
29 destdev = blk_get_device_by_str(argv[3], argv[4], &destdesc);
31 printf("Unable to open source device\n");
33 } else if (destdev < 0) {
34 printf("Unable to open destination device\n");
37 requested = simple_strtoul(argv[5], &unit, 10);
38 srcbz = srcdesc->blksz;
39 destbz = destdesc->blksz;
41 if ((srcbz * (buffersize / srcbz) != buffersize) ||
42 (destbz * (buffersize / destbz) != buffersize)) {
43 printf("failed: cannot match device block sizes\n");
47 unsigned long a = srcdesc->lba * srcdesc->blksz;
48 unsigned long b = destdesc->lba * destdesc->blksz;
58 requested *= 1024 * 1024 * 1024;
62 requested *= 1024 * 1024;
70 printf("Copying %ld bytes from %s:%s to %s:%s\n",
71 requested, argv[1], argv[2], argv[3], argv[4]);
74 buf = (char *)malloc(BUFSIZE);
78 while (wrcnt < requested) {
79 unsigned long toread = BUFSIZE / srcbz;
80 unsigned long towrite = BUFSIZE / destbz;
81 unsigned long offset = 0;
84 ret = blk_dread(srcdesc, srcblk, toread, buf + offset);
86 printf("Src read error @blk %ld\n", srcblk);
93 offset += ret * srcbz;
98 ret = blk_dwrite(destdesc, destblk, towrite, buf + offset);
100 printf("Dest write error @blk %ld\n", srcblk);
103 wrcnt += ret * destbz;
107 offset += ret * destbz;
113 timer = get_timer(timer);
114 timer = 1000 * timer / CONFIG_SYS_HZ;
115 printf("%ld read\n", rdcnt);
116 printf("%ld written\n", wrcnt);
117 printf("%ldms, %ldkB/s\n", timer, wrcnt / timer);
124 clone, 6, 1, do_clone,
125 "simple storage cloning",
126 "<src interface> <src dev> <dest interface> <dest dev> <size[K/M/G]>\n"
127 "clone storage from 'src dev' on 'src interface' to 'dest dev' on 'dest interface' with maximum 'size' bytes (or 0 for clone to end)"