windows-nt/Source/XPSP1/NT/drivers/storage/tffsport/doc2exb.c
2020-09-26 16:20:57 +08:00

778 lines
31 KiB
C

/*
* $Log: V:/Flite/archives/TrueFFS5/Src/DOC2EXB.C_V $
*
* Rev 1.26 Apr 15 2002 07:35:12 oris
* Moved doc2exb internal functions declaration to blockdev.c.
* Make sure all relevant data is stored in little endian format.
*
* Rev 1.25 Feb 19 2002 20:58:28 oris
* Moved include directive and routine prototypes from H file.
*
* Rev 1.24 Jan 23 2002 23:31:18 oris
* Removed warnings.
* Replaced Alon based DiskOnChip writeIPL code with the MTD writeIPL routine.
*
* Rev 1.23 Jan 21 2002 20:44:02 oris
* Bad support for firmware other then the default 3 firmwares (TrueFFS 4.3 backward compatibility firmware).
* Added support for DiskOnChip Millennium Plus 16MB firmware.
* Missing far heap initialization for DiskOnChip 2000 firmware.
*
* Rev 1.22 Jan 17 2002 22:58:32 oris
* Added new flags for placeExbByBuffer - Choose firmware to place
* Added firmware number to getExbInfo().
* Changed debug print to Dformat print.
* Removed exb size calculation when writing SPL - It is done as part of the firmware build
* Added support for far malloc heap.
* All DiskOnChip use the same STACK size definition.
*
* Rev 1.21 Nov 08 2001 10:44:50 oris
* Removed warnings.
*
* Rev 1.20 Sep 24 2001 18:23:10 oris
* Removed warnings.
*
* Rev 1.19 Sep 16 2001 21:47:42 oris
* Bug fix - support for 1KB IPL code for DiskOnChip2000 tsop.
*
* Rev 1.18 Sep 15 2001 23:44:54 oris
* Bug fix - The last 512 bytes of the last firmware were not written, and IPL was not loaded.
*
* Rev 1.17 Jul 30 2001 17:57:36 oris
* Removed warrnings
*
* Rev 1.16 Jul 30 2001 00:20:52 oris
* Support new IPL and SPL formats.
*
* Rev 1.15 Jul 13 2001 01:00:08 oris
* Changed constant stack space from magic numbers to contents.
* Added erase before write for the binary write operation.
*
* Rev 1.14 Jun 17 2001 08:17:16 oris
* Changed placeExbByBuffer exbflags argument to word instead of byte to support /empty flag.
* Adjust exb size field to fit OSAK 4.3 format.
* Added \empty flag - Leaves exb space empty.
*
* Rev 1.13 May 29 2001 19:47:12 oris
* Bug fix - trueffs heap size discounted boot units (heap too small)
* Doc2000 exbOffset hardcoded to 40.
*
* Rev 1.12 May 16 2001 21:16:50 oris
* Change "data" named variables to flData to avoid name clashes.
* Removed warnings.
*
* Rev 1.11 May 09 2001 00:31:52 oris
* Bug fix - Added check status to intializaion routine of place EXB by buffer.
*
* Rev 1.10 May 06 2001 22:41:34 oris
* Reduced tffs head size for Millennium Plus and DOC2000 tsop devices.
* Removed warnings.
*
* Rev 1.9 Apr 12 2001 06:48:46 oris
* Added call to download routine in order to load new IPL.
*
* Rev 1.8 Apr 10 2001 16:40:22 oris
* Removed warrnings.
*
* Rev 1.7 Apr 09 2001 14:59:04 oris
* Reduced exb size read by the SPL to minimum.
*
* Rev 1.6 Apr 03 2001 18:08:42 oris
* Bug fix - exb flags were not properly written.
*
* Rev 1.5 Apr 03 2001 16:34:50 oris
* Removed unsused variables.
*
* Rev 1.4 Apr 03 2001 14:36:46 oris
* Completly reviced in order to support alon devices.
*
* Rev 1.3 Apr 02 2001 00:54:32 oris
* Added doc2000 exb family.
* Supply the exact length of the exb in the binary partition.
* Removed the no_pnp_header from the media.
* Bug fix for calculation Spl size.
*
* Rev 1.2 Apr 01 2001 07:49:42 oris
* Updated copywrite notice.
* Added support for doc2300 firmware.
* Bug fixes for mdoc plus.
* Added support for 1k IPL.
* Added consideration in media type in calculating tffs heap size.
* Changed h\w to h/w
* Changed 2400 family to doc plus family.
*
* Rev 1.1 Feb 08 2001 10:37:54 oris
* Bug fix for unaligned file signature
*
* Rev 1.0 Feb 02 2001 12:59:48 oris
* Initial revision.
*
*/
/***********************************************************************************/
/* M-Systems Confidential */
/* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
/* All Rights Reserved */
/***********************************************************************************/
/* NOTICE OF M-SYSTEMS OEM */
/* SOFTWARE LICENSE AGREEMENT */
/* */
/* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
/* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
/* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
/* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
/* E-MAIL = info@m-sys.com */
/***********************************************************************************/
/*****************************************************************************
* File Header *
* ----------- *
* Project : TrueFFS source code *
* *
* Name : doc2exb.c *
* *
* Description : This file contains the code for analizing and writing *
* M-Systems EXB firmware files *
* *
*****************************************************************************/
#include "doc2exb.h"
#include "bddefs.h"
#ifdef WRITE_EXB_IMAGE
extern FLStatus absMountVolume(Volume vol);
#define BUFFER exb->buffer->flData
exbStruct exbs[SOCKETS];
#define roundedUpShift(a,bits) (((a - 1) >> bits)+1)
/*----------------------------------------------------------------------*/
/* g e t E x b I n f o */
/* */
/* Analize M-systems firmware file */
/* Analizes M-systems firmware (exb) file, calclating the media space */
/* required for it. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* buf : Pointer to EXB file buffer */
/* bufLen : Size of the buffer */
/* bufFlags : Flags for the EXB - specifing type of */
/* firmware to extract from the EXB file. */
/* */
/* Returns: */
/* FLStatus : flOK on success. */
/* flBadLength if buffer size is too small */
/* flBadParameter on any other failure */
/* vol.binaryLength : Total size needed in the binary partition */
/* exbs[i].firmwareStart : offset of the firmware begining in the file */
/* exbs[i].firmwareEnd : offset of the firmware end in the file */
/* exbs[i]l.splOffset : offset of the spl start in the file */
/* exbs[i]l.exbFileEnd : Total exb file size. */
/*----------------------------------------------------------------------*/
FLStatus getExbInfo(Volume vol, void FAR1 * buf, dword bufLen, word exbFlags)
{
byte i;
byte mediaType;
ExbGlobalHeader FAR1* globalHeader = (ExbGlobalHeader FAR1*)buf;
FirmwareHeader FAR1* firmwareHeader = (FirmwareHeader FAR1*)
flAddLongToFarPointer(buf,sizeof(ExbGlobalHeader));
/* Make sure size given is big enough */
if (bufLen < sizeof(FirmwareHeader) * LE4(globalHeader->noOfFirmwares) +
sizeof(ExbGlobalHeader))
{
DFORMAT_PRINT(("ERROR - Buffer size not big enough.\r\n"));
return flBadLength;
}
/* Make sure this is an M-systems EXB file */
if (tffscmp(globalHeader->mSysSign,SIGN_MSYS,SIGN_MSYS_SIZE) != 0)
{
DFORMAT_PRINT(("ERROR - Given file is not M-systems EXB file.\r\n"));
return flBadParameter;
}
i = (exbFlags & FIRMWARE_NO_MASK) >> FIRMWARE_NO_SHIFT;
if(i == 0)
{
/* Make sure this is the correct version of TrueFFS */
if (tffscmp(globalHeader->osakVer,TrueFFSVersion,SIGN_MSYS_SIZE) != 0)
{
DFORMAT_PRINT(("ERROR - Incorrect TrueFFS EXB file version.\r\n"));
return flBadParameter;
}
/* Find the corrent firmware in the file */
/* Automatic firmware detection - by DiskOnChip type */
switch (vol.flash->mediaType)
{
case DOC_TYPE:
case MDOC_TYPE:
mediaType = DOC2000_FAMILY_FIRMWARE;
break;
case MDOCP_TYPE:
mediaType = DOCPLUS_FAMILY_FIRMWARE;
break;
case MDOCP_16_TYPE:
mediaType = DOCPLUS_INT1_FAMILY_FIRMWARE;
break;
case DOC2000TSOP_TYPE:
mediaType = DOC2300_FAMILY_FIRMWARE;
break;
default:
DFORMAT_PRINT(("Unknown H/W - Try specifing the firmware manualy.\r\n"));
return flFeatureNotSupported;
}
for (i=0;i<LE4(globalHeader->noOfFirmwares);i++,firmwareHeader++)
{
if (LE4(firmwareHeader->type) == mediaType)
break;
}
}
else /* Use given firmware */
{
i--; /* 0 was used for automatic choose of firmware */
}
if (i >= LE4(globalHeader->noOfFirmwares))
{
DFORMAT_PRINT(("ERROR - The EXB file does not support the required firmware.\r\n"));
return flBadParameter;
}
/* Initialize the volumes EXB fields */
firmwareHeader = (FirmwareHeader FAR1*)flAddLongToFarPointer(buf,
(sizeof(ExbGlobalHeader) + (i * sizeof(FirmwareHeader))));
i = (byte)(&vol - vols);
/* Save firmware files statstics recieved from the files header */
exbs[i].firmwareStart = LE4(firmwareHeader->startOffset);
exbs[i].firmwareEnd = LE4(firmwareHeader->endOffset);
exbs[i].splStart = LE4(firmwareHeader->splStartOffset);
exbs[i].splEnd = LE4(firmwareHeader->splEndOffset);
exbs[i].exbFileEnd = LE4(globalHeader->fileSize);
/* Calculate the binary partition size (good bytes) used to
hold the EXB file. */
exbs[i].iplMod512 = (word)((exbs[i].splStart - exbs[i].firmwareStart)
>> SECTOR_SIZE_BITS);
switch (vol.flash->mediaType)
{
/* NFTL formated device - IPL is placed on the binary partition */
case DOC_TYPE:
/* Size of EXB minus IPL which is placed in ROM */
vol.binaryLength = exbs[i].firmwareEnd - exbs[i].splStart + 0x4000;
break;
case MDOC_TYPE: /* Millennium 8, write data as is */
/* Size of entire EXB */
vol.binaryLength = exbs[i].firmwareEnd - exbs[i].firmwareStart;
break;
/* INFTL formated device - IPL is not placed on the binary
partition, but on a dedicated flash area */
case DOC2000TSOP_TYPE: /* DOC2000 TSOP */
case MDOCP_TYPE: /* MDOC PLUS 32MB */
case MDOCP_16_TYPE: /* MDOC PLUS 16MB */
vol.binaryLength = exbs[i].firmwareEnd - exbs[i].splStart;
break;
default :
DFORMAT_PRINT(("ERROR - Firmware formater reports A None DiskOnChip media.\r\n"));
return flBadParameter;
}
return flOK;
}
/*------------------------------------------------------------------------*/
/* w a i t F o r H a l f B u f f e r */
/* */
/* Increament the EXB file pointers and store the files data unit a */
/* full sector of data is read. */
/* */
/* Parameters: */
/* exbs[i].bufferOffset : size of the buffer already filled with data */
/* exbs[i].exbFileOffset : offset from the beginning of the file */
/* exbs[i].buffer.data : internal volume buffer accumulation file data */
/* buf : buffer containing the files data */
/* bufLen : Length of the buffer containing the file data */
/* length : Length of the buffer not yet used */
/* half : Wait for full 512 bytes of only 256 */
/* Returns: */
/* boolean : TRUE on full buffer otherwise FALSE. */
/* length : Updated length of unused buffer */
/*------------------------------------------------------------------------*/
FLBoolean waitForFullBuffer(Volume vol , byte FAR1 * buf ,
dword bufLen , Sdword * length,FLBoolean half)
{
word bufferEnd;
word tmp;
byte i = (byte)(&vol - vols);
if (half == TRUE)
{
bufferEnd = (SECTOR_SIZE >> 1);
}
else
{
bufferEnd = SECTOR_SIZE;
}
tmp = (word)TFFSMIN(*length , bufferEnd - exbs[i].bufferOffset);
tffscpy(exbs[i].buffer->flData + exbs[i].bufferOffset ,
flAddLongToFarPointer(buf,(bufLen-(*length))), tmp);
exbs[i].bufferOffset += tmp;
exbs[i].exbFileOffset += tmp;
*length -= tmp;
if (*length+tmp < bufferEnd)
return FALSE;
exbs[i].bufferOffset = 0;
return TRUE;
}
/*------------------------------------------------------------------------*/
/* f i r s t T i m e I n i t */
/* */
/* Initialize data structures for placing exb file. */
/* full sector of data is read. */
/* */
/* Actions: */
/* 1) Analize exb file buffer. */
/* 2) Calculate TFFS heap size. */
/* 3) Check if binary area with SPL signature is big enough. */
/* 4) Calculate SPL start media address */
/* 5) Calculate binary area used for the firmware. */
/* 6) Initialize the volumes EXB record. */
/* */
/* Parameters: */
/* vol : Pointer to volume record describing the volume. */
/* exb : Pointer to exb record describing the volume. */
/* buf : Exb file buffer. */
/* bufLen : Length of exb file buffer. */
/* ioreq : Internal ioreq record for binary operaions. */
/* bdk : Bdk record which is a part of the ioreq packet. */
/* */
/* Affected Variables. */
/* */
/* Returns: */
/* flOK : On success. */
/* flNoSpaceInVolume : Not enough space on the binary area. */
/*------------------------------------------------------------------------*/
FLStatus firstTimeInit(Volume vol , exbStruct* exb, byte FAR1 * buf ,
dword bufLen , IOreq* ioreq , BDKStruct* bdk ,
word exbFlags)
{
if (vol.moduleNo == INVALID_MODULE_NO)
{
FLStatus status;
TLInfo info;
/* Use the sockets buffer */
exb->buffer = flBufferOf((unsigned)(exbs-exb));
/* Find the number of blocks used needed for the EXB file */
checkStatus(getExbInfo(&vol,buf,bufLen,exbFlags));
/* Find TFFS heap size */
if (!(vol.flags & VOLUME_ABS_MOUNTED))
checkStatus(absMountVolume(&vol));
ioreq->irData = &info;
checkStatus(vol.tl.getTLInfo(vol.tl.rec,&info));
exb->tffsHeapSize = (dword)(vol.flash->chipSize * vol.flash->noOfChips) >> info.tlUnitBits;
/* Add heap for dynamic allocation not related to convertion tables */
if((exbFlags & FIRMWARE_NO_MASK) >> FIRMWARE_NO_SHIFT == 0)
{
/* virutal TABLE + physical table */
exb->tffsFarHeapSize = (word)(((exb->tffsHeapSize * 3) >> SECTOR_SIZE_BITS) + 1);
exb->tffsHeapSize = INFTL_NEAR_HEAP_SIZE;
}
else /* Old TrueFFS source */
{
exb->tffsFarHeapSize = 0;
exb->tffsHeapSize = exb->tffsHeapSize * 3 + DEFAULT_DOC_STACK;
}
/* Check if binary partition is formated for EXB */
bdk->startingBlock = 0;
ioreq->irData = bdk;
status = bdkCall(FL_BINARY_PARTITION_INFO,ioreq,vol.flash);
if ((bdk->startingBlock < vol.binaryLength) || (status != flOK))
{
DFORMAT_PRINT(("ERROR - Not enough binary area marked for EXB.\r\n"));
return flNoSpaceInVolume;
}
/* initialize binary area for writting the EXB file */
bdk->length = ((vol.binaryLength-1) >> vol.flash->erasableBlockSizeBits) +1;
bdk->startingBlock = 0;
bdk->signOffset = EXB_SIGN_OFFSET;
checkStatus(bdkCall(FL_BINARY_ERASE,ioreq,vol.flash)); /* ERASE */
if ((exbFlags & LEAVE_EMPTY) == 0)
{
/* If actualy need to place firmware initialize Binary write */
bdk->length = vol.binaryLength;
bdk->flags = BDK_COMPLETE_IMAGE_UPDATE | EDC;
bdkVol->bdkGlobalStatus |= BDK_S_INFO_FOUND; /* do not research */
checkStatus(bdkCall(FL_BINARY_WRITE_INIT,ioreq,vol.flash));
tffsset(BUFFER,0xff,SECTOR_SIZE);
}
exb->exbFileOffset = 0; /* start of exb file */
exb->bufferOffset = 0; /* start of internal buffer */
exb->moduleLength = 0; /* size of the current module */
exb->exbFlags = exbFlags; /* see list in doc2exb.h */
vol.moduleNo = 0; /* module IPL */
}
return flOK;
}
/*----------------------------------------------------------------------*/
/* p l a c e E x b B y B u f f e r */
/* */
/* Place M-systems firmware file on the media. */
/* This routine analizes the exb file calclating the media space needed */
/* for it taking only the device specific code. */
/* */
/* Note : The media must be already formated with enough binary area */
/* already marked with the SPL signature. This routine is best used */
/* with the format routine where the format routine is givven the first */
/* 512 bytes while the rest of the file is given with this routine */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* buf : Buffer containing EXB file data */
/* bufLen : Size of the current buffer */
/* windowBase : Optional set window base address */
/* exbFlags : INSTALL_FIRST - Install device as drive C: */
/* FLOPPY - Install device as drive A: */
/* QUIET - Do not show TFFS titles */
/* INT15_DISABLE - Do not hook int 15 */
/* SIS5598 - Support for SIS5598 platforms */
/* NO_PNP_HEADER - Do not place the PNP bios header */
/* LEAVE_EMPTY - Leave space for firmware */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed */
/*----------------------------------------------------------------------*/
FLStatus placeExbByBuffer(Volume vol, byte FAR1 * buf, dword bufLen,
word docWinBase ,word exbFlags)
{
IOreq ioreq;
BDKStruct bdk;
word tmpWord;
Sdword length = bufLen;
byte anandMark[2] = {0x55,0x55};
exbStruct* exb = &exbs[(byte)(&vol-vols)];
BIOSHeader* hdr;
IplHeader *ipl;
SplHeader *spl;
TffsHeader *tffs;
/* Initialize binary partition call packet */
tffscpy(bdk.oldSign,SIGN_SPL,BINARY_SIGNATURE_NAME); /* firmware signature */
ioreq.irData = &bdk;
bdk.signOffset = EXB_SIGN_OFFSET;
ioreq.irHandle = 0;
/* First time initialization */
checkStatus(firstTimeInit(&vol,exb,buf,bufLen,&ioreq, &bdk, exbFlags));
/* Initialize the rest of the binary partition call packet */
bdk.bdkBuffer = BUFFER; /* internal bufer */
bdk.length = sizeof(BUFFER); /* buffer size */
bdk.flags |= ERASE_BEFORE_WRITE; /* Erase each unit before writing */
/* Make sure this is a relevant part of the file */
if (exb->exbFileOffset + length < exb->firmwareStart)
{
/* Before this specific device firmware */
exb->exbFileOffset += length;
return flOK;
}
if (exb->exbFileOffset >= exb->firmwareEnd)
{
/* After this specific device firmware */
exb->exbFileOffset += length;
if (exb->exbFileOffset >= exb->exbFileEnd)
{
vol.moduleNo = INVALID_MODULE_NO;
if (vol.flash->download != NULL)
return vol.flash->download(vol.flash); /* download IPL */
}
return flOK;
}
if (exb->exbFileOffset < exb->firmwareStart)
{
length -= exb->firmwareStart - exb->exbFileOffset;
exb->exbFileOffset = exb->firmwareStart;
}
/* Start writting the file modules */
while ((exb->firmwareEnd > exb->exbFileOffset) && (length >0))
{
/* Read next page into internal buffer */
/* DOC2000 IPL is ROM and it assumed small pages therefore
read only the first 256 bytes of each page. */
if ((vol.moduleNo == 1) && (vol.flash->mediaType == DOC_TYPE))
{
if (waitForFullBuffer(&vol , buf , bufLen , &length,
TRUE) == FALSE) /* 256 BYTES */
return flOK;
}
else
{
if ((waitForFullBuffer(&vol , buf , bufLen , &length,
FALSE) == FALSE) && /* 512 BYTES */
(exb->exbFileOffset != exb->exbFileEnd)) /* Not last buffer */
return flOK;
}
/* Update the module length according to its header */
if (exb->moduleLength == 0)
{
/* All modules except for the SPL start with biosHdr record
SPL has a 2 bytes opCode preciding the biosHdr and an
incorrect module length */
switch (vol.moduleNo) /* SPL */
{
case 1:
hdr = &((SplHeader *)BUFFER)->biosHdr;
/* calculate the number of buffers to use for the SPL */
exb->moduleLength = (word)((exb->splEnd-exb->splStart) >> SECTOR_SIZE_BITS);
/* Doc 2000 writes in chunks of 256 bytes therfore need to
double the amount of write operations */
if (vol.flash->mediaType == DOC_TYPE)
exb->moduleLength = (word)(exb->moduleLength << 1);
break;
default : /* Get size from header */
hdr = (BIOSHeader *) BUFFER;
exb->moduleLength = hdr->lenMod512;
}
/* Check validy of bios header */
if ((hdr->signature[0] != 0x55) || (hdr->signature[1] != 0xAA))
{
DFORMAT_PRINT(("ERROR - EXB file is missing one of the BIOS driver modules.\r\n"));
return flBadLength;
}
/* Update neccesary fields in the modules headers */
switch (vol.moduleNo)
{
case 0: /* IPL */
/* The IPL length is actualy the window size in order to */
/* supply the BIOS the expantion range. The real size */
/* if calculated according to the exb file header. */
if (vol.moduleNo==0)
exb->moduleLength = exb->iplMod512;
ipl = (IplHeader *)BUFFER;
/* Set 0000 pointer of ISA P&P Header */
if(exb->exbFlags & NO_PNP_HEADER)
{
ipl->dummy += ((byte)(ipl->pnpHeader >> 8) +
(byte)ipl->pnpHeader);
ipl->pnpHeader = 0;
}
/* Set DOC Window base explicitely */
if( docWinBase > 0 )
{
toLE2(ipl->windowBase , docWinBase);
ipl->dummy -= (byte)( docWinBase );
ipl->dummy -= (byte)( docWinBase >> 8 );
}
break;
case 1: /* SPL */
spl = (SplHeader *)BUFFER;
/* calculate EXB module size */
/* generate random run-time ID and write it into splHeader. */
tmpWord = (word)flRandByte();
toUNAL2(spl->runtimeID, tmpWord);
spl->chksumFix -= (byte)(tmpWord);
spl->chksumFix -= (byte)(tmpWord >> 8);
/* Write TFFS heap size into splHeader. */
toUNAL2(spl->tffsHeapSize, (word)exb->tffsHeapSize);
spl->chksumFix -= (byte)(exb->tffsHeapSize);
spl->chksumFix -= (byte)(exb->tffsHeapSize >> 8);
/* set explicit DOC window base */
if( docWinBase > 0 )
{
toUNAL2(spl->windowBase, docWinBase);
spl->chksumFix -= (byte)(docWinBase);
spl->chksumFix -= (byte)(docWinBase >> 8);
}
break;
case 2: /* Socket Services OR interupt 13 driver */
/* The doc2000 driver and or socket services start
at 0x4000 so we have to jump over there. */
if (vol.flash->mediaType == DOC_TYPE)
{
bdkVol->actualUpdateLen -= 0x4000 - bdkVol->curUpdateImageAddress;
bdkVol->curUpdateImageAddress = 0x4000;
}
tffs = (TffsHeader *)BUFFER;
tffs->chksumFix -= (byte)(exb->tffsFarHeapSize);
tffs->chksumFix -= (byte)(exb->tffsFarHeapSize >> 8);
toUNAL2(tffs->heapLen, exb->tffsFarHeapSize);
exb->exbFlags &= ~NO_PNP_HEADER;
default:
/* put "install as first drive" & QUIET mark
into the TFFS header */
tffs = (TffsHeader *)BUFFER;
tffs->exbFlags = (byte)exb->exbFlags;
tffs->chksumFix -= (byte)exb->exbFlags;
break;
} /* end - switch of module type */
} /* end - first buffer of module */
exb->moduleLength--;
/* Write module and clean buffer */
switch (vol.moduleNo)
{
case 0: /* IPL data */
switch (vol.flash->mediaType)
{
case MDOC_TYPE: /* Millennium 8 - use bdk to write IPL * 2 */
if (exb->moduleLength == exb->iplMod512 - 1)
{
/* Milennium DiskOnChip is the only device that the IPL
is duplicated in the exb file. The dupplication was
needed in earlier versions but it is currently ignored.
The IPL is still written twice only that the second
copy is not taken from the file but the first copy is
simply written twice. */
if ((exbFlags & LEAVE_EMPTY) == 0)
{
checkStatus(bdkCall(FL_BINARY_WRITE_BLOCK,
&ioreq,vol.flash));
checkStatus(bdkCall(FL_BINARY_WRITE_BLOCK,
&ioreq,vol.flash));
}
}
/* Change byte #406 to non-0xFF value to force
Internal EEprom Mode */
checkStatus(vol.flash->write(vol.flash,
ANAND_MARK_ADDRESS,anandMark,ANAND_MARK_SIZE,EXTRA));
break;
case DOC2000TSOP_TYPE: /* Doc 2000 tsop - write to block 0 */
case MDOCP_TYPE: /* Millennium Plus - use MTD specific routine */
case MDOCP_16_TYPE:
if (vol.flash->writeIPL == NULL)
return flFeatureNotSupported;
if ((exbFlags & LEAVE_EMPTY) != 0)
{
/* Erase previous IPL if all we need is to leave
space for the firmware and not realy write it */
tffsset(BUFFER,0xff,SECTOR_SIZE);
}
checkStatus(vol.flash->writeIPL(vol.flash,
BUFFER,SECTOR_SIZE,
(byte)(exb->iplMod512 - exb->moduleLength-1),
FL_IPL_MODE_NORMAL));
default: /* DiskOnChip 2000 */
break; /* IPL is burnt onto ROM */
}
break;
default:
if ((exbFlags & LEAVE_EMPTY) == 0)
{
checkStatus(bdkCall(FL_BINARY_WRITE_BLOCK,&ioreq,vol.flash));
}
}
tffsset(BUFFER,0xff,sizeof(BUFFER));
if (exb->moduleLength == 0)
vol.moduleNo++;
}
if (exb->exbFileOffset >= exb->firmwareEnd)
{
exb->exbFileOffset += length;
}
if (exb->exbFileOffset >= exb->exbFileEnd)
{
vol.moduleNo = INVALID_MODULE_NO;
if (vol.flash->download != NULL)
return vol.flash->download(vol.flash); /* download IPL */
}
return(flOK);
}
#endif /* WRITE_EXB_IMAGE */