]> git.sur5r.net Git - u-boot/blob - common/cmd_usb_mass_storage.c
block: pass block dev not num to read/write/erase()
[u-boot] / common / cmd_usb_mass_storage.c
1 /*
2  * Copyright (C) 2011 Samsung Electronics
3  * Lukasz Majewski <l.majewski@samsung.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <errno.h>
9 #include <common.h>
10 #include <command.h>
11 #include <console.h>
12 #include <g_dnl.h>
13 #include <part.h>
14 #include <usb.h>
15 #include <usb_mass_storage.h>
16
17 static int ums_read_sector(struct ums *ums_dev,
18                            ulong start, lbaint_t blkcnt, void *buf)
19 {
20         block_dev_desc_t *block_dev = ums_dev->block_dev;
21         lbaint_t blkstart = start + ums_dev->start_sector;
22
23         return block_dev->block_read(block_dev, blkstart, blkcnt, buf);
24 }
25
26 static int ums_write_sector(struct ums *ums_dev,
27                             ulong start, lbaint_t blkcnt, const void *buf)
28 {
29         block_dev_desc_t *block_dev = ums_dev->block_dev;
30         lbaint_t blkstart = start + ums_dev->start_sector;
31
32         return block_dev->block_write(block_dev, blkstart, blkcnt, buf);
33 }
34
35 static struct ums ums_dev = {
36         .read_sector = ums_read_sector,
37         .write_sector = ums_write_sector,
38         .name = "UMS disk",
39 };
40
41 struct ums *ums_init(const char *devtype, const char *devnum)
42 {
43         block_dev_desc_t *block_dev;
44         int ret;
45
46         ret = get_device(devtype, devnum, &block_dev);
47         if (ret < 0)
48                 return NULL;
49
50         /* f_mass_storage.c assumes SECTOR_SIZE sectors */
51         if (block_dev->blksz != SECTOR_SIZE)
52                 return NULL;
53
54         ums_dev.block_dev = block_dev;
55         ums_dev.start_sector = 0;
56         ums_dev.num_sectors = block_dev->lba;
57
58         printf("UMS: disk start sector: %#x, count: %#x\n",
59                ums_dev.start_sector, ums_dev.num_sectors);
60
61         return &ums_dev;
62 }
63
64 int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
65                                int argc, char * const argv[])
66 {
67         const char *usb_controller;
68         const char *devtype;
69         const char *devnum;
70         struct ums *ums;
71         unsigned int controller_index;
72         int rc;
73         int cable_ready_timeout __maybe_unused;
74
75         if (argc < 3)
76                 return CMD_RET_USAGE;
77
78         usb_controller = argv[1];
79         if (argc >= 4) {
80                 devtype = argv[2];
81                 devnum  = argv[3];
82         } else {
83                 devtype = "mmc";
84                 devnum  = argv[2];
85         }
86
87         ums = ums_init(devtype, devnum);
88         if (!ums)
89                 return CMD_RET_FAILURE;
90
91         controller_index = (unsigned int)(simple_strtoul(
92                                 usb_controller, NULL, 0));
93         if (board_usb_init(controller_index, USB_INIT_DEVICE)) {
94                 error("Couldn't init USB controller.");
95                 return CMD_RET_FAILURE;
96         }
97
98         rc = fsg_init(ums);
99         if (rc) {
100                 error("fsg_init failed");
101                 return CMD_RET_FAILURE;
102         }
103
104         rc = g_dnl_register("usb_dnl_ums");
105         if (rc) {
106                 error("g_dnl_register failed");
107                 return CMD_RET_FAILURE;
108         }
109
110         /* Timeout unit: seconds */
111         cable_ready_timeout = UMS_CABLE_READY_TIMEOUT;
112
113         if (!g_dnl_board_usb_cable_connected()) {
114                 /*
115                  * Won't execute if we don't know whether the cable is
116                  * connected.
117                  */
118                 puts("Please connect USB cable.\n");
119
120                 while (!g_dnl_board_usb_cable_connected()) {
121                         if (ctrlc()) {
122                                 puts("\rCTRL+C - Operation aborted.\n");
123                                 goto exit;
124                         }
125                         if (!cable_ready_timeout) {
126                                 puts("\rUSB cable not detected.\n" \
127                                      "Command exit.\n");
128                                 goto exit;
129                         }
130
131                         printf("\rAuto exit in: %.2d s.", cable_ready_timeout);
132                         mdelay(1000);
133                         cable_ready_timeout--;
134                 }
135                 puts("\r\n");
136         }
137
138         while (1) {
139                 usb_gadget_handle_interrupts(controller_index);
140
141                 rc = fsg_main_thread(NULL);
142                 if (rc) {
143                         /* Check I/O error */
144                         if (rc == -EIO)
145                                 printf("\rCheck USB cable connection\n");
146
147                         /* Check CTRL+C */
148                         if (rc == -EPIPE)
149                                 printf("\rCTRL+C - Operation aborted\n");
150
151                         goto exit;
152                 }
153         }
154 exit:
155         g_dnl_unregister();
156         board_usb_cleanup(controller_index, USB_INIT_DEVICE);
157         return CMD_RET_SUCCESS;
158 }
159
160 U_BOOT_CMD(ums, 4, 1, do_usb_mass_storage,
161         "Use the UMS [USB Mass Storage]",
162         "<USB_controller> [<devtype>] <devnum>  e.g. ums 0 mmc 0\n"
163         "    devtype defaults to mmc"
164 );