View difference between Paste ID: mFSb8Uqp and Hn2ny4Lt
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
}