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 | } |