fixed some bugs Eric made when transfer to stream interface
also remove the NEW_DOC stuff
This commit is contained in:
parent
da5f5bfee7
commit
15fbb207ba
1 changed files with 29 additions and 510 deletions
|
|
@ -7,13 +7,6 @@
|
|||
#include <stddef.h>
|
||||
#include <rom/read_bytes.h>
|
||||
|
||||
#include <rom/fill_inbuf.h>
|
||||
|
||||
#ifdef USE_NEW_DOC_CODE
|
||||
#include <mtd/doc2000.h>
|
||||
#include <mtd/nand.h>
|
||||
#include <mtd/nand_ids.h>
|
||||
#endif
|
||||
#ifndef DOC_KERNEL_START
|
||||
#define DOC_KERNEL_START 65536
|
||||
#endif
|
||||
|
|
@ -32,101 +25,32 @@ static int firstfill = 1;
|
|||
|
||||
static void memcpy_from_doc_mil(void *dest, const void *src, size_t n);
|
||||
static volatile unsigned char *doc_mil = (unsigned char *) DOC_MIL_BASE;
|
||||
#ifdef CHECK_DOC_MIL
|
||||
static unsigned char *checkbuf;
|
||||
#endif /* CHECK_DOC_MIL */
|
||||
|
||||
static unsigned char *ram;
|
||||
#define K64 (64 * 1024)
|
||||
|
||||
#ifdef RESET_DOC
|
||||
void
|
||||
reset_doc()
|
||||
{
|
||||
#ifdef USE_NEW_DOC_CODE
|
||||
doc_mil[DoC_DOCControl] = DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET;
|
||||
doc_mil[DoC_DOCControl] = DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET;
|
||||
|
||||
doc_mil[DoC_DOCControl] = DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL;
|
||||
doc_mil[DoC_DOCControl] = DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL;
|
||||
|
||||
#else
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x84;
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x84;
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x85;
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x85;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
fill_inbuf(void)
|
||||
{
|
||||
#ifdef CHECK_DOC_MIL
|
||||
redo:
|
||||
#endif
|
||||
if (firstfill) {
|
||||
// it is possible that we can get in here and the
|
||||
// doc has never been reset. So go ahead and reset it again.
|
||||
#ifdef RESET_DOC
|
||||
reset_doc();
|
||||
#endif
|
||||
if (firstfill) {
|
||||
if ((ram = malloc(K64)) == NULL) {
|
||||
printk_emerg("%6d:%s() - ram malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
__LINE__, __FUNCTION__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef CHECK_DOC_MIL
|
||||
if ((checkbuf = malloc(K64)) == NULL) {
|
||||
printk_emerg("%6d:%s() - checkbuf malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
printk_emerg("Checking disabled\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printk_debug("%6d:%s() - ram buffer:0x%p\n",
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
nvram = (unsigned char *) DOC_KERNEL_START;
|
||||
}
|
||||
|
||||
#ifdef CHECK_DOC_MIL
|
||||
printk_info("DOC MIL address 0x%x\n", nvram);
|
||||
#endif
|
||||
memcpy_from_doc_mil(ram, nvram, K64);
|
||||
|
||||
#ifdef CHECK_DOC_MIL
|
||||
if (checkbuf) {
|
||||
memcpy_from_doc_mil(checkbuf, nvram, K64);
|
||||
if (memcmp(checkbuf, ram, K64)) {
|
||||
int i;
|
||||
for(i = 0; i < K64; i++)
|
||||
if (checkbuf[i] != ram[i])
|
||||
printk_info("at %d First read 0x%x check 0x%x\n",
|
||||
i, ram[i], checkbuf[i]);
|
||||
printk_emerg("CHECKBUF FAILS for doc mil!\n");
|
||||
printk_emerg( "address 0x%x\n", nvram);
|
||||
goto redo;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
int i, j;
|
||||
for(i = 0; i < K64; i += 16) {
|
||||
printk_info("0x%x: ", ram + i);
|
||||
for(j = 0; j < 16; j++)
|
||||
printk_info("%x ",ram[i+j]);
|
||||
printk_info( "\n");
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
#endif
|
||||
|
||||
printk_debug("%6d:%s() - nvram:0x%p block_count:%d\n",
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
|
||||
nvram += K64;
|
||||
inbuf = ram;
|
||||
|
|
@ -138,412 +62,6 @@ redo:
|
|||
return inbuf[0];
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_NEW_DOC_CODE
|
||||
/**************************************************************************
|
||||
*
|
||||
* New DoC code for LinxuBIOS. This code is from:
|
||||
* doctest.c - a quick and dirty test for DoC2001 in MB BIOS socket
|
||||
*
|
||||
* compile: gcc -O2 -g -o doctest doctest.c
|
||||
*
|
||||
* Copyright Steven James <pyro@linuxlabs.com>, Linux Labs (www.linuxlabs.com)
|
||||
*
|
||||
* License GPL v2 or later (for what it's worth)
|
||||
*
|
||||
* DoC access code derived from Linux kernel drivers
|
||||
* (c) 1999 Machine Vision Holdings, Inc.
|
||||
* Author: David Woodhouse <dwmw2@mvhi.com>
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Access routines for DoC Mil */
|
||||
#define _WriteDoC(data, adr, reg) adr[reg] = data
|
||||
#define WriteDOC(data, adr, reg) _WriteDoC(data, adr, DoC_##reg)
|
||||
|
||||
#define _ReadDoC(adr, reg) adr[reg]
|
||||
#define ReadDOC(adr, reg) _ReadDoC(adr, DoC_##reg)
|
||||
|
||||
|
||||
/* Perform the required delsy cycles by reading from the NOP register */
|
||||
static void DoC_Delay(volatile char *docptr, unsigned short cycles)
|
||||
{
|
||||
volatile char dummy;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cycles; i++)
|
||||
dummy = ReadDOC(docptr, NOP);
|
||||
}
|
||||
|
||||
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
|
||||
static int _DoC_WaitReady(volatile char *docptr)
|
||||
{
|
||||
unsigned short c = 0xffff;
|
||||
|
||||
/* Out-of-line routine to wait for chip response */
|
||||
while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
|
||||
;
|
||||
|
||||
return (c == 0);
|
||||
}
|
||||
|
||||
static __inline__ int DoC_WaitReady(volatile char *docptr)
|
||||
{
|
||||
/* This is inline, to optimise the common case, where it's ready instantly */
|
||||
int ret = 0;
|
||||
|
||||
/* 4 read form NOP register should be issued in prior to the read from CDSNControl
|
||||
see Software Requirement 11.4 item 2. */
|
||||
DoC_Delay(docptr, 4);
|
||||
|
||||
if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
|
||||
/* Call the out-of-line routine to wait */
|
||||
ret = _DoC_WaitReady(docptr);
|
||||
|
||||
/* issue 2 read from NOP register after reading from CDSNControl register
|
||||
see Software Requirement 11.4 item 2. */
|
||||
DoC_Delay(docptr, 2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
|
||||
bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
|
||||
required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
|
||||
/* SURELY this is wrong what about bit 8? But I could be wrong... SMJ */
|
||||
|
||||
static __inline__ void DoC_Command(volatile char *docptr, unsigned char command,
|
||||
unsigned char xtraflags)
|
||||
{
|
||||
/* Assert the CLE (Command Latch Enable) line to the flash chip */
|
||||
WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
|
||||
DoC_Delay(docptr, 4);
|
||||
|
||||
/* Send the command */
|
||||
WriteDOC(command, docptr, CDSNSlowIO);
|
||||
WriteDOC(command, docptr, Mil_CDSN_IO);
|
||||
|
||||
/* Lower the CLE line */
|
||||
WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
|
||||
DoC_Delay(docptr, 4);
|
||||
}
|
||||
|
||||
/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
|
||||
bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
|
||||
required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
|
||||
static __inline__ void DoC_Address (volatile char *docptr, int numbytes, unsigned long ofs,
|
||||
unsigned char xtraflags1, unsigned char xtraflags2)
|
||||
{
|
||||
/* Assert the ALE (Address Latch Enable line to the flash chip */
|
||||
WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
|
||||
DoC_Delay(docptr, 4);
|
||||
|
||||
/* Send the address */
|
||||
switch (numbytes)
|
||||
{
|
||||
case 1:
|
||||
/* Send single byte, bits 0-7. */
|
||||
WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
|
||||
WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
|
||||
break;
|
||||
case 2:
|
||||
/* Send bits 9-16 followed by 17-23 */
|
||||
WriteDOC((ofs >> 9) & 0xff, docptr, CDSNSlowIO);
|
||||
WriteDOC((ofs >> 9) & 0xff, docptr, Mil_CDSN_IO);
|
||||
WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO);
|
||||
WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
|
||||
break;
|
||||
case 3:
|
||||
/* Send 0-7, 9-16, then 17-23 */
|
||||
WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
|
||||
WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
|
||||
WriteDOC((ofs >> 9) & 0xff, docptr, CDSNSlowIO);
|
||||
WriteDOC((ofs >> 9) & 0xff, docptr, Mil_CDSN_IO);
|
||||
WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO);
|
||||
WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lower the ALE line */
|
||||
WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
|
||||
DoC_Delay(docptr, 4);
|
||||
}
|
||||
|
||||
/* DoC_SelectChip: Select a given flash chip within the current floor */
|
||||
static int DoC_SelectChip(volatile char *docptr, int chip)
|
||||
{
|
||||
/* Select the individual flash chip requested */
|
||||
WriteDOC(chip, docptr, CDSNDeviceSelect);
|
||||
DoC_Delay(docptr, 4);
|
||||
|
||||
/* Wait for it to be ready */
|
||||
return DoC_WaitReady(docptr);
|
||||
}
|
||||
|
||||
/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
|
||||
static int DoC_SelectFloor(volatile char *docptr, int floor)
|
||||
{
|
||||
/* Select the floor (bank) of chips required */
|
||||
WriteDOC(floor, docptr, FloorSelect);
|
||||
|
||||
/* Wait for the chip to be ready */
|
||||
return DoC_WaitReady(docptr);
|
||||
}
|
||||
|
||||
/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
|
||||
static int DoC_IdentChip(volatile char *docptr, int floor, int chip, int *mfr, int *id)
|
||||
{
|
||||
int i;
|
||||
volatile char dummy;
|
||||
|
||||
/* Page in the required floor/chip
|
||||
FIXME: is this supported by Millennium ?? */
|
||||
|
||||
DoC_SelectFloor(docptr, floor);
|
||||
DoC_SelectChip(docptr, chip);
|
||||
|
||||
/* Reset the chip, see Software Requirement 11.4 item 1. */
|
||||
DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
|
||||
/* Read the NAND chip ID: 1. Send ReadID command */
|
||||
DoC_Command(docptr, NAND_CMD_READID, CDSN_CTRL_WP);
|
||||
|
||||
/* Read the NAND chip ID: 2. Send address byte zero */
|
||||
DoC_Address(docptr, 1, 0x00, CDSN_CTRL_WP, 0x00);
|
||||
|
||||
/* Read the manufacturer and device id codes of the flash device through
|
||||
CDSN Slow IO register see Software Requirement 11.4 item 5.*/
|
||||
dummy = ReadDOC(docptr, CDSNSlowIO);
|
||||
DoC_Delay(docptr, 2);
|
||||
*mfr = ReadDOC(docptr, Mil_CDSN_IO);
|
||||
|
||||
dummy = ReadDOC(docptr, CDSNSlowIO);
|
||||
DoC_Delay(docptr, 2);
|
||||
*id = ReadDOC(docptr, Mil_CDSN_IO);
|
||||
|
||||
/* No response - return failure */
|
||||
if (*mfr == 0xff || *mfr == 0)
|
||||
return 0;
|
||||
|
||||
/* FIXME: to deal with mulit-flash on multi-Millennium case more carefully */
|
||||
for (i = 0; nand_flash_ids[i].name != NULL; i++) {
|
||||
if (*mfr == nand_flash_ids[i].manufacture_id &&
|
||||
*id == nand_flash_ids[i].model_id) {
|
||||
printk_info("Flash chip found: Manufacture ID: %2.2X, Chip ID: %2.2X (%s)\n",
|
||||
*mfr, *id, nand_flash_ids[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nand_flash_ids[i].name == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int DoCMil_is_alias(volatile char *docptr1, volatile char *docptr2)
|
||||
{
|
||||
int tmp1, tmp2, retval;
|
||||
|
||||
if(docptr1 == docptr2)
|
||||
return(1);
|
||||
|
||||
/* Use the alias resolution register which was set aside for this
|
||||
* purpose. If it's value is the same on both chips, they might
|
||||
* be the same chip, and we write to one and check for a change in
|
||||
* the other. It's unclear if this register is usuable in the
|
||||
* DoC 2000 (it's in the Millenium docs), but it seems to work. */
|
||||
tmp1 = ReadDOC(docptr1, AliasResolution);
|
||||
tmp2 = ReadDOC(docptr2, AliasResolution);
|
||||
if (tmp1 != tmp2)
|
||||
return 0;
|
||||
|
||||
WriteDOC((tmp1+1) % 0xff, docptr1, AliasResolution);
|
||||
tmp2 = ReadDOC(docptr2, AliasResolution);
|
||||
if (tmp2 == (tmp1+1) % 0xff)
|
||||
retval = 1;
|
||||
else
|
||||
retval = 0;
|
||||
|
||||
/* Restore register contents. May not be necessary, but do it just to
|
||||
* be safe. */
|
||||
WriteDOC(tmp1, docptr1, AliasResolution);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
|
||||
{
|
||||
unsigned char eccbuf[6];
|
||||
volatile char dummy;
|
||||
int i;
|
||||
|
||||
|
||||
DoC_SelectFloor(docptr, 0);
|
||||
DoC_SelectChip(docptr, 0);
|
||||
|
||||
/* Reset the chip, see Software Requirement 11.4 item 1. */
|
||||
DoC_Command(docptr, NAND_CMD_RESET, 0x00);
|
||||
DoC_WaitReady(docptr);
|
||||
/* Set device to main plane of flash */
|
||||
DoC_Command(docptr, NAND_CMD_READ0, 0x00);
|
||||
|
||||
/* issue the Serial Data In command to initial the Page Program process
|
||||
*/
|
||||
DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
|
||||
DoC_Address(docptr, 3, block <<9, 0x00, 0x00);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
|
||||
|
||||
/* Write the data via the internal pipeline through CDSN IO register,
|
||||
see Pipelined Write Operations 11.2 */
|
||||
|
||||
for (i = 0; i < 512; i++) {
|
||||
/* N.B. you have to increase the source address in this way or the
|
||||
ECC logic will not work properly */
|
||||
WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
|
||||
WriteDOC(0x00, docptr, WritePipeTerm);
|
||||
|
||||
/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
|
||||
see Reed-Solomon EDC/ECC 11.1 */
|
||||
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
WriteDOC(0, docptr, NOP);
|
||||
|
||||
/* Read the ECC data through the DiskOnChip ECC logic */
|
||||
for (i = 0; i < 6; i++) {
|
||||
eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
|
||||
/* ignore the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
|
||||
/* Write the ECC data to flash */
|
||||
for (i = 0; i < 6; i++) {
|
||||
WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
|
||||
/* write the block status BLOCK_USED (0x5555) at the end of ECC data FIXME: this is only a hack for programming the IPL area for LinuxBIOS and should be replace with proper codes in user space utilities */
|
||||
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO);
|
||||
WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
|
||||
|
||||
WriteDOC(0x00, docptr, WritePipeTerm);
|
||||
|
||||
/* Commit the Page Program command and wait for ready
|
||||
see Software Requirement 11.4 item 1.*/
|
||||
|
||||
DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
/* Read the status of the flash device through CDSN Slow IO register
|
||||
see Software Requirement 11.4 item 5.*/
|
||||
DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
|
||||
dummy = ReadDOC(docptr, CDSNSlowIO);
|
||||
DoC_Delay(docptr, 2);
|
||||
|
||||
if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
|
||||
printk_info("Error programming flash\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
static int ReadBlockECC( volatile unsigned char *docptr, unsigned int block, char *buf)
|
||||
{
|
||||
int i, ret;
|
||||
volatile char dummy;
|
||||
unsigned char syndrome[6];
|
||||
unsigned char eccbuf[6];
|
||||
|
||||
/* issue the Read0 or Read1 command depend on which half of the page
|
||||
we are accessing. Polling the Flash Ready bit after issue 3 bytes
|
||||
address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/
|
||||
|
||||
/* This differs from SiS ipl.S which always issues 0! */
|
||||
|
||||
DoC_Command(docptr, 0, CDSN_CTRL_WP);
|
||||
// DoC_Command(docptr, block & 1, CDSN_CTRL_WP);
|
||||
DoC_Address(docptr, 3, block << 9, CDSN_CTRL_WP, 0x00);
|
||||
DoC_WaitReady(docptr);
|
||||
|
||||
WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
|
||||
WriteDOC (DOC_ECC_EN, docptr, ECCConf);
|
||||
|
||||
dummy = ReadDOC(docptr, ReadPipeInit);
|
||||
for (i = 0; i < 511; i++) {
|
||||
buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
|
||||
buf[511] = ReadDOC(docptr, LastDataRead);
|
||||
|
||||
/* Read the ECC data from Spare Data Area,
|
||||
see Reed-Solomon EDC/ECC 11.1 */
|
||||
|
||||
dummy = ReadDOC(docptr, ReadPipeInit);
|
||||
for (i = 0; i < 5; i++) {
|
||||
eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
|
||||
}
|
||||
|
||||
eccbuf[i] = ReadDOC(docptr, LastDataRead);
|
||||
|
||||
/* Flush the pipeline */
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
dummy = ReadDOC(docptr, ECCConf);
|
||||
|
||||
/* Check the ECC Status */
|
||||
if (ReadDOC(docptr, ECCConf) & 0x80) {
|
||||
int nb_errors;
|
||||
|
||||
/* There was an ECC error */
|
||||
printk_info("ECC error in block %u\n",block);
|
||||
|
||||
/* Read the ECC syndrom through the DiskOnChip ECC logic.
|
||||
syndrome will be all ZERO when there is no error */
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
|
||||
}
|
||||
#ifdef CHECK_ECC
|
||||
nb_errors = doc_decode_ecc(buf, syndrome);
|
||||
|
||||
if(nb_errors <0) {
|
||||
printk_info("ECC errors uncorrectable!\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
||||
printk_info("Corrected %u errors!\n",nb_errors);
|
||||
#else
|
||||
printk_info("ECC Syndrom bytes:\n");
|
||||
for(i=0; i<6 ; i++)
|
||||
printk_info("%02x,",syndrome[i]);
|
||||
printk_info("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* disable the ECC engine */
|
||||
WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
static void
|
||||
memcpy_from_doc_mil(void *dest, const void *src, size_t n)
|
||||
{
|
||||
|
|
@ -551,12 +69,9 @@ memcpy_from_doc_mil(void *dest, const void *src, size_t n)
|
|||
unsigned long address = (unsigned long) src;
|
||||
|
||||
for (i = n; i >= 0; i -= 0x200) {
|
||||
#ifdef USE_NEW_DOC_CODE
|
||||
ReadBlockECC(doc_mil,(address >> 9), dest);
|
||||
|
||||
#else
|
||||
unsigned short c = 0x1000;
|
||||
volatile unsigned char dummy;
|
||||
|
||||
/* issue Read00 flash command */
|
||||
*(volatile unsigned char *) (doc_mil + 0x1004) = 0x03;
|
||||
*(volatile unsigned char *) (doc_mil + 0x800) = 0x00;
|
||||
|
|
@ -578,20 +93,8 @@ memcpy_from_doc_mil(void *dest, const void *src, size_t n)
|
|||
|
||||
/* copy 512 bytes of data from CDSN_IO registers */
|
||||
dummy = *(volatile unsigned char *) (doc_mil + 0x101d);
|
||||
#ifdef CHECK_DOC_MIL
|
||||
{ unsigned char val; unsigned char *cp = dest;
|
||||
for(i = 0; i < 0x200; i++) {
|
||||
val = *(volatile unsigned char *) (doc_mil + 0x800 + i);
|
||||
printk_info("0x%x: 0x%x\n",
|
||||
i + address, val);
|
||||
cp[i] = val;
|
||||
}
|
||||
}
|
||||
#else
|
||||
memcpy(dest, doc_mil + 0x800, 0x200);
|
||||
#endif /* CHECK_DOC_MIL */
|
||||
|
||||
#endif /* USE_NEW_DOC_CODE */
|
||||
dest += 0x200;
|
||||
address += 0x200;
|
||||
}
|
||||
|
|
@ -604,28 +107,44 @@ memcpy_from_doc_mil(void *dest, const void *src, size_t n)
|
|||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||
|
||||
static int init_bytes(void)
|
||||
static int
|
||||
init_bytes(void)
|
||||
{
|
||||
return;
|
||||
// it is possible that we can get in here and the
|
||||
// doc has never been reset. So go ahead and reset it again.
|
||||
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x84;
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x84;
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x85;
|
||||
*(volatile unsigned char *) (doc_mil + 0x1002) = 0x85;
|
||||
|
||||
return 1;
|
||||
}
|
||||
static void fini_bytes(void)
|
||||
|
||||
static void
|
||||
fini_bytes(void)
|
||||
{
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
|
||||
static byte_offset_t
|
||||
read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
byte_offset_t bytes = 0;
|
||||
unsigned char *dest = vdest;
|
||||
while(bytes < count) {
|
||||
|
||||
while (bytes++ < count) {
|
||||
*(dest++) = get_byte();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
static byte_offset_t
|
||||
skip_bytes(byte_offset_t count)
|
||||
{
|
||||
byte_offset_t bytes = 0;
|
||||
while(bytes < count) {
|
||||
|
||||
while (bytes++ < count) {
|
||||
unsigned char byte;
|
||||
byte = get_byte();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue