Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1054/?format=api
{ "id": 1054, "url": "http://patchwork.ozlabs.org/api/patches/1054/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-mtd/patch/20080923122601.GB15504@edgar.se.axis.com/", "project": { "id": 3, "url": "http://patchwork.ozlabs.org/api/projects/3/?format=api", "name": "Linux MTD development", "link_name": "linux-mtd", "list_id": "linux-mtd.lists.infradead.org", "list_email": "linux-mtd@lists.infradead.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20080923122601.GB15504@edgar.se.axis.com>", "list_archive_url": null, "date": "2008-09-23T12:26:01", "name": "[MTD] NAND: Add panic_write for NAND flashes", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "77fc021aaf4c64eb523034579f946dfbdd529c74", "submitter": { "id": 155, "url": "http://patchwork.ozlabs.org/api/people/155/?format=api", "name": "Edgar E. Iglesias", "email": "edgar.iglesias@axis.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-mtd/patch/20080923122601.GB15504@edgar.se.axis.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/1054/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1054/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Received": [ "from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34])\n\t(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\n\t(Client did not present a certificate)\n\tby ozlabs.org (Postfix) with ESMTPS id C8DC0DDDF4\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 23 Sep 2008 22:28:21 +1000 (EST)", "from localhost ([127.0.0.1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux))\n\tid 1Ki6yA-0007As-FN; Tue, 23 Sep 2008 12:26:18 +0000", "from bart.se.axis.com ([195.60.68.10])\n\tby bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux))\n\tid 1Ki6y7-0006yp-UL\n\tfor linux-mtd@lists.infradead.org; Tue, 23 Sep 2008 12:26:16 +0000", "from bart.se.axis.com (bart.se.axis.com [127.0.0.1])\n\tby bart.se.axis.com (Postfix) with ESMTP id 05F1A64025\n\tfor <linux-mtd@lists.infradead.org>;\n\tTue, 23 Sep 2008 14:26:02 +0200 (CEST)", "from axis.com (edgar.se.axis.com [10.93.151.1])\n\tby bart.se.axis.com (Postfix) with ESMTP id ED6E963EFC\n\tfor <linux-mtd@lists.infradead.org>;\n\tTue, 23 Sep 2008 14:26:01 +0200 (CEST)", "(qmail 27515 invoked by uid 400); 23 Sep 2008 12:26:01 -0000" ], "Date": "Tue, 23 Sep 2008 14:26:01 +0200", "From": "\"Edgar E. Iglesias\" <edgar.iglesias@axis.com>", "To": "linux-mtd@lists.infradead.org", "Subject": "[PATCH] [MTD] NAND: Add panic_write for NAND flashes", "Message-ID": "<20080923122601.GB15504@edgar.se.axis.com>", "MIME-Version": "1.0", "Content-Disposition": "inline", "User-Agent": "Mutt/1.5.16 (2007-06-09)", "X-Spam-Score": "0.0 (/)", "X-BeenThere": "linux-mtd@lists.infradead.org", "X-Mailman-Version": "2.1.9", "Precedence": "list", "List-Id": "Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>", "List-Unsubscribe": "<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n\t<mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/linux-mtd>", "List-Post": "<mailto:linux-mtd@lists.infradead.org>", "List-Help": "<mailto:linux-mtd-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n\t<mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "linux-mtd-bounces@lists.infradead.org", "Errors-To": "linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org" }, "content": "Hello,\n\nThis is a quick and dirty patch to add panic_write for NAND flashes.\nThe patch seems to work OK on my CRIS board running a 2.6.26 kernel\nwith a ID: 0x20, Chip ID: 0xf1 (ST Micro NAND 128MiB 3,3V 8-bit).\nAlso compile tested on a fresh x86 MTD git clone.\n\nIf you find it useful feel free to apply it, otherwise >/dev/null.\n\nThanks,\n\nSigned-off-by: Edgar E. Iglesias <edgar@axis.com>\n\n drivers/mtd/nand/nand_base.c | 129 +++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 121 insertions(+), 8 deletions(-)", "diff": "diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c\nindex 0a9c9cd..442a7de 100644\n--- a/drivers/mtd/nand/nand_base.c\n+++ b/drivers/mtd/nand/nand_base.c\n@@ -414,6 +414,28 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,\n \treturn nand_isbad_bbt(mtd, ofs, allowbbt);\n }\n \n+/**\n+ * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.\n+ * @mtd:\tMTD device structure\n+ * @timeo:\tTimeout\n+ *\n+ * Helper function for nand_wait_ready used when needing to wait in interrupt\n+ * context.\n+ */\n+static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)\n+{\n+\tstruct nand_chip *chip = mtd->priv;\n+\tint i;\n+\n+\t/* Give the device 400 ms to get ready?\t */\n+\tfor (i = 0; i < timeo; i++) {\n+\t\tif (chip->dev_ready(mtd))\n+\t\t\tbreak;\n+\t\ttouch_softlockup_watchdog();\n+\t\tmdelay(1);\n+\t}\n+}\n+\n /*\n * Wait for the ready pin, after a command\n * The timeout is catched later.\n@@ -423,6 +445,10 @@ void nand_wait_ready(struct mtd_info *mtd)\n \tstruct nand_chip *chip = mtd->priv;\n \tunsigned long timeo = jiffies + 2;\n \n+\t/* 400ms timeout? */\n+\tif (in_interrupt())\n+\t\treturn panic_nand_wait_ready(mtd, 400);\n+\n \tled_trigger_event(nand_led_trigger, LED_FULL);\n \t/* wait until command is processed or timeout occures */\n \tdo {\n@@ -658,6 +684,23 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,\n }\n \n /**\n+ * panic_nand_get_device - [GENERIC] Get chip for selected access\n+ * @chip:\tthe nand chip descriptor\n+ * @mtd:\tMTD device structure\n+ * @new_state:\tthe state which is requested\n+ *\n+ * Used when in panic, no locks are taken.\n+ */\n+static void\n+panic_nand_get_device(struct nand_chip *chip,\n+\t\t struct mtd_info *mtd, int new_state)\n+{\n+\t/* Hardware controller shared among independend devices */\n+\tchip->controller->active = chip;\n+\tchip->state = new_state;\n+}\n+\n+/**\n * nand_get_device - [GENERIC] Get chip for selected access\n * @chip:\tthe nand chip descriptor\n * @mtd:\tMTD device structure\n@@ -697,6 +740,32 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)\n }\n \n /**\n+ * panic_nand_wait - [GENERIC] wait until the command is done\n+ * @mtd:\tMTD device structure\n+ * @chip:\tNAND chip structure\n+ * @timeo:\tTimeout\n+ *\n+ * Wait for command done. This is a helper function for nand_wait used when\n+ * we are in interrupt context. May happen when in panic and trying to write\n+ * an oops trough mtdoops.\n+ */\n+static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,\n+\t\t\t unsigned long timeo)\n+{\n+\tint i;\n+\tfor (i = 0; i < timeo; i++) {\n+\t\tif (chip->dev_ready) {\n+\t\t\tif (chip->dev_ready(mtd))\n+\t\t\t\tbreak;\n+\t\t} else {\n+\t\t\tif (chip->read_byte(mtd) & NAND_STATUS_READY)\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tmdelay(1);\n+ }\n+}\n+\n+/**\n * nand_wait - [DEFAULT] wait until the command is done\n * @mtd:\tMTD device structure\n * @chip:\tNAND chip structure\n@@ -727,15 +796,19 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)\n \telse\n \t\tchip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);\n \n-\twhile (time_before(jiffies, timeo)) {\n-\t\tif (chip->dev_ready) {\n-\t\t\tif (chip->dev_ready(mtd))\n-\t\t\t\tbreak;\n-\t\t} else {\n-\t\t\tif (chip->read_byte(mtd) & NAND_STATUS_READY)\n-\t\t\t\tbreak;\n+\tif (in_interrupt())\n+\t\tpanic_nand_wait(mtd, chip, timeo);\n+\telse {\n+\t\twhile (time_before(jiffies, timeo)) {\n+\t\t\tif (chip->dev_ready) {\n+\t\t\t\tif (chip->dev_ready(mtd))\n+\t\t\t\t\tbreak;\n+\t\t\t} else {\n+\t\t\t\tif (chip->read_byte(mtd) & NAND_STATUS_READY)\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tcond_resched();\n \t\t}\n-\t\tcond_resched();\n \t}\n \tled_trigger_event(nand_led_trigger, LED_OFF);\n \n@@ -1797,6 +1870,45 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,\n }\n \n /**\n+ * panic_nand_write - [MTD Interface] NAND write with ECC\n+ * @mtd:\tMTD device structure\n+ * @to:\t\toffset to write to\n+ * @len:\tnumber of bytes to write\n+ * @retlen:\tpointer to variable to store the number of written bytes\n+ * @buf:\tthe data to write\n+ *\n+ * NAND write with ECC. Used when performing writes in interrupt context, this\n+ * may for example be called by mtdoops when writing an oops while in panic.\n+ */\n+static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,\n+\t\t\t size_t *retlen, const uint8_t *buf)\n+{\n+\tstruct nand_chip *chip = mtd->priv;\n+\tint ret;\n+\n+\t/* Do not allow reads past end of device */\n+\tif ((to + len) > mtd->size)\n+\t\treturn -EINVAL;\n+\tif (!len)\n+\t\treturn 0;\n+\n+\t/* Wait for the device to get ready. */\n+\tpanic_nand_wait(mtd, chip, 400);\n+\n+\t/* Grab the device. */\n+\tpanic_nand_get_device(chip, mtd, FL_WRITING);\n+\n+\tchip->ops.len = len;\n+\tchip->ops.datbuf = (uint8_t *)buf;\n+\tchip->ops.oobbuf = NULL;\n+\n+\tret = nand_do_write_ops(mtd, to, &chip->ops);\n+\n+\t*retlen = chip->ops.retlen;\n+\treturn ret;\n+}\n+\n+/**\n * nand_write - [MTD Interface] NAND write with ECC\n * @mtd:\tMTD device structure\n * @to:\t\toffset to write to\n@@ -2694,6 +2806,7 @@ int nand_scan_tail(struct mtd_info *mtd)\n \tmtd->unpoint = NULL;\n \tmtd->read = nand_read;\n \tmtd->write = nand_write;\n+\tmtd->panic_write = panic_nand_write;\n \tmtd->read_oob = nand_read_oob;\n \tmtd->write_oob = nand_write_oob;\n \tmtd->sync = nand_sync;\n", "prefixes": [ "MTD" ] }