From df1f1d1cb43b4ffdef5ba5f0623e2f73e94ce030 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 22 May 2010 10:22:49 +0200 Subject: drivers/mtd: Use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Signed-off-by: David Woodhouse --- drivers/mtd/mtdchar.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8bb5e4a..8b223c0 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -404,14 +404,9 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd, if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) return -EINVAL; - ops.oobbuf = kmalloc(length, GFP_KERNEL); - if (!ops.oobbuf) - return -ENOMEM; - - if (copy_from_user(ops.oobbuf, ptr, length)) { - kfree(ops.oobbuf); - return -EFAULT; - } + ops.oobbuf = memdup_user(ptr, length); + if (IS_ERR(ops.oobbuf)) + return PTR_ERR(ops.oobbuf); start &= ~((uint64_t)mtd->oobsize - 1); ret = mtd->write_oob(mtd, start, &ops); -- cgit v1.1 From cc1fed00c9ba84f38717a6cab84409cd48f340e3 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 16:01:45 +0300 Subject: mtd/r852: register IRQ as last step Otherwise, if it fires right away, it might access uninitialized spinlock Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/r852.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 78a4232..20a654a 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -940,18 +940,19 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) r852_dma_test(dev); + dev->irq = pci_dev->irq; + spin_lock_init(&dev->irqlock); + + dev->card_detected = 0; + r852_card_update_present(dev); + /*register irq handler*/ error = -ENODEV; if (request_irq(pci_dev->irq, &r852_irq, IRQF_SHARED, DRV_NAME, dev)) goto error10; - dev->irq = pci_dev->irq; - spin_lock_init(&dev->irqlock); - /* kick initial present test */ - dev->card_detected = 0; - r852_card_update_present(dev); queue_delayed_work(dev->card_workqueue, &dev->card_detect_work, 0); -- cgit v1.1 From 9489be8ca234c07666e88a4472e4d5f2a2425aa5 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 16:01:46 +0300 Subject: mtd/r852: Fixes in case of DMA timeout * Don't call complete on dma completion * do a INIT_COMPLETE before using it each time * Report DMA read error via ecc 'correct' I finally managed to make my system do suspend to ram propertly, and I see that if card was inserted during suspend (while system was off), I get dma timeouts on resume. Simple card reinsert solves the issue. This patch solves a crash that would happen otherwise Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/r852.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 20a654a..3f219e6 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -150,7 +150,6 @@ static void r852_dma_done(struct r852_device *dev, int error) if (dev->phys_dma_addr && dev->phys_dma_addr != dev->phys_bounce_buffer) pci_unmap_single(dev->pci_dev, dev->phys_dma_addr, R852_DMA_LEN, dev->dma_dir ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); - complete(&dev->dma_done); } /* @@ -182,6 +181,7 @@ static void r852_do_dma(struct r852_device *dev, uint8_t *buf, int do_read) /* Set dma direction */ dev->dma_dir = do_read; dev->dma_stage = 1; + INIT_COMPLETION(dev->dma_done); dbg_verbose("doing dma %s ", do_read ? "read" : "write"); @@ -494,6 +494,11 @@ int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, if (dev->card_unstable) return 0; + if (dev->dma_error) { + dev->dma_error = 0; + return -1; + } + r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS); ecc_reg = r852_read_reg_dword(dev, R852_DATALINE); r852_write_reg(dev, R852_CTL, dev->ctlreg); @@ -796,6 +801,7 @@ static irqreturn_t r852_irq(int irq, void *data) if (dma_status & R852_DMA_IRQ_ERROR) { dbg("recieved dma error IRQ"); r852_dma_done(dev, -EIO); + complete(&dev->dma_done); goto out; } @@ -825,8 +831,10 @@ static irqreturn_t r852_irq(int irq, void *data) r852_dma_enable(dev); /* Operation done */ - if (dev->dma_stage == 3) + if (dev->dma_stage == 3) { r852_dma_done(dev, 0); + complete(&dev->dma_done); + } goto out; } @@ -1082,7 +1090,7 @@ int r852_resume(struct device *device) dev->card_detected ? "added" : "removed"); queue_delayed_work(dev->card_workqueue, - &dev->card_detect_work, 1000); + &dev->card_detect_work, msecs_to_jiffies(1000)); return 0; } -- cgit v1.1 From ac373f7e2286ed3690e8a93ebf9f6f1ae0c7d4a9 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 16:01:47 +0300 Subject: mtd/r852: update card detect early. This turns out to be the reason for DMA timeouts on resume, if card was inserted while system was suspended Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/r852.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 3f219e6..bcfc851 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -712,6 +712,7 @@ void r852_card_detect_work(struct work_struct *work) container_of(work, struct r852_device, card_detect_work.work); r852_card_update_present(dev); + r852_update_card_detect(dev); dev->card_unstable = 0; /* False alarm */ @@ -727,7 +728,6 @@ void r852_card_detect_work(struct work_struct *work) else r852_unregister_nand_device(dev); exit: - /* Update detection logic */ r852_update_card_detect(dev); } -- cgit v1.1 From 5869d2c387e75814334697c9d702d91b7c63a308 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 18:22:48 +0300 Subject: mtd: Fix NAND submenu Move MTD_NAND_ECC and MTD_NAND_ECC_SMC above NAND memuconfig, to unbreak display in xconfig. This shouldn't change any dependencies. Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/Kconfig | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 98a04b3..ffc3720 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,13 +1,3 @@ -menuconfig MTD_NAND - tristate "NAND Device Support" - depends on MTD - select MTD_NAND_IDS - select MTD_NAND_ECC - help - This enables support for accessing all type of NAND flash - devices. For further information see - . - config MTD_NAND_ECC tristate @@ -19,6 +9,17 @@ config MTD_NAND_ECC_SMC Software ECC according to the Smart Media Specification. The original Linux implementation had byte 0 and 1 swapped. + +menuconfig MTD_NAND + tristate "NAND Device Support" + depends on MTD + select MTD_NAND_IDS + select MTD_NAND_ECC + help + This enables support for accessing all type of NAND flash + devices. For further information see + . + if MTD_NAND config MTD_NAND_VERIFY_WRITE -- cgit v1.1