Skip to content

Commit 03498b7

Browse files
committed
Merge tag 'mtd/fixes-for-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull MTD fixes from Miquel Raynal: "Core fix: - Fix a possible data corruption of the 'part' field in mtd_info Rawnand fixes: - Fix the check on the return value of wait_for_completion_timeout - Fix wrong ECC parameters for mt7622 - Fix a possible memory corruption that might panic in the Qcom driver" * tag 'mtd/fixes-for-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: mtd: rawnand: qcom: fix memory corruption that causes panic mtd: fix 'part' field data corruption in mtd_info mtd: rawnand: Fix return value check of wait_for_completion_timeout mtd: rawnand: fix ecc parameters for mt7622
2 parents 233087c + ba7542e commit 03498b7

File tree

4 files changed

+31
-25
lines changed

4 files changed

+31
-25
lines changed

drivers/mtd/nand/raw/mtk_ecc.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
struct mtk_ecc_caps {
4545
u32 err_mask;
46+
u32 err_shift;
4647
const u8 *ecc_strength;
4748
const u32 *ecc_regs;
4849
u8 num_ecc_strength;
@@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] = {
7677
};
7778

7879
static const u8 ecc_strength_mt7622[] = {
79-
4, 6, 8, 10, 12, 14, 16
80+
4, 6, 8, 10, 12
8081
};
8182

8283
enum mtk_ecc_regs {
@@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
221222
for (i = 0; i < sectors; i++) {
222223
offset = (i >> 2) << 2;
223224
err = readl(ecc->regs + ECC_DECENUM0 + offset);
224-
err = err >> ((i % 4) * 8);
225+
err = err >> ((i % 4) * ecc->caps->err_shift);
225226
err &= ecc->caps->err_mask;
226227
if (err == ecc->caps->err_mask) {
227228
/* uncorrectable errors */
@@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
449450

450451
static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
451452
.err_mask = 0x3f,
453+
.err_shift = 8,
452454
.ecc_strength = ecc_strength_mt2701,
453455
.ecc_regs = mt2701_ecc_regs,
454456
.num_ecc_strength = 20,
@@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
459461

460462
static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
461463
.err_mask = 0x7f,
464+
.err_shift = 8,
462465
.ecc_strength = ecc_strength_mt2712,
463466
.ecc_regs = mt2712_ecc_regs,
464467
.num_ecc_strength = 23,
@@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
468471
};
469472

470473
static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
471-
.err_mask = 0x3f,
474+
.err_mask = 0x1f,
475+
.err_shift = 5,
472476
.ecc_strength = ecc_strength_mt7622,
473477
.ecc_regs = mt7622_ecc_regs,
474-
.num_ecc_strength = 7,
478+
.num_ecc_strength = 5,
475479
.ecc_mode_shift = 4,
476480
.parity_bits = 13,
477481
.pg_irq_sel = 0,

drivers/mtd/nand/raw/qcom_nandc.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,10 +2651,23 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
26512651
ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
26522652

26532653
mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
2654+
/* Free the initially allocated BAM transaction for reading the ONFI params */
2655+
if (nandc->props->is_bam)
2656+
free_bam_transaction(nandc);
26542657

26552658
nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
26562659
cwperpage);
26572660

2661+
/* Now allocate the BAM transaction based on updated max_cwperpage */
2662+
if (nandc->props->is_bam) {
2663+
nandc->bam_txn = alloc_bam_transaction(nandc);
2664+
if (!nandc->bam_txn) {
2665+
dev_err(nandc->dev,
2666+
"failed to allocate bam transaction\n");
2667+
return -ENOMEM;
2668+
}
2669+
}
2670+
26582671
/*
26592672
* DATA_UD_BYTES varies based on whether the read/write command protects
26602673
* spare data with ECC too. We protect spare data by default, so we set
@@ -2955,17 +2968,6 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
29552968
if (ret)
29562969
return ret;
29572970

2958-
if (nandc->props->is_bam) {
2959-
free_bam_transaction(nandc);
2960-
nandc->bam_txn = alloc_bam_transaction(nandc);
2961-
if (!nandc->bam_txn) {
2962-
dev_err(nandc->dev,
2963-
"failed to allocate bam transaction\n");
2964-
nand_cleanup(chip);
2965-
return -ENOMEM;
2966-
}
2967-
}
2968-
29692971
ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
29702972
if (ret)
29712973
nand_cleanup(chip);

drivers/mtd/nand/raw/sh_flctl.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
384384
dma_addr_t dma_addr;
385385
dma_cookie_t cookie;
386386
uint32_t reg;
387-
int ret;
387+
int ret = 0;
388+
unsigned long time_left;
388389

389390
if (dir == DMA_FROM_DEVICE) {
390391
chan = flctl->chan_fifo0_rx;
@@ -425,13 +426,14 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
425426
goto out;
426427
}
427428

428-
ret =
429+
time_left =
429430
wait_for_completion_timeout(&flctl->dma_complete,
430431
msecs_to_jiffies(3000));
431432

432-
if (ret <= 0) {
433+
if (time_left == 0) {
433434
dmaengine_terminate_all(chan);
434435
dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
436+
ret = -ETIMEDOUT;
435437
}
436438

437439
out:
@@ -441,7 +443,7 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
441443

442444
dma_unmap_single(chan->device->dev, dma_addr, len, dir);
443445

444-
/* ret > 0 is success */
446+
/* ret == 0 is success */
445447
return ret;
446448
}
447449

@@ -465,7 +467,7 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
465467

466468
/* initiate DMA transfer */
467469
if (flctl->chan_fifo0_rx && rlen >= 32 &&
468-
flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE) > 0)
470+
!flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE))
469471
goto convert; /* DMA success */
470472

471473
/* do polling transfer */
@@ -524,7 +526,7 @@ static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen,
524526

525527
/* initiate DMA transfer */
526528
if (flctl->chan_fifo0_tx && rlen >= 32 &&
527-
flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE) > 0)
529+
!flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE))
528530
return; /* DMA success */
529531

530532
/* do polling transfer */

include/linux/mtd/mtd.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,8 @@ struct mtd_info {
389389
/* List of partitions attached to this MTD device */
390390
struct list_head partitions;
391391

392-
union {
393-
struct mtd_part part;
394-
struct mtd_master master;
395-
};
392+
struct mtd_part part;
393+
struct mtd_master master;
396394
};
397395

398396
static inline struct mtd_info *mtd_get_master(struct mtd_info *mtd)

0 commit comments

Comments
 (0)