]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'master' of /home/tglx/work/kernel/git/mtd-2.6/
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>
Tue, 23 May 2006 10:37:31 +0000 (12:37 +0200)
committerThomas Gleixner <tglx@cruncher.tec.linutronix.de>
Tue, 23 May 2006 10:37:31 +0000 (12:37 +0200)
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1  2 
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/rtc_from4.c
fs/jffs2/wbuf.c

Simple merge
Simple merge
index 98792ec4c2dc34d7cf6a104c4c3fe38bab3b49e1,cd90a46bf56adffd484500756122c72cd8245869..778535006c83432ceafeff1e2d8e203bcc4c3417
@@@ -901,20 -895,20 +901,20 @@@ static int nand_write_page(struct mtd_i
                /* Software ecc 3/256, write all */
        case NAND_ECC_SOFT:
                for (; eccsteps; eccsteps--) {
 -                      this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
 +                      this->ecc.calculate(mtd, &this->data_poi[datidx], ecc_code);
                        for (i = 0; i < 3; i++, eccidx++)
                                oob_buf[oob_config[eccidx]] = ecc_code[i];
 -                      datidx += this->eccsize;
 +                      datidx += this->ecc.size;
                }
-               this->write_buf(mtd, this->data_poi, mtd->oobblock);
+               this->write_buf(mtd, this->data_poi, mtd->writesize);
                break;
        default:
 -              eccbytes = this->eccbytes;
 +              eccbytes = this->ecc.bytes;
                for (; eccsteps; eccsteps--) {
                        /* enable hardware ecc logic for write */
 -                      this->enable_hwecc(mtd, NAND_ECC_WRITE);
 -                      this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
 -                      this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
 +                      this->ecc.hwctl(mtd, NAND_ECC_WRITE);
 +                      this->write_buf(mtd, &this->data_poi[datidx], this->ecc.size);
 +                      this->ecc.calculate(mtd, &this->data_poi[datidx], ecc_code);
                        for (i = 0; i < eccbytes; i++, eccidx++)
                                oob_buf[oob_config[eccidx]] = ecc_code[i];
                        /* If the hardware ecc provides syndromes then
@@@ -1167,11 -1161,11 +1167,11 @@@ int nand_do_read_ecc(struct mtd_info *m
        page = realpage & this->pagemask;
  
        /* Get raw starting column */
-       col = from & (mtd->oobblock - 1);
+       col = from & (mtd->writesize - 1);
  
-       end = mtd->oobblock;
+       end = mtd->writesize;
 -      ecc = this->eccsize;
 -      eccbytes = this->eccbytes;
 +      ecc = this->ecc.size;
 +      eccbytes = this->ecc.bytes;
  
        if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
                compareecc = 0;
@@@ -1989,9 -1983,9 +1989,9 @@@ static int nand_writev_ecc(struct mtd_i
                         * tuple until we have a full page to write
                         */
                        int cnt = 0;
-                       while (cnt < mtd->oobblock) {
+                       while (cnt < mtd->writesize) {
                                if (vecs->iov_base != NULL && vecs->iov_len)
 -                                      this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
 +                                      this->data_buf[cnt++] = ((uint8_t *) vecs->iov_base)[len++];
                                /* Check, if we have to switch to the next tuple */
                                if (len >= (int)vecs->iov_len) {
                                        vecs++;
@@@ -2314,70 -2308,46 +2314,70 @@@ static void nand_resume(struct mtd_inf
        if (this->state == FL_PM_SUSPENDED)
                nand_release_device(mtd);
        else
 -              printk(KERN_ERR "resume() called for the chip which is not in suspended state\n");
 -
 +              printk(KERN_ERR "nand_resume() called for a chip which is not "
 +                     "in suspended state\n");
  }
  
 -/* module_text_address() isn't exported, and it's mostly a pointless
 -   test if this is a module _anyway_ -- they'd have to try _really_ hard
 -   to call us from in-kernel code if the core NAND support is modular. */
 -#ifdef MODULE
 -#define caller_is_module() (1)
 -#else
 -#define caller_is_module() module_text_address((unsigned long)__builtin_return_address(0))
 -#endif
 +/*
 + * Free allocated data structures
 + */
 +static void nand_free_kmem(struct nand_chip *this)
 +{
 +      /* Buffer allocated by nand_scan ? */
 +      if (this->options & NAND_OOBBUF_ALLOC)
 +              kfree(this->oob_buf);
 +      /* Buffer allocated by nand_scan ? */
 +      if (this->options & NAND_DATABUF_ALLOC)
 +              kfree(this->data_buf);
 +      /* Controller allocated by nand_scan ? */
 +      if (this->options & NAND_CONTROLLER_ALLOC)
 +              kfree(this->controller);
 +}
  
 -/**
 - * nand_scan - [NAND Interface] Scan for the NAND device
 - * @mtd:      MTD device structure
 - * @maxchips: Number of chips to scan for
 - *
 - * This fills out all the uninitialized function pointers
 - * with the defaults.
 - * The flash ID is read and the mtd/chip structures are
 - * filled with the appropriate values. Buffers are allocated if
 - * they are not provided by the board driver
 - * The mtd->owner field must be set to the module of the caller
 - *
 +/*
 + * Allocate buffers and data structures
   */
 -int nand_scan(struct mtd_info *mtd, int maxchips)
 +static int nand_allocate_kmem(struct mtd_info *mtd, struct nand_chip *this)
  {
 -      int i, nand_maf_id, nand_dev_id, busw, maf_id;
 -      struct nand_chip *this = mtd->priv;
 +      size_t len;
  
 -      /* Many callers got this wrong, so check for it for a while... */
 -      if (!mtd->owner && caller_is_module()) {
 -              printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
 -              BUG();
 +      if (!this->oob_buf) {
 +              len = mtd->oobsize <<
 +                      (this->phys_erase_shift - this->page_shift);
 +              this->oob_buf = kmalloc(len, GFP_KERNEL);
 +              if (!this->oob_buf)
 +                      goto outerr;
 +              this->options |= NAND_OOBBUF_ALLOC;
        }
  
 -      /* Get buswidth to select the correct functions */
 -      busw = this->options & NAND_BUSWIDTH_16;
 +      if (!this->data_buf) {
-               len = mtd->oobblock + mtd->oobsize;
++              len = mtd->writesize + mtd->oobsize;
 +              this->data_buf = kmalloc(len, GFP_KERNEL);
 +              if (!this->data_buf)
 +                      goto outerr;
 +              this->options |= NAND_DATABUF_ALLOC;
 +      }
 +
 +      if (!this->controller) {
 +              this->controller = kzalloc(sizeof(struct nand_hw_control),
 +                                         GFP_KERNEL);
 +              if (!this->controller)
 +                      goto outerr;
 +              this->options |= NAND_CONTROLLER_ALLOC;
 +      }
 +      return 0;
 +
 + outerr:
 +      printk(KERN_ERR "nand_scan(): Cannot allocate buffers\n");
 +      nand_free_kmem(this);
 +      return -ENOMEM;
 +}
  
 +/*
 + * Set default functions
 + */
 +static void nand_set_defaults(struct nand_chip *this, int busw)
 +{
        /* check for proper chip_delay setup, set 20us if not */
        if (!this->chip_delay)
                this->chip_delay = 20;
@@@ -2431,173 -2390,116 +2431,173 @@@ static struct nand_flash_dev *nand_get_
        this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
  
        /* Read manufacturer and device IDs */
 -      nand_maf_id = this->read_byte(mtd);
 -      nand_dev_id = this->read_byte(mtd);
 +      *maf_id = this->read_byte(mtd);
 +      dev_id = this->read_byte(mtd);
  
 -      /* Print and store flash device information */
 +      /* Lookup the flash id */
        for (i = 0; nand_flash_ids[i].name != NULL; i++) {
 +              if (dev_id == nand_flash_ids[i].id) {
 +                      type =  &nand_flash_ids[i];
 +                      break;
 +              }
 +      }
  
 -              if (nand_dev_id != nand_flash_ids[i].id)
 -                      continue;
 -
 -              if (!mtd->name)
 -                      mtd->name = nand_flash_ids[i].name;
 -              this->chipsize = nand_flash_ids[i].chipsize << 20;
 -
 -              /* New devices have all the information in additional id bytes */
 -              if (!nand_flash_ids[i].pagesize) {
 -                      int extid;
 -                      /* The 3rd id byte contains non relevant data ATM */
 -                      extid = this->read_byte(mtd);
 -                      /* The 4th id byte is the important one */
 -                      extid = this->read_byte(mtd);
 -                      /* Calc pagesize */
 -                      mtd->writesize = 1024 << (extid & 0x3);
 -                      extid >>= 2;
 -                      /* Calc oobsize */
 -                      mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
 -                      extid >>= 2;
 -                      /* Calc blocksize. Blocksize is multiples of 64KiB */
 -                      mtd->erasesize = (64 * 1024) << (extid & 0x03);
 -                      extid >>= 2;
 -                      /* Get buswidth information */
 -                      busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
 +      if (!type)
 +              return ERR_PTR(-ENODEV);
 +
 +      this->chipsize = nand_flash_ids[i].chipsize << 20;
 +
 +      /* Newer devices have all the information in additional id bytes */
 +      if (!nand_flash_ids[i].pagesize) {
 +              int extid;
 +              /* The 3rd id byte contains non relevant data ATM */
 +              extid = this->read_byte(mtd);
 +              /* The 4th id byte is the important one */
 +              extid = this->read_byte(mtd);
 +              /* Calc pagesize */
-               mtd->oobblock = 1024 << (extid & 0x3);
++              mtd->writesize = 1024 << (extid & 0x3);
 +              extid >>= 2;
 +              /* Calc oobsize */
-               mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
++              mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
 +              extid >>= 2;
 +              /* Calc blocksize. Blocksize is multiples of 64KiB */
 +              mtd->erasesize = (64 * 1024) << (extid & 0x03);
 +              extid >>= 2;
 +              /* Get buswidth information */
 +              busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
  
 -              } else {
 -                      /* Old devices have this data hardcoded in the
 -                       * device id table */
 -                      mtd->erasesize = nand_flash_ids[i].erasesize;
 -                      mtd->writesize = nand_flash_ids[i].pagesize;
 -                      mtd->oobsize = mtd->writesize / 32;
 -                      busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
 -              }
 +      } else {
 +              /*
 +               * Old devices have this data hardcoded in the device id table
 +               */
 +              mtd->erasesize = nand_flash_ids[i].erasesize;
-               mtd->oobblock = nand_flash_ids[i].pagesize;
-               mtd->oobsize = mtd->oobblock / 32;
++              mtd->writesize = nand_flash_ids[i].pagesize;
++              mtd->oobsize = mtd->writesize / 32;
 +              busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
 +      }
  
 -              /* Try to identify manufacturer */
 -              for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
 -                      if (nand_manuf_ids[maf_id].id == nand_maf_id)
 -                              break;
 -              }
 +      /* Try to identify manufacturer */
 +      for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_id++) {
 +              if (nand_manuf_ids[maf_idx].id == *maf_id)
 +                      break;
 +      }
  
 -              /* Check, if buswidth is correct. Hardware drivers should set
 -               * this correct ! */
 -              if (busw != (this->options & NAND_BUSWIDTH_16)) {
 -                      printk(KERN_INFO "NAND device: Manufacturer ID:"
 -                             " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
 -                             nand_manuf_ids[maf_id].name, mtd->name);
 -                      printk(KERN_WARNING
 -                             "NAND bus width %d instead %d bit\n",
 -                             (this->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8);
 -                      this->select_chip(mtd, -1);
 -                      return 1;
 -              }
 +      /*
 +       * Check, if buswidth is correct. Hardware drivers should set
 +       * this correct !
 +       */
 +      if (busw != (this->options & NAND_BUSWIDTH_16)) {
 +              printk(KERN_INFO "NAND device: Manufacturer ID:"
 +                     " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
 +                     dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
 +              printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
 +                     (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
 +                     busw ? 16 : 8);
 +              return ERR_PTR(-EINVAL);
 +      }
  
 -              /* Calculate the address shift from the page size */
 -              this->page_shift = ffs(mtd->writesize) - 1;
 -              this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
 -              this->chip_shift = ffs(this->chipsize) - 1;
 -
 -              /* Set the bad block position */
 -              this->badblockpos = mtd->writesize > 512 ? NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
 -
 -              /* Get chip options, preserve non chip based options */
 -              this->options &= ~NAND_CHIPOPTIONS_MSK;
 -              this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
 -              /* Set this as a default. Board drivers can override it, if necessary */
 -              this->options |= NAND_NO_AUTOINCR;
 -              /* Check if this is a not a samsung device. Do not clear the options
 -               * for chips which are not having an extended id.
 -               */
 -              if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
 -                      this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 +      /* Calculate the address shift from the page size */
-       this->page_shift = ffs(mtd->oobblock) - 1;
++      this->page_shift = ffs(mtd->writesize) - 1;
 +      /* Convert chipsize to number of pages per chip -1. */
 +      this->pagemask = (this->chipsize >> this->page_shift) - 1;
  
 -              /* Check for AND chips with 4 page planes */
 -              if (this->options & NAND_4PAGE_ARRAY)
 -                      this->erase_cmd = multi_erase_cmd;
 -              else
 -                      this->erase_cmd = single_erase_cmd;
 +      this->bbt_erase_shift = this->phys_erase_shift =
 +              ffs(mtd->erasesize) - 1;
 +      this->chip_shift = ffs(this->chipsize) - 1;
  
 -              /* Do not replace user supplied command function ! */
 -              if (mtd->writesize > 512 && this->cmdfunc == nand_command)
 -                      this->cmdfunc = nand_command_lp;
 +      /* Set the bad block position */
-       this->badblockpos = mtd->oobblock > 512 ?
++      this->badblockpos = mtd->writesize > 512 ?
 +              NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
  
 -              printk(KERN_INFO "NAND device: Manufacturer ID:"
 -                     " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
 -                     nand_manuf_ids[maf_id].name, nand_flash_ids[i].name);
 -              break;
 +      /* Get chip options, preserve non chip based options */
 +      this->options &= ~NAND_CHIPOPTIONS_MSK;
 +      this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
 +
 +      /*
 +       * Set this as a default. Board drivers can override it, if necessary
 +       */
 +      this->options |= NAND_NO_AUTOINCR;
 +
 +      /* Check if this is a not a samsung device. Do not clear the
 +       * options for chips which are not having an extended id.
 +       */
 +      if (*maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
 +              this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 +
 +      /* Check for AND chips with 4 page planes */
 +      if (this->options & NAND_4PAGE_ARRAY)
 +              this->erase_cmd = multi_erase_cmd;
 +      else
 +              this->erase_cmd = single_erase_cmd;
 +
 +      /* Do not replace user supplied command function ! */
-       if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
++      if (mtd->writesize > 512 && this->cmdfunc == nand_command)
 +              this->cmdfunc = nand_command_lp;
 +
 +      printk(KERN_INFO "NAND device: Manufacturer ID:"
 +             " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
 +             nand_manuf_ids[maf_idx].name, type->name);
 +
 +      return type;
 +}
 +
 +/* module_text_address() isn't exported, and it's mostly a pointless
 +   test if this is a module _anyway_ -- they'd have to try _really_ hard
 +   to call us from in-kernel code if the core NAND support is modular. */
 +#ifdef MODULE
 +#define caller_is_module() (1)
 +#else
 +#define caller_is_module() \
 +      module_text_address((unsigned long)__builtin_return_address(0))
 +#endif
 +
 +/**
 + * nand_scan - [NAND Interface] Scan for the NAND device
 + * @mtd:      MTD device structure
 + * @maxchips: Number of chips to scan for
 + *
 + * This fills out all the uninitialized function pointers
 + * with the defaults.
 + * The flash ID is read and the mtd/chip structures are
 + * filled with the appropriate values. Buffers are allocated if
 + * they are not provided by the board driver
 + * The mtd->owner field must be set to the module of the caller
 + *
 + */
 +int nand_scan(struct mtd_info *mtd, int maxchips)
 +{
 +      int i, busw, nand_maf_id;
 +      struct nand_chip *this = mtd->priv;
 +      struct nand_flash_dev *type;
 +
 +      /* Many callers got this wrong, so check for it for a while... */
 +      if (!mtd->owner && caller_is_module()) {
 +              printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n");
 +              BUG();
        }
  
 -      if (!nand_flash_ids[i].name) {
 +      /* Get buswidth to select the correct functions */
 +      busw = this->options & NAND_BUSWIDTH_16;
 +      /* Set the default functions */
 +      nand_set_defaults(this, busw);
 +
 +      /* Read the flash type */
 +      type = nand_get_flash_type(mtd, this, busw, &nand_maf_id);
 +
 +      if (IS_ERR(type)) {
                printk(KERN_WARNING "No NAND device found!!!\n");
                this->select_chip(mtd, -1);
 -              return 1;
 +              return PTR_ERR(type);
        }
  
 +      /* Check for a chip array */
        for (i = 1; i < maxchips; i++) {
                this->select_chip(mtd, i);
 -
                /* Send the command for reading device ID */
                this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 -
                /* Read manufacturer and device IDs */
                if (nand_maf_id != this->read_byte(mtd) ||
 -                  nand_dev_id != this->read_byte(mtd))
 +                  type->id != this->read_byte(mtd))
                        break;
        }
        if (i > 1)
                mtd->oobavail += this->autooob->oobfree[i][1];
  
        /*
 -       * check ECC mode, default to software
 -       * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
 -       * fallback to software ECC
 +       * check ECC mode, default to software if 3byte/512byte hardware ECC is
 +       * selected and we have 256 byte pagesize fallback to software ECC
         */
 -      this->eccsize = 256;    /* set default eccsize */
 -      this->eccbytes = 3;
 -
 -      switch (this->eccmode) {
 -      case NAND_ECC_HW12_2048:
 -              if (mtd->writesize < 2048) {
 -                      printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
 -                             mtd->writesize);
 -                      this->eccmode = NAND_ECC_SOFT;
 -                      this->calculate_ecc = nand_calculate_ecc;
 -                      this->correct_data = nand_correct_data;
 -              } else
 -                      this->eccsize = 2048;
 -              break;
 -
 -      case NAND_ECC_HW3_512:
 -      case NAND_ECC_HW6_512:
 -      case NAND_ECC_HW8_512:
 -              if (mtd->writesize == 256) {
 -                      printk(KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
 -                      this->eccmode = NAND_ECC_SOFT;
 -                      this->calculate_ecc = nand_calculate_ecc;
 -                      this->correct_data = nand_correct_data;
 -              } else
 -                      this->eccsize = 512;    /* set eccsize to 512 */
 -              break;
 +      switch (this->ecc.mode) {
 +      case NAND_ECC_HW:
 +      case NAND_ECC_HW_SYNDROME:
 +              if (!this->ecc.calculate || !this->ecc.correct ||
 +                  !this->ecc.hwctl) {
 +                      printk(KERN_WARNING "No ECC functions supplied, "
 +                             "Hardware ECC not possible\n");
 +                      BUG();
 +              }
-               if (mtd->oobblock >= this->ecc.size)
++              if (mtd->writesize >= this->ecc.size)
 +                      break;
 +              printk(KERN_WARNING "%d byte HW ECC not possible on "
 +                     "%d byte page size, fallback to SW ECC\n",
-                      this->ecc.size, mtd->oobblock);
++                     this->ecc.size, mtd->writesize);
 +              this->ecc.mode = NAND_ECC_SOFT;
  
 -      case NAND_ECC_HW3_256:
 +      case NAND_ECC_SOFT:
 +              this->ecc.calculate = nand_calculate_ecc;
 +              this->ecc.correct = nand_correct_data;
 +              this->ecc.size = 256;
 +              this->ecc.bytes = 3;
                break;
  
        case NAND_ECC_NONE:
 -              printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
 -              this->eccmode = NAND_ECC_NONE;
 -              break;
 -
 -      case NAND_ECC_SOFT:
 -              this->calculate_ecc = nand_calculate_ecc;
 -              this->correct_data = nand_correct_data;
 +              printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
 +                     "This is not recommended !!\n");
-               this->ecc.size = mtd->oobblock;
++              this->ecc.size = mtd->writesize;
 +              this->ecc.bytes = 0;
                break;
 -
        default:
 -              printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
 +              printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
 +                     this->ecc.mode);
                BUG();
        }
  
 -      /* Check hardware ecc function availability and adjust number of ecc bytes per
 -       * calculation step
 +      /*
 +       * Set the number of read / write steps for one page depending on ECC
 +       * mode
         */
-       this->ecc.steps = mtd->oobblock / this->ecc.size;
-       if(this->ecc.steps * this->ecc.size != mtd->oobblock) {
 -      switch (this->eccmode) {
 -      case NAND_ECC_HW12_2048:
 -              this->eccbytes += 4;
 -      case NAND_ECC_HW8_512:
 -              this->eccbytes += 2;
 -      case NAND_ECC_HW6_512:
 -              this->eccbytes += 3;
 -      case NAND_ECC_HW3_512:
 -      case NAND_ECC_HW3_256:
 -              if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
 -                      break;
 -              printk(KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
++      this->ecc.steps = mtd->writesize / this->ecc.size;
++      if(this->ecc.steps * this->ecc.size != mtd->writesize) {
 +              printk(KERN_WARNING "Invalid ecc parameters\n");
                BUG();
        }
  
Simple merge
Simple merge
diff --cc fs/jffs2/wbuf.c
index 0442a5753d33d0cd31d8085c8e33d0b61f91b4a2,c7e3040240b27872b6f677399eed667e7b526d54..916c87d3393b72e98415ddeff77615a8f3e987de
@@@ -649,26 -639,12 +649,13 @@@ int jffs2_flash_writev(struct jffs2_sb_
                memset(c->wbuf,0xff,c->wbuf_pagesize);
        }
  
-       /*
-        * Fixup the wbuf if we are moving to a new eraseblock. The
-        * checks below fail for ECC'd NOR because cleanmarker == 16,
-        * so a block starts at xxx0010.
-        */
-       if (jffs2_nor_ecc(c)) {
-               if (((c->wbuf_ofs % c->sector_size) == 0) && !c->wbuf_len) {
-                       c->wbuf_ofs = PAGE_DIV(to);
-                       c->wbuf_len = PAGE_MOD(to);
-                       memset(c->wbuf,0xff,c->wbuf_pagesize);
-               }
-       }
 -      /* Sanity checks on target address.
 -         It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
 -         and it's permitted to write at the beginning of a new
 -         erase block. Anything else, and you die.
 -         New block starts at xxx000c (0-b = block header)
 -      */
 +      /*
 +       * Sanity checks on target address.  It's permitted to write
 +       * at PAD(c->wbuf_len+c->wbuf_ofs), and it's permitted to
 +       * write at the beginning of a new erase block. Anything else,
 +       * and you die.  New block starts at xxx000c (0-b = block
 +       * header)
 +       */
        if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
                /* It's a write to a new block */
                if (c->wbuf_len) {