8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <asm/errno.h>
12 #include <asm/uaccess.h>
14 #include <linux/slab.h>
15 #include <linux/sched.h>
17 #include <linux/types.h>
18 #include <linux/bitops.h>
25 #define DOC_SUPPORT_2000
26 #define DOC_SUPPORT_2000TSOP
27 #define DOC_SUPPORT_MILLENNIUM
29 #ifdef DOC_SUPPORT_2000
30 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
32 #define DoC_is_2000(doc) (0)
35 #if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM)
36 #define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
38 #define DoC_is_Millennium(doc) (0)
52 static int doc_write(
struct mtd_info *
mtd, loff_t to,
size_t len,
54 static int doc_read_oob(
struct mtd_info *
mtd, loff_t ofs,
56 static int doc_write_oob(
struct mtd_info *
mtd, loff_t ofs,
58 static int doc_write_oob_nolock(
struct mtd_info *
mtd, loff_t ofs,
size_t len,
65 static void DoC_Delay(
struct DiskOnChip *doc,
unsigned short cycles)
70 for (i = 0; i < cycles; i++) {
80 static int _DoC_WaitReady(
struct DiskOnChip *doc)
83 unsigned long timeo =
jiffies + (
HZ * 10);
85 pr_debug(
"_DoC_WaitReady called for out-of-line wait\n");
94 pr_debug(
"_DoC_WaitReady timed out.\n");
104 static inline int DoC_WaitReady(
struct DiskOnChip *doc)
115 if (!(
ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
117 ret = _DoC_WaitReady(doc);
131 unsigned char xtraflags)
143 WriteDOC(command, docptr, CDSNSlowIO);
148 WriteDOC(command, docptr, WritePipeTerm);
155 return DoC_WaitReady(doc);
162 static int DoC_Address(
struct DiskOnChip *doc,
int numbytes,
unsigned long ofs,
163 unsigned char xtraflags1,
unsigned char xtraflags2)
190 WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
201 for (i = 0; i < doc->
pageadrlen; i++, ofs = ofs >> 8) {
203 WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
209 WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
223 return DoC_WaitReady(doc);
240 dummy =
ReadDOC(docptr, ReadPipeInit);
249 for (i = 0; i < len; i++)
253 buf[
i] =
ReadDOC(docptr, LastDataRead);
258 static void DoC_WriteBuf(
struct DiskOnChip *doc,
const u_char * buf,
int len)
266 for (i = 0; i < len; i++)
270 WriteDOC(0x00, docptr, WritePipeTerm);
277 static inline int DoC_SelectChip(
struct DiskOnChip *doc,
int chip)
287 WriteDOC(chip, docptr, CDSNDeviceSelect);
296 return DoC_WaitReady(doc);
306 WriteDOC(floor, docptr, FloorSelect);
309 return DoC_WaitReady(doc);
320 DoC_SelectFloor(doc, floor);
321 DoC_SelectChip(doc, chip);
325 pr_debug(
"DoC_Command (reset) for %d,%d returned true\n",
333 pr_debug(
"DoC_Command (ReadID) for %d,%d returned true\n",
364 if (mfr == 0xff || mfr == 0)
372 if (doc->
mfr == mfr && doc->
id ==
id)
376 "Flash chip at floor %d, chip %d is different:\n",
389 "Flash chip found: Manufacturer ID: %2.2X, "
390 "Chip ID: %2.2X (%s:%s)\n", mfr,
id,
418 static void DoC_ScanChips(
struct DiskOnChip *
this,
int maxchips)
429 for (floor = 0; floor <
MAX_FLOORS; floor++) {
432 for (chip = 0; chip < maxchips && ret != 0; chip++) {
434 ret = DoC_IdentChip(
this, floor, chip);
443 if (!this->numchips) {
459 for (floor = 0; floor <
MAX_FLOORS; floor++) {
460 for (chip = 0; chip < numchips[
floor]; chip++) {
470 this->
totlen = this->numchips * (1 << this->chipshift);
472 printk(
KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
473 this->numchips, this->
totlen >> 20);
494 if (tmp2 == (tmp1 + 1) % 0xff)
517 old = doc2klist->
priv;
520 if (DoC2k_is_alias(old,
this)) {
522 "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
537 mtd->
name =
"DiskOnChip 2000 TSOP";
544 mtd->
name =
"DiskOnChip 2000";
549 mtd->
name =
"DiskOnChip Millennium";
570 mtd->
_read = doc_read;
579 DoC_ScanChips(
this, maxchips);
595 static int doc_read(
struct mtd_info *mtd, loff_t
from,
size_t len,
596 size_t * retlen,
u_char * buf)
601 unsigned char syndrome[6], eccbuf[6];
603 int i, len256 = 0, ret=0;
611 if (from + len > ((from | 0x1ff) + 1))
612 len = ((from | 0x1ff) + 1) -
from;
617 "ECC needs a full sector read (adr: %lx size %lx)\n",
618 (
long) from, (
long) len);
624 mychip = &this->
chips[from >> (this->chipshift)];
626 if (this->curfloor != mychip->
floor) {
627 DoC_SelectFloor(
this, mychip->
floor);
628 DoC_SelectChip(
this, mychip->
chip);
629 }
else if (this->curchip != mychip->
chip) {
630 DoC_SelectChip(
this, mychip->
chip);
633 this->curfloor = mychip->
floor;
634 this->curchip = mychip->
chip;
648 if (this->page256 && from + len > (from | 0xff) + 1) {
649 len256 = (from | 0xff) + 1 - from;
650 DoC_ReadBuf(
this, buf, len256);
657 DoC_ReadBuf(
this, &buf[len256], len - len256);
665 DoC_ReadBuf(
this, eccbuf, 6);
669 dummy =
ReadDOC(docptr, ECCConf);
670 dummy =
ReadDOC(docptr, ECCConf);
673 dummy =
ReadDOC(docptr, 2k_ECCStatus);
674 dummy =
ReadDOC(docptr, 2k_ECCStatus);
675 i =
ReadDOC(docptr, 2k_ECCStatus);
683 printk(
KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (
long)from);
688 for (i = 0; i < 6; i++) {
690 ReadDOC(docptr, ECCSyndrome0 + i);
708 printk(
KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
709 (
long)from, eccbuf[0], eccbuf[1], eccbuf[2],
710 eccbuf[3], eccbuf[4], eccbuf[5]);
718 if(0 == ((from + len) & 0x1ff))
733 static int doc_write(
struct mtd_info *mtd, loff_t to,
size_t len,
734 size_t * retlen,
const u_char * buf)
739 unsigned char eccbuf[6];
751 if (to + len > ((to | 0x1ff) + 1))
752 len = ((to | 0x1ff) + 1) - to;
765 mychip = &this->
chips[to >> (this->chipshift)];
767 if (this->curfloor != mychip->
floor) {
768 DoC_SelectFloor(
this, mychip->
floor);
769 DoC_SelectChip(
this, mychip->
chip);
770 }
else if (this->curchip != mychip->
chip) {
771 DoC_SelectChip(
this, mychip->
chip);
774 this->curfloor = mychip->
floor;
775 this->curchip = mychip->
chip;
792 if (this->page256 && to + len > (to | 0xff) + 1) {
793 len256 = (to | 0xff) + 1 - to;
794 DoC_WriteBuf(
this, buf, len256);
801 dummy =
ReadDOC(docptr, CDSNSlowIO);
804 if (
ReadDOC_(docptr, this->ioreg) & 1) {
817 DoC_WriteBuf(
this, &buf[len256], len - len256);
835 for (di = 0; di < 6; di++) {
836 eccbuf[di] =
ReadDOC(docptr, ECCSyndrome0 + di);
844 (
"OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
845 (
long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
846 eccbuf[4], eccbuf[5]);
855 status =
ReadDOC(docptr, LastDataRead);
857 dummy =
ReadDOC(docptr, CDSNSlowIO);
859 status =
ReadDOC_(docptr, this->ioreg);
879 for (di=0; di<6; di++)
885 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
901 static int doc_read_oob(
struct mtd_info *mtd, loff_t ofs,
908 size_t len = ops->
len;
916 mychip = &this->
chips[ofs >> this->chipshift];
918 if (this->curfloor != mychip->
floor) {
919 DoC_SelectFloor(
this, mychip->
floor);
920 DoC_SelectChip(
this, mychip->
chip);
921 }
else if (this->curchip != mychip->
chip) {
922 DoC_SelectChip(
this, mychip->
chip);
924 this->curfloor = mychip->
floor;
925 this->curchip = mychip->
chip;
942 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
943 len256 = (ofs | 0x7) + 1 - ofs;
944 DoC_ReadBuf(
this, buf, len256);
951 DoC_ReadBuf(
this, &buf[len256], len - len256);
958 ret = DoC_WaitReady(
this);
965 static int doc_write_oob_nolock(
struct mtd_info *mtd, loff_t ofs,
size_t len,
966 size_t * retlen,
const u_char * buf)
971 struct Nand *mychip = &this->
chips[ofs >> this->chipshift];
979 if (this->curfloor != mychip->
floor) {
980 DoC_SelectFloor(
this, mychip->
floor);
981 DoC_SelectChip(
this, mychip->
chip);
982 }
else if (this->curchip != mychip->
chip) {
983 DoC_SelectChip(
this, mychip->
chip);
985 this->curfloor = mychip->
floor;
986 this->curchip = mychip->
chip;
1000 if (this->page256) {
1014 if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
1015 len256 = (ofs | 0x7) + 1 - ofs;
1016 DoC_WriteBuf(
this, buf, len256);
1023 ReadDOC(docptr, ReadPipeInit);
1024 status =
ReadDOC(docptr, LastDataRead);
1026 dummy =
ReadDOC(docptr, CDSNSlowIO);
1028 status =
ReadDOC_(docptr, this->ioreg);
1041 DoC_WriteBuf(
this, &buf[len256], len - len256);
1048 ReadDOC(docptr, ReadPipeInit);
1049 status =
ReadDOC(docptr, LastDataRead);
1051 dummy =
ReadDOC(docptr, CDSNSlowIO);
1053 status =
ReadDOC_(docptr, this->ioreg);
1068 static int doc_write_oob(
struct mtd_info *mtd, loff_t ofs,
1077 ret = doc_write_oob_nolock(mtd, ofs + ops->
ooboffs, ops->
len,
1091 struct Nand *mychip;
1105 mychip = &this->
chips[ofs >> this->chipshift];
1107 if (this->curfloor != mychip->
floor) {
1108 DoC_SelectFloor(
this, mychip->
floor);
1109 DoC_SelectChip(
this, mychip->
chip);
1110 }
else if (this->curchip != mychip->
chip) {
1111 DoC_SelectChip(
this, mychip->
chip);
1113 this->curfloor = mychip->
floor;
1114 this->curchip = mychip->
chip;
1117 DoC_Address(
this,
ADDR_PAGE, ofs, 0, 0);
1123 ReadDOC(docptr, ReadPipeInit);
1124 status =
ReadDOC(docptr, LastDataRead);
1126 dummy =
ReadDOC(docptr, CDSNSlowIO);
1128 status =
ReadDOC_(docptr, this->ioreg);
1156 static void __exit cleanup_doc2000(
void)
1161 while ((mtd = doc2klist)) {