]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - fs/ext2/dev.c
microblaze: Fix strict-aliasing rules for in_be32
[karo-tx-uboot.git] / fs / ext2 / dev.c
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
31 static block_dev_desc_t *ext2fs_block_dev_desc;
32 static disk_partition_t part_info;
33
34 int 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
53 int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf)
54 {
55         char sec_buf[SECTOR_SIZE];
56         unsigned sectors;
57
58         /*
59          *  Check partition boundaries
60          */
61         if ((sector < 0) ||
62             ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
63                 part_info.size)) {
64                 /* errnum = ERR_OUTSIDE_PART; */
65                 printf(" ** %s read outside partition sector %d\n",
66                        __func__,
67                        sector);
68                 return 0;
69         }
70
71         /*
72          *  Get the read to the beginning of a partition.
73          */
74         sector += byte_offset >> SECTOR_BITS;
75         byte_offset &= SECTOR_SIZE - 1;
76
77         debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
78
79         if (ext2fs_block_dev_desc == NULL) {
80                 printf(" ** %s Invalid Block Device Descriptor (NULL)\n",
81                        __func__);
82                 return 0;
83         }
84
85         if (byte_offset != 0) {
86                 /* read first part which isn't aligned with start of sector */
87                 if (ext2fs_block_dev_desc->
88                     block_read(ext2fs_block_dev_desc->dev,
89                                part_info.start + sector, 1,
90                                (unsigned long *) sec_buf) != 1) {
91                         printf(" ** %s read error **\n", __func__);
92                         return 0;
93                 }
94                 memcpy(buf, sec_buf + byte_offset,
95                        min(SECTOR_SIZE - byte_offset, byte_len));
96                 buf += min(SECTOR_SIZE - byte_offset, byte_len);
97                 byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
98                 sector++;
99         }
100
101         /*  read sector aligned part */
102         sectors = byte_len / SECTOR_SIZE;
103
104         if (sectors > 0) {
105                 if (ext2fs_block_dev_desc->block_read(
106                         ext2fs_block_dev_desc->dev,
107                         part_info.start + sector,
108                         sectors,
109                         (unsigned long *) buf) != sectors) {
110                         printf(" ** %s read error - block\n", __func__);
111                         return 0;
112                 }
113
114                 buf += sectors * SECTOR_SIZE;
115                 byte_len -= sectors * SECTOR_SIZE;
116                 sector += sectors;
117         }
118
119         if (byte_len != 0) {
120                 /* read rest of data which are not in whole sector */
121                 if (ext2fs_block_dev_desc->
122                     block_read(ext2fs_block_dev_desc->dev,
123                                part_info.start + sector, 1,
124                                (unsigned long *) sec_buf) != 1) {
125                         printf(" ** %s read error - last part\n", __func__);
126                         return 0;
127                 }
128                 memcpy(buf, sec_buf, byte_len);
129         }
130         return 1;
131 }