Blame view

cmd/usb_mass_storage.c 5.2 KB
b528f7139   Lukasz Majewski   usb:gadget: USB M...
1
2
3
4
  /*
   * Copyright (C) 2011 Samsung Electronics
   * Lukasz Majewski <l.majewski@samsung.com>
   *
02585eb3b   Stephen Warren   ums: support mult...
5
6
   * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
7
   * SPDX-License-Identifier:	GPL-2.0+
b528f7139   Lukasz Majewski   usb:gadget: USB M...
8
   */
351e9b206   Przemyslaw Marczak   usb: ums: add ums...
9
  #include <errno.h>
b528f7139   Lukasz Majewski   usb:gadget: USB M...
10
11
  #include <common.h>
  #include <command.h>
24b852a7a   Simon Glass   Move console defi...
12
  #include <console.h>
b528f7139   Lukasz Majewski   usb:gadget: USB M...
13
  #include <g_dnl.h>
abfe8afe8   Stephen Warren   ums: move IO supp...
14
  #include <part.h>
16297cfb2   Mateusz Zalega   usb: new board-sp...
15
  #include <usb.h>
b528f7139   Lukasz Majewski   usb:gadget: USB M...
16
  #include <usb_mass_storage.h>
abfe8afe8   Stephen Warren   ums: move IO supp...
17
18
19
  static int ums_read_sector(struct ums *ums_dev,
  			   ulong start, lbaint_t blkcnt, void *buf)
  {
4101f6879   Simon Glass   dm: Drop the bloc...
20
  	struct blk_desc *block_dev = &ums_dev->block_dev;
abfe8afe8   Stephen Warren   ums: move IO supp...
21
  	lbaint_t blkstart = start + ums_dev->start_sector;
abfe8afe8   Stephen Warren   ums: move IO supp...
22

c9f3c5f9c   Simon Glass   dm: usb: Use blk_...
23
  	return blk_dread(block_dev, blkstart, blkcnt, buf);
abfe8afe8   Stephen Warren   ums: move IO supp...
24
25
26
27
28
  }
  
  static int ums_write_sector(struct ums *ums_dev,
  			    ulong start, lbaint_t blkcnt, const void *buf)
  {
4101f6879   Simon Glass   dm: Drop the bloc...
29
  	struct blk_desc *block_dev = &ums_dev->block_dev;
abfe8afe8   Stephen Warren   ums: move IO supp...
30
  	lbaint_t blkstart = start + ums_dev->start_sector;
abfe8afe8   Stephen Warren   ums: move IO supp...
31

c9f3c5f9c   Simon Glass   dm: usb: Use blk_...
32
  	return blk_dwrite(block_dev, blkstart, blkcnt, buf);
abfe8afe8   Stephen Warren   ums: move IO supp...
33
  }
02585eb3b   Stephen Warren   ums: support mult...
34
35
36
37
38
39
40
41
42
43
  static struct ums *ums;
  static int ums_count;
  
  static void ums_fini(void)
  {
  	int i;
  
  	for (i = 0; i < ums_count; i++)
  		free((void *)ums[i].name);
  	free(ums);
d419026a0   Fabio Estevam   cmd: usb_mass_sto...
44
  	ums = NULL;
02585eb3b   Stephen Warren   ums: support mult...
45
46
47
48
  	ums_count = 0;
  }
  
  #define UMS_NAME_LEN 16
abfe8afe8   Stephen Warren   ums: move IO supp...
49

a2e3a1d86   John Tobias   usb: ums - expose...
50
  static int ums_init(const char *devtype, const char *devnums_part_str)
abfe8afe8   Stephen Warren   ums: move IO supp...
51
  {
a2e3a1d86   John Tobias   usb: ums - expose...
52
  	char *s, *t, *devnum_part_str, *name;
4101f6879   Simon Glass   dm: Drop the bloc...
53
  	struct blk_desc *block_dev;
a2e3a1d86   John Tobias   usb: ums - expose...
54
55
  	disk_partition_t info;
  	int partnum;
a238b0dac   Tom Rini   cmd/usb_mass_stor...
56
  	int ret = -1;
02585eb3b   Stephen Warren   ums: support mult...
57
  	struct ums *ums_new;
abfe8afe8   Stephen Warren   ums: move IO supp...
58

a2e3a1d86   John Tobias   usb: ums - expose...
59
  	s = strdup(devnums_part_str);
02585eb3b   Stephen Warren   ums: support mult...
60
61
62
63
64
65
66
  	if (!s)
  		return -1;
  
  	t = s;
  	ums_count = 0;
  
  	for (;;) {
a2e3a1d86   John Tobias   usb: ums - expose...
67
68
  		devnum_part_str = strsep(&t, ",");
  		if (!devnum_part_str)
02585eb3b   Stephen Warren   ums: support mult...
69
  			break;
a2e3a1d86   John Tobias   usb: ums - expose...
70
71
72
73
  		partnum = blk_get_device_part_str(devtype, devnum_part_str,
  					&block_dev, &info, 1);
  
  		if (partnum < 0)
02585eb3b   Stephen Warren   ums: support mult...
74
  			goto cleanup;
a2e3a1d86   John Tobias   usb: ums - expose...
75
76
77
78
79
80
  		/* Check if the argument is in legacy format. If yes,
  		 * expose all partitions by setting the partnum = 0
  		 * e.g. ums 0 mmc 0
  		 */
  		if (!strchr(devnum_part_str, ':'))
  			partnum = 0;
02585eb3b   Stephen Warren   ums: support mult...
81
  		/* f_mass_storage.c assumes SECTOR_SIZE sectors */
a238b0dac   Tom Rini   cmd/usb_mass_stor...
82
  		if (block_dev->blksz != SECTOR_SIZE)
02585eb3b   Stephen Warren   ums: support mult...
83
  			goto cleanup;
abfe8afe8   Stephen Warren   ums: move IO supp...
84

02585eb3b   Stephen Warren   ums: support mult...
85
  		ums_new = realloc(ums, (ums_count + 1) * sizeof(*ums));
a238b0dac   Tom Rini   cmd/usb_mass_stor...
86
  		if (!ums_new)
02585eb3b   Stephen Warren   ums: support mult...
87
  			goto cleanup;
02585eb3b   Stephen Warren   ums: support mult...
88
  		ums = ums_new;
a2e3a1d86   John Tobias   usb: ums - expose...
89
90
91
92
93
94
95
96
  		/* if partnum = 0, expose all partitions */
  		if (partnum == 0) {
  			ums[ums_count].start_sector = 0;
  			ums[ums_count].num_sectors = block_dev->lba;
  		} else {
  			ums[ums_count].start_sector = info.start;
  			ums[ums_count].num_sectors = info.size;
  		}
02585eb3b   Stephen Warren   ums: support mult...
97
98
  		ums[ums_count].read_sector = ums_read_sector;
  		ums[ums_count].write_sector = ums_write_sector;
a2e3a1d86   John Tobias   usb: ums - expose...
99

02585eb3b   Stephen Warren   ums: support mult...
100
  		name = malloc(UMS_NAME_LEN);
a238b0dac   Tom Rini   cmd/usb_mass_stor...
101
  		if (!name)
02585eb3b   Stephen Warren   ums: support mult...
102
  			goto cleanup;
02585eb3b   Stephen Warren   ums: support mult...
103
104
105
106
107
108
  		snprintf(name, UMS_NAME_LEN, "UMS disk %d", ums_count);
  		ums[ums_count].name = name;
  		ums[ums_count].block_dev = *block_dev;
  
  		printf("UMS: LUN %d, dev %d, hwpart %d, sector %#x, count %#x
  ",
bcce53d04   Simon Glass   dm: block: Rename...
109
  		       ums_count, ums[ums_count].block_dev.devnum,
02585eb3b   Stephen Warren   ums: support mult...
110
111
112
113
114
115
  		       ums[ums_count].block_dev.hwpart,
  		       ums[ums_count].start_sector,
  		       ums[ums_count].num_sectors);
  
  		ums_count++;
  	}
a238b0dac   Tom Rini   cmd/usb_mass_stor...
116
  	if (ums_count)
02585eb3b   Stephen Warren   ums: support mult...
117
  		ret = 0;
d0cc456dc   Stephen Warren   ums: use get_devi...
118

02585eb3b   Stephen Warren   ums: support mult...
119
120
  cleanup:
  	free(s);
abfe8afe8   Stephen Warren   ums: move IO supp...
121

02585eb3b   Stephen Warren   ums: support mult...
122
123
  	if (ret < 0)
  		ums_fini();
abfe8afe8   Stephen Warren   ums: move IO supp...
124

02585eb3b   Stephen Warren   ums: support mult...
125
  	return ret;
abfe8afe8   Stephen Warren   ums: move IO supp...
126
  }
b9203429a   Fabio Estevam   cmd: usb_mass_sto...
127
  static int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
b528f7139   Lukasz Majewski   usb:gadget: USB M...
128
129
  			       int argc, char * const argv[])
  {
1725f1288   Stephen Warren   ums: move all var...
130
131
132
  	const char *usb_controller;
  	const char *devtype;
  	const char *devnum;
1725f1288   Stephen Warren   ums: move all var...
133
134
135
  	unsigned int controller_index;
  	int rc;
  	int cable_ready_timeout __maybe_unused;
16297cfb2   Mateusz Zalega   usb: new board-sp...
136
137
  	if (argc < 3)
  		return CMD_RET_USAGE;
b528f7139   Lukasz Majewski   usb:gadget: USB M...
138

1725f1288   Stephen Warren   ums: move all var...
139
  	usb_controller = argv[1];
8c6004568   Stephen Warren   ums: allow the us...
140
141
142
143
144
145
146
  	if (argc >= 4) {
  		devtype = argv[2];
  		devnum  = argv[3];
  	} else {
  		devtype = "mmc";
  		devnum  = argv[2];
  	}
f4dacf7b9   Przemyslaw Marczak   usb: ums: allows ...
147

02585eb3b   Stephen Warren   ums: support mult...
148
149
  	rc = ums_init(devtype, devnum);
  	if (rc < 0)
f4dacf7b9   Przemyslaw Marczak   usb: ums: allows ...
150
  		return CMD_RET_FAILURE;
b528f7139   Lukasz Majewski   usb:gadget: USB M...
151

1725f1288   Stephen Warren   ums: move all var...
152
153
  	controller_index = (unsigned int)(simple_strtoul(
  				usb_controller,	NULL, 0));
16297cfb2   Mateusz Zalega   usb: new board-sp...
154
  	if (board_usb_init(controller_index, USB_INIT_DEVICE)) {
9b643e312   Masahiro Yamada   treewide: replace...
155
  		pr_err("Couldn't init USB controller.");
02585eb3b   Stephen Warren   ums: support mult...
156
157
  		rc = CMD_RET_FAILURE;
  		goto cleanup_ums_init;
16297cfb2   Mateusz Zalega   usb: new board-sp...
158
  	}
b528f7139   Lukasz Majewski   usb:gadget: USB M...
159

d903cd890   Ye Li   MLK-20887 usb: ga...
160
  	rc = fsg_init(ums, ums_count, controller_index);
b528f7139   Lukasz Majewski   usb:gadget: USB M...
161
  	if (rc) {
9b643e312   Masahiro Yamada   treewide: replace...
162
  		pr_err("fsg_init failed");
02585eb3b   Stephen Warren   ums: support mult...
163
164
  		rc = CMD_RET_FAILURE;
  		goto cleanup_board;
b528f7139   Lukasz Majewski   usb:gadget: USB M...
165
  	}
66b88b07c   Stephen Warren   usb: ums: add err...
166
167
  	rc = g_dnl_register("usb_dnl_ums");
  	if (rc) {
9b643e312   Masahiro Yamada   treewide: replace...
168
  		pr_err("g_dnl_register failed");
02585eb3b   Stephen Warren   ums: support mult...
169
170
  		rc = CMD_RET_FAILURE;
  		goto cleanup_board;
66b88b07c   Stephen Warren   usb: ums: add err...
171
  	}
b528f7139   Lukasz Majewski   usb:gadget: USB M...
172

3603e31db   Przemyslaw Marczak   usb: ums: wait fo...
173
  	/* Timeout unit: seconds */
1725f1288   Stephen Warren   ums: move all var...
174
  	cable_ready_timeout = UMS_CABLE_READY_TIMEOUT;
3603e31db   Przemyslaw Marczak   usb: ums: wait fo...
175

75504e959   Mateusz Zalega   usb: dfu: fix boa...
176
177
178
179
180
  	if (!g_dnl_board_usb_cable_connected()) {
  		/*
  		 * Won't execute if we don't know whether the cable is
  		 * connected.
  		 */
3603e31db   Przemyslaw Marczak   usb: ums: wait fo...
181
182
  		puts("Please connect USB cable.
  ");
75504e959   Mateusz Zalega   usb: dfu: fix boa...
183
  		while (!g_dnl_board_usb_cable_connected()) {
3603e31db   Przemyslaw Marczak   usb: ums: wait fo...
184
185
186
  			if (ctrlc()) {
  				puts("\rCTRL+C - Operation aborted.
  ");
02585eb3b   Stephen Warren   ums: support mult...
187
188
  				rc = CMD_RET_SUCCESS;
  				goto cleanup_register;
3603e31db   Przemyslaw Marczak   usb: ums: wait fo...
189
190
191
192
193
194
  			}
  			if (!cable_ready_timeout) {
  				puts("\rUSB cable not detected.
  " \
  				     "Command exit.
  ");
02585eb3b   Stephen Warren   ums: support mult...
195
196
  				rc = CMD_RET_SUCCESS;
  				goto cleanup_register;
3603e31db   Przemyslaw Marczak   usb: ums: wait fo...
197
198
199
200
201
202
203
204
205
  			}
  
  			printf("\rAuto exit in: %.2d s.", cable_ready_timeout);
  			mdelay(1000);
  			cable_ready_timeout--;
  		}
  		puts("\r
  ");
  	}
b528f7139   Lukasz Majewski   usb:gadget: USB M...
206
  	while (1) {
2d48aa69b   Kishon Vijay Abraham I   usb: modify usb_g...
207
  		usb_gadget_handle_interrupts(controller_index);
351e9b206   Przemyslaw Marczak   usb: ums: add ums...
208
209
210
211
212
213
214
215
216
217
218
219
  
  		rc = fsg_main_thread(NULL);
  		if (rc) {
  			/* Check I/O error */
  			if (rc == -EIO)
  				printf("\rCheck USB cable connection
  ");
  
  			/* Check CTRL+C */
  			if (rc == -EPIPE)
  				printf("\rCTRL+C - Operation aborted
  ");
02585eb3b   Stephen Warren   ums: support mult...
220
221
  			rc = CMD_RET_SUCCESS;
  			goto cleanup_register;
351e9b206   Przemyslaw Marczak   usb: ums: add ums...
222
  		}
b528f7139   Lukasz Majewski   usb:gadget: USB M...
223
  	}
02585eb3b   Stephen Warren   ums: support mult...
224
225
  
  cleanup_register:
b528f7139   Lukasz Majewski   usb:gadget: USB M...
226
  	g_dnl_unregister();
02585eb3b   Stephen Warren   ums: support mult...
227
  cleanup_board:
375f2d785   Inha Song   usb: gadget: UMS:...
228
  	board_usb_cleanup(controller_index, USB_INIT_DEVICE);
02585eb3b   Stephen Warren   ums: support mult...
229
230
231
232
  cleanup_ums_init:
  	ums_fini();
  
  	return rc;
b528f7139   Lukasz Majewski   usb:gadget: USB M...
233
  }
8c6004568   Stephen Warren   ums: allow the us...
234
  U_BOOT_CMD(ums, 4, 1, do_usb_mass_storage,
ee02a65e9   Fabio Estevam   cmd_usb_mass_stor...
235
  	"Use the UMS [USB Mass Storage]",
a2e3a1d86   John Tobias   usb: ums - expose...
236
237
  	"<USB_controller> [<devtype>] <dev[:part]>  e.g. ums 0 mmc 0
  "
8c6004568   Stephen Warren   ums: allow the us...
238
  	"    devtype defaults to mmc"
b528f7139   Lukasz Majewski   usb:gadget: USB M...
239
  );