mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 13:48:06 +00:00
kernel: mtk_bmt: extend debug interface
Add support for showing remapped blocks and garbage collecting old remapped blocks triggered by using the mark_good/mark_bad files Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
fde2421597
commit
31b6cfb288
@ -672,8 +672,103 @@ static int mtk_bmt_debug_mark_bad(void *data, u64 val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long *
|
||||
mtk_bmt_get_mapping_mask(void)
|
||||
{
|
||||
struct bbmt *bbmt = bmt_tbl(bmtd.bbt);
|
||||
int main_blocks = bmtd.mtd->size >> bmtd.blk_shift;
|
||||
unsigned long *used;
|
||||
int i, k;
|
||||
|
||||
used = kcalloc(sizeof(unsigned long), BIT_WORD(bmtd.bmt_blk_idx) + 1, GFP_KERNEL);
|
||||
if (!used)
|
||||
return NULL;
|
||||
|
||||
for (i = 1; i < main_blocks; i++) {
|
||||
if (bmtd.bbt->bb_tbl[i] == i)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < bmtd.bmt_blk_idx; k++) {
|
||||
if (bmtd.bbt->bb_tbl[i] != bbmt[k].block)
|
||||
continue;
|
||||
|
||||
set_bit(k, used);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
static int mtk_bmt_debug(void *data, u64 val)
|
||||
{
|
||||
struct bbmt *bbmt = bmt_tbl(bmtd.bbt);
|
||||
struct mtd_info *mtd = bmtd.mtd;
|
||||
unsigned long *used;
|
||||
int main_blocks = mtd->size >> bmtd.blk_shift;
|
||||
int n_remap = 0;
|
||||
int i;
|
||||
|
||||
used = mtk_bmt_get_mapping_mask();
|
||||
if (!used)
|
||||
return -ENOMEM;
|
||||
|
||||
switch (val) {
|
||||
case 0:
|
||||
for (i = 1; i < main_blocks; i++) {
|
||||
if (bmtd.bbt->bb_tbl[i] == i)
|
||||
continue;
|
||||
|
||||
printk("remap [%x->%x]\n", i, bmtd.bbt->bb_tbl[i]);
|
||||
n_remap++;
|
||||
}
|
||||
for (i = 0; i <= bmtd.bmt_blk_idx; i++) {
|
||||
char c;
|
||||
|
||||
switch (bbmt[i].mapped) {
|
||||
case NO_MAPPED:
|
||||
continue;
|
||||
case NORMAL_MAPPED:
|
||||
c = 'm';
|
||||
if (test_bit(i, used))
|
||||
c = 'M';
|
||||
break;
|
||||
case BMT_MAPPED:
|
||||
c = 'B';
|
||||
break;
|
||||
default:
|
||||
c = 'X';
|
||||
break;
|
||||
}
|
||||
printk("[%x:%c] = 0x%x\n", i, c, bbmt[i].block);
|
||||
}
|
||||
break;
|
||||
case 100:
|
||||
for (i = 0; i <= bmtd.bmt_blk_idx; i++) {
|
||||
if (bbmt[i].mapped != NORMAL_MAPPED)
|
||||
continue;
|
||||
|
||||
if (test_bit(i, used))
|
||||
continue;
|
||||
|
||||
n_remap++;
|
||||
bbmt[i].mapped = NO_MAPPED;
|
||||
printk("free block [%d:%x]\n", i, bbmt[i].block);
|
||||
}
|
||||
if (n_remap)
|
||||
bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx);
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(used);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_good, NULL, mtk_bmt_debug_mark_good, "%llu\n");
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_bad, NULL, mtk_bmt_debug_mark_bad, "%llu\n");
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_debug, NULL, mtk_bmt_debug, "%llu\n");
|
||||
|
||||
static void
|
||||
mtk_bmt_add_debugfs(void)
|
||||
@ -686,6 +781,7 @@ mtk_bmt_add_debugfs(void)
|
||||
|
||||
debugfs_create_file_unsafe("mark_good", S_IWUSR, dir, NULL, &fops_mark_good);
|
||||
debugfs_create_file_unsafe("mark_bad", S_IWUSR, dir, NULL, &fops_mark_bad);
|
||||
debugfs_create_file_unsafe("debug", S_IWUSR, dir, NULL, &fops_debug);
|
||||
}
|
||||
|
||||
void mtk_bmt_detach(struct mtd_info *mtd)
|
||||
|
Loading…
Reference in New Issue
Block a user