nand_base.c 71.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/*
 *  drivers/mtd/nand.c
 *
 *  Overview:
 *   This is the generic MTD driver for NAND flash devices. It should be
 *   capable of working with almost all NAND chips currently available.
 *   Basic support for AG-AND chips is provided.
8
 *
L
Linus Torvalds 已提交
9 10
 *	Additional technical information is available on
 *	http://www.linux-mtd.infradead.org/tech/nand.html
11
 *
L
Linus Torvalds 已提交
12
 *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13
 *		  2002 Thomas Gleixner (tglx@linutronix.de)
L
Linus Torvalds 已提交
14
 *
15
 *  02-08-2004  tglx: support for strange chips, which cannot auto increment
L
Linus Torvalds 已提交
16 17 18 19 20 21 22 23
 *		pages on read / read_oob
 *
 *  03-17-2004  tglx: Check ready before auto increment check. Simon Bayes
 *		pointed this out, as he marked an auto increment capable chip
 *		as NOAUTOINCR in the board driver.
 *		Make reads over block boundaries work too
 *
 *  04-14-2004	tglx: first working version for 2k page size chips
24
 *
L
Linus Torvalds 已提交
25 26 27
 *  05-19-2004  tglx: Basic support for Renesas AG-AND chips
 *
 *  09-24-2004  tglx: add support for hardware controllers (e.g. ECC) shared
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
 *		among multiple independend devices. Suggestions and initial
 *		patch from Ben Dooks <ben-mtd@fluff.org>
 *
 *  12-05-2004	dmarlin: add workaround for Renesas AG-AND chips "disturb"
 *		issue. Basically, any block not rewritten may lose data when
 *		surrounding blocks are rewritten many times.  JFFS2 ensures
 *		this doesn't happen for blocks it uses, but the Bad Block
 *		Table(s) may not be rewritten.  To ensure they do not lose
 *		data, force them to be rewritten when some of the surrounding
 *		blocks are erased.  Rather than tracking a specific nearby
 *		block (which could itself go bad), use a page address 'mask' to
 *		select several blocks in the same area, and rewrite the BBT
 *		when any of them are erased.
 *
 *  01-03-2005	dmarlin: added support for the device recovery command sequence
 *		for Renesas AG-AND chips.  If there was a sudden loss of power
 *		during an erase operation, a "device recovery" operation must
 *		be performed when power is restored to ensure correct
 *		operation.
 *
 *  01-20-2005	dmarlin: added support for optional hardware specific callback
 *		routine to perform extra error status checks on erase and write
 *		failures.  This required adding a wrapper function for
 *		nand_read_ecc.
52
 *
53 54
 * 08-20-2005	vwool: suspend/resume added
 *
L
Linus Torvalds 已提交
55
 * Credits:
56 57
 *	David Woodhouse for adding multichip support
 *
L
Linus Torvalds 已提交
58 59 60 61 62 63 64 65 66 67
 *	Aleph One Ltd. and Toby Churchill Ltd. for supporting the
 *	rework for 2K page size chips
 *
 * TODO:
 *	Enable cached programming for 2k page size chips
 *	Check, if mtd->ecctype should be set to MTD_ECC_HW
 *	if we have HW ecc support.
 *	The AG-AND chips have nice features for speed improvement,
 *	which are not supported yet. Read / program 4 pages in one go.
 *
68
 * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $
L
Linus Torvalds 已提交
69 70 71 72 73 74 75
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

76
#include <linux/module.h>
L
Linus Torvalds 已提交
77 78
#include <linux/delay.h>
#include <linux/errno.h>
T
Thomas Gleixner 已提交
79
#include <linux/err.h>
L
Linus Torvalds 已提交
80 81 82 83 84 85 86 87 88
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/compatmac.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
89
#include <linux/leds.h>
L
Linus Torvalds 已提交
90 91 92 93 94 95 96 97 98 99 100
#include <asm/io.h>

#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif

/* Define default oob placement schemes for large and small page devices */
static struct nand_oobinfo nand_oob_8 = {
	.useecc = MTD_NANDECC_AUTOPLACE,
	.eccbytes = 3,
	.eccpos = {0, 1, 2},
101
	.oobfree = {{3, 2}, {6, 2}}
L
Linus Torvalds 已提交
102 103 104 105 106 107
};

static struct nand_oobinfo nand_oob_16 = {
	.useecc = MTD_NANDECC_AUTOPLACE,
	.eccbytes = 6,
	.eccpos = {0, 1, 2, 3, 6, 7},
108
	.oobfree = {{8, 8}}
L
Linus Torvalds 已提交
109 110 111 112 113 114
};

static struct nand_oobinfo nand_oob_64 = {
	.useecc = MTD_NANDECC_AUTOPLACE,
	.eccbytes = 24,
	.eccpos = {
115 116 117 118
		   40, 41, 42, 43, 44, 45, 46, 47,
		   48, 49, 50, 51, 52, 53, 54, 55,
		   56, 57, 58, 59, 60, 61, 62, 63},
	.oobfree = {{2, 38}}
L
Linus Torvalds 已提交
119 120 121
};

/* This is used for padding purposes in nand_write_oob */
122
static uint8_t ffchars[] = {
L
Linus Torvalds 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};

/*
 * NAND low-level MTD interface functions
 */
136 137 138
static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
L
Linus Torvalds 已提交
139

140
static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
141
		     size_t *retlen, uint8_t *buf);
142
static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
143
			 size_t *retlen, uint8_t *buf);
144
static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
145
		      size_t *retlen, const uint8_t *buf);
146
static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
147
			  size_t *retlen, const uint8_t *buf);
148 149
static int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
static void nand_sync(struct mtd_info *mtd);
L
Linus Torvalds 已提交
150 151

/* Some internal functions */
152
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this,
153
			   int page, uint8_t * oob_buf,
154
			   struct nand_oobinfo *oobsel, int mode);
L
Linus Torvalds 已提交
155
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
156
static int nand_verify_pages(struct mtd_info *mtd, struct nand_chip *this,
157
			     int page, int numpages, uint8_t *oob_buf,
158 159
			     struct nand_oobinfo *oobsel, int chipnr,
			     int oobmode);
L
Linus Torvalds 已提交
160 161 162
#else
#define nand_verify_pages(...) (0)
#endif
163

164 165
static int nand_get_device(struct nand_chip *this, struct mtd_info *mtd,
			   int new_state);
L
Linus Torvalds 已提交
166

T
Thomas Gleixner 已提交
167 168 169 170 171 172
/*
 * For devices which display every fart in the system on a seperate LED. Is
 * compiled away when LED support is disabled.
 */
DEFINE_LED_TRIGGER(nand_led_trigger);

L
Linus Torvalds 已提交
173 174 175
/**
 * nand_release_device - [GENERIC] release chip
 * @mtd:	MTD device structure
176 177
 *
 * Deselect, release chip lock and wake up anyone waiting on the device
L
Linus Torvalds 已提交
178
 */
179
static void nand_release_device(struct mtd_info *mtd)
L
Linus Torvalds 已提交
180 181 182 183 184
{
	struct nand_chip *this = mtd->priv;

	/* De-select the NAND device */
	this->select_chip(mtd, -1);
185

T
Thomas Gleixner 已提交
186 187 188 189 190 191
	/* Release the controller and the chip */
	spin_lock(&this->controller->lock);
	this->controller->active = NULL;
	this->state = FL_READY;
	wake_up(&this->controller->wq);
	spin_unlock(&this->controller->lock);
L
Linus Torvalds 已提交
192 193 194 195 196 197 198 199
}

/**
 * nand_read_byte - [DEFAULT] read one byte from the chip
 * @mtd:	MTD device structure
 *
 * Default read function for 8bit buswith
 */
200
static uint8_t nand_read_byte(struct mtd_info *mtd)
L
Linus Torvalds 已提交
201 202 203 204 205 206 207 208 209
{
	struct nand_chip *this = mtd->priv;
	return readb(this->IO_ADDR_R);
}

/**
 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
 * @mtd:	MTD device structure
 *
210
 * Default read function for 16bit buswith with
L
Linus Torvalds 已提交
211 212
 * endianess conversion
 */
213
static uint8_t nand_read_byte16(struct mtd_info *mtd)
L
Linus Torvalds 已提交
214 215
{
	struct nand_chip *this = mtd->priv;
216
	return (uint8_t) cpu_to_le16(readw(this->IO_ADDR_R));
L
Linus Torvalds 已提交
217 218 219 220 221 222
}

/**
 * nand_read_word - [DEFAULT] read one word from the chip
 * @mtd:	MTD device structure
 *
223
 * Default read function for 16bit buswith without
L
Linus Torvalds 已提交
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
 * endianess conversion
 */
static u16 nand_read_word(struct mtd_info *mtd)
{
	struct nand_chip *this = mtd->priv;
	return readw(this->IO_ADDR_R);
}

/**
 * nand_select_chip - [DEFAULT] control CE line
 * @mtd:	MTD device structure
 * @chip:	chipnumber to select, -1 for deselect
 *
 * Default select function for 1 chip devices.
 */
static void nand_select_chip(struct mtd_info *mtd, int chip)
{
	struct nand_chip *this = mtd->priv;
242
	switch (chip) {
L
Linus Torvalds 已提交
243
	case -1:
244
		this->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
L
Linus Torvalds 已提交
245 246
		break;
	case 0:
247
		this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
L
Linus Torvalds 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
		break;

	default:
		BUG();
	}
}

/**
 * nand_write_buf - [DEFAULT] write buffer to chip
 * @mtd:	MTD device structure
 * @buf:	data buffer
 * @len:	number of bytes to write
 *
 * Default write function for 8bit buswith
 */
263
static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
L
Linus Torvalds 已提交
264 265 266 267
{
	int i;
	struct nand_chip *this = mtd->priv;

268
	for (i = 0; i < len; i++)
L
Linus Torvalds 已提交
269 270 271 272
		writeb(buf[i], this->IO_ADDR_W);
}

/**
273
 * nand_read_buf - [DEFAULT] read chip data into buffer
L
Linus Torvalds 已提交
274 275 276 277 278 279
 * @mtd:	MTD device structure
 * @buf:	buffer to store date
 * @len:	number of bytes to read
 *
 * Default read function for 8bit buswith
 */
280
static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
L
Linus Torvalds 已提交
281 282 283 284
{
	int i;
	struct nand_chip *this = mtd->priv;

285
	for (i = 0; i < len; i++)
L
Linus Torvalds 已提交
286 287 288 289
		buf[i] = readb(this->IO_ADDR_R);
}

/**
290
 * nand_verify_buf - [DEFAULT] Verify chip data against buffer
L
Linus Torvalds 已提交
291 292 293 294 295 296
 * @mtd:	MTD device structure
 * @buf:	buffer containing the data to compare
 * @len:	number of bytes to compare
 *
 * Default verify function for 8bit buswith
 */
297
static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
L
Linus Torvalds 已提交
298 299 300 301
{
	int i;
	struct nand_chip *this = mtd->priv;

302
	for (i = 0; i < len; i++)
L
Linus Torvalds 已提交
303 304 305 306 307 308 309 310 311 312 313 314 315 316
		if (buf[i] != readb(this->IO_ADDR_R))
			return -EFAULT;

	return 0;
}

/**
 * nand_write_buf16 - [DEFAULT] write buffer to chip
 * @mtd:	MTD device structure
 * @buf:	data buffer
 * @len:	number of bytes to write
 *
 * Default write function for 16bit buswith
 */
317
static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
L
Linus Torvalds 已提交
318 319 320 321 322
{
	int i;
	struct nand_chip *this = mtd->priv;
	u16 *p = (u16 *) buf;
	len >>= 1;
323

324
	for (i = 0; i < len; i++)
L
Linus Torvalds 已提交
325
		writew(p[i], this->IO_ADDR_W);
326

L
Linus Torvalds 已提交
327 328 329
}

/**
330
 * nand_read_buf16 - [DEFAULT] read chip data into buffer
L
Linus Torvalds 已提交
331 332 333 334 335 336
 * @mtd:	MTD device structure
 * @buf:	buffer to store date
 * @len:	number of bytes to read
 *
 * Default read function for 16bit buswith
 */
337
static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
L
Linus Torvalds 已提交
338 339 340 341 342 343
{
	int i;
	struct nand_chip *this = mtd->priv;
	u16 *p = (u16 *) buf;
	len >>= 1;

344
	for (i = 0; i < len; i++)
L
Linus Torvalds 已提交
345 346 347 348
		p[i] = readw(this->IO_ADDR_R);
}

/**
349
 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
L
Linus Torvalds 已提交
350 351 352 353 354 355
 * @mtd:	MTD device structure
 * @buf:	buffer containing the data to compare
 * @len:	number of bytes to compare
 *
 * Default verify function for 16bit buswith
 */
356
static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
L
Linus Torvalds 已提交
357 358 359 360 361 362
{
	int i;
	struct nand_chip *this = mtd->priv;
	u16 *p = (u16 *) buf;
	len >>= 1;

363
	for (i = 0; i < len; i++)
L
Linus Torvalds 已提交
364 365 366 367 368 369 370 371 372 373 374 375
		if (p[i] != readw(this->IO_ADDR_R))
			return -EFAULT;

	return 0;
}

/**
 * nand_block_bad - [DEFAULT] Read bad block marker from the chip
 * @mtd:	MTD device structure
 * @ofs:	offset from device start
 * @getchip:	0, if the chip is already selected
 *
376
 * Check, if the block is bad.
L
Linus Torvalds 已提交
377 378 379 380 381 382 383 384 385 386 387 388
 */
static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
{
	int page, chipnr, res = 0;
	struct nand_chip *this = mtd->priv;
	u16 bad;

	if (getchip) {
		page = (int)(ofs >> this->page_shift);
		chipnr = (int)(ofs >> this->chip_shift);

		/* Grab the lock and see if the device is available */
389
		nand_get_device(this, mtd, FL_READING);
L
Linus Torvalds 已提交
390 391 392

		/* Select the NAND device */
		this->select_chip(mtd, chipnr);
393
	} else
394
		page = (int)ofs;
L
Linus Torvalds 已提交
395 396

	if (this->options & NAND_BUSWIDTH_16) {
397 398
		this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE,
			      page & this->pagemask);
L
Linus Torvalds 已提交
399 400
		bad = cpu_to_le16(this->read_word(mtd));
		if (this->badblockpos & 0x1)
401
			bad >>= 8;
L
Linus Torvalds 已提交
402 403 404
		if ((bad & 0xFF) != 0xff)
			res = 1;
	} else {
405 406
		this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos,
			      page & this->pagemask);
L
Linus Torvalds 已提交
407 408 409
		if (this->read_byte(mtd) != 0xff)
			res = 1;
	}
410

L
Linus Torvalds 已提交
411 412 413
	if (getchip) {
		/* Deselect and wake up anyone waiting on the device */
		nand_release_device(mtd);
414 415
	}

L
Linus Torvalds 已提交
416 417 418 419 420 421 422 423 424 425 426 427 428 429
	return res;
}

/**
 * nand_default_block_markbad - [DEFAULT] mark a block bad
 * @mtd:	MTD device structure
 * @ofs:	offset from device start
 *
 * This is the default implementation, which can be overridden by
 * a hardware specific driver.
*/
static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
	struct nand_chip *this = mtd->priv;
430
	uint8_t buf[2] = { 0, 0 };
431
	size_t retlen;
L
Linus Torvalds 已提交
432
	int block;
433

L
Linus Torvalds 已提交
434
	/* Get block number */
435
	block = ((int)ofs) >> this->bbt_erase_shift;
436 437
	if (this->bbt)
		this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
L
Linus Torvalds 已提交
438 439 440

	/* Do we have a flash based bad block table ? */
	if (this->options & NAND_USE_FLASH_BBT)
441
		return nand_update_bbt(mtd, ofs);
442

L
Linus Torvalds 已提交
443 444
	/* We write two bytes, so we dont have to mess with 16 bit access */
	ofs += mtd->oobsize + (this->badblockpos & ~0x01);
445
	return nand_write_oob(mtd, ofs, 2, &retlen, buf);
L
Linus Torvalds 已提交
446 447
}

448
/**
L
Linus Torvalds 已提交
449 450
 * nand_check_wp - [GENERIC] check if the chip is write protected
 * @mtd:	MTD device structure
451
 * Check, if the device is write protected
L
Linus Torvalds 已提交
452
 *
453
 * The function expects, that the device is already selected
L
Linus Torvalds 已提交
454
 */
455
static int nand_check_wp(struct mtd_info *mtd)
L
Linus Torvalds 已提交
456 457 458
{
	struct nand_chip *this = mtd->priv;
	/* Check the WP bit */
459
	this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
460
	return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
L
Linus Torvalds 已提交
461 462 463 464 465 466 467 468 469 470 471 472
}

/**
 * nand_block_checkbad - [GENERIC] Check if a block is marked bad
 * @mtd:	MTD device structure
 * @ofs:	offset from device start
 * @getchip:	0, if the chip is already selected
 * @allowbbt:	1, if its allowed to access the bbt area
 *
 * Check, if the block is bad. Either by reading the bad block table or
 * calling of the scan function.
 */
473 474
static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
			       int allowbbt)
L
Linus Torvalds 已提交
475 476
{
	struct nand_chip *this = mtd->priv;
477

L
Linus Torvalds 已提交
478 479
	if (!this->bbt)
		return this->block_bad(mtd, ofs, getchip);
480

L
Linus Torvalds 已提交
481
	/* Return info from the table */
482
	return nand_isbad_bbt(mtd, ofs, allowbbt);
L
Linus Torvalds 已提交
483 484
}

485
/*
486 487 488 489 490 491
 * Wait for the ready pin, after a command
 * The timeout is catched later.
 */
static void nand_wait_ready(struct mtd_info *mtd)
{
	struct nand_chip *this = mtd->priv;
492
	unsigned long timeo = jiffies + 2;
493

494
	led_trigger_event(nand_led_trigger, LED_FULL);
495 496 497
	/* wait until command is processed or timeout occures */
	do {
		if (this->dev_ready(mtd))
498
			break;
I
Ingo Molnar 已提交
499
		touch_softlockup_watchdog();
500
	} while (time_before(jiffies, timeo));
501
	led_trigger_event(nand_led_trigger, LED_OFF);
502 503
}

L
Linus Torvalds 已提交
504 505 506 507 508 509 510 511 512 513
/**
 * nand_command - [DEFAULT] Send command to NAND device
 * @mtd:	MTD device structure
 * @command:	the command to be sent
 * @column:	the column address for this command, -1 if none
 * @page_addr:	the page address for this command, -1 if none
 *
 * Send command to NAND device. This function is used for small page
 * devices (256/512 Bytes per page)
 */
514 515
static void nand_command(struct mtd_info *mtd, unsigned int command,
			 int column, int page_addr)
L
Linus Torvalds 已提交
516 517
{
	register struct nand_chip *this = mtd->priv;
518
	int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
L
Linus Torvalds 已提交
519 520 521 522 523 524 525

	/*
	 * Write out the command to the device.
	 */
	if (command == NAND_CMD_SEQIN) {
		int readcmd;

J
Joern Engel 已提交
526
		if (column >= mtd->writesize) {
L
Linus Torvalds 已提交
527
			/* OOB area */
J
Joern Engel 已提交
528
			column -= mtd->writesize;
L
Linus Torvalds 已提交
529 530 531 532 533 534 535 536
			readcmd = NAND_CMD_READOOB;
		} else if (column < 256) {
			/* First 256 bytes --> READ0 */
			readcmd = NAND_CMD_READ0;
		} else {
			column -= 256;
			readcmd = NAND_CMD_READ1;
		}
537 538
		this->cmd_ctrl(mtd, readcmd, ctrl);
		ctrl &= ~NAND_CTRL_CHANGE;
L
Linus Torvalds 已提交
539
	}
540
	this->cmd_ctrl(mtd, command, ctrl);
L
Linus Torvalds 已提交
541

542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
	/*
	 * Address cycle, when necessary
	 */
	ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
	/* Serially input address */
	if (column != -1) {
		/* Adjust columns for 16 bit buswidth */
		if (this->options & NAND_BUSWIDTH_16)
			column >>= 1;
		this->cmd_ctrl(mtd, column, ctrl);
		ctrl &= ~NAND_CTRL_CHANGE;
	}
	if (page_addr != -1) {
		this->cmd_ctrl(mtd, page_addr, ctrl);
		ctrl &= ~NAND_CTRL_CHANGE;
		this->cmd_ctrl(mtd, page_addr >> 8, ctrl);
		/* One more address cycle for devices > 32MiB */
		if (this->chipsize > (32 << 20))
			this->cmd_ctrl(mtd, page_addr >> 16, ctrl);
L
Linus Torvalds 已提交
561
	}
562
	this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
563 564 565

	/*
	 * program and erase have their own busy handlers
L
Linus Torvalds 已提交
566
	 * status and sequential in needs no delay
567
	 */
L
Linus Torvalds 已提交
568
	switch (command) {
569

L
Linus Torvalds 已提交
570 571 572 573 574
	case NAND_CMD_PAGEPROG:
	case NAND_CMD_ERASE1:
	case NAND_CMD_ERASE2:
	case NAND_CMD_SEQIN:
	case NAND_CMD_STATUS:
575
		this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
L
Linus Torvalds 已提交
576 577 578
		return;

	case NAND_CMD_RESET:
579
		if (this->dev_ready)
L
Linus Torvalds 已提交
580 581
			break;
		udelay(this->chip_delay);
582 583 584
		this->cmd_ctrl(mtd, NAND_CMD_STATUS,
			       NAND_CTRL_CLE | NAND_CTRL_CHANGE);
		this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
585
		while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ;
L
Linus Torvalds 已提交
586 587
		return;

588
		/* This applies to read commands */
L
Linus Torvalds 已提交
589
	default:
590
		/*
L
Linus Torvalds 已提交
591 592
		 * If we don't have access to the busy pin, we apply the given
		 * command delay
593
		 */
L
Linus Torvalds 已提交
594
		if (!this->dev_ready) {
595
			udelay(this->chip_delay);
L
Linus Torvalds 已提交
596
			return;
597
		}
L
Linus Torvalds 已提交
598 599 600
	}
	/* Apply this short delay always to ensure that we do wait tWB in
	 * any case on any machine. */
601
	ndelay(100);
602 603

	nand_wait_ready(mtd);
L
Linus Torvalds 已提交
604 605 606 607 608 609 610 611 612
}

/**
 * nand_command_lp - [DEFAULT] Send command to NAND large page device
 * @mtd:	MTD device structure
 * @command:	the command to be sent
 * @column:	the column address for this command, -1 if none
 * @page_addr:	the page address for this command, -1 if none
 *
613 614 615
 * Send command to NAND device. This is the version for the new large page
 * devices We dont have the separate regions as we have in the small page
 * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
L
Linus Torvalds 已提交
616 617
 *
 */
618 619
static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
			    int column, int page_addr)
L
Linus Torvalds 已提交
620 621 622 623 624
{
	register struct nand_chip *this = mtd->priv;

	/* Emulate NAND_CMD_READOOB */
	if (command == NAND_CMD_READOOB) {
J
Joern Engel 已提交
625
		column += mtd->writesize;
L
Linus Torvalds 已提交
626 627
		command = NAND_CMD_READ0;
	}
628

629 630 631
	/* Command latch cycle */
	this->cmd_ctrl(mtd, command & 0xff,
		       NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
L
Linus Torvalds 已提交
632 633

	if (column != -1 || page_addr != -1) {
634
		int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
L
Linus Torvalds 已提交
635 636 637 638 639 640

		/* Serially input address */
		if (column != -1) {
			/* Adjust columns for 16 bit buswidth */
			if (this->options & NAND_BUSWIDTH_16)
				column >>= 1;
641 642 643
			this->cmd_ctrl(mtd, column, ctrl);
			ctrl &= ~NAND_CTRL_CHANGE;
			this->cmd_ctrl(mtd, column >> 8, ctrl);
644
		}
L
Linus Torvalds 已提交
645
		if (page_addr != -1) {
646 647 648
			this->cmd_ctrl(mtd, page_addr, ctrl);
			this->cmd_ctrl(mtd, page_addr >> 8,
				       NAND_NCE | NAND_ALE);
L
Linus Torvalds 已提交
649 650
			/* One more address cycle for devices > 128MiB */
			if (this->chipsize > (128 << 20))
651 652
				this->cmd_ctrl(mtd, page_addr >> 16,
					       NAND_NCE | NAND_ALE);
L
Linus Torvalds 已提交
653 654
		}
	}
655
	this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
656 657 658

	/*
	 * program and erase have their own busy handlers
659 660
	 * status, sequential in, and deplete1 need no delay
	 */
L
Linus Torvalds 已提交
661
	switch (command) {
662

L
Linus Torvalds 已提交
663 664 665 666 667 668
	case NAND_CMD_CACHEDPROG:
	case NAND_CMD_PAGEPROG:
	case NAND_CMD_ERASE1:
	case NAND_CMD_ERASE2:
	case NAND_CMD_SEQIN:
	case NAND_CMD_STATUS:
669
	case NAND_CMD_DEPLETE1:
L
Linus Torvalds 已提交
670 671
		return;

672 673 674
		/*
		 * read error status commands require only a short delay
		 */
675 676 677 678 679 680 681
	case NAND_CMD_STATUS_ERROR:
	case NAND_CMD_STATUS_ERROR0:
	case NAND_CMD_STATUS_ERROR1:
	case NAND_CMD_STATUS_ERROR2:
	case NAND_CMD_STATUS_ERROR3:
		udelay(this->chip_delay);
		return;
L
Linus Torvalds 已提交
682 683

	case NAND_CMD_RESET:
684
		if (this->dev_ready)
L
Linus Torvalds 已提交
685 686
			break;
		udelay(this->chip_delay);
687 688
		this->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_NCE | NAND_CLE);
		this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
689
		while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ;
L
Linus Torvalds 已提交
690 691 692
		return;

	case NAND_CMD_READ0:
693 694
		this->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_NCE | NAND_CLE);
		this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
695

696
		/* This applies to read commands */
L
Linus Torvalds 已提交
697
	default:
698
		/*
L
Linus Torvalds 已提交
699 700
		 * If we don't have access to the busy pin, we apply the given
		 * command delay
701
		 */
L
Linus Torvalds 已提交
702
		if (!this->dev_ready) {
703
			udelay(this->chip_delay);
L
Linus Torvalds 已提交
704
			return;
705
		}
L
Linus Torvalds 已提交
706
	}
707

L
Linus Torvalds 已提交
708 709
	/* Apply this short delay always to ensure that we do wait tWB in
	 * any case on any machine. */
710
	ndelay(100);
711 712

	nand_wait_ready(mtd);
L
Linus Torvalds 已提交
713 714 715 716 717 718
}

/**
 * nand_get_device - [GENERIC] Get chip for selected access
 * @this:	the nand chip descriptor
 * @mtd:	MTD device structure
719
 * @new_state:	the state which is requested
L
Linus Torvalds 已提交
720 721 722
 *
 * Get the device and lock it for exclusive access
 */
723 724
static int
nand_get_device(struct nand_chip *this, struct mtd_info *mtd, int new_state)
L
Linus Torvalds 已提交
725
{
T
Thomas Gleixner 已提交
726 727
	spinlock_t *lock = &this->controller->lock;
	wait_queue_head_t *wq = &this->controller->wq;
728 729
	DECLARE_WAITQUEUE(wait, current);
 retry:
730 731
	spin_lock(lock);

L
Linus Torvalds 已提交
732
	/* Hardware controller shared among independend devices */
T
Thomas Gleixner 已提交
733 734 735 736 737
	/* Hardware controller shared among independend devices */
	if (!this->controller->active)
		this->controller->active = this;

	if (this->controller->active == this && this->state == FL_READY) {
738 739
		this->state = new_state;
		spin_unlock(lock);
740 741 742 743 744
		return 0;
	}
	if (new_state == FL_PM_SUSPENDED) {
		spin_unlock(lock);
		return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
745 746 747 748 749 750
	}
	set_current_state(TASK_UNINTERRUPTIBLE);
	add_wait_queue(wq, &wait);
	spin_unlock(lock);
	schedule();
	remove_wait_queue(wq, &wait);
L
Linus Torvalds 已提交
751 752 753 754 755 756 757 758 759 760
	goto retry;
}

/**
 * nand_wait - [DEFAULT]  wait until the command is done
 * @mtd:	MTD device structure
 * @this:	NAND chip structure
 * @state:	state to select the max. timeout value
 *
 * Wait for command done. This applies to erase and program only
761
 * Erase can take up to 400ms and program up to 20ms according to
L
Linus Torvalds 已提交
762 763 764 765 766 767
 * general NAND and SmartMedia specs
 *
*/
static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
{

768 769
	unsigned long timeo = jiffies;
	int status;
770

L
Linus Torvalds 已提交
771
	if (state == FL_ERASING)
772
		timeo += (HZ * 400) / 1000;
L
Linus Torvalds 已提交
773
	else
774
		timeo += (HZ * 20) / 1000;
L
Linus Torvalds 已提交
775

776 777
	led_trigger_event(nand_led_trigger, LED_FULL);

L
Linus Torvalds 已提交
778 779
	/* Apply this short delay always to ensure that we do wait tWB in
	 * any case on any machine. */
780
	ndelay(100);
L
Linus Torvalds 已提交
781 782

	if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
783
		this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
784
	else
785
		this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
L
Linus Torvalds 已提交
786

787
	while (time_before(jiffies, timeo)) {
L
Linus Torvalds 已提交
788 789 790 791 792 793
		/* Check, if we were interrupted */
		if (this->state != state)
			return 0;

		if (this->dev_ready) {
			if (this->dev_ready(mtd))
794
				break;
L
Linus Torvalds 已提交
795 796 797 798
		} else {
			if (this->read_byte(mtd) & NAND_STATUS_READY)
				break;
		}
799
		cond_resched();
L
Linus Torvalds 已提交
800
	}
801 802
	led_trigger_event(nand_led_trigger, LED_OFF);

803
	status = (int)this->read_byte(mtd);
L
Linus Torvalds 已提交
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
	return status;
}

/**
 * nand_write_page - [GENERIC] write one page
 * @mtd:	MTD device structure
 * @this:	NAND chip structure
 * @page: 	startpage inside the chip, must be called with (page & this->pagemask)
 * @oob_buf:	out of band data buffer
 * @oobsel:	out of band selecttion structre
 * @cached:	1 = enable cached programming if supported by chip
 *
 * Nand_page_program function is used for write and writev !
 * This function will always program a full page of data
 * If you call it with a non page aligned buffer, you're lost :)
 *
 * Cached programming is not supported yet.
 */
822
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int page,
823
			   uint8_t *oob_buf, struct nand_oobinfo *oobsel, int cached)
L
Linus Torvalds 已提交
824
{
825
	int i, status;
826
	uint8_t ecc_code[32];
T
Thomas Gleixner 已提交
827
	int eccmode = oobsel->useecc ? this->ecc.mode : NAND_ECC_NONE;
828
	int *oob_config = oobsel->eccpos;
T
Thomas Gleixner 已提交
829
	int datidx = 0, eccidx = 0, eccsteps = this->ecc.steps;
830
	int eccbytes = 0;
831

L
Linus Torvalds 已提交
832 833
	/* FIXME: Enable cached programming */
	cached = 0;
834

L
Linus Torvalds 已提交
835
	/* Send command to begin auto page programming */
836
	this->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
L
Linus Torvalds 已提交
837 838 839

	/* Write out complete page of data, take care of eccmode */
	switch (eccmode) {
840
		/* No ecc, write all */
L
Linus Torvalds 已提交
841
	case NAND_ECC_NONE:
842
		printk(KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
J
Joern Engel 已提交
843
		this->write_buf(mtd, this->data_poi, mtd->writesize);
L
Linus Torvalds 已提交
844
		break;
845

846
		/* Software ecc 3/256, write all */
L
Linus Torvalds 已提交
847 848
	case NAND_ECC_SOFT:
		for (; eccsteps; eccsteps--) {
T
Thomas Gleixner 已提交
849
			this->ecc.calculate(mtd, &this->data_poi[datidx], ecc_code);
L
Linus Torvalds 已提交
850 851
			for (i = 0; i < 3; i++, eccidx++)
				oob_buf[oob_config[eccidx]] = ecc_code[i];
T
Thomas Gleixner 已提交
852
			datidx += this->ecc.size;
L
Linus Torvalds 已提交
853
		}
J
Joern Engel 已提交
854
		this->write_buf(mtd, this->data_poi, mtd->writesize);
L
Linus Torvalds 已提交
855 856
		break;
	default:
T
Thomas Gleixner 已提交
857
		eccbytes = this->ecc.bytes;
L
Linus Torvalds 已提交
858 859
		for (; eccsteps; eccsteps--) {
			/* enable hardware ecc logic for write */
T
Thomas Gleixner 已提交
860 861 862
			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);
L
Linus Torvalds 已提交
863 864 865 866 867 868 869
			for (i = 0; i < eccbytes; i++, eccidx++)
				oob_buf[oob_config[eccidx]] = ecc_code[i];
			/* If the hardware ecc provides syndromes then
			 * the ecc code must be written immidiately after
			 * the data bytes (words) */
			if (this->options & NAND_HWECC_SYNDROME)
				this->write_buf(mtd, ecc_code, eccbytes);
T
Thomas Gleixner 已提交
870
			datidx += this->ecc.size;
L
Linus Torvalds 已提交
871 872 873
		}
		break;
	}
874

L
Linus Torvalds 已提交
875 876 877
	/* Write out OOB data */
	if (this->options & NAND_HWECC_SYNDROME)
		this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
878
	else
L
Linus Torvalds 已提交
879 880 881
		this->write_buf(mtd, oob_buf, mtd->oobsize);

	/* Send command to actually program the data */
882
	this->cmdfunc(mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
L
Linus Torvalds 已提交
883 884 885

	if (!cached) {
		/* call wait ready function */
886
		status = this->waitfunc(mtd, this, FL_WRITING);
887 888 889 890 891 892

		/* See if operation failed and additional status checks are available */
		if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
			status = this->errstat(mtd, this, FL_WRITING, status, page);
		}

L
Linus Torvalds 已提交
893
		/* See if device thinks it succeeded */
894
		if (status & NAND_STATUS_FAIL) {
895
			DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
L
Linus Torvalds 已提交
896 897 898 899
			return -EIO;
		}
	} else {
		/* FIXME: Implement cached programming ! */
900
		/* wait until cache is ready */
L
Linus Torvalds 已提交
901 902
		// status = this->waitfunc (mtd, this, FL_CACHEDRPG);
	}
903
	return 0;
L
Linus Torvalds 已提交
904 905 906 907 908 909 910
}

#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
/**
 * nand_verify_pages - [GENERIC] verify the chip contents after a write
 * @mtd:	MTD device structure
 * @this:	NAND chip structure
911
 * @page:	startpage inside the chip, must be called with (page & this->pagemask)
L
Linus Torvalds 已提交
912 913 914 915 916 917 918
 * @numpages:	number of pages to verify
 * @oob_buf:	out of band data buffer
 * @oobsel:	out of band selecttion structre
 * @chipnr:	number of the current chip
 * @oobmode:	1 = full buffer verify, 0 = ecc only
 *
 * The NAND device assumes that it is always writing to a cleanly erased page.
919
 * Hence, it performs its internal write verification only on bits that
L
Linus Torvalds 已提交
920
 * transitioned from 1 to 0. The device does NOT verify the whole page on a
921 922 923
 * byte by byte basis. It is possible that the page was not completely erased
 * or the page is becoming unusable due to wear. The read with ECC would catch
 * the error later when the ECC page check fails, but we would rather catch
L
Linus Torvalds 已提交
924 925
 * it early in the page write stage. Better to write no data than invalid data.
 */
926
static int nand_verify_pages(struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
927
			     uint8_t *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
L
Linus Torvalds 已提交
928
{
929 930 931
	int i, j, datidx = 0, oobofs = 0, res = -EIO;
	int eccsteps = this->eccsteps;
	int hweccbytes;
932
	uint8_t oobdata[64];
L
Linus Torvalds 已提交
933 934 935 936

	hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;

	/* Send command to read back the first page */
937
	this->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
L
Linus Torvalds 已提交
938

939
	for (;;) {
L
Linus Torvalds 已提交
940 941 942
		for (j = 0; j < eccsteps; j++) {
			/* Loop through and verify the data */
			if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
943
				DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
L
Linus Torvalds 已提交
944 945 946 947 948 949 950
				goto out;
			}
			datidx += mtd->eccsize;
			/* Have we a hw generator layout ? */
			if (!hweccbytes)
				continue;
			if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
951
				DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
L
Linus Torvalds 已提交
952 953 954 955 956 957 958 959 960 961
				goto out;
			}
			oobofs += hweccbytes;
		}

		/* check, if we must compare all data or if we just have to
		 * compare the ecc bytes
		 */
		if (oobmode) {
			if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
962
				DEBUG(MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
L
Linus Torvalds 已提交
963 964 965 966 967 968 969 970
				goto out;
			}
		} else {
			/* Read always, else autoincrement fails */
			this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);

			if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
				int ecccnt = oobsel->eccbytes;
971

L
Linus Torvalds 已提交
972 973
				for (i = 0; i < ecccnt; i++) {
					int idx = oobsel->eccpos[i];
974 975 976
					if (oobdata[idx] != oob_buf[oobofs + idx]) {
						DEBUG(MTD_DEBUG_LEVEL0, "%s: Failed ECC write verify, page 0x%08x, %6i bytes were succesful\n",
						      __FUNCTION__, page, i);
L
Linus Torvalds 已提交
977 978 979
						goto out;
					}
				}
980
			}
L
Linus Torvalds 已提交
981 982 983 984 985
		}
		oobofs += mtd->oobsize - hweccbytes * eccsteps;
		page++;
		numpages--;

986
		/* Apply delay or wait for ready/busy pin
L
Linus Torvalds 已提交
987 988 989 990 991
		 * Do this before the AUTOINCR check, so no problems
		 * arise if a chip which does auto increment
		 * is marked as NOAUTOINCR by the board driver.
		 * Do this also before returning, so the chip is
		 * ready for the next command.
992
		 */
993
		if (!this->dev_ready)
994
			udelay(this->chip_delay);
L
Linus Torvalds 已提交
995
		else
996
			nand_wait_ready(mtd);
L
Linus Torvalds 已提交
997 998 999 1000

		/* All done, return happy */
		if (!numpages)
			return 0;
1001 1002

		/* Check, if the chip supports auto page increment */
L
Linus Torvalds 已提交
1003
		if (!NAND_CANAUTOINCR(this))
1004
			this->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
L
Linus Torvalds 已提交
1005
	}
1006
	/*
L
Linus Torvalds 已提交
1007 1008 1009
	 * Terminate the read command. We come here in case of an error
	 * So we must issue a reset command.
	 */
1010 1011
 out:
	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
L
Linus Torvalds 已提交
1012 1013 1014 1015 1016
	return res;
}
#endif

/**
1017
 * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
L
Linus Torvalds 已提交
1018 1019 1020 1021 1022 1023
 * @mtd:	MTD device structure
 * @from:	offset to read from
 * @len:	number of bytes to read
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:	the databuffer to put data
 *
1024 1025 1026
 * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
 * and flags = 0xff
 */
1027
static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, uint8_t *buf)
L
Linus Torvalds 已提交
1028
{
1029
	return nand_do_read_ecc(mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
1030
}
L
Linus Torvalds 已提交
1031

1032 1033 1034 1035 1036 1037 1038
/**
 * nand_do_read_ecc - [MTD Interface] Read data with ECC
 * @mtd:	MTD device structure
 * @from:	offset to read from
 * @len:	number of bytes to read
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:	the databuffer to put data
1039
 * @oob_buf:	filesystem supplied oob data buffer (can be NULL)
1040
 * @oobsel:	oob selection structure
1041 1042 1043 1044 1045 1046 1047
 * @flags:	flag to indicate if nand_get_device/nand_release_device should be preformed
 *		and how many corrected error bits are acceptable:
 *		  bits 0..7 - number of tolerable errors
 *		  bit  8    - 0 == do not get/release chip, 1 == get/release chip
 *
 * NAND read with ECC
 */
1048
int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1049
		     size_t *retlen, uint8_t *buf, uint8_t *oob_buf, struct nand_oobinfo *oobsel, int flags)
L
Linus Torvalds 已提交
1050
{
1051

L
Linus Torvalds 已提交
1052 1053 1054
	int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
	int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
	struct nand_chip *this = mtd->priv;
1055 1056 1057
	uint8_t *data_poi, *oob_data = oob_buf;
	uint8_t ecc_calc[32];
	uint8_t ecc_code[32];
1058 1059 1060 1061 1062 1063
	int eccmode, eccsteps;
	int *oob_config, datidx;
	int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
	int eccbytes;
	int compareecc = 1;
	int oobreadlen;
L
Linus Torvalds 已提交
1064

1065
	DEBUG(MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int)from, (int)len);
L
Linus Torvalds 已提交
1066 1067 1068

	/* Do not allow reads past end of device */
	if ((from + len) > mtd->size) {
1069
		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
L
Linus Torvalds 已提交
1070 1071 1072 1073 1074
		*retlen = 0;
		return -EINVAL;
	}

	/* Grab the lock and see if the device is available */
1075
	if (flags & NAND_GET_DEVICE)
1076
		nand_get_device(this, mtd, FL_READING);
L
Linus Torvalds 已提交
1077 1078 1079 1080

	/* Autoplace of oob data ? Use the default placement scheme */
	if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
		oobsel = this->autooob;
1081

T
Thomas Gleixner 已提交
1082
	eccmode = oobsel->useecc ? this->ecc.mode : NAND_ECC_NONE;
L
Linus Torvalds 已提交
1083 1084 1085 1086 1087 1088 1089
	oob_config = oobsel->eccpos;

	/* Select the NAND device */
	chipnr = (int)(from >> this->chip_shift);
	this->select_chip(mtd, chipnr);

	/* First we calculate the starting page */
1090
	realpage = (int)(from >> this->page_shift);
L
Linus Torvalds 已提交
1091 1092 1093
	page = realpage & this->pagemask;

	/* Get raw starting column */
J
Joern Engel 已提交
1094
	col = from & (mtd->writesize - 1);
L
Linus Torvalds 已提交
1095

J
Joern Engel 已提交
1096
	end = mtd->writesize;
T
Thomas Gleixner 已提交
1097 1098
	ecc = this->ecc.size;
	eccbytes = this->ecc.bytes;
1099

L
Linus Torvalds 已提交
1100 1101 1102 1103
	if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
		compareecc = 0;

	oobreadlen = mtd->oobsize;
1104
	if (this->options & NAND_HWECC_SYNDROME)
L
Linus Torvalds 已提交
1105 1106 1107 1108
		oobreadlen -= oobsel->eccbytes;

	/* Loop until all data read */
	while (read < len) {
1109

L
Linus Torvalds 已提交
1110
		int aligned = (!col && (len - read) >= end);
1111
		/*
L
Linus Torvalds 已提交
1112 1113 1114 1115 1116
		 * If the read is not page aligned, we have to read into data buffer
		 * due to ecc, else we read into return buffer direct
		 */
		if (aligned)
			data_poi = &buf[read];
1117
		else
L
Linus Torvalds 已提交
1118
			data_poi = this->data_buf;
1119 1120

		/* Check, if we have this page in the buffer
L
Linus Torvalds 已提交
1121 1122 1123 1124 1125 1126 1127
		 *
		 * FIXME: Make it work when we must provide oob data too,
		 * check the usage of data_buf oob field
		 */
		if (realpage == this->pagebuf && !oob_buf) {
			/* aligned read ? */
			if (aligned)
1128
				memcpy(data_poi, this->data_buf, end);
L
Linus Torvalds 已提交
1129 1130 1131 1132 1133
			goto readdata;
		}

		/* Check, if we must send the read command */
		if (sndcmd) {
1134
			this->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
L
Linus Torvalds 已提交
1135
			sndcmd = 0;
1136
		}
L
Linus Torvalds 已提交
1137 1138

		/* get oob area, if we have no oob buffer from fs-driver */
1139 1140
		if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
			oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
L
Linus Torvalds 已提交
1141 1142
			oob_data = &this->data_buf[end];

T
Thomas Gleixner 已提交
1143
		eccsteps = this->ecc.steps;
1144

L
Linus Torvalds 已提交
1145
		switch (eccmode) {
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
		case NAND_ECC_NONE:{
				/* No ECC, Read in a page */
				static unsigned long lastwhinge = 0;
				if ((lastwhinge / HZ) != (jiffies / HZ)) {
					printk(KERN_WARNING
					       "Reading data from NAND FLASH without ECC is not recommended\n");
					lastwhinge = jiffies;
				}
				this->read_buf(mtd, data_poi, end);
				break;
L
Linus Torvalds 已提交
1156
			}
1157

L
Linus Torvalds 已提交
1158 1159
		case NAND_ECC_SOFT:	/* Software ECC 3/256: Read in a page + oob data */
			this->read_buf(mtd, data_poi, end);
1160
			for (i = 0, datidx = 0; eccsteps; eccsteps--, i += 3, datidx += ecc)
T
Thomas Gleixner 已提交
1161
				this->ecc.calculate(mtd, &data_poi[datidx], &ecc_calc[i]);
1162
			break;
L
Linus Torvalds 已提交
1163 1164

		default:
1165
			for (i = 0, datidx = 0; eccsteps; eccsteps--, i += eccbytes, datidx += ecc) {
T
Thomas Gleixner 已提交
1166
				this->ecc.hwctl(mtd, NAND_ECC_READ);
L
Linus Torvalds 已提交
1167 1168 1169 1170 1171 1172 1173
				this->read_buf(mtd, &data_poi[datidx], ecc);

				/* HW ecc with syndrome calculation must read the
				 * syndrome from flash immidiately after the data */
				if (!compareecc) {
					/* Some hw ecc generators need to know when the
					 * syndrome is read from flash */
T
Thomas Gleixner 已提交
1174
					this->ecc.hwctl(mtd, NAND_ECC_READSYN);
L
Linus Torvalds 已提交
1175 1176 1177 1178
					this->read_buf(mtd, &oob_data[i], eccbytes);
					/* We calc error correction directly, it checks the hw
					 * generator for an error, reads back the syndrome and
					 * does the error correction on the fly */
T
Thomas Gleixner 已提交
1179
					ecc_status = this->ecc.correct(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
1180
					if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1181 1182
						DEBUG(MTD_DEBUG_LEVEL0, "nand_read_ecc: "
						      "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
L
Linus Torvalds 已提交
1183 1184 1185
						ecc_failed++;
					}
				} else {
T
Thomas Gleixner 已提交
1186
					this->ecc.calculate(mtd, &data_poi[datidx], &ecc_calc[i]);
1187
				}
L
Linus Torvalds 已提交
1188
			}
1189
			break;
L
Linus Torvalds 已提交
1190 1191 1192 1193 1194 1195 1196
		}

		/* read oobdata */
		this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);

		/* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
		if (!compareecc)
1197 1198
			goto readoob;

L
Linus Torvalds 已提交
1199 1200 1201 1202
		/* Pick the ECC bytes out of the oob data */
		for (j = 0; j < oobsel->eccbytes; j++)
			ecc_code[j] = oob_data[oob_config[j]];

1203
		/* correct data, if necessary */
T
Thomas Gleixner 已提交
1204 1205
		for (i = 0, j = 0, datidx = 0; i < this->ecc.steps; i++, datidx += ecc) {
			ecc_status = this->ecc.correct(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
1206

L
Linus Torvalds 已提交
1207 1208
			/* Get next chunk of ecc bytes */
			j += eccbytes;
1209 1210

			/* Check, if we have a fs supplied oob-buffer,
L
Linus Torvalds 已提交
1211 1212 1213
			 * This is the legacy mode. Used by YAFFS1
			 * Should go away some day
			 */
1214
			if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
L
Linus Torvalds 已提交
1215 1216 1217
				int *p = (int *)(&oob_data[mtd->oobsize]);
				p[i] = ecc_status;
			}
1218 1219

			if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1220
				DEBUG(MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
L
Linus Torvalds 已提交
1221 1222
				ecc_failed++;
			}
1223
		}
L
Linus Torvalds 已提交
1224

1225
	      readoob:
L
Linus Torvalds 已提交
1226 1227 1228
		/* check, if we have a fs supplied oob-buffer */
		if (oob_buf) {
			/* without autoplace. Legacy mode used by YAFFS1 */
1229
			switch (oobsel->useecc) {
L
Linus Torvalds 已提交
1230
			case MTD_NANDECC_AUTOPLACE:
1231
			case MTD_NANDECC_AUTOPL_USR:
L
Linus Torvalds 已提交
1232
				/* Walk through the autoplace chunks */
1233
				for (i = 0; oobsel->oobfree[i][1]; i++) {
L
Linus Torvalds 已提交
1234 1235 1236
					int from = oobsel->oobfree[i][0];
					int num = oobsel->oobfree[i][1];
					memcpy(&oob_buf[oob], &oob_data[from], num);
1237
					oob += num;
L
Linus Torvalds 已提交
1238 1239 1240 1241
				}
				break;
			case MTD_NANDECC_PLACE:
				/* YAFFS1 legacy mode */
T
Thomas Gleixner 已提交
1242
				oob_data += this->ecc.steps * sizeof(int);
L
Linus Torvalds 已提交
1243 1244 1245 1246 1247 1248
			default:
				oob_data += mtd->oobsize;
			}
		}
	readdata:
		/* Partial page read, transfer data into fs buffer */
1249
		if (!aligned) {
L
Linus Torvalds 已提交
1250 1251
			for (j = col; j < end && read < len; j++)
				buf[read++] = data_poi[j];
1252 1253
			this->pagebuf = realpage;
		} else
J
Joern Engel 已提交
1254
			read += mtd->writesize;
L
Linus Torvalds 已提交
1255

1256
		/* Apply delay or wait for ready/busy pin
L
Linus Torvalds 已提交
1257 1258 1259
		 * Do this before the AUTOINCR check, so no problems
		 * arise if a chip which does auto increment
		 * is marked as NOAUTOINCR by the board driver.
1260
		 */
1261
		if (!this->dev_ready)
1262
			udelay(this->chip_delay);
L
Linus Torvalds 已提交
1263
		else
1264
			nand_wait_ready(mtd);
1265

L
Linus Torvalds 已提交
1266
		if (read == len)
1267
			break;
L
Linus Torvalds 已提交
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280

		/* For subsequent reads align to page boundary. */
		col = 0;
		/* Increment page address */
		realpage++;

		page = realpage & this->pagemask;
		/* Check, if we cross a chip boundary */
		if (!page) {
			chipnr++;
			this->select_chip(mtd, -1);
			this->select_chip(mtd, chipnr);
		}
1281 1282
		/* Check, if the chip supports auto page increment
		 * or if we have hit a block boundary.
1283
		 */
L
Linus Torvalds 已提交
1284
		if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1285
			sndcmd = 1;
L
Linus Torvalds 已提交
1286 1287 1288
	}

	/* Deselect and wake up anyone waiting on the device */
1289 1290
	if (flags & NAND_GET_DEVICE)
		nand_release_device(mtd);
L
Linus Torvalds 已提交
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310

	/*
	 * Return success, if no ECC failures, else -EBADMSG
	 * fs driver will take care of that, because
	 * retlen == desired len and result == -EBADMSG
	 */
	*retlen = read;
	return ecc_failed ? -EBADMSG : 0;
}

/**
 * nand_read_oob - [MTD Interface] NAND read out-of-band
 * @mtd:	MTD device structure
 * @from:	offset to read from
 * @len:	number of bytes to read
 * @retlen:	pointer to variable to store the number of read bytes
 * @buf:	the databuffer to put data
 *
 * NAND read out-of-band data from the spare area
 */
1311
static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, uint8_t *buf)
L
Linus Torvalds 已提交
1312 1313 1314
{
	int i, col, page, chipnr;
	struct nand_chip *this = mtd->priv;
1315
	int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
L
Linus Torvalds 已提交
1316

1317
	DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int)from, (int)len);
L
Linus Torvalds 已提交
1318 1319 1320 1321

	/* Shift to get page */
	page = (int)(from >> this->page_shift);
	chipnr = (int)(from >> this->chip_shift);
1322

L
Linus Torvalds 已提交
1323 1324 1325 1326 1327 1328 1329 1330
	/* Mask to get column */
	col = from & (mtd->oobsize - 1);

	/* Initialize return length value */
	*retlen = 0;

	/* Do not allow reads past end of device */
	if ((from + len) > mtd->size) {
1331
		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
L
Linus Torvalds 已提交
1332 1333 1334 1335 1336
		*retlen = 0;
		return -EINVAL;
	}

	/* Grab the lock and see if the device is available */
1337
	nand_get_device(this, mtd, FL_READING);
L
Linus Torvalds 已提交
1338 1339 1340 1341 1342

	/* Select the NAND device */
	this->select_chip(mtd, chipnr);

	/* Send the read command */
1343
	this->cmdfunc(mtd, NAND_CMD_READOOB, col, page & this->pagemask);
1344
	/*
L
Linus Torvalds 已提交
1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365
	 * Read the data, if we read more than one page
	 * oob data, let the device transfer the data !
	 */
	i = 0;
	while (i < len) {
		int thislen = mtd->oobsize - col;
		thislen = min_t(int, thislen, len);
		this->read_buf(mtd, &buf[i], thislen);
		i += thislen;

		/* Read more ? */
		if (i < len) {
			page++;
			col = 0;

			/* Check, if we cross a chip boundary */
			if (!(page & this->pagemask)) {
				chipnr++;
				this->select_chip(mtd, -1);
				this->select_chip(mtd, chipnr);
			}
1366 1367

			/* Apply delay or wait for ready/busy pin
1368 1369 1370 1371
			 * Do this before the AUTOINCR check, so no problems
			 * arise if a chip which does auto increment
			 * is marked as NOAUTOINCR by the board driver.
			 */
1372
			if (!this->dev_ready)
1373
				udelay(this->chip_delay);
1374 1375 1376
			else
				nand_wait_ready(mtd);

1377 1378
			/* Check, if the chip supports auto page increment
			 * or if we have hit a block boundary.
1379
			 */
L
Linus Torvalds 已提交
1380 1381
			if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
				/* For subsequent page reads set offset to 0 */
1382
				this->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
L
Linus Torvalds 已提交
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
			}
		}
	}

	/* Deselect and wake up anyone waiting on the device */
	nand_release_device(mtd);

	/* Return happy */
	*retlen = len;
	return 0;
}

/**
 * nand_read_raw - [GENERIC] Read raw data including oob into buffer
 * @mtd:	MTD device structure
 * @buf:	temporary buffer
 * @from:	offset to read from
 * @len:	number of bytes to read
 * @ooblen:	number of oob data bytes to read
 *
 * Read raw data including oob into buffer
 */
1405
int nand_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
L
Linus Torvalds 已提交
1406 1407
{
	struct nand_chip *this = mtd->priv;
1408 1409
	int page = (int)(from >> this->page_shift);
	int chip = (int)(from >> this->chip_shift);
L
Linus Torvalds 已提交
1410 1411
	int sndcmd = 1;
	int cnt = 0;
J
Joern Engel 已提交
1412
	int pagesize = mtd->writesize + mtd->oobsize;
1413
	int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
L
Linus Torvalds 已提交
1414 1415 1416

	/* Do not allow reads past end of device */
	if ((from + len) > mtd->size) {
1417
		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
L
Linus Torvalds 已提交
1418 1419 1420 1421
		return -EINVAL;
	}

	/* Grab the lock and see if the device is available */
1422
	nand_get_device(this, mtd, FL_READING);
L
Linus Torvalds 已提交
1423

1424
	this->select_chip(mtd, chip);
1425

L
Linus Torvalds 已提交
1426 1427
	/* Add requested oob length */
	len += ooblen;
1428

L
Linus Torvalds 已提交
1429 1430
	while (len) {
		if (sndcmd)
1431
			this->cmdfunc(mtd, NAND_CMD_READ0, 0, page & this->pagemask);
1432
		sndcmd = 0;
L
Linus Torvalds 已提交
1433

1434
		this->read_buf(mtd, &buf[cnt], pagesize);
L
Linus Torvalds 已提交
1435 1436 1437 1438

		len -= pagesize;
		cnt += pagesize;
		page++;
1439 1440

		if (!this->dev_ready)
1441
			udelay(this->chip_delay);
L
Linus Torvalds 已提交
1442
		else
1443
			nand_wait_ready(mtd);
1444 1445

		/* Check, if the chip supports auto page increment */
L
Linus Torvalds 已提交
1446 1447 1448 1449 1450 1451 1452 1453 1454
		if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
			sndcmd = 1;
	}

	/* Deselect and wake up anyone waiting on the device */
	nand_release_device(mtd);
	return 0;
}

1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
/**
 * nand_write_raw - [GENERIC] Write raw data including oob
 * @mtd:	MTD device structure
 * @buf:	source buffer
 * @to:		offset to write to
 * @len:	number of bytes to write
 * @buf:	source buffer
 * @oob:	oob buffer
 *
 * Write raw data including oob
 */
int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
		   uint8_t *buf, uint8_t *oob)
{
	struct nand_chip *this = mtd->priv;
	int page = (int)(to >> this->page_shift);
	int chip = (int)(to >> this->chip_shift);
	int ret;

	*retlen = 0;

	/* Do not allow writes past end of device */
	if ((to + len) > mtd->size) {
		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt write "
		      "beyond end of device\n");
		return -EINVAL;
	}

	/* Grab the lock and see if the device is available */
	nand_get_device(this, mtd, FL_WRITING);

	this->select_chip(mtd, chip);
	this->data_poi = buf;

	while (len != *retlen) {
		ret = nand_write_page(mtd, this, page, oob, &mtd->oobinfo, 0);
		if (ret)
			return ret;
		page++;
		*retlen += mtd->writesize;
		this->data_poi += mtd->writesize;
		oob += mtd->oobsize;
	}

	/* Deselect and wake up anyone waiting on the device */
	nand_release_device(mtd);
	return 0;
}
T
Thomas Gleixner 已提交
1503
EXPORT_SYMBOL_GPL(nand_write_raw);
1504

1505 1506
/**
 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
L
Linus Torvalds 已提交
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527
 * @mtd:	MTD device structure
 * @fsbuf:	buffer given by fs driver
 * @oobsel:	out of band selection structre
 * @autoplace:	1 = place given buffer into the oob bytes
 * @numpages:	number of pages to prepare
 *
 * Return:
 * 1. Filesystem buffer available and autoplacement is off,
 *    return filesystem buffer
 * 2. No filesystem buffer or autoplace is off, return internal
 *    buffer
 * 3. Filesystem buffer is given and autoplace selected
 *    put data from fs buffer into internal buffer and
 *    retrun internal buffer
 *
 * Note: The internal buffer is filled with 0xff. This must
 * be done only once, when no autoplacement happens
 * Autoplacement sets the buffer dirty flag, which
 * forces the 0xff fill before using the buffer again.
 *
*/
1528
static uint8_t *nand_prepare_oobbuf(struct mtd_info *mtd, uint8_t *fsbuf, struct nand_oobinfo *oobsel,
1529
				   int autoplace, int numpages)
L
Linus Torvalds 已提交
1530 1531 1532 1533 1534
{
	struct nand_chip *this = mtd->priv;
	int i, len, ofs;

	/* Zero copy fs supplied buffer */
1535
	if (fsbuf && !autoplace)
L
Linus Torvalds 已提交
1536 1537 1538
		return fsbuf;

	/* Check, if the buffer must be filled with ff again */
1539
	if (this->oobdirty) {
1540
		memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
L
Linus Torvalds 已提交
1541
		this->oobdirty = 0;
1542 1543
	}

L
Linus Torvalds 已提交
1544 1545 1546
	/* If we have no autoplacement or no fs buffer use the internal one */
	if (!autoplace || !fsbuf)
		return this->oob_buf;
1547

L
Linus Torvalds 已提交
1548 1549 1550 1551 1552 1553 1554
	/* Walk through the pages and place the data */
	this->oobdirty = 1;
	ofs = 0;
	while (numpages--) {
		for (i = 0, len = 0; len < mtd->oobavail; i++) {
			int to = ofs + oobsel->oobfree[i][0];
			int num = oobsel->oobfree[i][1];
1555
			memcpy(&this->oob_buf[to], fsbuf, num);
L
Linus Torvalds 已提交
1556 1557 1558 1559 1560 1561 1562 1563
			len += num;
			fsbuf += num;
		}
		ofs += mtd->oobavail;
	}
	return this->oob_buf;
}

J
Joern Engel 已提交
1564
#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0
L
Linus Torvalds 已提交
1565 1566

/**
1567
 * nand_write - [MTD Interface] NAND write with ECC
L
Linus Torvalds 已提交
1568 1569 1570 1571 1572 1573 1574 1575
 * @mtd:	MTD device structure
 * @to:		offset to write to
 * @len:	number of bytes to write
 * @retlen:	pointer to variable to store the number of written bytes
 * @buf:	the data to write
 *
 * NAND write with ECC
 */
1576 1577
static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
			  size_t *retlen, const uint8_t *buf)
L
Linus Torvalds 已提交
1578 1579 1580 1581
{
	int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
	int autoplace = 0, numpages, totalpages;
	struct nand_chip *this = mtd->priv;
1582
	uint8_t *oobbuf, *bufstart, *eccbuf = NULL;
1583
	int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
1584
	struct nand_oobinfo *oobsel = &mtd->oobinfo;
L
Linus Torvalds 已提交
1585

1586
	DEBUG(MTD_DEBUG_LEVEL3, "nand_write: to = 0x%08x, len = %i\n", (unsigned int)to, (int)len);
L
Linus Torvalds 已提交
1587 1588 1589 1590 1591 1592

	/* Initialize retlen, in case of early exit */
	*retlen = 0;

	/* Do not allow write past end of device */
	if ((to + len) > mtd->size) {
1593
		DEBUG(MTD_DEBUG_LEVEL0, "nand_write: Attempt to write past end of page\n");
L
Linus Torvalds 已提交
1594 1595 1596
		return -EINVAL;
	}

1597
	/* reject writes, which are not page aligned */
1598
	if (NOTALIGNED(to) || NOTALIGNED(len)) {
1599
		printk(KERN_NOTICE "nand_write: Attempt to write not page aligned data\n");
L
Linus Torvalds 已提交
1600 1601 1602 1603
		return -EINVAL;
	}

	/* Grab the lock and see if the device is available */
1604
	nand_get_device(this, mtd, FL_WRITING);
L
Linus Torvalds 已提交
1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618

	/* Calculate chipnr */
	chipnr = (int)(to >> this->chip_shift);
	/* Select the NAND device */
	this->select_chip(mtd, chipnr);

	/* Check, if it is write protected */
	if (nand_check_wp(mtd))
		goto out;

	/* Autoplace of oob data ? Use the default placement scheme */
	if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
		oobsel = this->autooob;
		autoplace = 1;
1619
	}
1620 1621
	if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
		autoplace = 1;
L
Linus Torvalds 已提交
1622 1623 1624

	/* Setup variables and oob buffer */
	totalpages = len >> this->page_shift;
1625
	page = (int)(to >> this->page_shift);
L
Linus Torvalds 已提交
1626
	/* Invalidate the page cache, if we write to the cached page */
1627
	if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
L
Linus Torvalds 已提交
1628
		this->pagebuf = -1;
1629

L
Linus Torvalds 已提交
1630 1631 1632 1633
	/* Set it relative to chip */
	page &= this->pagemask;
	startpage = page;
	/* Calc number of pages we can write in one go */
1634 1635
	numpages = min(ppblock - (startpage & (ppblock - 1)), totalpages);
	oobbuf = nand_prepare_oobbuf(mtd, eccbuf, oobsel, autoplace, numpages);
1636
	bufstart = (uint8_t *) buf;
L
Linus Torvalds 已提交
1637 1638 1639 1640

	/* Loop until all data is written */
	while (written < len) {

1641
		this->data_poi = (uint8_t *) &buf[written];
L
Linus Torvalds 已提交
1642 1643 1644 1645 1646
		/* Write one page. If this is the last page to write
		 * or the last page in this block, then use the
		 * real pageprogram command, else select cached programming
		 * if supported by the chip.
		 */
1647
		ret = nand_write_page(mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
L
Linus Torvalds 已提交
1648
		if (ret) {
1649
			DEBUG(MTD_DEBUG_LEVEL0, "nand_write: write_page failed %d\n", ret);
L
Linus Torvalds 已提交
1650
			goto out;
1651
		}
L
Linus Torvalds 已提交
1652 1653 1654
		/* Next oob page */
		oob += mtd->oobsize;
		/* Update written bytes count */
J
Joern Engel 已提交
1655
		written += mtd->writesize;
1656
		if (written == len)
L
Linus Torvalds 已提交
1657
			goto cmp;
1658

L
Linus Torvalds 已提交
1659 1660 1661 1662 1663 1664
		/* Increment page address */
		page++;

		/* Have we hit a block boundary ? Then we have to verify and
		 * if verify is ok, we have to setup the oob buffer for
		 * the next pages.
1665 1666
		 */
		if (!(page & (ppblock - 1))) {
L
Linus Torvalds 已提交
1667 1668
			int ofs;
			this->data_poi = bufstart;
1669 1670
			ret = nand_verify_pages(mtd, this, startpage, page - startpage,
						oobbuf, oobsel, chipnr, (eccbuf != NULL));
L
Linus Torvalds 已提交
1671
			if (ret) {
1672
				DEBUG(MTD_DEBUG_LEVEL0, "nand_write: verify_pages failed %d\n", ret);
L
Linus Torvalds 已提交
1673
				goto out;
1674
			}
L
Linus Torvalds 已提交
1675 1676 1677 1678 1679 1680
			*retlen = written;

			ofs = autoplace ? mtd->oobavail : mtd->oobsize;
			if (eccbuf)
				eccbuf += (page - startpage) * ofs;
			totalpages -= page - startpage;
1681
			numpages = min(totalpages, ppblock);
L
Linus Torvalds 已提交
1682 1683
			page &= this->pagemask;
			startpage = page;
1684
			oobbuf = nand_prepare_oobbuf(mtd, eccbuf, oobsel, autoplace, numpages);
1685
			oob = 0;
L
Linus Torvalds 已提交
1686 1687 1688 1689 1690 1691 1692 1693 1694
			/* Check, if we cross a chip boundary */
			if (!page) {
				chipnr++;
				this->select_chip(mtd, -1);
				this->select_chip(mtd, chipnr);
			}
		}
	}
	/* Verify the remaining pages */
1695
 cmp:
L
Linus Torvalds 已提交
1696
	this->data_poi = bufstart;
1697
	ret = nand_verify_pages(mtd, this, startpage, totalpages, oobbuf, oobsel, chipnr, (eccbuf != NULL));
L
Linus Torvalds 已提交
1698 1699
	if (!ret)
		*retlen = written;
1700
	else
1701
		DEBUG(MTD_DEBUG_LEVEL0, "nand_write: verify_pages failed %d\n", ret);
L
Linus Torvalds 已提交
1702

1703
 out:
L
Linus Torvalds 已提交
1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
	/* Deselect and wake up anyone waiting on the device */
	nand_release_device(mtd);

	return ret;
}

/**
 * nand_write_oob - [MTD Interface] NAND write out-of-band
 * @mtd:	MTD device structure
 * @to:		offset to write to
 * @len:	number of bytes to write
 * @retlen:	pointer to variable to store the number of written bytes
 * @buf:	the data to write
 *
 * NAND write out-of-band
 */
1720
static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf)
L
Linus Torvalds 已提交
1721 1722 1723 1724
{
	int column, page, status, ret = -EIO, chipnr;
	struct nand_chip *this = mtd->priv;

1725
	DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int)to, (int)len);
L
Linus Torvalds 已提交
1726 1727

	/* Shift to get page */
1728 1729
	page = (int)(to >> this->page_shift);
	chipnr = (int)(to >> this->chip_shift);
L
Linus Torvalds 已提交
1730 1731 1732 1733 1734 1735 1736 1737 1738

	/* Mask to get column */
	column = to & (mtd->oobsize - 1);

	/* Initialize return length value */
	*retlen = 0;

	/* Do not allow write past end of page */
	if ((column + len) > mtd->oobsize) {
1739
		DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
L
Linus Torvalds 已提交
1740 1741 1742 1743
		return -EINVAL;
	}

	/* Grab the lock and see if the device is available */
1744
	nand_get_device(this, mtd, FL_WRITING);
L
Linus Torvalds 已提交
1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758

	/* Select the NAND device */
	this->select_chip(mtd, chipnr);

	/* Reset the chip. Some chips (like the Toshiba TC5832DC found
	   in one of my DiskOnChip 2000 test units) will clear the whole
	   data page too if we don't do this. I have no clue why, but
	   I seem to have 'fixed' it in the doc2000 driver in
	   August 1999.  dwmw2. */
	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);

	/* Check, if it is write protected */
	if (nand_check_wp(mtd))
		goto out;
1759

L
Linus Torvalds 已提交
1760 1761 1762 1763 1764 1765
	/* Invalidate the page cache, if we write to the cached page */
	if (page == this->pagebuf)
		this->pagebuf = -1;

	if (NAND_MUST_PAD(this)) {
		/* Write out desired data */
J
Joern Engel 已提交
1766
		this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page & this->pagemask);
L
Linus Torvalds 已提交
1767 1768 1769 1770 1771
		/* prepad 0xff for partial programming */
		this->write_buf(mtd, ffchars, column);
		/* write data */
		this->write_buf(mtd, buf, len);
		/* postpad 0xff for partial programming */
1772
		this->write_buf(mtd, ffchars, mtd->oobsize - (len + column));
L
Linus Torvalds 已提交
1773 1774
	} else {
		/* Write out desired data */
J
Joern Engel 已提交
1775
		this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + column, page & this->pagemask);
L
Linus Torvalds 已提交
1776 1777 1778 1779
		/* write data */
		this->write_buf(mtd, buf, len);
	}
	/* Send command to program the OOB data */
1780
	this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
L
Linus Torvalds 已提交
1781

1782
	status = this->waitfunc(mtd, this, FL_WRITING);
L
Linus Torvalds 已提交
1783 1784

	/* See if device thinks it succeeded */
1785
	if (status & NAND_STATUS_FAIL) {
1786
		DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
L
Linus Torvalds 已提交
1787 1788 1789 1790 1791 1792 1793 1794
		ret = -EIO;
		goto out;
	}
	/* Return happy */
	*retlen = len;

#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
	/* Send command to read back the data */
1795
	this->cmdfunc(mtd, NAND_CMD_READOOB, column, page & this->pagemask);
L
Linus Torvalds 已提交
1796 1797

	if (this->verify_buf(mtd, buf, len)) {
1798
		DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
L
Linus Torvalds 已提交
1799 1800 1801 1802 1803
		ret = -EIO;
		goto out;
	}
#endif
	ret = 0;
1804
 out:
L
Linus Torvalds 已提交
1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817
	/* Deselect and wake up anyone waiting on the device */
	nand_release_device(mtd);

	return ret;
}

/**
 * single_erease_cmd - [GENERIC] NAND standard block erase command function
 * @mtd:	MTD device structure
 * @page:	the page address of the block which will be erased
 *
 * Standard erase command for NAND chips
 */
1818
static void single_erase_cmd(struct mtd_info *mtd, int page)
L
Linus Torvalds 已提交
1819 1820 1821
{
	struct nand_chip *this = mtd->priv;
	/* Send commands to erase a block */
1822 1823
	this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
	this->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
L
Linus Torvalds 已提交
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833
}

/**
 * multi_erease_cmd - [GENERIC] AND specific block erase command function
 * @mtd:	MTD device structure
 * @page:	the page address of the block which will be erased
 *
 * AND multi block erase command function
 * Erase 4 consecutive blocks
 */
1834
static void multi_erase_cmd(struct mtd_info *mtd, int page)
L
Linus Torvalds 已提交
1835 1836 1837
{
	struct nand_chip *this = mtd->priv;
	/* Send commands to erase a block */
1838 1839 1840 1841 1842
	this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
	this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
	this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
	this->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
	this->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
L
Linus Torvalds 已提交
1843 1844 1845 1846 1847 1848 1849 1850 1851
}

/**
 * nand_erase - [MTD Interface] erase block(s)
 * @mtd:	MTD device structure
 * @instr:	erase instruction
 *
 * Erase one ore more blocks
 */
1852
static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
L
Linus Torvalds 已提交
1853
{
1854
	return nand_erase_nand(mtd, instr, 0);
L
Linus Torvalds 已提交
1855
}
1856

1857
#define BBT_PAGE_MASK	0xffffff3f
L
Linus Torvalds 已提交
1858 1859 1860 1861 1862 1863 1864 1865
/**
 * nand_erase_intern - [NAND Interface] erase block(s)
 * @mtd:	MTD device structure
 * @instr:	erase instruction
 * @allowbbt:	allow erasing the bbt area
 *
 * Erase one ore more blocks
 */
1866
int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
L
Linus Torvalds 已提交
1867 1868 1869
{
	int page, len, status, pages_per_block, ret, chipnr;
	struct nand_chip *this = mtd->priv;
1870 1871 1872 1873
	int rewrite_bbt[NAND_MAX_CHIPS]={0};	/* flags to indicate the page, if bbt needs to be rewritten. */
	unsigned int bbt_masked_page;		/* bbt mask to compare to page being erased. */
						/* It is used to see if the current page is in the same */
						/*   256 block group and the same bank as the bbt. */
L
Linus Torvalds 已提交
1874

1875
	DEBUG(MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n", (unsigned int)instr->addr, (unsigned int)instr->len);
L
Linus Torvalds 已提交
1876 1877 1878

	/* Start address must align on block boundary */
	if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
1879
		DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
L
Linus Torvalds 已提交
1880 1881 1882 1883 1884
		return -EINVAL;
	}

	/* Length must align on block boundary */
	if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
1885
		DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
L
Linus Torvalds 已提交
1886 1887 1888 1889 1890
		return -EINVAL;
	}

	/* Do not allow erase past end of device */
	if ((instr->len + instr->addr) > mtd->size) {
1891
		DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
L
Linus Torvalds 已提交
1892 1893 1894 1895 1896 1897
		return -EINVAL;
	}

	instr->fail_addr = 0xffffffff;

	/* Grab the lock and see if the device is available */
1898
	nand_get_device(this, mtd, FL_ERASING);
L
Linus Torvalds 已提交
1899 1900

	/* Shift to get first page */
1901 1902
	page = (int)(instr->addr >> this->page_shift);
	chipnr = (int)(instr->addr >> this->chip_shift);
L
Linus Torvalds 已提交
1903 1904 1905 1906 1907 1908 1909 1910 1911 1912

	/* Calculate pages in each block */
	pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);

	/* Select the NAND device */
	this->select_chip(mtd, chipnr);

	/* Check the WP bit */
	/* Check, if it is write protected */
	if (nand_check_wp(mtd)) {
1913
		DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
L
Linus Torvalds 已提交
1914 1915 1916 1917
		instr->state = MTD_ERASE_FAILED;
		goto erase_exit;
	}

1918 1919 1920 1921 1922 1923 1924
	/* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
	if (this->options & BBT_AUTO_REFRESH) {
		bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
	} else {
		bbt_masked_page = 0xffffffff;	/* should not match anything */
	}

L
Linus Torvalds 已提交
1925 1926 1927 1928 1929 1930 1931 1932
	/* Loop through the pages */
	len = instr->len;

	instr->state = MTD_ERASING;

	while (len) {
		/* Check if we have a bad block, we do not erase bad blocks ! */
		if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
1933
			printk(KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
L
Linus Torvalds 已提交
1934 1935 1936
			instr->state = MTD_ERASE_FAILED;
			goto erase_exit;
		}
1937 1938

		/* Invalidate the page cache, if we erase the block which contains
L
Linus Torvalds 已提交
1939 1940 1941 1942
		   the current cached page */
		if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
			this->pagebuf = -1;

1943
		this->erase_cmd(mtd, page & this->pagemask);
1944

1945
		status = this->waitfunc(mtd, this, FL_ERASING);
L
Linus Torvalds 已提交
1946

1947 1948 1949 1950 1951
		/* See if operation failed and additional status checks are available */
		if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
			status = this->errstat(mtd, this, FL_ERASING, status, page);
		}

L
Linus Torvalds 已提交
1952
		/* See if block erase succeeded */
1953
		if (status & NAND_STATUS_FAIL) {
1954
			DEBUG(MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
L
Linus Torvalds 已提交
1955 1956 1957 1958
			instr->state = MTD_ERASE_FAILED;
			instr->fail_addr = (page << this->page_shift);
			goto erase_exit;
		}
1959 1960 1961

		/* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
		if (this->options & BBT_AUTO_REFRESH) {
1962
			if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
1963 1964 1965 1966
			     (page != this->bbt_td->pages[chipnr])) {
				rewrite_bbt[chipnr] = (page << this->page_shift);
			}
		}
1967

L
Linus Torvalds 已提交
1968 1969 1970 1971 1972 1973 1974 1975 1976
		/* Increment page address and decrement length */
		len -= (1 << this->phys_erase_shift);
		page += pages_per_block;

		/* Check, if we cross a chip boundary */
		if (len && !(page & this->pagemask)) {
			chipnr++;
			this->select_chip(mtd, -1);
			this->select_chip(mtd, chipnr);
1977

1978
			/* if BBT requires refresh and BBT-PERCHIP,
1979 1980 1981 1982 1983
			 *   set the BBT page mask to see if this BBT should be rewritten */
			if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
				bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
			}

L
Linus Torvalds 已提交
1984 1985 1986 1987
		}
	}
	instr->state = MTD_ERASE_DONE;

1988
 erase_exit:
L
Linus Torvalds 已提交
1989 1990 1991 1992 1993 1994 1995 1996 1997

	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
	/* Do call back function */
	if (!ret)
		mtd_erase_callback(instr);

	/* Deselect and wake up anyone waiting on the device */
	nand_release_device(mtd);

1998 1999 2000 2001 2002
	/* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
	if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
		for (chipnr = 0; chipnr < this->numchips; chipnr++) {
			if (rewrite_bbt[chipnr]) {
				/* update the BBT for chip */
2003 2004 2005
				DEBUG(MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
				      chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
				nand_update_bbt(mtd, rewrite_bbt[chipnr]);
2006 2007 2008 2009
			}
		}
	}

L
Linus Torvalds 已提交
2010 2011 2012 2013 2014 2015 2016 2017 2018 2019
	/* Return more or less happy */
	return ret;
}

/**
 * nand_sync - [MTD Interface] sync
 * @mtd:	MTD device structure
 *
 * Sync is actually a wait for chip ready function
 */
2020
static void nand_sync(struct mtd_info *mtd)
L
Linus Torvalds 已提交
2021 2022 2023
{
	struct nand_chip *this = mtd->priv;

2024
	DEBUG(MTD_DEBUG_LEVEL3, "nand_sync: called\n");
L
Linus Torvalds 已提交
2025 2026

	/* Grab the lock and see if the device is available */
2027
	nand_get_device(this, mtd, FL_SYNCING);
L
Linus Torvalds 已提交
2028
	/* Release it and go back */
2029
	nand_release_device(mtd);
L
Linus Torvalds 已提交
2030 2031 2032 2033 2034 2035 2036
}

/**
 * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
 * @mtd:	MTD device structure
 * @ofs:	offset relative to mtd start
 */
2037
static int nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
L
Linus Torvalds 已提交
2038 2039
{
	/* Check for invalid offset */
2040
	if (ofs > mtd->size)
L
Linus Torvalds 已提交
2041
		return -EINVAL;
2042

2043
	return nand_block_checkbad(mtd, ofs, 1, 0);
L
Linus Torvalds 已提交
2044 2045 2046 2047 2048 2049 2050
}

/**
 * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
 * @mtd:	MTD device structure
 * @ofs:	offset relative to mtd start
 */
2051
static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
L
Linus Torvalds 已提交
2052 2053 2054 2055
{
	struct nand_chip *this = mtd->priv;
	int ret;

2056 2057
	if ((ret = nand_block_isbad(mtd, ofs))) {
		/* If it was bad already, return success and do nothing. */
L
Linus Torvalds 已提交
2058 2059
		if (ret > 0)
			return 0;
2060 2061
		return ret;
	}
L
Linus Torvalds 已提交
2062 2063 2064 2065

	return this->block_markbad(mtd, ofs);
}

2066 2067 2068 2069 2070 2071 2072 2073
/**
 * nand_suspend - [MTD Interface] Suspend the NAND flash
 * @mtd:	MTD device structure
 */
static int nand_suspend(struct mtd_info *mtd)
{
	struct nand_chip *this = mtd->priv;

2074
	return nand_get_device(this, mtd, FL_PM_SUSPENDED);
2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087
}

/**
 * nand_resume - [MTD Interface] Resume the NAND flash
 * @mtd:	MTD device structure
 */
static void nand_resume(struct mtd_info *mtd)
{
	struct nand_chip *this = mtd->priv;

	if (this->state == FL_PM_SUSPENDED)
		nand_release_device(mtd);
	else
2088 2089
		printk(KERN_ERR "nand_resume() called for a chip which is not "
		       "in suspended state\n");
2090 2091
}

T
Thomas Gleixner 已提交
2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
/*
 * 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);
}

T
Thomas Gleixner 已提交
2108 2109
/*
 * Allocate buffers and data structures
L
Linus Torvalds 已提交
2110
 */
T
Thomas Gleixner 已提交
2111
static int nand_allocate_kmem(struct mtd_info *mtd, struct nand_chip *this)
L
Linus Torvalds 已提交
2112
{
T
Thomas Gleixner 已提交
2113
	size_t len;
L
Linus Torvalds 已提交
2114

T
Thomas Gleixner 已提交
2115 2116 2117 2118 2119 2120 2121
	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;
2122 2123
	}

T
Thomas Gleixner 已提交
2124
	if (!this->data_buf) {
2125
		len = mtd->writesize + mtd->oobsize;
T
Thomas Gleixner 已提交
2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
		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;
L
Linus Torvalds 已提交
2140

T
Thomas Gleixner 已提交
2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151
 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)
{
L
Linus Torvalds 已提交
2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181
	/* check for proper chip_delay setup, set 20us if not */
	if (!this->chip_delay)
		this->chip_delay = 20;

	/* check, if a user supplied command function given */
	if (this->cmdfunc == NULL)
		this->cmdfunc = nand_command;

	/* check, if a user supplied wait function given */
	if (this->waitfunc == NULL)
		this->waitfunc = nand_wait;

	if (!this->select_chip)
		this->select_chip = nand_select_chip;
	if (!this->read_byte)
		this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
	if (!this->read_word)
		this->read_word = nand_read_word;
	if (!this->block_bad)
		this->block_bad = nand_block_bad;
	if (!this->block_markbad)
		this->block_markbad = nand_default_block_markbad;
	if (!this->write_buf)
		this->write_buf = busw ? nand_write_buf16 : nand_write_buf;
	if (!this->read_buf)
		this->read_buf = busw ? nand_read_buf16 : nand_read_buf;
	if (!this->verify_buf)
		this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
	if (!this->scan_bbt)
		this->scan_bbt = nand_default_bbt;
T
Thomas Gleixner 已提交
2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192
}

/*
 * Get the flash and manufacturer id and lookup if the typ is supported
 */
static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
						  struct nand_chip *this,
						  int busw, int *maf_id)
{
	struct nand_flash_dev *type = NULL;
	int i, dev_id, maf_idx;
L
Linus Torvalds 已提交
2193 2194 2195 2196 2197

	/* Select the device */
	this->select_chip(mtd, 0);

	/* Send the command for reading device ID */
2198
	this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
L
Linus Torvalds 已提交
2199 2200

	/* Read manufacturer and device IDs */
T
Thomas Gleixner 已提交
2201 2202
	*maf_id = this->read_byte(mtd);
	dev_id = this->read_byte(mtd);
L
Linus Torvalds 已提交
2203

T
Thomas Gleixner 已提交
2204
	/* Lookup the flash id */
L
Linus Torvalds 已提交
2205
	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
T
Thomas Gleixner 已提交
2206 2207 2208 2209 2210
		if (dev_id == nand_flash_ids[i].id) {
			type =  &nand_flash_ids[i];
			break;
		}
	}
2211

T
Thomas Gleixner 已提交
2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224
	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 */
2225
		mtd->writesize = 1024 << (extid & 0x3);
T
Thomas Gleixner 已提交
2226 2227
		extid >>= 2;
		/* Calc oobsize */
2228
		mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
T
Thomas Gleixner 已提交
2229 2230 2231 2232 2233 2234
		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;
2235

T
Thomas Gleixner 已提交
2236 2237 2238 2239 2240
	} else {
		/*
		 * Old devices have this data hardcoded in the device id table
		 */
		mtd->erasesize = nand_flash_ids[i].erasesize;
2241 2242
		mtd->writesize = nand_flash_ids[i].pagesize;
		mtd->oobsize = mtd->writesize / 32;
T
Thomas Gleixner 已提交
2243 2244
		busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
	}
L
Linus Torvalds 已提交
2245

T
Thomas Gleixner 已提交
2246 2247 2248 2249 2250
	/* 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;
	}
2251

T
Thomas Gleixner 已提交
2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264
	/*
	 * 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);
	}
2265

T
Thomas Gleixner 已提交
2266
	/* Calculate the address shift from the page size */
2267
	this->page_shift = ffs(mtd->writesize) - 1;
T
Thomas Gleixner 已提交
2268 2269
	/* Convert chipsize to number of pages per chip -1. */
	this->pagemask = (this->chipsize >> this->page_shift) - 1;
2270

T
Thomas Gleixner 已提交
2271 2272 2273
	this->bbt_erase_shift = this->phys_erase_shift =
		ffs(mtd->erasesize) - 1;
	this->chip_shift = ffs(this->chipsize) - 1;
L
Linus Torvalds 已提交
2274

T
Thomas Gleixner 已提交
2275
	/* Set the bad block position */
2276
	this->badblockpos = mtd->writesize > 512 ?
T
Thomas Gleixner 已提交
2277
		NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
2278

T
Thomas Gleixner 已提交
2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300
	/* 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 ! */
2301
	if (mtd->writesize > 512 && this->cmdfunc == nand_command)
T
Thomas Gleixner 已提交
2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343
		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();
L
Linus Torvalds 已提交
2344 2345
	}

T
Thomas Gleixner 已提交
2346 2347 2348 2349 2350 2351 2352 2353 2354
	/* 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)) {
2355
		printk(KERN_WARNING "No NAND device found!!!\n");
L
Linus Torvalds 已提交
2356
		this->select_chip(mtd, -1);
T
Thomas Gleixner 已提交
2357
		return PTR_ERR(type);
L
Linus Torvalds 已提交
2358 2359
	}

T
Thomas Gleixner 已提交
2360
	/* Check for a chip array */
2361
	for (i = 1; i < maxchips; i++) {
L
Linus Torvalds 已提交
2362 2363
		this->select_chip(mtd, i);
		/* Send the command for reading device ID */
2364
		this->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
L
Linus Torvalds 已提交
2365 2366
		/* Read manufacturer and device IDs */
		if (nand_maf_id != this->read_byte(mtd) ||
T
Thomas Gleixner 已提交
2367
		    type->id != this->read_byte(mtd))
L
Linus Torvalds 已提交
2368 2369 2370 2371
			break;
	}
	if (i > 1)
		printk(KERN_INFO "%d NAND chips detected\n", i);
2372

L
Linus Torvalds 已提交
2373 2374 2375
	/* Store the number of chips and calc total size for mtd */
	this->numchips = i;
	mtd->size = i * this->chipsize;
T
Thomas Gleixner 已提交
2376 2377 2378 2379 2380

	/* Allocate buffers and data structures */
	if (nand_allocate_kmem(mtd, this))
		return -ENOMEM;

L
Linus Torvalds 已提交
2381
	/* Preset the internal oob buffer */
T
Thomas Gleixner 已提交
2382 2383
	memset(this->oob_buf, 0xff,
	       mtd->oobsize << (this->phys_erase_shift - this->page_shift));
L
Linus Torvalds 已提交
2384

T
Thomas Gleixner 已提交
2385 2386 2387
	/*
	 * If no default placement scheme is given, select an appropriate one
	 */
L
Linus Torvalds 已提交
2388
	if (!this->autooob) {
2389
		switch (mtd->oobsize) {
L
Linus Torvalds 已提交
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399
		case 8:
			this->autooob = &nand_oob_8;
			break;
		case 16:
			this->autooob = &nand_oob_16;
			break;
		case 64:
			this->autooob = &nand_oob_64;
			break;
		default:
T
Thomas Gleixner 已提交
2400 2401
			printk(KERN_WARNING "No oob scheme defined for "
			       "oobsize %d\n", mtd->oobsize);
L
Linus Torvalds 已提交
2402 2403 2404
			BUG();
		}
	}
2405

T
Thomas Gleixner 已提交
2406 2407 2408 2409
	/*
	 * The number of bytes available for the filesystem to place fs
	 * dependend oob data
	 */
2410 2411 2412
	mtd->oobavail = 0;
	for (i = 0; this->autooob->oobfree[i][1]; i++)
		mtd->oobavail += this->autooob->oobfree[i][1];
L
Linus Torvalds 已提交
2413

2414
	/*
T
Thomas Gleixner 已提交
2415 2416
	 * check ECC mode, default to software if 3byte/512byte hardware ECC is
	 * selected and we have 256 byte pagesize fallback to software ECC
2417
	 */
T
Thomas Gleixner 已提交
2418 2419 2420 2421 2422 2423 2424 2425 2426
	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();
		}
2427
		if (mtd->writesize >= this->ecc.size)
T
Thomas Gleixner 已提交
2428 2429 2430
			break;
		printk(KERN_WARNING "%d byte HW ECC not possible on "
		       "%d byte page size, fallback to SW ECC\n",
2431
		       this->ecc.size, mtd->writesize);
T
Thomas Gleixner 已提交
2432
		this->ecc.mode = NAND_ECC_SOFT;
2433

T
Thomas Gleixner 已提交
2434 2435 2436 2437 2438
	case NAND_ECC_SOFT:
		this->ecc.calculate = nand_calculate_ecc;
		this->ecc.correct = nand_correct_data;
		this->ecc.size = 256;
		this->ecc.bytes = 3;
L
Linus Torvalds 已提交
2439
		break;
2440 2441

	case NAND_ECC_NONE:
T
Thomas Gleixner 已提交
2442 2443
		printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
		       "This is not recommended !!\n");
2444
		this->ecc.size = mtd->writesize;
T
Thomas Gleixner 已提交
2445
		this->ecc.bytes = 0;
L
Linus Torvalds 已提交
2446 2447
		break;
	default:
T
Thomas Gleixner 已提交
2448
		printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
T
Thomas Gleixner 已提交
2449
		       this->ecc.mode);
2450
		BUG();
L
Linus Torvalds 已提交
2451
	}
2452

T
Thomas Gleixner 已提交
2453 2454 2455 2456
	/*
	 * Set the number of read / write steps for one page depending on ECC
	 * mode
	 */
2457 2458
	this->ecc.steps = mtd->writesize / this->ecc.size;
	if(this->ecc.steps * this->ecc.size != mtd->writesize) {
T
Thomas Gleixner 已提交
2459 2460
		printk(KERN_WARNING "Invalid ecc parameters\n");
		BUG();
L
Linus Torvalds 已提交
2461
	}
2462

L
Linus Torvalds 已提交
2463 2464
	/* Initialize state, waitqueue and spinlock */
	this->state = FL_READY;
T
Thomas Gleixner 已提交
2465 2466
	init_waitqueue_head(&this->controller->wq);
	spin_lock_init(&this->controller->lock);
L
Linus Torvalds 已提交
2467 2468 2469 2470 2471 2472 2473 2474 2475

	/* De-select the device */
	this->select_chip(mtd, -1);

	/* Invalidate the pagebuffer reference */
	this->pagebuf = -1;

	/* Fill in remaining MTD driver data */
	mtd->type = MTD_NANDFLASH;
J
Joern Engel 已提交
2476
	mtd->flags = MTD_CAP_NANDFLASH;
L
Linus Torvalds 已提交
2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487
	mtd->ecctype = MTD_ECC_SW;
	mtd->erase = nand_erase;
	mtd->point = NULL;
	mtd->unpoint = NULL;
	mtd->read = nand_read;
	mtd->write = nand_write;
	mtd->read_oob = nand_read_oob;
	mtd->write_oob = nand_write_oob;
	mtd->sync = nand_sync;
	mtd->lock = NULL;
	mtd->unlock = NULL;
2488 2489
	mtd->suspend = nand_suspend;
	mtd->resume = nand_resume;
L
Linus Torvalds 已提交
2490 2491 2492 2493 2494 2495
	mtd->block_isbad = nand_block_isbad;
	mtd->block_markbad = nand_block_markbad;

	/* and make the autooob the default one */
	memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));

2496 2497 2498
	/* Check, if we should skip the bad block table scan */
	if (this->options & NAND_SKIP_BBTSCAN)
		return 0;
L
Linus Torvalds 已提交
2499 2500

	/* Build bad block table */
2501
	return this->scan_bbt(mtd);
L
Linus Torvalds 已提交
2502 2503 2504
}

/**
2505
 * nand_release - [NAND Interface] Free resources held by the NAND device
L
Linus Torvalds 已提交
2506 2507
 * @mtd:	MTD device structure
*/
2508
void nand_release(struct mtd_info *mtd)
L
Linus Torvalds 已提交
2509 2510 2511 2512 2513
{
	struct nand_chip *this = mtd->priv;

#ifdef CONFIG_MTD_PARTITIONS
	/* Deregister partitions */
2514
	del_mtd_partitions(mtd);
L
Linus Torvalds 已提交
2515 2516
#endif
	/* Deregister the device */
2517
	del_mtd_device(mtd);
L
Linus Torvalds 已提交
2518

J
Jesper Juhl 已提交
2519
	/* Free bad block table memory */
2520
	kfree(this->bbt);
T
Thomas Gleixner 已提交
2521 2522
	/* Free buffers */
	nand_free_kmem(this);
L
Linus Torvalds 已提交
2523 2524
}

2525 2526
EXPORT_SYMBOL_GPL(nand_scan);
EXPORT_SYMBOL_GPL(nand_release);
2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541

static int __init nand_base_init(void)
{
	led_trigger_register_simple("nand-disk", &nand_led_trigger);
	return 0;
}

static void __exit nand_base_exit(void)
{
	led_trigger_unregister_simple(nand_led_trigger);
}

module_init(nand_base_init);
module_exit(nand_base_exit);

2542 2543 2544
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
MODULE_DESCRIPTION("Generic NAND flash driver code");