Skip to content

Commit 3fbe507

Browse files
rc-matthew-l-webermiquelraynal
authored andcommitted
mtd: mtdconcat: map through panic write handler
Allows a mtdconcat's subdevice->_panic_write to be used for capturing a mtdoops dump. Note: The ->_panic_write is mapped through from the first chip that is part of the concat virtual device. Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com> [miquel.raynal@bootlin.com: return err, not void] Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20200602143403.13465-1-matthew.weber@rockwellcollins.com
1 parent 3e1b646 commit 3fbe507

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

drivers/mtd/mtdconcat.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,48 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
102102
return -EINVAL;
103103
}
104104

105+
static int
106+
concat_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
107+
size_t * retlen, const u_char * buf)
108+
{
109+
struct mtd_concat *concat = CONCAT(mtd);
110+
int err = -EINVAL;
111+
int i;
112+
for (i = 0; i < concat->num_subdev; i++) {
113+
struct mtd_info *subdev = concat->subdev[i];
114+
size_t size, retsize;
115+
116+
if (to >= subdev->size) {
117+
size = 0;
118+
to -= subdev->size;
119+
continue;
120+
}
121+
if (to + len > subdev->size)
122+
size = subdev->size - to;
123+
else
124+
size = len;
125+
126+
err = mtd_panic_write(subdev, to, size, &retsize, buf);
127+
if (err == -EOPNOTSUPP) {
128+
printk(KERN_ERR "mtdconcat: Cannot write from panic without panic_write\n");
129+
return err;
130+
}
131+
if (err)
132+
break;
133+
134+
*retlen += retsize;
135+
len -= size;
136+
if (len == 0)
137+
break;
138+
139+
err = -EINVAL;
140+
buf += size;
141+
to = 0;
142+
}
143+
return err;
144+
}
145+
146+
105147
static int
106148
concat_write(struct mtd_info *mtd, loff_t to, size_t len,
107149
size_t * retlen, const u_char * buf)
@@ -648,6 +690,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
648690
concat->mtd._block_isbad = concat_block_isbad;
649691
if (subdev[0]->_block_markbad)
650692
concat->mtd._block_markbad = concat_block_markbad;
693+
if (subdev[0]->_panic_write)
694+
concat->mtd._panic_write = concat_panic_write;
651695

652696
concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
653697

0 commit comments

Comments
 (0)