uboot/fs/ext2/dev.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2004
   3 *  esd gmbh <www.esd-electronics.com>
   4 *  Reinhard Arlt <reinhard.arlt@esd-electronics.com>
   5 *
   6 *  based on code of fs/reiserfs/dev.c by
   7 *
   8 *  (C) Copyright 2003 - 2004
   9 *  Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2 of the License, or
  14 *  (at your option) any later version.
  15 *
  16 *  This program is distributed in the hope that it will be useful,
  17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *  GNU General Public License for more details.
  20 *
  21 *  You should have received a copy of the GNU General Public License
  22 *  along with this program; if not, write to the Free Software
  23 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 */
  25
  26
  27#include <common.h>
  28#include <config.h>
  29#include <ext2fs.h>
  30
  31static block_dev_desc_t *ext2fs_block_dev_desc;
  32static disk_partition_t part_info;
  33
  34int ext2fs_set_blk_dev (block_dev_desc_t * rbdd, int part)
  35{
  36        ext2fs_block_dev_desc = rbdd;
  37
  38        if (part == 0) {
  39                /* disk doesn't use partition table */
  40                part_info.start = 0;
  41                part_info.size = rbdd->lba;
  42                part_info.blksz = rbdd->blksz;
  43        } else {
  44                if (get_partition_info
  45                    (ext2fs_block_dev_desc, part, &part_info)) {
  46                        return 0;
  47                }
  48        }
  49        return (part_info.size);
  50}
  51
  52
  53int ext2fs_devread (int sector, int byte_offset, int byte_len, char *buf) {
  54        char sec_buf[SECTOR_SIZE];
  55        unsigned block_len;
  56
  57/*
  58 *  Check partition boundaries
  59 */
  60        if ((sector < 0)
  61            || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
  62                part_info.size)) {
  63        /*      errnum = ERR_OUTSIDE_PART; */
  64                printf (" ** ext2fs_devread() read outside partition sector %d\n", sector);
  65                return (0);
  66        }
  67
  68/*
  69 *  Get the read to the beginning of a partition.
  70 */
  71        sector += byte_offset >> SECTOR_BITS;
  72        byte_offset &= SECTOR_SIZE - 1;
  73
  74        debug (" <%d, %d, %d>\n", sector, byte_offset, byte_len);
  75
  76        if (ext2fs_block_dev_desc == NULL) {
  77                printf ("** Invalid Block Device Descriptor (NULL)\n");
  78                return (0);
  79        }
  80
  81        if (byte_offset != 0) {
  82                /* read first part which isn't aligned with start of sector */
  83                if (ext2fs_block_dev_desc->
  84                    block_read (ext2fs_block_dev_desc->dev,
  85                                part_info.start + sector, 1,
  86                                (unsigned long *) sec_buf) != 1) {
  87                        printf (" ** ext2fs_devread() read error **\n");
  88                        return (0);
  89                }
  90                memcpy (buf, sec_buf + byte_offset,
  91                        min (SECTOR_SIZE - byte_offset, byte_len));
  92                buf += min (SECTOR_SIZE - byte_offset, byte_len);
  93                byte_len -= min (SECTOR_SIZE - byte_offset, byte_len);
  94                sector++;
  95        }
  96
  97        if (byte_len == 0)
  98                return 1;
  99
 100        /*  read sector aligned part */
 101        block_len = byte_len & ~(SECTOR_SIZE - 1);
 102
 103        if (block_len == 0) {
 104                u8 p[SECTOR_SIZE];
 105
 106                block_len = SECTOR_SIZE;
 107                ext2fs_block_dev_desc->block_read(ext2fs_block_dev_desc->dev,
 108                                                  part_info.start + sector,
 109                                                  1, (unsigned long *)p);
 110                memcpy(buf, p, byte_len);
 111                return 1;
 112        }
 113
 114        if (ext2fs_block_dev_desc->block_read (ext2fs_block_dev_desc->dev,
 115                                               part_info.start + sector,
 116                                               block_len / SECTOR_SIZE,
 117                                               (unsigned long *) buf) !=
 118            block_len / SECTOR_SIZE) {
 119                printf (" ** ext2fs_devread() read error - block\n");
 120                return (0);
 121        }
 122        block_len = byte_len & ~(SECTOR_SIZE - 1);
 123        buf += block_len;
 124        byte_len -= block_len;
 125        sector += block_len / SECTOR_SIZE;
 126
 127        if (byte_len != 0) {
 128                /* read rest of data which are not in whole sector */
 129                if (ext2fs_block_dev_desc->
 130                    block_read (ext2fs_block_dev_desc->dev,
 131                                part_info.start + sector, 1,
 132                                (unsigned long *) sec_buf) != 1) {
 133                        printf (" ** ext2fs_devread() read error - last part\n");
 134                        return (0);
 135                }
 136                memcpy (buf, sec_buf, byte_len);
 137        }
 138        return (1);
 139}
 140