1 /* 2 * Copyright 2017 Rockchip Electronics Co., Ltd 3 * Frank Wang <frank.wang@rock-chips.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 <dm/device.h> 13 #include <g_dnl.h> 14 #include <part.h> 15 #include <usb.h> 16 #include <usb_mass_storage.h> 17 #include <rockusb.h> 18 19 static struct rockusb rkusb; 20 static struct rockusb *g_rkusb; 21 22 static int rkusb_read_sector(struct ums *ums_dev, 23 ulong start, lbaint_t blkcnt, void *buf) 24 { 25 struct blk_desc *block_dev = &ums_dev->block_dev; 26 lbaint_t blkstart = start + ums_dev->start_sector; 27 int ret; 28 29 if ((blkstart + blkcnt) > RKUSB_READ_LIMIT_ADDR) { 30 memset(buf, 0xcc, blkcnt * SECTOR_SIZE); 31 return blkcnt; 32 } else { 33 ret = blk_dread(block_dev, blkstart, blkcnt, buf); 34 if (!ret) 35 ret = -EIO; 36 return ret; 37 } 38 } 39 40 static int rkusb_write_sector(struct ums *ums_dev, 41 ulong start, lbaint_t blkcnt, const void *buf) 42 { 43 struct blk_desc *block_dev = &ums_dev->block_dev; 44 lbaint_t blkstart = start + ums_dev->start_sector; 45 struct blk_desc *mtd_blk = NULL; 46 int ret; 47 48 if (block_dev->if_type == IF_TYPE_MTD) { 49 mtd_blk = dev_get_uclass_platdata(block_dev->bdev); 50 mtd_blk->op_flag |= BLK_MTD_CONT_WRITE; 51 } 52 53 ret = blk_dwrite(block_dev, blkstart, blkcnt, buf); 54 if (!ret) 55 ret = -EIO; 56 #if defined(CONFIG_SCSI) && defined(CONFIG_CMD_SCSI) && (defined(CONFIG_UFS)) 57 if (block_dev->if_type == IF_TYPE_SCSI && block_dev->rawblksz == 4096) { 58 /* write loader to UFS BootA */ 59 if (blkstart < 8192 && blkstart >= 64) 60 blk_write_devnum(IF_TYPE_SCSI, 1, blkstart, blkcnt, (ulong *)buf); 61 } 62 #endif 63 if (block_dev->if_type == IF_TYPE_MTD) { 64 mtd_blk->op_flag &= ~(BLK_MTD_CONT_WRITE); 65 } 66 return ret; 67 } 68 69 static int rkusb_erase_sector(struct ums *ums_dev, 70 ulong start, lbaint_t blkcnt) 71 { 72 struct blk_desc *block_dev = &ums_dev->block_dev; 73 lbaint_t blkstart = start + ums_dev->start_sector; 74 75 #if defined(CONFIG_SCSI) && defined(CONFIG_CMD_SCSI) && (defined(CONFIG_UFS)) 76 if (block_dev->if_type == IF_TYPE_SCSI && block_dev->rawblksz == 4096) { 77 /* write loader to UFS BootA */ 78 if (blkstart < 8192) { 79 lbaint_t cur_cnt = 8192 - blkstart; 80 81 if (cur_cnt > blkcnt) 82 cur_cnt = blkcnt; 83 blk_erase_devnum(IF_TYPE_SCSI, 1, blkstart, cur_cnt); 84 } 85 } 86 #endif 87 88 return blk_derase(block_dev, blkstart, blkcnt); 89 } 90 91 static void rkusb_fini(void) 92 { 93 int i; 94 95 for (i = 0; i < g_rkusb->ums_cnt; i++) 96 free((void *)g_rkusb->ums[i].name); 97 free(g_rkusb->ums); 98 g_rkusb->ums = NULL; 99 g_rkusb->ums_cnt = 0; 100 g_rkusb = NULL; 101 } 102 103 #define RKUSB_NAME_LEN 16 104 105 static int rkusb_init(const char *devtype, const char *devnums_part_str) 106 { 107 char *s, *t, *devnum_part_str, *name; 108 struct blk_desc *block_dev; 109 disk_partition_t info; 110 int partnum, cnt; 111 int ret = -1; 112 struct ums *ums_new; 113 114 s = strdup(devnums_part_str); 115 if (!s) 116 return -1; 117 118 t = s; 119 g_rkusb->ums_cnt = 0; 120 121 for (;;) { 122 devnum_part_str = strsep(&t, ","); 123 if (!devnum_part_str) 124 break; 125 #if defined(CONFIG_SCSI) && defined(CONFIG_CMD_SCSI) && (defined(CONFIG_UFS)) 126 if (!strcmp(devtype, "scsi")) { 127 block_dev= blk_get_devnum_by_typename(devtype, 0); 128 if (block_dev == NULL) 129 return -ENXIO; 130 } else 131 #endif 132 { 133 partnum = blk_get_device_part_str(devtype, devnum_part_str, 134 &block_dev, &info, 1); 135 if (partnum < 0) 136 goto cleanup; 137 } 138 139 /* f_mass_storage.c assumes SECTOR_SIZE sectors */ 140 if (block_dev->blksz != SECTOR_SIZE) 141 goto cleanup; 142 143 ums_new = realloc(g_rkusb->ums, (g_rkusb->ums_cnt + 1) * 144 sizeof(*g_rkusb->ums)); 145 if (!ums_new) 146 goto cleanup; 147 g_rkusb->ums = ums_new; 148 cnt = g_rkusb->ums_cnt; 149 150 /* Expose all partitions for rockusb command */ 151 g_rkusb->ums[cnt].start_sector = 0; 152 g_rkusb->ums[cnt].num_sectors = block_dev->lba; 153 154 g_rkusb->ums[cnt].read_sector = rkusb_read_sector; 155 g_rkusb->ums[cnt].write_sector = rkusb_write_sector; 156 g_rkusb->ums[cnt].erase_sector = rkusb_erase_sector; 157 158 name = malloc(RKUSB_NAME_LEN); 159 if (!name) 160 goto cleanup; 161 snprintf(name, RKUSB_NAME_LEN, "rkusb disk %d", cnt); 162 g_rkusb->ums[cnt].name = name; 163 g_rkusb->ums[cnt].block_dev = *block_dev; 164 165 printf("RKUSB: LUN %d, dev %d, hwpart %d, sector %#x, count %#x\n", 166 g_rkusb->ums_cnt, 167 g_rkusb->ums[cnt].block_dev.devnum, 168 g_rkusb->ums[cnt].block_dev.hwpart, 169 g_rkusb->ums[cnt].start_sector, 170 g_rkusb->ums[cnt].num_sectors); 171 172 g_rkusb->ums_cnt++; 173 } 174 175 if (g_rkusb->ums_cnt) 176 ret = 0; 177 178 cleanup: 179 free(s); 180 if (ret < 0) 181 rkusb_fini(); 182 183 return ret; 184 } 185 186 void rkusb_force_to_usb2(bool enable) 187 { 188 if (g_rkusb) 189 g_rkusb->force_usb2 = enable; 190 } 191 192 bool rkusb_force_usb2_enabled(void) 193 { 194 if (!g_rkusb) 195 return true; 196 197 return g_rkusb->force_usb2; 198 } 199 200 void rkusb_switch_to_usb3_enable(bool enable) 201 { 202 if (g_rkusb) 203 g_rkusb->switch_usb3 = enable; 204 } 205 206 bool rkusb_switch_usb3_enabled(void) 207 { 208 if (!g_rkusb) 209 return false; 210 211 return g_rkusb->switch_usb3; 212 } 213 214 static int do_rkusb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 215 { 216 const char *usb_controller; 217 const char *devtype; 218 const char *devnum; 219 unsigned int controller_index; 220 int rc; 221 int cable_ready_timeout __maybe_unused; 222 const char *s; 223 224 if (argc != 4) 225 return CMD_RET_USAGE; 226 227 usb_controller = argv[1]; 228 devtype = argv[2]; 229 devnum = argv[3]; 230 231 if (!strcmp(devtype, "mmc") && !strcmp(devnum, "1")) { 232 pr_err("Forbid to flash mmc 1(sdcard)\n"); 233 return CMD_RET_FAILURE; 234 } else if ((!strcmp(devtype, "nvme") || !strcmp(devtype, "scsi")) && !strcmp(devnum, "0")) { 235 /* 236 * Add partnum ":0" to active 'allow_whole_dev' partition 237 * search mechanism on multi storage, where there maybe not 238 * valid partition table. 239 */ 240 devnum = "0:0"; 241 } 242 243 g_rkusb = &rkusb; 244 rc = rkusb_init(devtype, devnum); 245 if (rc < 0) 246 return CMD_RET_FAILURE; 247 248 if (g_rkusb->ums[0].block_dev.if_type == IF_TYPE_MTD && 249 g_rkusb->ums[0].block_dev.devnum == BLK_MTD_NAND) { 250 #ifdef CONFIG_CMD_GO 251 pr_err("Enter bootrom rockusb...\n"); 252 flushc(); 253 run_command("rbrom", 0); 254 #else 255 pr_err("rockusb: count not support loader upgrade!\n"); 256 #endif 257 } 258 259 re_enumerate: 260 controller_index = (unsigned int)(simple_strtoul( 261 usb_controller, NULL, 0)); 262 rc = usb_gadget_initialize(controller_index); 263 if (rc) { 264 pr_err("Couldn't init USB controller."); 265 rc = CMD_RET_FAILURE; 266 goto cleanup_rkusb; 267 } 268 269 rc = fsg_init(g_rkusb->ums, g_rkusb->ums_cnt); 270 if (rc) { 271 pr_err("fsg_init failed"); 272 rc = CMD_RET_FAILURE; 273 goto cleanup_board; 274 } 275 276 if (rkusb_switch_usb3_enabled()) { 277 /* Maskrom usb3 serialnumber get from upgrade tool */ 278 rkusb_switch_to_usb3_enable(false); 279 } else { 280 s = env_get("serial#"); 281 if (s) { 282 char *sn = (char *)calloc(strlen(s) + 1, sizeof(char)); 283 char *sn_p = sn; 284 285 if (!sn) 286 goto cleanup_board; 287 288 memcpy(sn, s, strlen(s)); 289 while (*sn_p) { 290 if (*sn_p == '\\' || *sn_p == '/') 291 *sn_p = '_'; 292 sn_p++; 293 } 294 295 g_dnl_set_serialnumber(sn); 296 free(sn); 297 #if defined(CONFIG_SUPPORT_USBPLUG) 298 } else { 299 char sn[9] = "Rockchip"; 300 301 g_dnl_set_serialnumber(sn); 302 #endif 303 } 304 } 305 306 rc = g_dnl_register("rkusb_ums_dnl"); 307 if (rc) { 308 pr_err("g_dnl_register failed"); 309 rc = CMD_RET_FAILURE; 310 goto cleanup_board; 311 } 312 313 /* Timeout unit: seconds */ 314 cable_ready_timeout = UMS_CABLE_READY_TIMEOUT; 315 316 if (!g_dnl_board_usb_cable_connected()) { 317 puts("Please connect USB cable.\n"); 318 319 while (!g_dnl_board_usb_cable_connected()) { 320 if (ctrlc()) { 321 puts("\rCTRL+C - Operation aborted.\n"); 322 rc = CMD_RET_SUCCESS; 323 goto cleanup_register; 324 } 325 if (!cable_ready_timeout) { 326 puts("\rUSB cable not detected.\nCommand exit.\n"); 327 rc = CMD_RET_SUCCESS; 328 goto cleanup_register; 329 } 330 331 printf("\rAuto exit in: %.2d s.", cable_ready_timeout); 332 mdelay(1000); 333 cable_ready_timeout--; 334 } 335 puts("\r\n"); 336 } 337 338 while (1) { 339 usb_gadget_handle_interrupts(controller_index); 340 341 rc = fsg_main_thread(NULL); 342 if (rc) { 343 if (rc == -ENODEV && rkusb_usb3_capable() && 344 !rkusb_force_usb2_enabled()) { 345 printf("wait for usb3 connect timeout\n"); 346 rkusb_force_to_usb2(true); 347 g_dnl_unregister(); 348 usb_gadget_release(controller_index); 349 goto re_enumerate; 350 } 351 352 /* Check I/O error */ 353 if (rc == -EIO) 354 printf("\rCheck USB cable connection\n"); 355 356 /* Check CTRL+C */ 357 if (rc == -EPIPE) 358 printf("\rCTRL+C - Operation aborted\n"); 359 360 rc = CMD_RET_SUCCESS; 361 goto cleanup_register; 362 } 363 364 if (rkusb_switch_usb3_enabled()) { 365 printf("rockusb switch to usb3\n"); 366 g_dnl_unregister(); 367 usb_gadget_release(controller_index); 368 goto re_enumerate; 369 } 370 } 371 372 cleanup_register: 373 g_dnl_unregister(); 374 cleanup_board: 375 usb_gadget_release(controller_index); 376 cleanup_rkusb: 377 rkusb_fini(); 378 379 return rc; 380 } 381 382 U_BOOT_CMD_ALWAYS(rockusb, 4, 1, do_rkusb, 383 "Use the rockusb Protocol", 384 "<USB_controller> <devtype> <dev[:part]> e.g. rockusb 0 mmc 0\n" 385 ); 386