kernel: mtk_bmt: allow get_mapping_block to return an error
Used by the mapping implementation to indicate that no backing block is available Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
601c7b4adb
commit
b4c7f8c5f7
4 changed files with 25 additions and 8 deletions
|
@ -111,9 +111,12 @@ mtk_bmt_read(struct mtd_info *mtd, loff_t from,
|
||||||
|
|
||||||
u32 offset = from & (bmtd.blk_size - 1);
|
u32 offset = from & (bmtd.blk_size - 1);
|
||||||
u32 block = from >> bmtd.blk_shift;
|
u32 block = from >> bmtd.blk_shift;
|
||||||
u32 cur_block;
|
int cur_block;
|
||||||
|
|
||||||
cur_block = bmtd.ops->get_mapping_block(block);
|
cur_block = bmtd.ops->get_mapping_block(block);
|
||||||
|
if (cur_block < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset;
|
cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset;
|
||||||
|
|
||||||
cur_ops.oobretlen = 0;
|
cur_ops.oobretlen = 0;
|
||||||
|
@ -174,9 +177,12 @@ mtk_bmt_write(struct mtd_info *mtd, loff_t to,
|
||||||
while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
|
while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
|
||||||
u32 offset = to & (bmtd.blk_size - 1);
|
u32 offset = to & (bmtd.blk_size - 1);
|
||||||
u32 block = to >> bmtd.blk_shift;
|
u32 block = to >> bmtd.blk_shift;
|
||||||
u32 cur_block;
|
int cur_block;
|
||||||
|
|
||||||
cur_block = bmtd.ops->get_mapping_block(block);
|
cur_block = bmtd.ops->get_mapping_block(block);
|
||||||
|
if (cur_block < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset;
|
cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset;
|
||||||
|
|
||||||
cur_ops.oobretlen = 0;
|
cur_ops.oobretlen = 0;
|
||||||
|
@ -219,7 +225,8 @@ mtk_bmt_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
u64 start_addr, end_addr;
|
u64 start_addr, end_addr;
|
||||||
int ret;
|
int ret;
|
||||||
u16 orig_block, block;
|
u16 orig_block;
|
||||||
|
int block;
|
||||||
|
|
||||||
start_addr = instr->addr & (~mtd->erasesize_mask);
|
start_addr = instr->addr & (~mtd->erasesize_mask);
|
||||||
end_addr = instr->addr + instr->len;
|
end_addr = instr->addr + instr->len;
|
||||||
|
@ -227,6 +234,8 @@ mtk_bmt_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||||
while (start_addr < end_addr) {
|
while (start_addr < end_addr) {
|
||||||
orig_block = start_addr >> bmtd.blk_shift;
|
orig_block = start_addr >> bmtd.blk_shift;
|
||||||
block = bmtd.ops->get_mapping_block(orig_block);
|
block = bmtd.ops->get_mapping_block(orig_block);
|
||||||
|
if (block < 0)
|
||||||
|
return -EIO;
|
||||||
mapped_instr.addr = (loff_t)block << bmtd.blk_shift;
|
mapped_instr.addr = (loff_t)block << bmtd.blk_shift;
|
||||||
ret = bmtd._erase(mtd, &mapped_instr);
|
ret = bmtd._erase(mtd, &mapped_instr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -265,7 +274,11 @@ static int
|
||||||
mtk_bmt_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
mtk_bmt_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
||||||
{
|
{
|
||||||
u16 orig_block = ofs >> bmtd.blk_shift;
|
u16 orig_block = ofs >> bmtd.blk_shift;
|
||||||
u16 block = bmtd.ops->get_mapping_block(orig_block);
|
int block;
|
||||||
|
|
||||||
|
block = bmtd.ops->get_mapping_block(orig_block);
|
||||||
|
if (block < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
bmtd.ops->remap_block(orig_block, block, bmtd.blk_size);
|
bmtd.ops->remap_block(orig_block, block, bmtd.blk_size);
|
||||||
|
|
||||||
|
@ -298,7 +311,11 @@ static int mtk_bmt_debug_mark_good(void *data, u64 val)
|
||||||
static int mtk_bmt_debug_mark_bad(void *data, u64 val)
|
static int mtk_bmt_debug_mark_bad(void *data, u64 val)
|
||||||
{
|
{
|
||||||
u32 block = val >> bmtd.blk_shift;
|
u32 block = val >> bmtd.blk_shift;
|
||||||
u16 cur_block = bmtd.ops->get_mapping_block(block);
|
int cur_block;
|
||||||
|
|
||||||
|
cur_block = bmtd.ops->get_mapping_block(block);
|
||||||
|
if (cur_block < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
bmtd.ops->remap_block(block, cur_block, bmtd.blk_size);
|
bmtd.ops->remap_block(block, cur_block, bmtd.blk_size);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct mtk_bmt_ops {
|
||||||
int (*init)(struct device_node *np);
|
int (*init)(struct device_node *np);
|
||||||
bool (*remap_block)(u16 block, u16 mapped_block, int copy_len);
|
bool (*remap_block)(u16 block, u16 mapped_block, int copy_len);
|
||||||
void (*unmap_block)(u16 block);
|
void (*unmap_block)(u16 block);
|
||||||
u16 (*get_mapping_block)(int block);
|
int (*get_mapping_block)(int block);
|
||||||
int (*debug)(void *data, u64 val);
|
int (*debug)(void *data, u64 val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ bbt_set_block_state(u16 block, bool bad)
|
||||||
write_bmt(bmtd.bmt_blk_idx, bmtd.bbt_buf);
|
write_bmt(bmtd.bmt_blk_idx, bmtd.bbt_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16
|
static int
|
||||||
get_mapping_block_index_bbt(int block)
|
get_mapping_block_index_bbt(int block)
|
||||||
{
|
{
|
||||||
int start, end, ofs;
|
int start, end, ofs;
|
||||||
|
|
|
@ -306,7 +306,7 @@ static bool remap_block_v2(u16 block, u16 mapped_block, int copy_len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16 get_mapping_block_index_v2(int block)
|
static int get_mapping_block_index_v2(int block)
|
||||||
{
|
{
|
||||||
int start, end;
|
int start, end;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue