mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 00:34:20 +08:00
SPI NOR:
* Fix the SFDP parsing code (bugs reported by Geert Uytterhoeven) NAND: * Fix a resource leak in the lpc32xx_mlc driver * Fix a build warning in the core -----BEGIN PGP SIGNATURE----- iQJABAABCAAqBQJZw3NuIxxib3Jpcy5icmV6aWxsb25AZnJlZS1lbGVjdHJvbnMu Y29tAAoJEGXtNgF+CLcAdp8P/R8wm4cZIDqfqEJwee9807uF0TM82XVXw/NSqmBA +4UiMTeBPsOCsUC+Ti1MZzHJB6jhk9J4bs5N4wZ98f7JhcG5ub8aW0TRQvhF8XIj AEnQvkY9/2RTNxfnaOVE7fdB/NZz7USQ9A0A6aZB/yZDenIHpUqlpHZIXJGpB5T5 NsMMYo336NtMK7eW3A4b0UIGiXYpLHHllIQZHjNyzgTdK5FSQHoDploesc0ASc7J 8TPfq7gxkUxgEvTMuZKq3van+8ey08zzU5kNL0cwhtJxXny+CG5hOGJ0M0eDanU8 /i9Pqjm7oIOueGAd0ZgKW0IzaOxwuZ+GqYl5bout10Ies2DzT5W6UMyMNFcQj/ET qH0D1lk4tAhw+7AIMP08O/oURoMrBhNeODKiomYp15O4zByGSprQL8VYcGYCH11x TnQ/Q6HDEh+m4m+8hTko5hTAQRn8RPAxQHFlIltyiTRUczwKhAydDdQvoT2jChXl cOOC6E7/KqJoLJYaNslMNNEki8JXeOa3J6+KABDvGFi9uXfvEYTA2u1FGs3h8ImU JDNYpUYk3zlmCQnWDHLNwVk1ZBRCK3KQpL0V32Lu3PrGe+oGhvIUdbgRT6icX4L2 aK/f5i5NqoK0c+lKEtB87hVqsU/9gEZLNo5sgSqf0OUBy+BkUzm5dEBc5Oafy7VS 3d+a =mlAt -----END PGP SIGNATURE----- Merge tag 'mtd/fixes-for-4.14-rc2' of git://git.infradead.org/linux-mtd Pull mtd fixes from Boris Brezillon: "SPI NOR: - Fix the SFDP parsing code (bugs reported by Geert Uytterhoeven) NAND: - Fix a resource leak in the lpc32xx_mlc driver - Fix a build warning in the core" * tag 'mtd/fixes-for-4.14-rc2' of git://git.infradead.org/linux-mtd: mtd: nand: remove unused blockmask variable mtd: nand: lpc32xx_mlc: Fix an error handling path in lpc32xx_nand_probe() mtd: spi-nor: fix DMA unsafe buffer issue in spi_nor_read_sfdp() mtd: spi-nor: Check consistency of the memory size extracted from the SFDP
This commit is contained in:
commit
d9fde26982
@ -707,7 +707,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
|
||||
}
|
||||
res = clk_prepare_enable(host->clk);
|
||||
if (res)
|
||||
goto err_exit1;
|
||||
goto err_put_clk;
|
||||
|
||||
nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
|
||||
nand_chip->dev_ready = lpc32xx_nand_device_ready;
|
||||
@ -814,6 +814,7 @@ err_exit3:
|
||||
dma_release_channel(host->dma_chan);
|
||||
err_exit2:
|
||||
clk_disable_unprepare(host->clk);
|
||||
err_put_clk:
|
||||
clk_put(host->clk);
|
||||
err_exit1:
|
||||
lpc32xx_wp_enable(host);
|
||||
|
@ -2668,7 +2668,7 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
|
||||
static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
|
||||
struct mtd_oob_ops *ops)
|
||||
{
|
||||
int chipnr, realpage, page, blockmask, column;
|
||||
int chipnr, realpage, page, column;
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
uint32_t writelen = ops->len;
|
||||
|
||||
@ -2704,7 +2704,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
|
||||
|
||||
realpage = (int)(to >> chip->page_shift);
|
||||
page = realpage & chip->pagemask;
|
||||
blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
|
||||
|
||||
/* Invalidate the page cache, when we write to the cached page */
|
||||
if (to <= ((loff_t)chip->pagebuf << chip->page_shift) &&
|
||||
|
@ -1784,7 +1784,7 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp,
|
||||
* @nor: pointer to a 'struct spi_nor'
|
||||
* @addr: offset in the SFDP area to start reading data from
|
||||
* @len: number of bytes to read
|
||||
* @buf: buffer where the SFDP data are copied into
|
||||
* @buf: buffer where the SFDP data are copied into (dma-safe memory)
|
||||
*
|
||||
* Whatever the actual numbers of bytes for address and dummy cycles are
|
||||
* for (Fast) Read commands, the Read SFDP (5Ah) instruction is always
|
||||
@ -1829,6 +1829,36 @@ read_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* spi_nor_read_sfdp_dma_unsafe() - read Serial Flash Discoverable Parameters.
|
||||
* @nor: pointer to a 'struct spi_nor'
|
||||
* @addr: offset in the SFDP area to start reading data from
|
||||
* @len: number of bytes to read
|
||||
* @buf: buffer where the SFDP data are copied into
|
||||
*
|
||||
* Wrap spi_nor_read_sfdp() using a kmalloc'ed bounce buffer as @buf is now not
|
||||
* guaranteed to be dma-safe.
|
||||
*
|
||||
* Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp()
|
||||
* otherwise.
|
||||
*/
|
||||
static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr,
|
||||
size_t len, void *buf)
|
||||
{
|
||||
void *dma_safe_buf;
|
||||
int ret;
|
||||
|
||||
dma_safe_buf = kmalloc(len, GFP_KERNEL);
|
||||
if (!dma_safe_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = spi_nor_read_sfdp(nor, addr, len, dma_safe_buf);
|
||||
memcpy(buf, dma_safe_buf, len);
|
||||
kfree(dma_safe_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct sfdp_parameter_header {
|
||||
u8 id_lsb;
|
||||
u8 minor;
|
||||
@ -2101,7 +2131,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
|
||||
bfpt_header->length * sizeof(u32));
|
||||
addr = SFDP_PARAM_HEADER_PTP(bfpt_header);
|
||||
memset(&bfpt, 0, sizeof(bfpt));
|
||||
err = spi_nor_read_sfdp(nor, addr, len, &bfpt);
|
||||
err = spi_nor_read_sfdp_dma_unsafe(nor, addr, len, &bfpt);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -2127,6 +2157,15 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
|
||||
params->size = bfpt.dwords[BFPT_DWORD(2)];
|
||||
if (params->size & BIT(31)) {
|
||||
params->size &= ~BIT(31);
|
||||
|
||||
/*
|
||||
* Prevent overflows on params->size. Anyway, a NOR of 2^64
|
||||
* bits is unlikely to exist so this error probably means
|
||||
* the BFPT we are reading is corrupted/wrong.
|
||||
*/
|
||||
if (params->size > 63)
|
||||
return -EINVAL;
|
||||
|
||||
params->size = 1ULL << params->size;
|
||||
} else {
|
||||
params->size++;
|
||||
@ -2243,7 +2282,7 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
|
||||
int i, err;
|
||||
|
||||
/* Get the SFDP header. */
|
||||
err = spi_nor_read_sfdp(nor, 0, sizeof(header), &header);
|
||||
err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(header), &header);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user