SHOW:
|
|
- or go back to the newest paste.
1 | static int part_erase(struct mtd_info *mtd, struct erase_info *instr) | |
2 | { | |
3 | struct mtd_part *part = mtd_to_part(mtd); | |
4 | int ret; | |
5 | size_t wrlen = 0; | |
6 | u8 *erase_buf = NULL; | |
7 | u32 erase_buf_ofs = 0; | |
8 | bool partial_start = false; | |
9 | ||
10 | if (mtd->flags & MTD_ERASE_PARTIAL) { | |
11 | size_t readlen = 0; | |
12 | u64 mtd_ofs; | |
13 | ||
14 | erase_buf = kmalloc(part->parent->erasesize, GFP_ATOMIC); | |
15 | if (!erase_buf) | |
16 | return -ENOMEM; | |
17 | ||
18 | mtd_ofs = part->offset + instr->addr; | |
19 | erase_buf_ofs = do_div(mtd_ofs, part->parent->erasesize); | |
20 | ||
21 | if (erase_buf_ofs > 0) { | |
22 | instr->addr -= erase_buf_ofs; | |
23 | ret = mtd_read(part->parent, | |
24 | instr->addr + part->offset, | |
25 | part->parent->erasesize, | |
26 | &readlen, erase_buf); | |
27 | ||
28 | instr->len += erase_buf_ofs; | |
29 | partial_start = true; | |
30 | } else { | |
31 | mtd_ofs = part->offset + part->mtd.size; | |
32 | erase_buf_ofs = part->parent->erasesize - | |
33 | do_div(mtd_ofs, part->parent->erasesize); | |
34 | ||
35 | if (erase_buf_ofs > 0) { | |
36 | instr->len += erase_buf_ofs; | |
37 | ret = mtd_read(part->parent, | |
38 | part->offset + instr->addr + | |
39 | instr->len - part->parent->erasesize, | |
40 | part->parent->erasesize, &readlen, | |
41 | erase_buf); | |
42 | } else { | |
43 | ret = 0; | |
44 | } | |
45 | } | |
46 | if (ret < 0) { | |
47 | kfree(erase_buf); | |
48 | return ret; | |
49 | } | |
50 | ||
51 | } | |
52 | ||
53 | instr->addr += part->offset; | |
54 | ret = part->parent->_erase(part->parent, instr); | |
55 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) | |
56 | instr->fail_addr -= part->offset; | |
57 | instr->addr -= part->offset; | |
58 | ||
59 | if (mtd->flags & MTD_ERASE_PARTIAL) { | |
60 | if (partial_start) { | |
61 | - | part->parent->_write(part->parent, |
61 | + | part_write(mtd, |
62 | instr->addr, erase_buf_ofs, | |
63 | &wrlen, erase_buf); | |
64 | instr->addr += erase_buf_ofs; | |
65 | } else { | |
66 | instr->len -= erase_buf_ofs; | |
67 | - | part->parent->_write(part->parent, |
67 | + | part_write(mtd, |
68 | instr->addr + instr->len, | |
69 | erase_buf_ofs, &wrlen, | |
70 | erase_buf + | |
71 | part->parent->erasesize - | |
72 | erase_buf_ofs); | |
73 | } | |
74 | kfree(erase_buf); | |
75 | } | |
76 | ||
77 | return ret; | |
78 | } |