
/*
 * Linux driver for Disk-On-Chip 2000 and Millennium
 * (c) 1999 Machine Vision Holdings, Inc.
 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
 *
 * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/bitops.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/doc2000.h>

#define DOC_SUPPORT_2000
#define DOC_SUPPORT_2000TSOP
#define DOC_SUPPORT_MILLENNIUM

#ifdef DOC_SUPPORT_2000
#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
#else
#define DoC_is_2000(doc) (0)
#endif

#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM)
#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
#else
#define DoC_is_Millennium(doc) (0)
#endif

/* #define ECC_DEBUG */

/* I have no idea why some DoC chips can not use memcpy_from|to_io().
 * This may be due to the different revisions of the ASIC controller built-in or
 * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
 * this:
 #undef USE_MEMCPY
*/

static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t *retlen, u_char *buf);
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t *retlen, const u_char *buf);
static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
			size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
			 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
			  unsigned long count, loff_t to, size_t *retlen,
			  u_char *eccbuf, struct nand_oobinfo *oobsel);
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
			size_t *retlen, u_char *buf);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
			 size_t *retlen, const u_char *buf);
static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
			 size_t *retlen, const u_char *buf);
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);

static struct mtd_info *doc2klist = NULL;

/* Perform the required delay cycles by reading from the appropriate register */
static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
{
	volatile char dummy;
	int i;

	for (i = 0; i < cycles; i++) {
		if (DoC_is_Millennium(doc))
			dummy = ReadDOC(doc->virtadr, NOP);
		else
			dummy = ReadDOC(doc->virtadr, DOCStatus);
	}

}

/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
static int _DoC_WaitReady(struct DiskOnChip *doc)
{
	void __iomem *docptr = doc->virtadr;
	unsigned long timeo = jiffies + (HZ * 10);

	DEBUG(MTD_DEBUG_LEVEL3,
	      "_DoC_WaitReady called for out-of-line wait\n");

	/* Out-of-line routine to wait for chip response */
	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
		/* issue 2 read from NOP register after reading from CDSNControl register
	   	see Software Requirement 11.4 item 2. */
		DoC_Delay(doc, 2);

		if (time_after(jiffies, timeo)) {
			DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
			return -EIO;
		}
		udelay(1);
		cond_resched();
	}

	return 0;
}

static inline int DoC_WaitReady(struct DiskOnChip *doc)
{
	void __iomem *docptr = doc->virtadr;

	/* This is inline, to optimise the common case, where it's ready instantly */
	int ret = 0;

	/* 4 read form NOP register should be issued in prior to the read from CDSNControl
	   see Software Requirement 11.4 item 2. */
	DoC_Delay(doc, 4);

	if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
		/* Call the out-of-line routine to wait */
		ret = _DoC_WaitReady(doc);

	/* issue 2 read from NOP register after reading from CDSNControl register
	   see Software Requirement 11.4 item 2. */
	DoC_Delay(doc, 2);

	return ret;
}

/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */

static int DoC_Command(struct DiskOnChip *doc, unsigned char command,
			      unsigned char xtraflags)
{
	void __iomem *docptr = doc->virtadr;

	if (DoC_is_2000(doc))
		xtraflags |= CDSN_CTRL_FLASH_IO;

	/* Assert the CLE (Command Latch Enable) line to the flash chip */
	WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */

	if (DoC_is_Millennium(doc))
		WriteDOC(command, docptr, CDSNSlowIO);

	/* Send the command */
	WriteDOC_(command, docptr, doc->ioreg);
	if (DoC_is_Millennium(doc))
		WriteDOC(command, docptr, WritePipeTerm);

	/* Lower the CLE line */
	WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */

	/* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
	return DoC_WaitReady(doc);
}

/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */

static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
		       unsigned char xtraflags1, unsigned char xtraflags2)
{
	int i;
	void __iomem *docptr = doc->virtadr;

	if (DoC_is_2000(doc))
		xtraflags1 |= CDSN_CTRL_FLASH_IO;

	/* Assert the ALE (Address Latch Enable) line to the flash chip */
	WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);

	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */

	/* Send the address */
	/* Devices with 256-byte page are addressed as:
	   Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
	   * there is no device on the market with page256
	   and more than 24 bits.
	   Devices with 512-byte page are addressed as:
	   Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
	   * 25-31 is sent only if the chip support it.
	   * bit 8 changes the read command to be sent
	   (NAND_CMD_READ0 or NAND_CMD_READ1).
	 */

	if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
		if (DoC_is_Millennium(doc))
			WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
		WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
	}

	if (doc->page256) {
		ofs = ofs >> 8;
	} else {
		ofs = ofs >> 9;
	}

	if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
		for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
			if (DoC_is_Millennium(doc))
				WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
			WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
		}
	}

	if (DoC_is_Millennium(doc))
		WriteDOC(ofs & 0xff, docptr, WritePipeTerm);

	DoC_Delay(doc, 2);	/* Needed for some slow flash chips. mf. */

	/* FIXME: The SlowIO's for millennium could be replaced by
	   a single WritePipeTerm here. mf. */

	/* Lower the ALE line */
	WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
		 CDSNControl);

	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */

	/* Wait for the chip to respond - Software requirement 11.4.1 */
	return DoC_WaitReady(doc);
}

/* Read a buffer from DoC, taking care of Millennium odditys */
static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
{
	volatile int dummy;
	int modulus = 0xffff;
	void __iomem *docptr = doc->virtadr;
	int i;

	if (len <= 0)
		return;

	if (DoC_is_Millennium(doc)) {
		/* Read the data via the internal pipeline through CDSN IO register,
		   see Pipelined Read Operations 11.3 */
		dummy = ReadDOC(docptr, ReadPipeInit);

		/* Millennium should use the LastDataRead register - Pipeline Reads */
		len--;

		/* This is needed for correctly ECC calculation */
		modulus = 0xff;
	}

	for (i = 0; i < len; i++)
		buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));

	if (DoC_is_Millennium(doc)) {
		buf[i] = ReadDOC(docptr, LastDataRead);
	}
}

/* Write a buffer to DoC, taking care of Millennium odditys */
static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
{
	void __iomem *docptr = doc->virtadr;
	int i;

	if (len <= 0)
		return;

	for (i = 0; i < len; i++)
		WriteDOC_(buf[i], docptr, doc->ioreg + i);

	if (DoC_is_Millennium(doc)) {
		WriteDOC(0x00, docptr, WritePipeTerm);
	}
}


/* DoC_SelectChip: Select a given flash chip within the current floor */

static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
{
	void __iomem *docptr = doc->virtadr;

	/* Software requirement 11.4.4 before writing DeviceSelect */
	/* Deassert the CE line to eliminate glitches on the FCE# outputs */
	WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */

	/* Select the individual flash chip requested */
	WriteDOC(chip, docptr, CDSNDeviceSelect);
	DoC_Delay(doc, 4);

	/* Reassert the CE line */
	WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
		 CDSNControl);
	DoC_Delay(doc, 4);	/* Software requirement 11.4.3 for Millennium */

	/* Wait for it to be ready */
	return DoC_WaitReady(doc);
}

/* DoC_SelectFloor: Select a given floor (bank of flash chips) */

static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
{
	void __iomem *docptr = doc->virtadr;

	/* Select the floor (bank) of chips required */
	WriteDOC(floor, docptr, FloorSelect);

	/* Wait for the chip to be ready */
	return DoC_WaitReady(doc);
}

/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */

static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
{
	int mfr, id, i, j;
	volatile char dummy;

	/* Page in the required floor/chip */
	DoC_SelectFloor(doc, floor);
	DoC_SelectChip(doc, chip);

	/* Reset the chip */
	if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
		DEBUG(MTD_DEBUG_LEVEL2,
		      "DoC_Command (reset) for %d,%d returned true\n",
		      floor, chip);
		return 0;
	}


	/* Read the NAND chip ID: 1. Send ReadID command */
	if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
		DEBUG(MTD_DEBUG_LEVEL2,
		      "DoC_Command (ReadID) for %d,%d returned true\n",
		      floor, chip);
		return 0;
	}

	/* Read the NAND chip ID: 2. Send address byte zero */
	DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);

	/* Read the manufacturer and device id codes from the device */

	if (DoC_is_Millennium(doc)) {
		DoC_Delay(doc, 2);
		dummy = ReadDOC(doc->virtadr, ReadPipeInit);
		mfr = ReadDOC(doc->virtadr, LastDataRead);

		DoC_Delay(doc, 2);
		dummy = ReadDOC(doc->virtadr, ReadPipeInit);
		id = ReadDOC(doc->virtadr, LastDataRead);
	} else {
		/* CDSN Slow IO register see Software Req 11.4 item 5. */
		dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
		DoC_Delay(doc, 2);
		mfr = ReadDOC_(doc->virtadr, doc->ioreg);

		/* CDSN Slow IO register see Software Req 11.4 item 5. */
		dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
		DoC_Delay(doc, 2);
		id = ReadDOC_(doc->virtadr, doc->ioreg);
	}

	/* No response - return failure */
	if (mfr == 0xff || mfr == 0)
		return 0;

	/* Check it's the same as the first chip we identified.
	 * M-Systems say that any given DiskOnChip device should only
	 * contain _one_ type of flash part, although that's not a
	 * hardware restriction. */
	if (doc->mfr) {
		if (doc->mfr == mfr && doc->id == id)
			return 1;	/* This is another the same the first */
		else
			printk(KERN_WARNING
			       "Flash chip at floor %d, chip %d is different:\n",
			       floor, chip);
	}

	/* Print and store the manufacturer and ID codes. */
	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
		if (id == nand_flash_ids[i].id) {
			/* Try to identify manufacturer */
			for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
				if (nand_manuf_ids[j].id == mfr)
					break;
			}
			printk(KERN_INFO
			       "Flash chip found: Manufacturer ID: %2.2X, "
			       "Chip ID: %2.2X (%s:%s)\n", mfr, id,
			       nand_manuf_ids[j].name, nand_flash_ids[i].name);
			if (!doc->mfr) {
				doc->mfr = mfr;
				doc->id = id;
				doc->chipshift =
					ffs((nand_flash_ids[i].chipsize << 20)) - 1;
				doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
				doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
				doc->erasesize =
				    nand_flash_ids[i].erasesize;
				return 1;
			}
			return 0;
		}
	}


	/* We haven't fully identified the chip. Print as much as we know. */
	printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n",
	       id, mfr);

	printk(KERN_WARNING "Please report to dwmw2@infradead.org\n");
	return 0;
}

/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */

static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
{
	int floor, chip;
	int numchips[MAX_FLOORS];
	int ret = 1;

	this->numchips = 0;
	this->mfr = 0;
	this->id = 0;

	/* For each floor, find the number of valid chips it contains */
	for (floor = 0; floor < MAX_FLOORS; floor++) {
		ret = 1;
		numchips[floor] = 0;
		for (chip = 0; chip < maxchips && ret != 0; chip++) {

			ret = DoC_IdentChip(this, floor, chip);
			if (ret) {
				numchips[floor]++;
				this->numchips++;
			}
		}
	}

	/* If there are none at all that we recognise, bail */
	if (!this->numchips) {
		printk(KERN_NOTICE "No flash chips recognised.\n");
		return;
	}

	/* Allocate an array to hold the information for each chip */
	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
	if (!this->chips) {
		printk(KERN_NOTICE "No memory for allocating chip info structures\n");
		return;
	}

	ret = 0;

	/* Fill out the chip array with {floor, chipno} for each
	 * detected chip in the device. */
	for (floor = 0; floor < MAX_FLOORS; floor++) {
		for (chip = 0; chip < numchips[floor]; chip++) {
			this->chips[ret].floor = floor;
			this->chips[ret].chip = chip;
			this->chips[ret].curadr = 0;
			this->chips[ret].curmode = 0x50;
			ret++;
		}
	}

	/* Calculate and print the total size of the device */
	this->totlen = this->numchips * (1 << this->chipshift);

	printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
	       this->numchips, this->totlen >> 20);
}

static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
{
	int tmp1, tmp2, retval;
	if (doc1->physadr == doc2->physadr)
		return 1;

	/* Use the alias resolution register which was set aside for this
	 * purpose. If it's value is the same on both chips, they might
	 * be the same chip, and we write to one and check for a change in
	 * the other. It's unclear if this register is usuable in the
	 * DoC 2000 (it's in the Millennium docs), but it seems to work. */
	tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
	if (tmp1 != tmp2)
		return 0;

	WriteDOC((tmp1 + 1) % 0xff, doc1->virtadr, AliasResolution);
	tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
	if (tmp2 == (tmp1 + 1) % 0xff)
		retval = 1;
	else
		retval = 0;

	/* Restore register contents.  May not be necessary, but do it just to
	 * be safe. */
	WriteDOC(tmp1, doc1->virtadr, AliasResolution);

	return retval;
}

static const char im_name[] = "DoC2k_init";

/* This routine is made available to other mtd code via
 * inter_module_register.  It must only be accessed through
 * inter_module_get which will bump the use count of this module.  The
 * addresses passed back in mtd are valid as long as the use count of
 * this module is non-zero, i.e. between inter_module_get and
 * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
 */
static void DoC2k_init(struct mtd_info *mtd)
{
	struct DiskOnChip *this = mtd->priv;
	struct DiskOnChip *old = NULL;
	int maxchips;

	/* We must avoid being called twice for the same device. */

	if (doc2klist)
		old = doc2klist->priv;

	while (old) {
		if (DoC2k_is_alias(old, this)) {
			printk(KERN_NOTICE
			       "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
			       this->physadr);
			iounmap(this->virtadr);
			kfree(mtd);
			return;
		}
		if (old->nextdoc)
			old = old->nextdoc->priv;
		else
			old = NULL;
	}


	switch (this->ChipID) {
	case DOC_ChipID_Doc2kTSOP:
		mtd->name = "DiskOnChip 2000 TSOP";
		this->ioreg = DoC_Mil_CDSN_IO;
		/* Pretend it's a Millennium */
		this->ChipID = DOC_ChipID_DocMil;
		maxchips = MAX_CHIPS;
		break;
	case DOC_ChipID_Doc2k:
		mtd->name = "DiskOnChip 2000";
		this->ioreg = DoC_2k_CDSN_IO;
		maxchips = MAX_CHIPS;
		break;
	case DOC_ChipID_DocMil:
		mtd->name = "DiskOnChip Millennium";
		this->ioreg = DoC_Mil_CDSN_IO;
		maxchips = MAX_CHIPS_MIL;
		break;
	default:
		printk("Unknown ChipID 0x%02x\n", this->ChipID);
		kfree(mtd);
		iounmap(this->virtadr);
		return;
	}

	printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
	       this->physadr);

	mtd->type = MTD_NANDFLASH;
	mtd->flags = MTD_CAP_NANDFLASH;
	mtd->ecctype = MTD_ECC_RS_DiskOnChip;
	mtd->size = 0;
	mtd->erasesize = 0;
	mtd->oobblock = 512;
	mtd->oobsize = 16;
	mtd->owner = THIS_MODULE;
	mtd->erase = doc_erase;
	mtd->point = NULL;
	mtd->unpoint = NULL;
	mtd->read = doc_read;
	mtd->write = doc_write;
	mtd->read_ecc = doc_read_ecc;
	mtd->write_ecc = doc_write_ecc;
	mtd->writev_ecc = doc_writev_ecc;
	mtd->read_oob = doc_read_oob;
	mtd->write_oob = doc_write_oob;
	mtd->sync = NULL;

	this->totlen = 0;
	this->numchips = 0;

	this->curfloor = -1;
	this->curchip = -1;
	init_MUTEX(&this->lock);

	/* Ident all the chips present. */
	DoC_ScanChips(this, maxchips);

	if (!this->totlen) {
		kfree(mtd);
		iounmap(this->virtadr);
	} else {
		this->nextdoc = doc2klist;
		doc2klist = mtd;
		mtd->size = this->totlen;
		mtd->erasesize = this->erasesize;
		add_mtd_device(mtd);
		return;
	}
}

static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t * retlen, u_char * buf)
{
	/* Just a special case of doc_read_ecc */
	return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
}

static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
			size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
{
	struct DiskOnChip *this = mtd->priv;
	void __iomem *docptr = this->virtadr;
	struct Nand *mychip;
	unsigned char syndrome[6];
	volatile char dummy;
	int i, len256 = 0, ret=0;
	size_t left = len;

	/* Don't allow read past end of device */
	if (from >= this->totlen)
		return -EINVAL;

	down(&this->lock);

	*retlen = 0;
	while (left) {
		len = left;

		/* Don't allow a single read to cross a 512-byte block boundary */
		if (from + len > ((from | 0x1ff) + 1))
			len = ((from | 0x1ff) + 1) - from;

		/* The ECC will not be calculated correctly if less than 512 is read */
		if (len != 0x200 && eccbuf)
			printk(KERN_WARNING
			       "ECC needs a full sector read (adr: %lx size %lx)\n",
			       (long) from, (long) len);

		/* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */


		/* Find the chip which is to be used and select it */
		mychip = &this->chips[from >> (this->chipshift)];

		if (this->curfloor != mychip->floor) {
			DoC_SelectFloor(this, mychip->floor);
			DoC_SelectChip(this, mychip->chip);
		} else if (this->curchip != mychip->chip) {
			DoC_SelectChip(this, mychip->chip);
		}

		this->curfloor = mychip->floor;
		this->curchip = mychip->chip;

		DoC_Command(this,
			    (!this->page256
			     && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
			    CDSN_CTRL_WP);
		DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
			    CDSN_CTRL_ECC_IO);

		if (eccbuf) {
			/* Prime the ECC engine */
			WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
			WriteDOC(DOC_ECC_EN, docptr, ECCConf);
		} else {
			/* disable the ECC engine */
			WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
			WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
		}

		/* treat crossing 256-byte sector for 2M x 8bits devices */
		if (this->page256 && from + len > (from | 0xff) + 1) {
			len256 = (from | 0xff) + 1 - from;
			DoC_ReadBuf(this, buf, len256);

			DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
			DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
				    CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
		}

		DoC_ReadBuf(this, &buf[len256], len - len256);

		/* Let the caller know we completed it */
		*retlen += len;

		if (eccbuf) {
			/* Read the ECC data through the DiskOnChip ECC logic */
			/* Note: this will work even with 2M x 8bit devices as   */
			/*       they have 8 bytes of OOB per 256 page. mf.      */
			DoC_ReadBuf(this, eccbuf, 6);

			/* Flush the pipeline */
			if (DoC_is_Millennium(this)) {
				dummy = ReadDOC(docptr, ECCConf);
				dummy = ReadDOC(docptr, ECCConf);
				i = ReadDOC(docptr, ECCConf);
			} else {
				dummy = ReadDOC(docptr, 2k_ECCStatus);
				dummy = ReadDOC(docptr, 2k_ECCStatus);
				i = ReadDOC(docptr, 2k_ECCStatus);
			}

			/* Check the ECC Status */
			if (i & 0x80) {
				int nb_errors;
				/* There was an ECC error */
#ifdef ECC_DEBUG
				printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
#endif
				/* Read the ECC syndrom through the DiskOnChip ECC logic.
				   These syndrome will be all ZERO when there is no error */
				for (i = 0; i < 6; i++) {
					syndrome[i] =
					    ReadDOC(docptr, ECCSyndrome0 + i);
				}
	                        nb_errors = doc_decode_ecc(buf, syndrome);

#ifdef ECC_DEBUG
				printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
#endif
	                        if (nb_errors < 0) {
					/* We return error, but have actually done the read. Not that
					   this can be told to user-space, via sys_read(), but at least
					   MTD-aware stuff can know about it by checking *retlen */
					ret = -EIO;
	                        }
			}

#ifdef PSYCHO_DEBUG
			printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
				     (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
				     eccbuf[3], eccbuf[4], eccbuf[5]);
#endif

			/* disable the ECC engine */
			WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
		}

		/* according to 11.4.1, we need to wait for the busy line
	         * drop if we read to the end of the page.  */
		if(0 == ((from + len) & 0x1ff))
		{
		    DoC_WaitReady(this);
		}

		from += len;
		left -= len;
		buf += len;
	}

	up(&this->lock);

	return ret;
}

static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t * retlen, const u_char * buf)
{
	char eccbuf[6];
	return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
}

static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
			 size_t * retlen, const u_char * buf,
			 u_char * eccbuf, struct nand_oobinfo *oobsel)
{
	struct DiskOnChip *this = mtd->priv;
	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
	void __iomem *docptr = this->virtadr;
	volatile char dummy;
	int len256 = 0;
	struct Nand *mychip;
	size_t left = len;
	int status;

	/* Don't allow write past end of device */
	if (to >= this->totlen)
		return -EINVAL;

	down(&this->lock);

	*retlen = 0;
	while (left) {
		len = left;

		/* Don't allow a single write to cross a 512-byte block boundary */
		if (to + len > ((to | 0x1ff) + 1))
			len = ((to | 0x1ff) + 1) - to;

		/* The ECC will not be calculated correctly if less than 512 is written */
/* DBB-
		if (len != 0x200 && eccbuf)
			printk(KERN_WARNING
			       "ECC needs a full sector write (adr: %lx size %lx)\n",
			       (long) to, (long) len);
   -DBB */

		/* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */

		/* Find the chip which is to be used and select it */
		mychip = &this->chips[to >> (this->chipshift)];

		if (this->curfloor != mychip->floor) {
			DoC_SelectFloor(this, mychip->floor);
			DoC_SelectChip(this, mychip->chip);
		} else if (this->curchip != mychip->chip) {
			DoC_SelectChip(this, mychip->chip);
		}

		this->curfloor = mychip->floor;
		this->curchip = mychip->chip;

		/* Set device to main plane of flash */
		DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
		DoC_Command(this,
			    (!this->page256
			     && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
			    CDSN_CTRL_WP);

		DoC_Command(this, NAND_CMD_SEQIN, 0);
		DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);

		if (eccbuf) {
			/* Prime the ECC engine */
			WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
			WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
		} else {
			/* disable the ECC engine */
			WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
			WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
		}

		/* treat crossing 256-byte sector for 2M x 8bits devices */
		if (this->page256 && to + len > (to | 0xff) + 1) {
			len256 = (to | 0xff) + 1 - to;
			DoC_WriteBuf(this, buf, len256);

			DoC_Command(this, NAND_CMD_PAGEPROG, 0);

			DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
			/* There's an implicit DoC_WaitReady() in DoC_Command */

			dummy = ReadDOC(docptr, CDSNSlowIO);
			DoC_Delay(this, 2);

			if (ReadDOC_(docptr, this->ioreg) & 1) {
				printk(KERN_ERR "Error programming flash\n");
				/* Error in programming */
				*retlen = 0;
				up(&this->lock);
				return -EIO;
			}

			DoC_Command(this, NAND_CMD_SEQIN, 0);
			DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
				    CDSN_CTRL_ECC_IO);
		}

		DoC_WriteBuf(this, &buf[len256], len - len256);

		if (eccbuf) {
			WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
				 CDSNControl);

			if (DoC_is_Millennium(this)) {
				WriteDOC(0, docptr, NOP);
				WriteDOC(0, docptr, NOP);
				WriteDOC(0, docptr, NOP);
			} else {
				WriteDOC_(0, docptr, this->ioreg);
				WriteDOC_(0, docptr, this->ioreg);
				WriteDOC_(0, docptr, this->ioreg);
			}

			WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
				 CDSNControl);

			/* Read the ECC data through the DiskOnChip ECC logic */
			for (di = 0; di < 6; di++) {
				eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
			}

			/* Reset the ECC engine */
			WriteDOC(DOC_ECC_DIS, docptr, ECCConf);

#ifdef PSYCHO_DEBUG
			printk
			    ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
			     (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
			     eccbuf[4], eccbuf[5]);
#endif
		}

		DoC_Command(this, NAND_CMD_PAGEPROG, 0);

		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
		/* There's an implicit DoC_WaitReady() in DoC_Command */

		if (DoC_is_Millennium(this)) {
			ReadDOC(docptr, ReadPipeInit);
			status = ReadDOC(docptr, LastDataRead);
		} else {
			dummy = ReadDOC(docptr, CDSNSlowIO);
			DoC_Delay(this, 2);
			status = ReadDOC_(docptr, this->ioreg);
		}

		if (status & 1) {
			printk(KERN_ERR "Error programming flash\n");
			/* Error in programming */
			*retlen = 0;
			up(&this->lock);
			return -EIO;
		}

		/* Let the caller know we completed it */
		*retlen += len;

		if (eccbuf) {
			unsigned char x[8];
			size_t dummy;
			int ret;

			/* Write the ECC data to flash */
			for (di=0; di<6; di++)
				x[di] = eccbuf[di];

			x[6]=0x55;
			x[7]=0x55;

			ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
			if (ret) {
				up(&this->lock);
				return ret;
			}
		}

		to += len;
		left -= len;
		buf += len;
	}

	up(&this->lock);
	return 0;
}

static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
			  unsigned long count, loff_t to, size_t *retlen,
			  u_char *eccbuf, struct nand_oobinfo *oobsel)
{
	static char static_buf[512];
	static DECLARE_MUTEX(writev_buf_sem);

	size_t totretlen = 0;
	size_t thisvecofs = 0;
	int ret= 0;

	down(&writev_buf_sem);

	while(count) {
		size_t thislen, thisretlen;
		unsigned char *buf;

		buf = vecs->iov_base + thisvecofs;
		thislen = vecs->iov_len - thisvecofs;


		if (thislen >= 512) {
			thislen = thislen & ~(512-1);
			thisvecofs += thislen;
		} else {
			/* Not enough to fill a page. Copy into buf */
			memcpy(static_buf, buf, thislen);
			buf = &static_buf[thislen];

			while(count && thislen < 512) {
				vecs++;
				count--;
				thisvecofs = min((512-thislen), vecs->iov_len);
				memcpy(buf, vecs->iov_base, thisvecofs);
				thislen += thisvecofs;
				buf += thisvecofs;
			}
			buf = static_buf;
		}
		if (count && thisvecofs == vecs->iov_len) {
			thisvecofs = 0;
			vecs++;
			count--;
		}
		ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);

		totretlen += thisretlen;

		if (ret || thisretlen != thislen)
			break;

		to += thislen;
	}

	up(&writev_buf_sem);
	*retlen = totretlen;
	return ret;
}


static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
			size_t * retlen, u_char * buf)
{
	struct DiskOnChip *this = mtd->priv;
	int len256 = 0, ret;
	struct Nand *mychip;

	down(&this->lock);

	mychip = &this->chips[ofs >> this->chipshift];

	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(this, mychip->floor);
		DoC_SelectChip(this, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(this, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* update address for 2M x 8bit devices. OOB starts on the second */
	/* page to maintain compatibility with doc_read_ecc. */
	if (this->page256) {
		if (!(ofs & 0x8))
			ofs += 0x100;
		else
			ofs -= 0x8;
	}

	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);

	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
	/* Note: datasheet says it should automaticaly wrap to the */
	/*       next OOB block, but it didn't work here. mf.      */
	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
		len256 = (ofs | 0x7) + 1 - ofs;
		DoC_ReadBuf(this, buf, len256);

		DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
			    CDSN_CTRL_WP, 0);
	}

	DoC_ReadBuf(this, &buf[len256], len - len256);

	*retlen = len;
	/* Reading the full OOB data drops us off of the end of the page,
         * causing the flash device to go into busy mode, so we need
         * to wait until ready 11.4.1 and Toshiba TC58256FT docs */

	ret = DoC_WaitReady(this);

	up(&this->lock);
	return ret;

}

static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
				size_t * retlen, const u_char * buf)
{
	struct DiskOnChip *this = mtd->priv;
	int len256 = 0;
	void __iomem *docptr = this->virtadr;
	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
	volatile int dummy;
	int status;

	//      printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
	//   buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);

	/* Find the chip which is to be used and select it */
	if (this->curfloor != mychip->floor) {
		DoC_SelectFloor(this, mychip->floor);
		DoC_SelectChip(this, mychip->chip);
	} else if (this->curchip != mychip->chip) {
		DoC_SelectChip(this, mychip->chip);
	}
	this->curfloor = mychip->floor;
	this->curchip = mychip->chip;

	/* disable the ECC engine */
	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
	WriteDOC (DOC_ECC_DIS, docptr, ECCConf);

	/* Reset the chip, see Software Requirement 11.4 item 1. */
	DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);

	/* issue the Read2 command to set the pointer to the Spare Data Area. */
	DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);

	/* update address for 2M x 8bit devices. OOB starts on the second */
	/* page to maintain compatibility with doc_read_ecc. */
	if (this->page256) {
		if (!(ofs & 0x8))
			ofs += 0x100;
		else
			ofs -= 0x8;
	}

	/* issue the Serial Data In command to initial the Page Program process */
	DoC_Command(this, NAND_CMD_SEQIN, 0);
	DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);

	/* treat crossing 8-byte OOB data for 2M x 8bit devices */
	/* Note: datasheet says it should automaticaly wrap to the */
	/*       next OOB block, but it didn't work here. mf.      */
	if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
		len256 = (ofs | 0x7) + 1 - ofs;
		DoC_WriteBuf(this, buf, len256);

		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
		DoC_Command(this, NAND_CMD_STATUS, 0);
		/* DoC_WaitReady() is implicit in DoC_Command */

		if (DoC_is_Millennium(this)) {
			ReadDOC(docptr, ReadPipeInit);
			status = ReadDOC(docptr, LastDataRead);
		} else {
			dummy = ReadDOC(docptr, CDSNSlowIO);
			DoC_Delay(this, 2);
			status = ReadDOC_(docptr, this->ioreg);
		}

		if (status & 1) {
			printk(KERN_ERR "Error programming oob data\n");
			/* There was an error */
			*retlen = 0;
			return -EIO;
		}
		DoC_Command(this, NAND_CMD_SEQIN, 0);
		DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
	}

	DoC_WriteBuf(this, &buf[len256], len - len256);

	DoC_Command(this, NAND_CMD_PAGEPROG, 0);
	DoC_Command(this, NAND_CMD_STATUS, 0);
	/* DoC_WaitReady() is implicit in DoC_Command */

	if (DoC_is_Millennium(this)) {
		ReadDOC(docptr, ReadPipeInit);
		status = ReadDOC(docptr, LastDataRead);
	} else {
		dummy = ReadDOC(docptr, CDSNSlowIO);
		DoC_Delay(this, 2);
		status = ReadDOC_(docptr, this->ioreg);
	}

	if (status & 1) {
		printk(KERN_ERR "Error programming oob data\n");
		/* There was an error */
		*retlen = 0;
		return -EIO;
	}

	*retlen = len;
	return 0;

}

static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 			 size_t * retlen, const u_char * buf)
{
 	struct DiskOnChip *this = mtd->priv;
 	int ret;

 	down(&this->lock);
 	ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);

 	up(&this->lock);
 	return ret;
}

static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct DiskOnChip *this = mtd->priv;
	__u32 ofs = instr->addr;
	__u32 len = instr->len;
	volatile int dummy;
	void __iomem *docptr = this->virtadr;
	struct Nand *mychip;
	int status;

 	down(&this->lock);

	if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
		up(&this->lock);
		return -EINVAL;
	}

	instr->state = MTD_ERASING;

	/* FIXME: Do this in the background. Use timers or schedule_task() */
	while(len) {
		mychip = &this->chips[ofs >> this->chipshift];

		if (this->curfloor != mychip->floor) {
			DoC_SelectFloor(this, mychip->floor);
			DoC_SelectChip(this, mychip->chip);
		} else if (this->curchip != mychip->chip) {
			DoC_SelectChip(this, mychip->chip);
		}
		this->curfloor = mychip->floor;
		this->curchip = mychip->chip;

		DoC_Command(this, NAND_CMD_ERASE1, 0);
		DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
		DoC_Command(this, NAND_CMD_ERASE2, 0);

		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);

		if (DoC_is_Millennium(this)) {
			ReadDOC(docptr, ReadPipeInit);
			status = ReadDOC(docptr, LastDataRead);
		} else {
			dummy = ReadDOC(docptr, CDSNSlowIO);
			DoC_Delay(this, 2);
			status = ReadDOC_(docptr, this->ioreg);
		}

		if (status & 1) {
			printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
			/* There was an error */
			instr->state = MTD_ERASE_FAILED;
			goto callback;
		}
		ofs += mtd->erasesize;
		len -= mtd->erasesize;
	}
	instr->state = MTD_ERASE_DONE;

 callback:
	mtd_erase_callback(instr);

	up(&this->lock);
	return 0;
}


/****************************************************************************
 *
 * Module stuff
 *
 ****************************************************************************/

static int __init init_doc2000(void)
{
       inter_module_register(im_name, THIS_MODULE, &DoC2k_init);
       return 0;
}

static void __exit cleanup_doc2000(void)
{
	struct mtd_info *mtd;
	struct DiskOnChip *this;

	while ((mtd = doc2klist)) {
		this = mtd->priv;
		doc2klist = this->nextdoc;

		del_mtd_device(mtd);

		iounmap(this->virtadr);
		kfree(this->chips);
		kfree(mtd);
	}
	inter_module_unregister(im_name);
}

module_exit(cleanup_doc2000);
module_init(init_doc2000);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
MODULE_DESCRIPTION("MTD driver for DiskOnChip 2000 and Millennium");

