diff options
author | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-05-23 05:54:38 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-05-23 05:54:38 -0400 |
commit | 7aa65bfd6793a56cc3bbce8436abbfea3a7bdd1f (patch) | |
tree | 1f87d2645b888a838c0fac90da148170d4c8cd63 /drivers/mtd/nand | |
parent | 58dd8f2bfdcad1b219a4a92a2aadd8ea8c819f79 (diff) |
[MTD] NAND cleanup nand_scan
Seperate functionality out of nand_scan so the code is more
readable. No functional change. First step of simplifying
the nand driver.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 407 |
1 files changed, 233 insertions, 174 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index afa77d1ed900..37db98a58c34 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -76,6 +76,7 @@ | |||
76 | #include <linux/module.h> | 76 | #include <linux/module.h> |
77 | #include <linux/delay.h> | 77 | #include <linux/delay.h> |
78 | #include <linux/errno.h> | 78 | #include <linux/errno.h> |
79 | #include <linux/err.h> | ||
79 | #include <linux/sched.h> | 80 | #include <linux/sched.h> |
80 | #include <linux/slab.h> | 81 | #include <linux/slab.h> |
81 | #include <linux/types.h> | 82 | #include <linux/types.h> |
@@ -2333,42 +2334,50 @@ static void nand_free_kmem(struct nand_chip *this) | |||
2333 | kfree(this->controller); | 2334 | kfree(this->controller); |
2334 | } | 2335 | } |
2335 | 2336 | ||
2336 | /* module_text_address() isn't exported, and it's mostly a pointless | 2337 | /* |
2337 | test if this is a module _anyway_ -- they'd have to try _really_ hard | 2338 | * Allocate buffers and data structures |
2338 | to call us from in-kernel code if the core NAND support is modular. */ | ||
2339 | #ifdef MODULE | ||
2340 | #define caller_is_module() (1) | ||
2341 | #else | ||
2342 | #define caller_is_module() module_text_address((unsigned long)__builtin_return_address(0)) | ||
2343 | #endif | ||
2344 | |||
2345 | /** | ||
2346 | * nand_scan - [NAND Interface] Scan for the NAND device | ||
2347 | * @mtd: MTD device structure | ||
2348 | * @maxchips: Number of chips to scan for | ||
2349 | * | ||
2350 | * This fills out all the uninitialized function pointers | ||
2351 | * with the defaults. | ||
2352 | * The flash ID is read and the mtd/chip structures are | ||
2353 | * filled with the appropriate values. Buffers are allocated if | ||
2354 | * they are not provided by the board driver | ||
2355 | * The mtd->owner field must be set to the module of the caller | ||
2356 | * | ||
2357 | */ | 2339 | */ |
2358 | int nand_scan(struct mtd_info *mtd, int maxchips) | 2340 | static int nand_allocate_kmem(struct mtd_info *mtd, struct nand_chip *this) |
2359 | { | 2341 | { |
2360 | int i, nand_maf_id, nand_dev_id, busw, maf_id; | 2342 | size_t len; |
2361 | struct nand_chip *this = mtd->priv; | ||
2362 | 2343 | ||
2363 | /* Many callers got this wrong, so check for it for a while... */ | 2344 | if (!this->oob_buf) { |
2364 | if (!mtd->owner && caller_is_module()) { | 2345 | len = mtd->oobsize << |
2365 | printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); | 2346 | (this->phys_erase_shift - this->page_shift); |
2366 | BUG(); | 2347 | this->oob_buf = kmalloc(len, GFP_KERNEL); |
2348 | if (!this->oob_buf) | ||
2349 | goto outerr; | ||
2350 | this->options |= NAND_OOBBUF_ALLOC; | ||
2367 | } | 2351 | } |
2368 | 2352 | ||
2369 | /* Get buswidth to select the correct functions */ | 2353 | if (!this->data_buf) { |
2370 | busw = this->options & NAND_BUSWIDTH_16; | 2354 | len = mtd->oobblock + mtd->oobsize; |
2355 | this->data_buf = kmalloc(len, GFP_KERNEL); | ||
2356 | if (!this->data_buf) | ||
2357 | goto outerr; | ||
2358 | this->options |= NAND_DATABUF_ALLOC; | ||
2359 | } | ||
2371 | 2360 | ||
2361 | if (!this->controller) { | ||
2362 | this->controller = kzalloc(sizeof(struct nand_hw_control), | ||
2363 | GFP_KERNEL); | ||
2364 | if (!this->controller) | ||
2365 | goto outerr; | ||
2366 | this->options |= NAND_CONTROLLER_ALLOC; | ||
2367 | } | ||
2368 | return 0; | ||
2369 | |||
2370 | outerr: | ||
2371 | printk(KERN_ERR "nand_scan(): Cannot allocate buffers\n"); | ||
2372 | nand_free_kmem(this); | ||
2373 | return -ENOMEM; | ||
2374 | } | ||
2375 | |||
2376 | /* | ||
2377 | * Set default functions | ||
2378 | */ | ||
2379 | static void nand_set_defaults(struct nand_chip *this, int busw) | ||
2380 | { | ||
2372 | /* check for proper chip_delay setup, set 20us if not */ | 2381 | /* check for proper chip_delay setup, set 20us if not */ |
2373 | if (!this->chip_delay) | 2382 | if (!this->chip_delay) |
2374 | this->chip_delay = 20; | 2383 | this->chip_delay = 20; |
@@ -2403,6 +2412,17 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2403 | this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; | 2412 | this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; |
2404 | if (!this->scan_bbt) | 2413 | if (!this->scan_bbt) |
2405 | this->scan_bbt = nand_default_bbt; | 2414 | this->scan_bbt = nand_default_bbt; |
2415 | } | ||
2416 | |||
2417 | /* | ||
2418 | * Get the flash and manufacturer id and lookup if the typ is supported | ||
2419 | */ | ||
2420 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | ||
2421 | struct nand_chip *this, | ||
2422 | int busw, int *maf_id) | ||
2423 | { | ||
2424 | struct nand_flash_dev *type = NULL; | ||
2425 | int i, dev_id, maf_idx; | ||
2406 | 2426 | ||
2407 | /* Select the device */ | 2427 | /* Select the device */ |
2408 | this->select_chip(mtd, 0); | 2428 | this->select_chip(mtd, 0); |
@@ -2411,158 +2431,194 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2411 | this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 2431 | this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2412 | 2432 | ||
2413 | /* Read manufacturer and device IDs */ | 2433 | /* Read manufacturer and device IDs */ |
2414 | nand_maf_id = this->read_byte(mtd); | 2434 | *maf_id = this->read_byte(mtd); |
2415 | nand_dev_id = this->read_byte(mtd); | 2435 | dev_id = this->read_byte(mtd); |
2416 | 2436 | ||
2417 | /* Print and store flash device information */ | 2437 | /* Lookup the flash id */ |
2418 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { | 2438 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { |
2439 | if (dev_id == nand_flash_ids[i].id) { | ||
2440 | type = &nand_flash_ids[i]; | ||
2441 | break; | ||
2442 | } | ||
2443 | } | ||
2419 | 2444 | ||
2420 | if (nand_dev_id != nand_flash_ids[i].id) | 2445 | if (!type) |
2421 | continue; | 2446 | return ERR_PTR(-ENODEV); |
2422 | 2447 | ||
2423 | if (!mtd->name) | 2448 | this->chipsize = nand_flash_ids[i].chipsize << 20; |
2424 | mtd->name = nand_flash_ids[i].name; | 2449 | |
2425 | this->chipsize = nand_flash_ids[i].chipsize << 20; | 2450 | /* Newer devices have all the information in additional id bytes */ |
2426 | 2451 | if (!nand_flash_ids[i].pagesize) { | |
2427 | /* New devices have all the information in additional id bytes */ | 2452 | int extid; |
2428 | if (!nand_flash_ids[i].pagesize) { | 2453 | /* The 3rd id byte contains non relevant data ATM */ |
2429 | int extid; | 2454 | extid = this->read_byte(mtd); |
2430 | /* The 3rd id byte contains non relevant data ATM */ | 2455 | /* The 4th id byte is the important one */ |
2431 | extid = this->read_byte(mtd); | 2456 | extid = this->read_byte(mtd); |
2432 | /* The 4th id byte is the important one */ | 2457 | /* Calc pagesize */ |
2433 | extid = this->read_byte(mtd); | 2458 | mtd->oobblock = 1024 << (extid & 0x3); |
2434 | /* Calc pagesize */ | 2459 | extid >>= 2; |
2435 | mtd->oobblock = 1024 << (extid & 0x3); | 2460 | /* Calc oobsize */ |
2436 | extid >>= 2; | 2461 | mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9); |
2437 | /* Calc oobsize */ | 2462 | extid >>= 2; |
2438 | mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9); | 2463 | /* Calc blocksize. Blocksize is multiples of 64KiB */ |
2439 | extid >>= 2; | 2464 | mtd->erasesize = (64 * 1024) << (extid & 0x03); |
2440 | /* Calc blocksize. Blocksize is multiples of 64KiB */ | 2465 | extid >>= 2; |
2441 | mtd->erasesize = (64 * 1024) << (extid & 0x03); | 2466 | /* Get buswidth information */ |
2442 | extid >>= 2; | 2467 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; |
2443 | /* Get buswidth information */ | ||
2444 | busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; | ||
2445 | 2468 | ||
2446 | } else { | 2469 | } else { |
2447 | /* Old devices have this data hardcoded in the | 2470 | /* |
2448 | * device id table */ | 2471 | * Old devices have this data hardcoded in the device id table |
2449 | mtd->erasesize = nand_flash_ids[i].erasesize; | 2472 | */ |
2450 | mtd->oobblock = nand_flash_ids[i].pagesize; | 2473 | mtd->erasesize = nand_flash_ids[i].erasesize; |
2451 | mtd->oobsize = mtd->oobblock / 32; | 2474 | mtd->oobblock = nand_flash_ids[i].pagesize; |
2452 | busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16; | 2475 | mtd->oobsize = mtd->oobblock / 32; |
2453 | } | 2476 | busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16; |
2477 | } | ||
2454 | 2478 | ||
2455 | /* Try to identify manufacturer */ | 2479 | /* Try to identify manufacturer */ |
2456 | for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) { | 2480 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_id++) { |
2457 | if (nand_manuf_ids[maf_id].id == nand_maf_id) | 2481 | if (nand_manuf_ids[maf_idx].id == *maf_id) |
2458 | break; | 2482 | break; |
2459 | } | 2483 | } |
2460 | 2484 | ||
2461 | /* Check, if buswidth is correct. Hardware drivers should set | 2485 | /* |
2462 | * this correct ! */ | 2486 | * Check, if buswidth is correct. Hardware drivers should set |
2463 | if (busw != (this->options & NAND_BUSWIDTH_16)) { | 2487 | * this correct ! |
2464 | printk(KERN_INFO "NAND device: Manufacturer ID:" | 2488 | */ |
2465 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, | 2489 | if (busw != (this->options & NAND_BUSWIDTH_16)) { |
2466 | nand_manuf_ids[maf_id].name, mtd->name); | 2490 | printk(KERN_INFO "NAND device: Manufacturer ID:" |
2467 | printk(KERN_WARNING | 2491 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, |
2468 | "NAND bus width %d instead %d bit\n", | 2492 | dev_id, nand_manuf_ids[maf_idx].name, mtd->name); |
2469 | (this->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8); | 2493 | printk(KERN_WARNING "NAND bus width %d instead %d bit\n", |
2470 | this->select_chip(mtd, -1); | 2494 | (this->options & NAND_BUSWIDTH_16) ? 16 : 8, |
2471 | return 1; | 2495 | busw ? 16 : 8); |
2472 | } | 2496 | return ERR_PTR(-EINVAL); |
2497 | } | ||
2473 | 2498 | ||
2474 | /* Calculate the address shift from the page size */ | 2499 | /* Calculate the address shift from the page size */ |
2475 | this->page_shift = ffs(mtd->oobblock) - 1; | 2500 | this->page_shift = ffs(mtd->oobblock) - 1; |
2476 | this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; | 2501 | /* Convert chipsize to number of pages per chip -1. */ |
2477 | this->chip_shift = ffs(this->chipsize) - 1; | 2502 | this->pagemask = (this->chipsize >> this->page_shift) - 1; |
2478 | |||
2479 | /* Set the bad block position */ | ||
2480 | this->badblockpos = mtd->oobblock > 512 ? NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; | ||
2481 | |||
2482 | /* Get chip options, preserve non chip based options */ | ||
2483 | this->options &= ~NAND_CHIPOPTIONS_MSK; | ||
2484 | this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK; | ||
2485 | /* Set this as a default. Board drivers can override it, if necessary */ | ||
2486 | this->options |= NAND_NO_AUTOINCR; | ||
2487 | /* Check if this is a not a samsung device. Do not clear the options | ||
2488 | * for chips which are not having an extended id. | ||
2489 | */ | ||
2490 | if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) | ||
2491 | this->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
2492 | 2503 | ||
2493 | /* Check for AND chips with 4 page planes */ | 2504 | this->bbt_erase_shift = this->phys_erase_shift = |
2494 | if (this->options & NAND_4PAGE_ARRAY) | 2505 | ffs(mtd->erasesize) - 1; |
2495 | this->erase_cmd = multi_erase_cmd; | 2506 | this->chip_shift = ffs(this->chipsize) - 1; |
2496 | else | ||
2497 | this->erase_cmd = single_erase_cmd; | ||
2498 | 2507 | ||
2499 | /* Do not replace user supplied command function ! */ | 2508 | /* Set the bad block position */ |
2500 | if (mtd->oobblock > 512 && this->cmdfunc == nand_command) | 2509 | this->badblockpos = mtd->oobblock > 512 ? |
2501 | this->cmdfunc = nand_command_lp; | 2510 | NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; |
2502 | 2511 | ||
2503 | printk(KERN_INFO "NAND device: Manufacturer ID:" | 2512 | /* Get chip options, preserve non chip based options */ |
2504 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, | 2513 | this->options &= ~NAND_CHIPOPTIONS_MSK; |
2505 | nand_manuf_ids[maf_id].name, nand_flash_ids[i].name); | 2514 | this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK; |
2506 | break; | 2515 | |
2516 | /* | ||
2517 | * Set this as a default. Board drivers can override it, if necessary | ||
2518 | */ | ||
2519 | this->options |= NAND_NO_AUTOINCR; | ||
2520 | |||
2521 | /* Check if this is a not a samsung device. Do not clear the | ||
2522 | * options for chips which are not having an extended id. | ||
2523 | */ | ||
2524 | if (*maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) | ||
2525 | this->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
2526 | |||
2527 | /* Check for AND chips with 4 page planes */ | ||
2528 | if (this->options & NAND_4PAGE_ARRAY) | ||
2529 | this->erase_cmd = multi_erase_cmd; | ||
2530 | else | ||
2531 | this->erase_cmd = single_erase_cmd; | ||
2532 | |||
2533 | /* Do not replace user supplied command function ! */ | ||
2534 | if (mtd->oobblock > 512 && this->cmdfunc == nand_command) | ||
2535 | this->cmdfunc = nand_command_lp; | ||
2536 | |||
2537 | printk(KERN_INFO "NAND device: Manufacturer ID:" | ||
2538 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, | ||
2539 | nand_manuf_ids[maf_idx].name, type->name); | ||
2540 | |||
2541 | return type; | ||
2542 | } | ||
2543 | |||
2544 | /* module_text_address() isn't exported, and it's mostly a pointless | ||
2545 | test if this is a module _anyway_ -- they'd have to try _really_ hard | ||
2546 | to call us from in-kernel code if the core NAND support is modular. */ | ||
2547 | #ifdef MODULE | ||
2548 | #define caller_is_module() (1) | ||
2549 | #else | ||
2550 | #define caller_is_module() \ | ||
2551 | module_text_address((unsigned long)__builtin_return_address(0)) | ||
2552 | #endif | ||
2553 | |||
2554 | /** | ||
2555 | * nand_scan - [NAND Interface] Scan for the NAND device | ||
2556 | * @mtd: MTD device structure | ||
2557 | * @maxchips: Number of chips to scan for | ||
2558 | * | ||
2559 | * This fills out all the uninitialized function pointers | ||
2560 | * with the defaults. | ||
2561 | * The flash ID is read and the mtd/chip structures are | ||
2562 | * filled with the appropriate values. Buffers are allocated if | ||
2563 | * they are not provided by the board driver | ||
2564 | * The mtd->owner field must be set to the module of the caller | ||
2565 | * | ||
2566 | */ | ||
2567 | int nand_scan(struct mtd_info *mtd, int maxchips) | ||
2568 | { | ||
2569 | int i, busw, nand_maf_id; | ||
2570 | struct nand_chip *this = mtd->priv; | ||
2571 | struct nand_flash_dev *type; | ||
2572 | |||
2573 | /* Many callers got this wrong, so check for it for a while... */ | ||
2574 | if (!mtd->owner && caller_is_module()) { | ||
2575 | printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); | ||
2576 | BUG(); | ||
2507 | } | 2577 | } |
2508 | 2578 | ||
2509 | if (!nand_flash_ids[i].name) { | 2579 | /* Get buswidth to select the correct functions */ |
2580 | busw = this->options & NAND_BUSWIDTH_16; | ||
2581 | /* Set the default functions */ | ||
2582 | nand_set_defaults(this, busw); | ||
2583 | |||
2584 | /* Read the flash type */ | ||
2585 | type = nand_get_flash_type(mtd, this, busw, &nand_maf_id); | ||
2586 | |||
2587 | if (IS_ERR(type)) { | ||
2510 | printk(KERN_WARNING "No NAND device found!!!\n"); | 2588 | printk(KERN_WARNING "No NAND device found!!!\n"); |
2511 | this->select_chip(mtd, -1); | 2589 | this->select_chip(mtd, -1); |
2512 | return 1; | 2590 | return PTR_ERR(type); |
2513 | } | 2591 | } |
2514 | 2592 | ||
2593 | /* Check for a chip array */ | ||
2515 | for (i = 1; i < maxchips; i++) { | 2594 | for (i = 1; i < maxchips; i++) { |
2516 | this->select_chip(mtd, i); | 2595 | this->select_chip(mtd, i); |
2517 | |||
2518 | /* Send the command for reading device ID */ | 2596 | /* Send the command for reading device ID */ |
2519 | this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 2597 | this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2520 | |||
2521 | /* Read manufacturer and device IDs */ | 2598 | /* Read manufacturer and device IDs */ |
2522 | if (nand_maf_id != this->read_byte(mtd) || | 2599 | if (nand_maf_id != this->read_byte(mtd) || |
2523 | nand_dev_id != this->read_byte(mtd)) | 2600 | type->id != this->read_byte(mtd)) |
2524 | break; | 2601 | break; |
2525 | } | 2602 | } |
2526 | if (i > 1) | 2603 | if (i > 1) |
2527 | printk(KERN_INFO "%d NAND chips detected\n", i); | 2604 | printk(KERN_INFO "%d NAND chips detected\n", i); |
2528 | 2605 | ||
2529 | /* Allocate buffers, if necessary */ | ||
2530 | if (!this->oob_buf) { | ||
2531 | size_t len; | ||
2532 | len = mtd->oobsize << (this->phys_erase_shift - this->page_shift); | ||
2533 | this->oob_buf = kmalloc(len, GFP_KERNEL); | ||
2534 | if (!this->oob_buf) { | ||
2535 | printk(KERN_ERR "nand_scan(): Cannot allocate oob_buf\n"); | ||
2536 | return -ENOMEM; | ||
2537 | } | ||
2538 | this->options |= NAND_OOBBUF_ALLOC; | ||
2539 | } | ||
2540 | |||
2541 | if (!this->data_buf) { | ||
2542 | size_t len; | ||
2543 | len = mtd->oobblock + mtd->oobsize; | ||
2544 | this->data_buf = kmalloc(len, GFP_KERNEL); | ||
2545 | if (!this->data_buf) { | ||
2546 | printk(KERN_ERR "nand_scan(): Cannot allocate data_buf\n"); | ||
2547 | nand_free_kmem(this); | ||
2548 | return -ENOMEM; | ||
2549 | } | ||
2550 | this->options |= NAND_DATABUF_ALLOC; | ||
2551 | } | ||
2552 | |||
2553 | /* Store the number of chips and calc total size for mtd */ | 2606 | /* Store the number of chips and calc total size for mtd */ |
2554 | this->numchips = i; | 2607 | this->numchips = i; |
2555 | mtd->size = i * this->chipsize; | 2608 | mtd->size = i * this->chipsize; |
2556 | /* Convert chipsize to number of pages per chip -1. */ | 2609 | |
2557 | this->pagemask = (this->chipsize >> this->page_shift) - 1; | 2610 | /* Allocate buffers and data structures */ |
2611 | if (nand_allocate_kmem(mtd, this)) | ||
2612 | return -ENOMEM; | ||
2613 | |||
2558 | /* Preset the internal oob buffer */ | 2614 | /* Preset the internal oob buffer */ |
2559 | memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift)); | 2615 | memset(this->oob_buf, 0xff, |
2616 | mtd->oobsize << (this->phys_erase_shift - this->page_shift)); | ||
2560 | 2617 | ||
2561 | /* If no default placement scheme is given, select an | 2618 | /* |
2562 | * appropriate one */ | 2619 | * If no default placement scheme is given, select an appropriate one |
2620 | */ | ||
2563 | if (!this->autooob) { | 2621 | if (!this->autooob) { |
2564 | /* Select the appropriate default oob placement scheme for | ||
2565 | * placement agnostic filesystems */ | ||
2566 | switch (mtd->oobsize) { | 2622 | switch (mtd->oobsize) { |
2567 | case 8: | 2623 | case 8: |
2568 | this->autooob = &nand_oob_8; | 2624 | this->autooob = &nand_oob_8; |
@@ -2574,29 +2630,32 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2574 | this->autooob = &nand_oob_64; | 2630 | this->autooob = &nand_oob_64; |
2575 | break; | 2631 | break; |
2576 | default: | 2632 | default: |
2577 | printk(KERN_WARNING "No oob scheme defined for oobsize %d\n", mtd->oobsize); | 2633 | printk(KERN_WARNING "No oob scheme defined for " |
2634 | "oobsize %d\n", mtd->oobsize); | ||
2578 | BUG(); | 2635 | BUG(); |
2579 | } | 2636 | } |
2580 | } | 2637 | } |
2581 | 2638 | ||
2582 | /* The number of bytes available for the filesystem to place fs dependend | 2639 | /* |
2583 | * oob data */ | 2640 | * The number of bytes available for the filesystem to place fs |
2641 | * dependend oob data | ||
2642 | */ | ||
2584 | mtd->oobavail = 0; | 2643 | mtd->oobavail = 0; |
2585 | for (i = 0; this->autooob->oobfree[i][1]; i++) | 2644 | for (i = 0; this->autooob->oobfree[i][1]; i++) |
2586 | mtd->oobavail += this->autooob->oobfree[i][1]; | 2645 | mtd->oobavail += this->autooob->oobfree[i][1]; |
2587 | 2646 | ||
2588 | /* | 2647 | /* |
2589 | * check ECC mode, default to software | 2648 | * check ECC mode, default to software if 3byte/512byte hardware ECC is |
2590 | * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize | 2649 | * selected and we have 256 byte pagesize fallback to software ECC |
2591 | * fallback to software ECC | ||
2592 | */ | 2650 | */ |
2593 | this->eccsize = 256; /* set default eccsize */ | 2651 | this->eccsize = 256; |
2594 | this->eccbytes = 3; | 2652 | this->eccbytes = 3; |
2595 | 2653 | ||
2596 | switch (this->eccmode) { | 2654 | switch (this->eccmode) { |
2597 | case NAND_ECC_HW12_2048: | 2655 | case NAND_ECC_HW12_2048: |
2598 | if (mtd->oobblock < 2048) { | 2656 | if (mtd->oobblock < 2048) { |
2599 | printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", | 2657 | printk(KERN_WARNING "2048 byte HW ECC not possible on " |
2658 | "%d byte page size, fallback to SW ECC\n", | ||
2600 | mtd->oobblock); | 2659 | mtd->oobblock); |
2601 | this->eccmode = NAND_ECC_SOFT; | 2660 | this->eccmode = NAND_ECC_SOFT; |
2602 | this->calculate_ecc = nand_calculate_ecc; | 2661 | this->calculate_ecc = nand_calculate_ecc; |
@@ -2609,7 +2668,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2609 | case NAND_ECC_HW6_512: | 2668 | case NAND_ECC_HW6_512: |
2610 | case NAND_ECC_HW8_512: | 2669 | case NAND_ECC_HW8_512: |
2611 | if (mtd->oobblock == 256) { | 2670 | if (mtd->oobblock == 256) { |
2612 | printk(KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); | 2671 | printk(KERN_WARNING "512 byte HW ECC not possible on " |
2672 | "256 Byte pagesize, fallback to SW ECC \n"); | ||
2613 | this->eccmode = NAND_ECC_SOFT; | 2673 | this->eccmode = NAND_ECC_SOFT; |
2614 | this->calculate_ecc = nand_calculate_ecc; | 2674 | this->calculate_ecc = nand_calculate_ecc; |
2615 | this->correct_data = nand_correct_data; | 2675 | this->correct_data = nand_correct_data; |
@@ -2621,7 +2681,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2621 | break; | 2681 | break; |
2622 | 2682 | ||
2623 | case NAND_ECC_NONE: | 2683 | case NAND_ECC_NONE: |
2624 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); | 2684 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " |
2685 | "This is not recommended !!\n"); | ||
2625 | this->eccmode = NAND_ECC_NONE; | 2686 | this->eccmode = NAND_ECC_NONE; |
2626 | break; | 2687 | break; |
2627 | 2688 | ||
@@ -2631,12 +2692,14 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2631 | break; | 2692 | break; |
2632 | 2693 | ||
2633 | default: | 2694 | default: |
2634 | printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); | 2695 | printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", |
2696 | this->eccmode); | ||
2635 | BUG(); | 2697 | BUG(); |
2636 | } | 2698 | } |
2637 | 2699 | ||
2638 | /* Check hardware ecc function availability and adjust number of ecc bytes per | 2700 | /* |
2639 | * calculation step | 2701 | * Check hardware ecc function availability and adjust number of ecc |
2702 | * bytes per calculation step | ||
2640 | */ | 2703 | */ |
2641 | switch (this->eccmode) { | 2704 | switch (this->eccmode) { |
2642 | case NAND_ECC_HW12_2048: | 2705 | case NAND_ECC_HW12_2048: |
@@ -2647,15 +2710,20 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2647 | this->eccbytes += 3; | 2710 | this->eccbytes += 3; |
2648 | case NAND_ECC_HW3_512: | 2711 | case NAND_ECC_HW3_512: |
2649 | case NAND_ECC_HW3_256: | 2712 | case NAND_ECC_HW3_256: |
2650 | if (this->calculate_ecc && this->correct_data && this->enable_hwecc) | 2713 | if (this->calculate_ecc && this->correct_data && |
2714 | this->enable_hwecc) | ||
2651 | break; | 2715 | break; |
2652 | printk(KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); | 2716 | printk(KERN_WARNING "No ECC functions supplied, " |
2717 | "Hardware ECC not possible\n"); | ||
2653 | BUG(); | 2718 | BUG(); |
2654 | } | 2719 | } |
2655 | 2720 | ||
2656 | mtd->eccsize = this->eccsize; | 2721 | mtd->eccsize = this->eccsize; |
2657 | 2722 | ||
2658 | /* Set the number of read / write steps for one page to ensure ECC generation */ | 2723 | /* |
2724 | * Set the number of read / write steps for one page depending on ECC | ||
2725 | * mode | ||
2726 | */ | ||
2659 | switch (this->eccmode) { | 2727 | switch (this->eccmode) { |
2660 | case NAND_ECC_HW12_2048: | 2728 | case NAND_ECC_HW12_2048: |
2661 | this->eccsteps = mtd->oobblock / 2048; | 2729 | this->eccsteps = mtd->oobblock / 2048; |
@@ -2677,15 +2745,6 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2677 | 2745 | ||
2678 | /* Initialize state, waitqueue and spinlock */ | 2746 | /* Initialize state, waitqueue and spinlock */ |
2679 | this->state = FL_READY; | 2747 | this->state = FL_READY; |
2680 | if (!this->controller) { | ||
2681 | this->controller = kzalloc(sizeof(struct nand_hw_control), | ||
2682 | GFP_KERNEL); | ||
2683 | if (!this->controller) { | ||
2684 | nand_free_kmem(this); | ||
2685 | return -ENOMEM; | ||
2686 | } | ||
2687 | this->options |= NAND_CONTROLLER_ALLOC; | ||
2688 | } | ||
2689 | init_waitqueue_head(&this->controller->wq); | 2748 | init_waitqueue_head(&this->controller->wq); |
2690 | spin_lock_init(&this->controller->lock); | 2749 | spin_lock_init(&this->controller->lock); |
2691 | 2750 | ||