2 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include <linux/blkdev.h>
21 #include "exfat_config.h"
22 #include "exfat_global.h"
23 #include "exfat_blkdev.h"
24 #include "exfat_data.h"
25 #include "exfat_api.h"
26 #include "exfat_super.h"
33 INT32 bdev_shutdown(void)
38 INT32 bdev_open(struct super_block *sb)
40 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
42 if (p_bd->opened) return(FFS_SUCCESS);
44 p_bd->sector_size = bdev_logical_block_size(sb->s_bdev);
45 p_bd->sector_size_bits = my_log2(p_bd->sector_size);
46 p_bd->sector_size_mask = p_bd->sector_size - 1;
47 p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> p_bd->sector_size_bits;
54 INT32 bdev_close(struct super_block *sb)
56 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
58 if (!p_bd->opened) return(FFS_SUCCESS);
64 INT32 bdev_read(struct super_block *sb, UINT32 secno, struct buffer_head **bh, UINT32 num_secs, INT32 read)
66 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
67 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
68 #if EXFAT_CONFIG_KERNEL_DEBUG
69 struct exfat_sb_info *sbi = EXFAT_SB(sb);
70 long flags = sbi->debug_flags;
72 if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR);
75 if (!p_bd->opened) return(FFS_MEDIAERR);
77 if (*bh) __brelse(*bh);
80 *bh = __bread(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits);
82 *bh = __getblk(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits);
84 if (*bh) return(FFS_SUCCESS);
86 WARN(!p_fs->dev_ejected,
87 "[EXFAT] No bh, device seems wrong or to be ejected.\n");
92 INT32 bdev_write(struct super_block *sb, UINT32 secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync)
95 struct buffer_head *bh2;
96 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
97 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
98 #if EXFAT_CONFIG_KERNEL_DEBUG
99 struct exfat_sb_info *sbi = EXFAT_SB(sb);
100 long flags = sbi->debug_flags;
102 if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR);
105 if (!p_bd->opened) return(FFS_MEDIAERR);
107 if (secno == bh->b_blocknr) {
108 set_buffer_uptodate(bh);
109 mark_buffer_dirty(bh);
111 if (sync && (sync_dirty_buffer(bh) != 0))
112 return (FFS_MEDIAERR);
114 count = num_secs << p_bd->sector_size_bits;
116 bh2 = __getblk(sb->s_bdev, secno, count);
122 MEMCPY(bh2->b_data, bh->b_data, count);
123 set_buffer_uptodate(bh2);
124 mark_buffer_dirty(bh2);
126 if (sync && (sync_dirty_buffer(bh2) != 0)) {
136 WARN(!p_fs->dev_ejected,
137 "[EXFAT] No bh, device seems wrong or to be ejected.\n");
139 return (FFS_MEDIAERR);
142 INT32 bdev_sync(struct super_block *sb)
144 BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
145 #if EXFAT_CONFIG_KERNEL_DEBUG
146 struct exfat_sb_info *sbi = EXFAT_SB(sb);
147 long flags = sbi->debug_flags;
149 if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR);
152 if (!p_bd->opened) return(FFS_MEDIAERR);
154 return sync_blockdev(sb->s_bdev);