1 /* 2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 * 6 * Alternatively, this software may be distributed under the terms of the 7 * GNU General Public License ("GPL") version 2 as published by the Free 8 * Software Foundation. 9 */ 10 11 #include <common.h> 12 #include <command.h> 13 #include <part.h> 14 15 int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 16 { 17 char *ep; 18 struct blk_desc *dev_desc = NULL; 19 int dev; 20 int part = 0; 21 disk_partition_t part_info; 22 ulong offset = 0u; 23 ulong limit = 0u; 24 void *addr; 25 uint blk; 26 uint cnt; 27 28 if (argc != 6) { 29 cmd_usage(cmdtp); 30 return 1; 31 } 32 33 dev = (int)simple_strtoul(argv[2], &ep, 16); 34 if (*ep) { 35 if (*ep != ':') { 36 printf("Invalid block device %s\n", argv[2]); 37 return 1; 38 } 39 part = (int)simple_strtoul(++ep, NULL, 16); 40 } 41 42 dev_desc = blk_get_dev(argv[1], dev); 43 if (dev_desc == NULL) { 44 printf("Block device %s %d not supported\n", argv[1], dev); 45 return 1; 46 } 47 48 addr = (void *)simple_strtoul(argv[3], NULL, 16); 49 blk = simple_strtoul(argv[4], NULL, 16); 50 cnt = simple_strtoul(argv[5], NULL, 16); 51 52 if (part != 0) { 53 if (part_get_info(dev_desc, part, &part_info)) { 54 printf("Cannot find partition %d\n", part); 55 return 1; 56 } 57 offset = part_info.start; 58 limit = part_info.size; 59 } else { 60 /* Largest address not available in struct blk_desc. */ 61 limit = ~0; 62 } 63 64 if (cnt + blk > limit) { 65 printf("Read out of range\n"); 66 return 1; 67 } 68 69 if (blk_dread(dev_desc, offset + blk, cnt, addr) < 0) { 70 printf("Error reading blocks\n"); 71 return 1; 72 } 73 74 return 0; 75 } 76 77 U_BOOT_CMD( 78 read, 6, 0, do_read, 79 "Load binary data from a partition", 80 "<interface> <dev[:part]> addr blk# cnt" 81 ); 82