Skip to content
Snippets Groups Projects
cmd_read.c 1.74 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
     * Use of this source code is governed by a BSD-style license that can be
     * found in the LICENSE file.
     *
     * Alternatively, this software may be distributed under the terms of the
     * GNU General Public License ("GPL") version 2 as published by the Free
     * Software Foundation.
     */
    
    #include <common.h>
    #include <command.h>
    #include <part.h>
    
    int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    {
    	char *ep;
    	block_dev_desc_t *dev_desc = NULL;
    	int dev;
    	int part = 0;
    	disk_partition_t part_info;
    	ulong offset = 0u;
    	ulong limit = 0u;
    	void *addr;
    	uint blk;
    	uint cnt;
    
    	if (argc != 6) {
    		cmd_usage(cmdtp);
    		return 1;
    	}
    
    	dev = (int)simple_strtoul(argv[2], &ep, 16);
    	if (*ep) {
    		if (*ep != ':') {
    			printf("Invalid block device %s\n", argv[2]);
    			return 1;
    		}
    		part = (int)simple_strtoul(++ep, NULL, 16);
    	}
    
    	dev_desc = get_dev(argv[1], dev);
    	if (dev_desc == NULL) {
    		printf("Block device %s %d not supported\n", argv[1], dev);
    		return 1;
    	}
    
    	addr = (void *)simple_strtoul(argv[3], NULL, 16);
    	blk = simple_strtoul(argv[4], NULL, 16);
    	cnt = simple_strtoul(argv[5], NULL, 16);
    
    	if (part != 0) {
    		if (get_partition_info(dev_desc, part, &part_info)) {
    			printf("Cannot find partition %d\n", part);
    			return 1;
    		}
    		offset = part_info.start;
    		limit = part_info.size;
    	} else {
    		/* Largest address not available in block_dev_desc_t. */
    		limit = ~0;
    	}
    
    	if (cnt + blk > limit) {
    		printf("Read out of range\n");
    		return 1;
    	}
    
    	if (dev_desc->block_read(dev, offset + blk, cnt, addr) < 0) {
    		printf("Error reading blocks\n");
    		return 1;
    	}
    
    	return 0;
    }
    
    U_BOOT_CMD(
    	read,	6,	0,	do_read,
    	"Load binary data from a partition",
    	"<interface> <dev[:part]> addr blk# cnt"
    );