1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// SPDX-License-Identifier: GPL-2.0+
/*
* Handling of common block commands
*
* Copyright (c) 2017 Google, Inc
*
* (C) Copyright 2000-2011
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#include <blk.h>
#include <command.h>
#include <mapmem.h>
#include <vsprintf.h>
int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
int *cur_devnump)
{
const char *if_name = blk_get_uclass_name(uclass_id);
switch (argc) {
case 0:
case 1:
return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1], "inf", 3) == 0) {
blk_list_devices(uclass_id);
return CMD_RET_SUCCESS;
} else if (strncmp(argv[1], "dev", 3) == 0) {
if (blk_print_device_num(uclass_id, *cur_devnump)) {
printf("\nno %s devices available\n", if_name);
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
} else if (strncmp(argv[1], "part", 4) == 0) {
if (blk_list_part(uclass_id))
printf("\nno %s partition table available\n",
if_name);
return CMD_RET_SUCCESS;
}
return CMD_RET_USAGE;
case 3:
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int)dectoul(argv[2], NULL);
if (!blk_show_device(uclass_id, dev)) {
*cur_devnump = dev;
printf("... is now current device\n");
} else {
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
} else if (strncmp(argv[1], "part", 4) == 0) {
int dev = (int)dectoul(argv[2], NULL);
if (blk_print_part_devnum(uclass_id, dev)) {
printf("\n%s device %d not available\n",
if_name, dev);
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
return CMD_RET_USAGE;
default: /* at least 4 args */
if (strcmp(argv[1], "read") == 0) {
phys_addr_t paddr = hextoul(argv[2], NULL);
lbaint_t blk = hextoul(argv[3], NULL);
ulong cnt = hextoul(argv[4], NULL);
struct blk_desc *desc;
void *vaddr;
ulong n;
int ret;
printf("\n%s read: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
ret = blk_get_desc(uclass_id, *cur_devnump, &desc);
if (ret)
return CMD_RET_FAILURE;
vaddr = map_sysmem(paddr, desc->blksz * cnt);
n = blk_dread(desc, blk, cnt, vaddr);
unmap_sysmem(vaddr);
printf("%ld blocks read: %s\n", n,
n == cnt ? "OK" : "ERROR");
return n == cnt ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
} else if (strcmp(argv[1], "write") == 0) {
phys_addr_t paddr = hextoul(argv[2], NULL);
lbaint_t blk = hextoul(argv[3], NULL);
ulong cnt = hextoul(argv[4], NULL);
struct blk_desc *desc;
void *vaddr;
ulong n;
int ret;
printf("\n%s write: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
ret = blk_get_desc(uclass_id, *cur_devnump, &desc);
if (ret)
return CMD_RET_FAILURE;
vaddr = map_sysmem(paddr, desc->blksz * cnt);
n = blk_dwrite(desc, blk, cnt, vaddr);
unmap_sysmem(vaddr);
printf("%ld blocks written: %s\n", n,
n == cnt ? "OK" : "ERROR");
return n == cnt ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
} else if (strcmp(argv[1], "erase") == 0) {
lbaint_t blk = hextoul(argv[2], NULL);
ulong cnt = hextoul(argv[3], NULL);
struct blk_desc *desc;
ulong n;
printf("\n%s erase: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
if (blk_get_desc(uclass_id, *cur_devnump, &desc))
return CMD_RET_FAILURE;
n = blk_derase(desc, blk, cnt);
printf("%ld blocks erased: %s\n", n,
n == cnt ? "OK" : "ERROR");
return n == cnt ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
} else {
return CMD_RET_USAGE;
}
}
}
|