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