xref: /rk3399_rockchip-uboot/fs/reiserfs/dev.c (revision 650f36641ccfe1c2444277891da7c76cdde99f8b)
1518e2e1aSwdenk /*
2518e2e1aSwdenk  *  (C) Copyright 2003 - 2004
3518e2e1aSwdenk  *  Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
4518e2e1aSwdenk  *
5518e2e1aSwdenk  *  This program is free software; you can redistribute it and/or modify
6518e2e1aSwdenk  *  it under the terms of the GNU General Public License as published by
7518e2e1aSwdenk  *  the Free Software Foundation; either version 2 of the License, or
8518e2e1aSwdenk  *  (at your option) any later version.
9518e2e1aSwdenk  *
10518e2e1aSwdenk  *  This program is distributed in the hope that it will be useful,
11518e2e1aSwdenk  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12518e2e1aSwdenk  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13518e2e1aSwdenk  *  GNU General Public License for more details.
14518e2e1aSwdenk  *
15518e2e1aSwdenk  *  You should have received a copy of the GNU General Public License
16518e2e1aSwdenk  *  along with this program; if not, write to the Free Software
17518e2e1aSwdenk  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18518e2e1aSwdenk  */
19518e2e1aSwdenk 
20518e2e1aSwdenk 
21518e2e1aSwdenk #include <common.h>
22518e2e1aSwdenk #include <config.h>
23518e2e1aSwdenk #include <reiserfs.h>
24518e2e1aSwdenk 
25518e2e1aSwdenk #include "reiserfs_private.h"
26518e2e1aSwdenk 
27518e2e1aSwdenk static block_dev_desc_t *reiserfs_block_dev_desc;
28*650f3664SRob Herring static disk_partition_t *part_info;
29518e2e1aSwdenk 
30518e2e1aSwdenk 
31*650f3664SRob Herring void reiserfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
32518e2e1aSwdenk {
33518e2e1aSwdenk 	reiserfs_block_dev_desc = rbdd;
34*650f3664SRob Herring 	part_info = info;
35518e2e1aSwdenk }
36518e2e1aSwdenk 
37518e2e1aSwdenk 
38518e2e1aSwdenk int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
39518e2e1aSwdenk {
40518e2e1aSwdenk 	char sec_buf[SECTOR_SIZE];
41518e2e1aSwdenk 	unsigned block_len;
42518e2e1aSwdenk /*
43518e2e1aSwdenk 	unsigned len = byte_len;
44518e2e1aSwdenk 	u8 *start = buf;
45518e2e1aSwdenk */
46518e2e1aSwdenk 	/*
47518e2e1aSwdenk 	*  Check partition boundaries
48518e2e1aSwdenk 	*/
49518e2e1aSwdenk 	if (sector < 0
50518e2e1aSwdenk 	    || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
51*650f3664SRob Herring 	    >= part_info->size)) {
52b79a11ccSwdenk /*		errnum = ERR_OUTSIDE_PART; */
53518e2e1aSwdenk 		printf (" ** reiserfs_devread() read outside partition\n");
54518e2e1aSwdenk 		return 0;
55518e2e1aSwdenk 	}
56518e2e1aSwdenk 
57518e2e1aSwdenk 	/*
58518e2e1aSwdenk 	 *  Get the read to the beginning of a partition.
59518e2e1aSwdenk 	 */
60518e2e1aSwdenk 	sector += byte_offset >> SECTOR_BITS;
61518e2e1aSwdenk 	byte_offset &= SECTOR_SIZE - 1;
62518e2e1aSwdenk 
63518e2e1aSwdenk #if defined(DEBUG)
64518e2e1aSwdenk 	printf (" <%d, %d, %d> ", sector, byte_offset, byte_len);
65518e2e1aSwdenk #endif
66518e2e1aSwdenk 
67518e2e1aSwdenk 
68518e2e1aSwdenk 	if (reiserfs_block_dev_desc == NULL)
69518e2e1aSwdenk 		return 0;
70518e2e1aSwdenk 
71518e2e1aSwdenk 
72518e2e1aSwdenk 	if (byte_offset != 0) {
73518e2e1aSwdenk 		/* read first part which isn't aligned with start of sector */
74518e2e1aSwdenk 		if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev,
75*650f3664SRob Herring 		    part_info->start + sector, 1,
76*650f3664SRob Herring 		    (unsigned long *)sec_buf) != 1) {
77518e2e1aSwdenk 			printf (" ** reiserfs_devread() read error\n");
78518e2e1aSwdenk 			return 0;
79518e2e1aSwdenk 		}
80518e2e1aSwdenk 		memcpy(buf, sec_buf+byte_offset, min(SECTOR_SIZE-byte_offset, byte_len));
81518e2e1aSwdenk 		buf+=min(SECTOR_SIZE-byte_offset, byte_len);
82518e2e1aSwdenk 		byte_len-=min(SECTOR_SIZE-byte_offset, byte_len);
83518e2e1aSwdenk 		sector++;
84518e2e1aSwdenk 	}
85518e2e1aSwdenk 
86518e2e1aSwdenk 	/* read sector aligned part */
87518e2e1aSwdenk 	block_len = byte_len & ~(SECTOR_SIZE-1);
88518e2e1aSwdenk 	if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev,
89*650f3664SRob Herring 	    part_info->start + sector, block_len/SECTOR_SIZE,
90*650f3664SRob Herring 	    (unsigned long *)buf) != block_len/SECTOR_SIZE) {
91518e2e1aSwdenk 		printf (" ** reiserfs_devread() read error - block\n");
92518e2e1aSwdenk 		return 0;
93518e2e1aSwdenk 	}
94518e2e1aSwdenk 	buf+=block_len;
95518e2e1aSwdenk 	byte_len-=block_len;
96518e2e1aSwdenk 	sector+= block_len/SECTOR_SIZE;
97518e2e1aSwdenk 
98518e2e1aSwdenk 	if ( byte_len != 0 ) {
99518e2e1aSwdenk 		/* read rest of data which are not in whole sector */
100518e2e1aSwdenk 		if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev,
101*650f3664SRob Herring 		    part_info->start + sector, 1,
102*650f3664SRob Herring 		    (unsigned long *)sec_buf) != 1) {
103518e2e1aSwdenk 			printf (" ** reiserfs_devread() read error - last part\n");
104518e2e1aSwdenk 			return 0;
105518e2e1aSwdenk 		}
106518e2e1aSwdenk 		memcpy(buf, sec_buf, byte_len);
107518e2e1aSwdenk 	}
108518e2e1aSwdenk 
109518e2e1aSwdenk 	return 1;
110518e2e1aSwdenk }
111