Skip to content
Snippets Groups Projects
dev.c 3.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • Stefan Roese's avatar
    Stefan Roese committed
    /*
     * (C) Copyright 2004
     *  esd gmbh <www.esd-electronics.com>
     *  Reinhard Arlt <reinhard.arlt@esd-electronics.com>
     *
     *  based on code of fs/reiserfs/dev.c by
     *
     *  (C) Copyright 2003 - 2004
     *  Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 2 of the License, or
     *  (at your option) any later version.
     *
     *  This program is distributed in the hope that it will be useful,
     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *  GNU General Public License for more details.
     *
     *  You should have received a copy of the GNU General Public License
     *  along with this program; if not, write to the Free Software
     *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     */
    
    
    #include <common.h>
    #if (CONFIG_COMMANDS & CFG_CMD_EXT2)
    
    #include <config.h>
    #include <ext2fs.h>
    
    static block_dev_desc_t *ext2fs_block_dev_desc;
    static disk_partition_t part_info;
    
    #undef DEBUG
    int ext2fs_set_blk_dev
        (
        block_dev_desc_t *rbdd, 
        int               part
        )
        {
        ext2fs_block_dev_desc = rbdd;
    
        if (part == 0) 
            {
    	/* disk doesn't use partition table */
    	part_info.start = 0;
    	part_info.size = rbdd->lba;
    	part_info.blksz = rbdd->blksz;
    	} 
        else 
            {
    	if (get_partition_info (ext2fs_block_dev_desc, part, &part_info)) 
    	    {
    	    return 0;
    	    }
    	}
        return (part_info.size);
        }
    
    
    int ext2fs_devread 
        (
        int   sector, 
        int   byte_offset, 
        int   byte_len, 
        char *buf
        )
        {
        char sec_buf[SECTOR_SIZE];
        unsigned block_len;
    /*
     *  Check partition boundaries
     */
        if ((sector < 0) || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= part_info.size)) 
            {
    /*      errnum = ERR_OUTSIDE_PART; */
    	printf (" ** ext2fs_devread() read outside partition sector %d\n", sector);
    	return(0);
    	}
    
    /*
     *  Get the read to the beginning of a partition.
     */
        sector += byte_offset >> SECTOR_BITS;
        byte_offset &= SECTOR_SIZE - 1;
    
    #if defined(DEBUG)
        printf (" <%d, %d, %d>\n", sector, byte_offset, byte_len);
    #endif
    
        if (ext2fs_block_dev_desc == NULL)
            {
            printf("** Invalid Block Device Descriptor (NULL)\n");
    	return(0);
    	}
    
        if (byte_offset != 0) 
            {
    /*      read first part which isn't aligned with start of sector */
    	if (ext2fs_block_dev_desc->block_read(ext2fs_block_dev_desc->dev, part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) 
    	    {
    	    printf (" ** ext2fs_devread() read error **\n");
    	    return(0);
    	    }
    	memcpy(buf, sec_buf+byte_offset, min(SECTOR_SIZE-byte_offset, byte_len));
    	buf+=min(SECTOR_SIZE-byte_offset, byte_len);
    	byte_len-=min(SECTOR_SIZE-byte_offset, byte_len);
    	sector++;
    	}
    
    /*  read sector aligned part */
        block_len = byte_len & ~(SECTOR_SIZE-1);
        if (ext2fs_block_dev_desc->block_read(ext2fs_block_dev_desc->dev, 
    					  part_info.start+sector, 
    					  block_len/SECTOR_SIZE, 
    					  (unsigned long *)buf) != block_len/SECTOR_SIZE) 
            {
    	printf (" ** ext2fs_devread() read error - block\n");
    	return(0);
    	}
        buf+=block_len;
        byte_len-=block_len;
        sector+= block_len/SECTOR_SIZE;
    
        if (byte_len != 0) 
            {
    /*      read rest of data which are not in whole sector */
    	if (ext2fs_block_dev_desc->block_read(ext2fs_block_dev_desc->dev,
    					      part_info.start+sector, 
    					      1, 
    					      (unsigned long *)sec_buf) != 1) 
    	    {
    	    printf (" ** ext2fs_devread() read error - last part\n");
    	    return(0);
    	    }
    	memcpy(buf, sec_buf, byte_len);
    	}
        return(1);
        }
    #endif /* CFG_CMD_EXT2FS */