Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /* * (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 defined(CONFIG_CMD_EXT2) #include <config.h> #include <ext2fs.h> static block_dev_desc_t *ext2fs_block_dev_desc; static disk_partition_t part_info; 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; debug (" <%d, %d, %d>\n", sector, byte_offset, byte_len); 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++; } if (byte_len == 0) return 1; /* read sector aligned part */ block_len = byte_len & ~(SECTOR_SIZE - 1); if (block_len == 0) { u8 p[SECTOR_SIZE]; block_len = SECTOR_SIZE; ext2fs_block_dev_desc->block_read(ext2fs_block_dev_desc->dev, part_info.start + sector, 1, (unsigned long *)p); memcpy(buf, p, byte_len); return 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); } block_len = byte_len & ~(SECTOR_SIZE - 1); 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 |