aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-09 13:34:55 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-09 13:34:55 -0500
commit6e96783f586cc0a64651087cb518209a8577123f (patch)
tree8b74a5a8fda055ffeaa0c1ae3c070772599f8b3b /drivers
parent8466c833799b30ab343c5108cd2e460f9f16c9d8 (diff)
parent0feba829ee82a6e43baabe3f0bdf91bd937a67a1 (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: [JFFS2] print a message when marking bad block [JFFS2] Check for all-zero node headers [MTD] [OneNAND] Classify the page data and oob buffer [MTD] [OneNAND] Exit the loop when transferring/filling of the oob is finished [MTD] [OneNAND] add Nokia Copyright and a credit [MTD] [OneNAND] Fix typo & wrong comments [MTD] [OneNAND] Use oob buffer instead of main one in oob functions [MTD] Correct partition failed erase address [JFFS2] Use yield() between GC passes in background thread. [MTD] [NAND] Correct misspelled preprocessor variable. [MTD] [MAPS] dilnetpc: Fix printk warning [MTD] [NOR] Fix oops in cfi_amdstd_sync [MTD] ESB2 check for closed ROM window [JFFS2] Fix writebuffer recovery in the first page of a block [MTD] [NAND] make oobavail public
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c2
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c2
-rw-r--r--drivers/mtd/maps/dilnetpc.c4
-rw-r--r--drivers/mtd/maps/esb2rom.c11
-rw-r--r--drivers/mtd/mtdconcat.c1
-rw-r--r--drivers/mtd/mtdpart.c7
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/nand_base.c1
-rw-r--r--drivers/mtd/onenand/onenand_base.c77
9 files changed, 74 insertions, 33 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index e3acd398fb3..1f644584046 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -359,6 +359,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
359 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; 359 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
360 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 360 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
361 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 361 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
362 cfi->chips[i].ref_point_counter = 0;
363 init_waitqueue_head(&(cfi->chips[i].wq));
362 } 364 }
363 365
364 map->fldrv = &cfi_amdstd_chipdrv; 366 map->fldrv = &cfi_amdstd_chipdrv;
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 69d49e0250a..b344ff858b2 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -158,6 +158,8 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
158 cfi->chips[i].word_write_time = 128; 158 cfi->chips[i].word_write_time = 128;
159 cfi->chips[i].buffer_write_time = 128; 159 cfi->chips[i].buffer_write_time = 128;
160 cfi->chips[i].erase_time = 1024; 160 cfi->chips[i].erase_time = 1024;
161 cfi->chips[i].ref_point_counter = 0;
162 init_waitqueue_head(&(cfi->chips[i].wq));
161 } 163 }
162 164
163 return cfi_staa_setup(map); 165 return cfi_staa_setup(map);
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index b1104fe1f20..1c3b34ad732 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -402,8 +402,8 @@ static int __init init_dnpc(void)
402 ++higlvl_partition_info[i].name; 402 ++higlvl_partition_info[i].name;
403 } 403 }
404 404
405 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", 405 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%llx\n",
406 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys); 406 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, (unsigned long long)dnpc_map.phys);
407 407
408 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size); 408 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
409 409
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c
index 0bc013fd66a..aa64a475278 100644
--- a/drivers/mtd/maps/esb2rom.c
+++ b/drivers/mtd/maps/esb2rom.c
@@ -30,7 +30,7 @@
30 30
31#define ROM_PROBE_STEP_SIZE (64*1024) /* 64KiB */ 31#define ROM_PROBE_STEP_SIZE (64*1024) /* 64KiB */
32 32
33#define BIOS_CNTL 0xDC 33#define BIOS_CNTL 0xDC
34#define BIOS_LOCK_ENABLE 0x02 34#define BIOS_LOCK_ENABLE 0x02
35#define BIOS_WRITE_ENABLE 0x01 35#define BIOS_WRITE_ENABLE 0x01
36 36
@@ -145,7 +145,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window)
145} 145}
146 146
147static int __devinit esb2rom_init_one(struct pci_dev *pdev, 147static int __devinit esb2rom_init_one(struct pci_dev *pdev,
148 const struct pci_device_id *ent) 148 const struct pci_device_id *ent)
149{ 149{
150 static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; 150 static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
151 struct esb2rom_window *window = &esb2rom_window; 151 struct esb2rom_window *window = &esb2rom_window;
@@ -185,7 +185,7 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
185 /* Find a region continuous to the end of the ROM window */ 185 /* Find a region continuous to the end of the ROM window */
186 window->phys = 0; 186 window->phys = 0;
187 pci_read_config_word(pdev, FWH_DEC_EN1, &word); 187 pci_read_config_word(pdev, FWH_DEC_EN1, &word);
188 printk(KERN_DEBUG "pci_read_config_byte : %x\n", word); 188 printk(KERN_DEBUG "pci_read_config_word : %x\n", word);
189 189
190 if ((word & FWH_8MiB) == FWH_8MiB) 190 if ((word & FWH_8MiB) == FWH_8MiB)
191 window->phys = 0xff400000; 191 window->phys = 0xff400000;
@@ -212,6 +212,11 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
212 else if ((word & FWH_0_5MiB) == FWH_0_5MiB) 212 else if ((word & FWH_0_5MiB) == FWH_0_5MiB)
213 window->phys = 0xfff80000; 213 window->phys = 0xfff80000;
214 214
215 if (window->phys == 0) {
216 printk(KERN_ERR MOD_NAME ": Rom window is closed\n");
217 goto out;
218 }
219
215 /* reserved 0x0020 and 0x0010 */ 220 /* reserved 0x0020 and 0x0010 */
216 window->phys -= 0x400000UL; 221 window->phys -= 0x400000UL;
217 window->size = (0xffffffffUL - window->phys) + 1UL; 222 window->size = (0xffffffffUL - window->phys) + 1UL;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 880580c44e0..41844ea0246 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -727,6 +727,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
727 concat->mtd.erasesize = subdev[0]->erasesize; 727 concat->mtd.erasesize = subdev[0]->erasesize;
728 concat->mtd.writesize = subdev[0]->writesize; 728 concat->mtd.writesize = subdev[0]->writesize;
729 concat->mtd.oobsize = subdev[0]->oobsize; 729 concat->mtd.oobsize = subdev[0]->oobsize;
730 concat->mtd.oobavail = subdev[0]->oobavail;
730 if (subdev[0]->writev) 731 if (subdev[0]->writev)
731 concat->mtd.writev = concat_writev; 732 concat->mtd.writev = concat_writev;
732 if (subdev[0]->read_oob) 733 if (subdev[0]->read_oob)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 633def3fb08..1af989023c6 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -200,6 +200,11 @@ static int part_erase (struct mtd_info *mtd, struct erase_info *instr)
200 return -EINVAL; 200 return -EINVAL;
201 instr->addr += part->offset; 201 instr->addr += part->offset;
202 ret = part->master->erase(part->master, instr); 202 ret = part->master->erase(part->master, instr);
203 if (ret) {
204 if (instr->fail_addr != 0xffffffff)
205 instr->fail_addr -= part->offset;
206 instr->addr -= part->offset;
207 }
203 return ret; 208 return ret;
204} 209}
205 210
@@ -338,6 +343,7 @@ int add_mtd_partitions(struct mtd_info *master,
338 slave->mtd.size = parts[i].size; 343 slave->mtd.size = parts[i].size;
339 slave->mtd.writesize = master->writesize; 344 slave->mtd.writesize = master->writesize;
340 slave->mtd.oobsize = master->oobsize; 345 slave->mtd.oobsize = master->oobsize;
346 slave->mtd.oobavail = master->oobavail;
341 slave->mtd.subpage_sft = master->subpage_sft; 347 slave->mtd.subpage_sft = master->subpage_sft;
342 348
343 slave->mtd.name = parts[i].name; 349 slave->mtd.name = parts[i].name;
@@ -559,4 +565,3 @@ EXPORT_SYMBOL_GPL(deregister_mtd_parser);
559MODULE_LICENSE("GPL"); 565MODULE_LICENSE("GPL");
560MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>"); 566MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
561MODULE_DESCRIPTION("Generic support for partitioning of MTD devices"); 567MODULE_DESCRIPTION("Generic support for partitioning of MTD devices");
562
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 12608c13cce..595208f965a 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -114,7 +114,7 @@ module_param(no_autopart, int, 0);
114static int show_firmware_partition = 0; 114static int show_firmware_partition = 0;
115module_param(show_firmware_partition, int, 0); 115module_param(show_firmware_partition, int, 0);
116 116
117#ifdef MTD_NAND_DISKONCHIP_BBTWRITE 117#ifdef CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE
118static int inftl_bbt_write = 1; 118static int inftl_bbt_write = 1;
119#else 119#else
120static int inftl_bbt_write = 0; 120static int inftl_bbt_write = 0;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index acaf97bc80d..6af37b8cff6 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2524,6 +2524,7 @@ int nand_scan_tail(struct mtd_info *mtd)
2524 for (i = 0; chip->ecc.layout->oobfree[i].length; i++) 2524 for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
2525 chip->ecc.layout->oobavail += 2525 chip->ecc.layout->oobavail +=
2526 chip->ecc.layout->oobfree[i].length; 2526 chip->ecc.layout->oobfree[i].length;
2527 mtd->oobavail = chip->ecc.layout->oobavail;
2527 2528
2528 /* 2529 /*
2529 * Set the number of read / write steps for one page depending on ECC 2530 * Set the number of read / write steps for one page depending on ECC
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7f1cb6e5dcc..9e14a26ca4e 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -4,6 +4,11 @@
4 * Copyright (C) 2005-2007 Samsung Electronics 4 * Copyright (C) 2005-2007 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com> 5 * Kyungmin Park <kyungmin.park@samsung.com>
6 * 6 *
7 * Credits:
8 * Adrian Hunter <ext-adrian.hunter@nokia.com>:
9 * auto-placement support, read-while load support, various fixes
10 * Copyright (C) Nokia Corporation, 2007
11 *
7 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
@@ -831,7 +836,7 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
831 int readcol = column; 836 int readcol = column;
832 int readend = column + thislen; 837 int readend = column + thislen;
833 int lastgap = 0; 838 int lastgap = 0;
834 uint8_t *oob_buf = this->page_buf + mtd->writesize; 839 uint8_t *oob_buf = this->oob_buf;
835 840
836 for (free = this->ecclayout->oobfree; free->length; ++free) { 841 for (free = this->ecclayout->oobfree; free->length; ++free) {
837 if (readcol >= lastgap) 842 if (readcol >= lastgap)
@@ -849,7 +854,8 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
849 int n = ed - st; 854 int n = ed - st;
850 memcpy(buf, oob_buf + st, n); 855 memcpy(buf, oob_buf + st, n);
851 buf += n; 856 buf += n;
852 } 857 } else
858 break;
853 } 859 }
854 return 0; 860 return 0;
855} 861}
@@ -947,9 +953,9 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
947 953
948/** 954/**
949 * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band 955 * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
950 * @mtd: MTD device structure 956 * @param mtd: MTD device structure
951 * @from: offset to read from 957 * @param from: offset to read from
952 * @ops: oob operation description structure 958 * @param ops: oob operation description structure
953 */ 959 */
954static int onenand_read_oob(struct mtd_info *mtd, loff_t from, 960static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
955 struct mtd_oob_ops *ops) 961 struct mtd_oob_ops *ops)
@@ -1017,7 +1023,7 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1017 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan 1023 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
1018 * @param mtd MTD device structure 1024 * @param mtd MTD device structure
1019 * @param from offset to read from 1025 * @param from offset to read from
1020 * @param @ops oob operation description structure 1026 * @param ops oob operation description structure
1021 * 1027 *
1022 * OneNAND read out-of-band data from the spare area for bbt scan 1028 * OneNAND read out-of-band data from the spare area for bbt scan
1023 */ 1029 */
@@ -1093,7 +1099,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1093static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to) 1099static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
1094{ 1100{
1095 struct onenand_chip *this = mtd->priv; 1101 struct onenand_chip *this = mtd->priv;
1096 char *readp = this->page_buf + mtd->writesize; 1102 char oobbuf[64];
1097 int status, i; 1103 int status, i;
1098 1104
1099 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); 1105 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -1102,9 +1108,9 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
1102 if (status) 1108 if (status)
1103 return status; 1109 return status;
1104 1110
1105 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize); 1111 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1106 for(i = 0; i < mtd->oobsize; i++) 1112 for (i = 0; i < mtd->oobsize; i++)
1107 if (buf[i] != 0xFF && buf[i] != readp[i]) 1113 if (buf[i] != 0xFF && buf[i] != oobbuf[i])
1108 return -EBADMSG; 1114 return -EBADMSG;
1109 1115
1110 return 0; 1116 return 0;
@@ -1290,7 +1296,8 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1290 int n = ed - st; 1296 int n = ed - st;
1291 memcpy(oob_buf + st, buf, n); 1297 memcpy(oob_buf + st, buf, n);
1292 buf += n; 1298 buf += n;
1293 } 1299 } else
1300 break;
1294 } 1301 }
1295 return 0; 1302 return 0;
1296} 1303}
@@ -1312,6 +1319,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1312 struct onenand_chip *this = mtd->priv; 1319 struct onenand_chip *this = mtd->priv;
1313 int column, ret = 0, oobsize; 1320 int column, ret = 0, oobsize;
1314 int written = 0; 1321 int written = 0;
1322 u_char *oobbuf;
1315 1323
1316 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1324 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1317 1325
@@ -1331,7 +1339,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1331 } 1339 }
1332 1340
1333 /* For compatibility with NAND: Do not allow write past end of page */ 1341 /* For compatibility with NAND: Do not allow write past end of page */
1334 if (column + len > oobsize) { 1342 if (unlikely(column + len > oobsize)) {
1335 printk(KERN_ERR "onenand_write_oob: " 1343 printk(KERN_ERR "onenand_write_oob: "
1336 "Attempt to write past end of page\n"); 1344 "Attempt to write past end of page\n");
1337 return -EINVAL; 1345 return -EINVAL;
@@ -1348,6 +1356,8 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1348 /* Grab the lock and see if the device is available */ 1356 /* Grab the lock and see if the device is available */
1349 onenand_get_device(mtd, FL_WRITING); 1357 onenand_get_device(mtd, FL_WRITING);
1350 1358
1359 oobbuf = this->oob_buf;
1360
1351 /* Loop until all data write */ 1361 /* Loop until all data write */
1352 while (written < len) { 1362 while (written < len) {
1353 int thislen = min_t(int, oobsize, len - written); 1363 int thislen = min_t(int, oobsize, len - written);
@@ -1358,12 +1368,12 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1358 1368
1359 /* We send data to spare ram with oobsize 1369 /* We send data to spare ram with oobsize
1360 * to prevent byte access */ 1370 * to prevent byte access */
1361 memset(this->page_buf, 0xff, mtd->oobsize); 1371 memset(oobbuf, 0xff, mtd->oobsize);
1362 if (mode == MTD_OOB_AUTO) 1372 if (mode == MTD_OOB_AUTO)
1363 onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen); 1373 onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
1364 else 1374 else
1365 memcpy(this->page_buf + column, buf, thislen); 1375 memcpy(oobbuf + column, buf, thislen);
1366 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize); 1376 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1367 1377
1368 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 1378 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
1369 1379
@@ -1375,7 +1385,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1375 break; 1385 break;
1376 } 1386 }
1377 1387
1378 ret = onenand_verify_oob(mtd, this->page_buf, to); 1388 ret = onenand_verify_oob(mtd, oobbuf, to);
1379 if (ret) { 1389 if (ret) {
1380 printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret); 1390 printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
1381 break; 1391 break;
@@ -1400,9 +1410,9 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1400 1410
1401/** 1411/**
1402 * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band 1412 * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
1403 * @mtd: MTD device structure 1413 * @param mtd: MTD device structure
1404 * @from: offset to read from 1414 * @param to: offset to write
1405 * @ops: oob operation description structure 1415 * @param ops: oob operation description structure
1406 */ 1416 */
1407static int onenand_write_oob(struct mtd_info *mtd, loff_t to, 1417static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1408 struct mtd_oob_ops *ops) 1418 struct mtd_oob_ops *ops)
@@ -1616,6 +1626,7 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1616 * @param mtd MTD device structure 1626 * @param mtd MTD device structure
1617 * @param ofs offset relative to mtd start 1627 * @param ofs offset relative to mtd start
1618 * @param len number of bytes to lock or unlock 1628 * @param len number of bytes to lock or unlock
1629 * @param cmd lock or unlock command
1619 * 1630 *
1620 * Lock or unlock one or more blocks 1631 * Lock or unlock one or more blocks
1621 */ 1632 */
@@ -2117,10 +2128,11 @@ static void onenand_check_features(struct mtd_info *mtd)
2117} 2128}
2118 2129
2119/** 2130/**
2120 * onenand_print_device_info - Print device ID 2131 * onenand_print_device_info - Print device & version ID
2121 * @param device device ID 2132 * @param device device ID
2133 * @param version version ID
2122 * 2134 *
2123 * Print device ID 2135 * Print device & version ID
2124 */ 2136 */
2125static void onenand_print_device_info(int device, int version) 2137static void onenand_print_device_info(int device, int version)
2126{ 2138{
@@ -2320,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2320 2332
2321 /* Allocate buffers, if necessary */ 2333 /* Allocate buffers, if necessary */
2322 if (!this->page_buf) { 2334 if (!this->page_buf) {
2323 size_t len; 2335 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
2324 len = mtd->writesize + mtd->oobsize;
2325 this->page_buf = kmalloc(len, GFP_KERNEL);
2326 if (!this->page_buf) { 2336 if (!this->page_buf) {
2327 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); 2337 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
2328 return -ENOMEM; 2338 return -ENOMEM;
2329 } 2339 }
2330 this->options |= ONENAND_PAGEBUF_ALLOC; 2340 this->options |= ONENAND_PAGEBUF_ALLOC;
2331 } 2341 }
2342 if (!this->oob_buf) {
2343 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
2344 if (!this->oob_buf) {
2345 printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n");
2346 if (this->options & ONENAND_PAGEBUF_ALLOC) {
2347 this->options &= ~ONENAND_PAGEBUF_ALLOC;
2348 kfree(this->page_buf);
2349 }
2350 return -ENOMEM;
2351 }
2352 this->options |= ONENAND_OOBBUF_ALLOC;
2353 }
2332 2354
2333 this->state = FL_READY; 2355 this->state = FL_READY;
2334 init_waitqueue_head(&this->wq); 2356 init_waitqueue_head(&this->wq);
@@ -2367,6 +2389,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2367 for (i = 0; this->ecclayout->oobfree[i].length; i++) 2389 for (i = 0; this->ecclayout->oobfree[i].length; i++)
2368 this->ecclayout->oobavail += 2390 this->ecclayout->oobavail +=
2369 this->ecclayout->oobfree[i].length; 2391 this->ecclayout->oobfree[i].length;
2392 mtd->oobavail = this->ecclayout->oobavail;
2370 2393
2371 mtd->ecclayout = this->ecclayout; 2394 mtd->ecclayout = this->ecclayout;
2372 2395
@@ -2424,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd)
2424 kfree(bbm->bbt); 2447 kfree(bbm->bbt);
2425 kfree(this->bbm); 2448 kfree(this->bbm);
2426 } 2449 }
2427 /* Buffer allocated by onenand_scan */ 2450 /* Buffers allocated by onenand_scan */
2428 if (this->options & ONENAND_PAGEBUF_ALLOC) 2451 if (this->options & ONENAND_PAGEBUF_ALLOC)
2429 kfree(this->page_buf); 2452 kfree(this->page_buf);
2453 if (this->options & ONENAND_OOBBUF_ALLOC)
2454 kfree(this->oob_buf);
2430} 2455}
2431 2456
2432EXPORT_SYMBOL_GPL(onenand_scan); 2457EXPORT_SYMBOL_GPL(onenand_scan);