~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/fs/ext4/dev.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2011 - 2012 Samsung Electronics
 
3
 * EXT4 filesystem implementation in Uboot by
 
4
 * Uma Shankar <uma.shankar@samsung.com>
 
5
 * Manjunatha C Achar <a.manjunatha@samsung.com>
 
6
 *
 
7
 * made from existing ext2/dev.c file of Uboot
 
8
 * (C) Copyright 2004
 
9
 * esd gmbh <www.esd-electronics.com>
 
10
 * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
 
11
 *
 
12
 * based on code of fs/reiserfs/dev.c by
 
13
 *
 
14
 * (C) Copyright 2003 - 2004
 
15
 * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
 
16
 *
 
17
 * SPDX-License-Identifier:     GPL-2.0+
 
18
 */
 
19
 
 
20
/*
 
21
 * Changelog:
 
22
 *      0.1 - Newly created file for ext4fs support. Taken from
 
23
 *              fs/ext2/dev.c file in uboot.
 
24
 */
 
25
 
 
26
#include <common.h>
 
27
#include <config.h>
 
28
#include <ext4fs.h>
 
29
#include <ext_common.h>
 
30
#include "ext4_common.h"
 
31
 
 
32
lbaint_t part_offset;
 
33
 
 
34
static block_dev_desc_t *ext4fs_block_dev_desc;
 
35
static disk_partition_t *part_info;
 
36
 
 
37
void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
 
38
{
 
39
        assert(rbdd->blksz == (1 << rbdd->log2blksz));
 
40
        ext4fs_block_dev_desc = rbdd;
 
41
        get_fs()->dev_desc = rbdd;
 
42
        part_info = info;
 
43
        part_offset = info->start;
 
44
        get_fs()->total_sect = ((uint64_t)info->size * info->blksz) >>
 
45
                get_fs()->dev_desc->log2blksz;
 
46
}
 
47
 
 
48
int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
 
49
{
 
50
        unsigned block_len;
 
51
        int log2blksz = ext4fs_block_dev_desc->log2blksz;
 
52
        ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, (ext4fs_block_dev_desc ?
 
53
                                                 ext4fs_block_dev_desc->blksz :
 
54
                                                 0));
 
55
        if (ext4fs_block_dev_desc == NULL) {
 
56
                printf("** Invalid Block Device Descriptor (NULL)\n");
 
57
                return 0;
 
58
        }
 
59
 
 
60
        /* Check partition boundaries */
 
61
        if ((sector < 0) ||
 
62
            ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
 
63
             >= part_info->size)) {
 
64
                printf("%s read outside partition " LBAFU "\n", __func__,
 
65
                       sector);
 
66
                return 0;
 
67
        }
 
68
 
 
69
        /* Get the read to the beginning of a partition */
 
70
        sector += byte_offset >> log2blksz;
 
71
        byte_offset &= ext4fs_block_dev_desc->blksz - 1;
 
72
 
 
73
        debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len);
 
74
 
 
75
        if (byte_offset != 0) {
 
76
                /* read first part which isn't aligned with start of sector */
 
77
                if (ext4fs_block_dev_desc->
 
78
                    block_read(ext4fs_block_dev_desc->dev,
 
79
                                part_info->start + sector, 1,
 
80
                                (unsigned long *) sec_buf) != 1) {
 
81
                        printf(" ** ext2fs_devread() read error **\n");
 
82
                        return 0;
 
83
                }
 
84
                memcpy(buf, sec_buf + byte_offset,
 
85
                        min(ext4fs_block_dev_desc->blksz
 
86
                            - byte_offset, byte_len));
 
87
                buf += min(ext4fs_block_dev_desc->blksz
 
88
                           - byte_offset, byte_len);
 
89
                byte_len -= min(ext4fs_block_dev_desc->blksz
 
90
                                - byte_offset, byte_len);
 
91
                sector++;
 
92
        }
 
93
 
 
94
        if (byte_len == 0)
 
95
                return 1;
 
96
 
 
97
        /* read sector aligned part */
 
98
        block_len = byte_len & ~(ext4fs_block_dev_desc->blksz - 1);
 
99
 
 
100
        if (block_len == 0) {
 
101
                ALLOC_CACHE_ALIGN_BUFFER(u8, p, ext4fs_block_dev_desc->blksz);
 
102
 
 
103
                block_len = ext4fs_block_dev_desc->blksz;
 
104
                ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
 
105
                                                  part_info->start + sector,
 
106
                                                  1, (unsigned long *)p);
 
107
                memcpy(buf, p, byte_len);
 
108
                return 1;
 
109
        }
 
110
 
 
111
        if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
 
112
                                               part_info->start + sector,
 
113
                                               block_len >> log2blksz,
 
114
                                               (unsigned long *) buf) !=
 
115
                                               block_len >> log2blksz) {
 
116
                printf(" ** %s read error - block\n", __func__);
 
117
                return 0;
 
118
        }
 
119
        block_len = byte_len & ~(ext4fs_block_dev_desc->blksz - 1);
 
120
        buf += block_len;
 
121
        byte_len -= block_len;
 
122
        sector += block_len / ext4fs_block_dev_desc->blksz;
 
123
 
 
124
        if (byte_len != 0) {
 
125
                /* read rest of data which are not in whole sector */
 
126
                if (ext4fs_block_dev_desc->
 
127
                    block_read(ext4fs_block_dev_desc->dev,
 
128
                                part_info->start + sector, 1,
 
129
                                (unsigned long *) sec_buf) != 1) {
 
130
                        printf("* %s read error - last part\n", __func__);
 
131
                        return 0;
 
132
                }
 
133
                memcpy(buf, sec_buf, byte_len);
 
134
        }
 
135
        return 1;
 
136
}
 
137
 
 
138
int ext4_read_superblock(char *buffer)
 
139
{
 
140
        struct ext_filesystem *fs = get_fs();
 
141
        int sect = SUPERBLOCK_START >> fs->dev_desc->log2blksz;
 
142
        int off = SUPERBLOCK_START % fs->dev_desc->blksz;
 
143
 
 
144
        return ext4fs_devread(sect, off, SUPERBLOCK_SIZE,
 
145
                                buffer);
 
146
}