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