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

811 lines
26 KiB
C

/*
* $Log: V:/Flite/archives/TrueFFS5/Src/PROTECTP.C_V $
*
* Rev 1.18 Apr 15 2002 07:38:44 oris
* Added static qualifier for private functions (findChecksum and makeDPS).
* Removed readDPS and writeDPS routine prototypes (no longer exist).
* Added setStickyBit routine for DiskOnChip Plus 128Mbit.
*
* Rev 1.17 Jan 28 2002 21:26:24 oris
* Removed the use of back-slashes in macro definitions.
*
* Rev 1.16 Jan 17 2002 23:04:54 oris
* Replaced docsysp include directive with docsys.
* Changed the use of vol (macro *pVol) to *flash.
* Add support for DiskOnChip Millennium Plus 16MB :
* - Copy extra area of IPL independently of the EDC to copy Strong arm mark.
* - DPS 0 and 1 location where changed - affects protectionSet routine.
* Bug fix - Wrong usage of findChecksum, caused the use of the second copy of the DPS instead of the first.
*
* Rev 1.15 Sep 24 2001 18:24:18 oris
* removed ifdef and forced using flRead8bitRegPlus instead of reading with flRead16bitRegPlus.
*
* Rev 1.14 Sep 15 2001 23:47:56 oris
* Remove all 8-bit access to uneven addresses.
*
* Rev 1.13 Jul 16 2001 17:41:54 oris
* Ignore write protection of the DPSs.
*
* Rev 1.12 Jul 13 2001 01:09:26 oris
* Bug fix for protection boundaries when using Millennium Plus devices that can not access a single byte.
* Added send default key before trying a protection violation command.
* Bug fix - bad IPL second copy offset.
*
* Rev 1.11 May 16 2001 21:21:42 oris
* Removed warnings.
*
* Rev 1.10 May 09 2001 00:35:48 oris
* Bug fix - Lock asserted was reported opposite of the real state.
* Bug fix - Make sure to return "key inserted" if the partition is not read\write protected.
* This is to enable a partition that does not span over all of the media floors to return "key inserted".
*
* Rev 1.9 May 06 2001 22:42:18 oris
* Bug fix - insert key does not try to insert key to a floor that is not read\write protected.
* Bug fix - protection type does not return key inserted is one of the floors key is not inserted.
* Bug fix - set protection no longer clears the IPL.
* redundant was misspelled.
*
* Rev 1.8 May 01 2001 14:24:56 oris
* Bug fix - CHANGEABLE_PRTOECTION was never reported.
*
* Rev 1.7 Apr 18 2001 17:19:02 oris
* Bug fix - bad status code returned by protection set routine du to calling changaInterleave while in access error.
*
* Rev 1.6 Apr 18 2001 09:29:32 oris
* Bug fix - remove key routine always return bad status code.
*
* Rev 1.5 Apr 16 2001 13:58:28 oris
* Removed warrnings.
*
* Rev 1.4 Apr 12 2001 06:52:32 oris
* Changed protectionBounries and protectionSet routine to be floor specific.
*
* Rev 1.3 Apr 10 2001 23:56:30 oris
* Bug fix - protectionBounries routine - floor did not change.
* Bug fix - protectionSet routine - floors with no protected areas were not updated.
* Bug fix - protectionBounries routine - bad paranthesis in MAX calculation.
*
* Rev 1.2 Apr 09 2001 19:04:24 oris
* Removed warrnings.
*
*/
/*******************************************************************
*
* DESCRIPTION: MTD protection mechanism routines for the MDOC32
*
* AUTHOR: arie tamam
*
* HISTORY: created november 14, 2000
*
*******************************************************************/
/** include files **/
#include "mdocplus.h"
#include "protectp.h"
#include "docsys.h"
/** local definitions **/
/* default settings */
/** external functions **/
/** external data **/
/** internal functions **/
static byte findChecksum(byte * buffer, word size);
static void makeDPS(CardAddress addressLow, CardAddress addressHigh,
byte FAR1* key , word flag, byte* buffer);
#define MINUS_FLOORSIZE(arg) ((arg > NFDC21thisVars->floorSize) ? arg - NFDC21thisVars->floorSize : 0)
/** public data **/
/** private data **/
/** public functions **/
#ifdef HW_PROTECTION
/**********/
/* Macros */
/**********/
/* check if key is correct */
#define isArea0Protected(flash) (((flRead8bitRegPlus(flash,NdataProtect0Status) & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) ? TRUE : FALSE)
#define isArea1Protected(flash) (((flRead8bitRegPlus(flash,NdataProtect1Status) & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) ? TRUE : FALSE)
/*----------------------------------------------------------------------*/
/* s e t S t i c k y B i t */
/* */
/* Set the sticky bit to prevent the insertion of the protection key. */
/* */
/* Parameters: */
/* flash : Pointer identifying drive. */
/* */
/* Returns: */
/* flOK on success, none zero otherwise. */
/*----------------------------------------------------------------------*/
FLStatus setStickyBit(FLFlash * flash)
{
volatile Reg8bitType val;
register int i;
/* Raise the sticky bit, while keeping the other bits of the register */
for(i=0;i<flash->noOfFloors;i++)
{
/* Remove last bit */
val = flRead8bitRegPlus(flash, NoutputControl) |
OUT_CNTRL_STICKY_BIT_ENABLE;
flWrite8bitRegPlus(flash, NoutputControl, val);
}
return flOK;
}
/*
** protectBoundries
*
*
* PARAMETERS:
* flash : Pointer identifying drive
* area : indicated which protection area to work on. 0 or 1.
* AddressLow : address of lower boundary of protected area
* AddressHigh : address of upper boundary of protected area
*
* DESCRIPTION: Gets protection boundaries from registers
*
* NOTE : protection areas are assumed to be consequtive although they
* may skip DPS , OTP and header units.
*
* RETURNS:
* flOK on success
*
*/
FLStatus protectionBoundries(FLFlash * flash, byte area,CardAddress* addressLow,
CardAddress* addressHigh, byte floorNo)
{
/* Check mode of ASIC and set to NORMAL.*/
FLStatus status = chkASICmode(flash);
if(status != flOK)
return status;
setFloor(flash,floorNo);
switch (area)
{
case 0: /* data protect structure 0 */
/* read the data protect 0 addresses */
*addressLow = ((dword)flRead8bitRegPlus(flash,NdataProtect0LowAddr) << 10)| /* ADDR_1 */
((dword)flRead8bitRegPlus(flash,NdataProtect0LowAddr+1) << 18); /* ADDR_2 */
*addressHigh = ((dword)flRead8bitRegPlus(flash,NdataProtect0UpAddr) << 10)| /* ADDR_1 */
((dword)flRead8bitRegPlus(flash,NdataProtect0UpAddr+1) << 18); /* ADDR_2 */
break;
case 1: /* data protect structure 1 */
/* read the data protect 1 addresses */
*addressLow = ((dword)flRead8bitRegPlus(flash,NdataProtect1LowAddr) << 10)| /* ADDR_1 */
((dword)flRead8bitRegPlus(flash,NdataProtect1LowAddr+1) << 18); /* ADDR_2 */
*addressHigh = ((dword)flRead8bitRegPlus(flash,NdataProtect1UpAddr) << 10)| /* ADDR_1 */
((dword)flRead8bitRegPlus(flash,NdataProtect1UpAddr+1) << 18); /* ADDR_2 */
break;
default: /* No such protection area */
return flGeneralFailure;
}
return(flOK);
}
/*
** tryKey
*
*
* PARAMETERS:
* flash : Pointer identifying drive
* area : indicated which protection area to work on. 0 or 1.
* Key : an 8 byte long array containing the protection password.
* unsigned char * is an 8 bytes unsigned char array
*
* DESCRIPTION: Sends protection key
*
* RETURNS:
* flOK on success otherwise flWrongKey
*
*/
FLStatus tryKey(FLFlash * flash, byte area, unsigned char FAR1* key)
{
int i;
switch (area)
{
case 0: /* data protect structure 0 */
for(i=0; i<PROTECTION_KEY_LENGTH; i++) /* Send key */
flWrite8bitRegPlus(flash,NdataProtect0Key, key[i]);
/* check if key is valid */
if (isArea0Protected(flash) == TRUE)
{
return flWrongKey;
}
else
{
return flOK;
}
case 1: /* data protect structure 0 */
for(i=0; i<PROTECTION_KEY_LENGTH; i++) /* Send key */
flWrite8bitRegPlus(flash,NdataProtect1Key, key[i]);
/* check if key is valid */
if (isArea1Protected(flash) == TRUE)
{
return flWrongKey;
}
else
{
return flOK;
}
default: /* No such protection area */
return flGeneralFailure;
}
}
/*
** protectKeyInsert
*
*
* PARAMETERS:
* flash : Pointer identifying drive
* area : indicated which protection area to work on. 0 or 1.
* Key : an 8 byte long array containing the protection password.
* unsigned char * is an 8 bytes unsigned char array
*
* DESCRIPTION: Sends protection key only to protected areas.
*
* NOTE : If key is already inserted the given key will not be sent.
* NOTE : The key will be sent to all the devices floors even if a key
* did not fit one of them.
* NOTE : This 2 notes above allow inserting diffrent key to
* diffrent floors in the case of power failure while formmating
* the device.
*
* RETURNS:
* flOK on success otherwise flWrongKey
*
*/
FLStatus protectionKeyInsert(FLFlash * flash, byte area, unsigned char FAR1* key)
{
byte floor;
FLStatus status;
FLStatus tmpStatus;
/* Check mode of ASIC and set to NORMAL.*/
status = chkASICmode(flash);
if(status != flOK)
return status;
/* Send key to all floors */
for (floor = 0;floor<flash->noOfFloors;floor++)
{
setFloor(flash,floor);
switch (area)
{
case 0: /* data protect structure 0 */
/* check if key is already inserted */
if ((isArea0Protected(flash) == FALSE) || /* Key is in */
((flRead8bitRegPlus(flash,NdataProtect0Status) & /* Or not protected */
(PROTECT_STAT_WP_MASK | PROTECT_STAT_RP_MASK)) == 0))
continue;
break;
case 1: /* data protect structure 1 */
/* check if key is already inserted */
if ((isArea1Protected(flash) == FALSE) || /* Key is in */
((flRead8bitRegPlus(flash,NdataProtect1Status) & /* Or not protected */
(PROTECT_STAT_WP_MASK | PROTECT_STAT_RP_MASK)) == 0))
continue;
break;
default: /* No such protection area */
return flGeneralFailure;
}
tmpStatus = tryKey(flash,area,key);
if (tmpStatus == flOK)
continue;
/* Try default key */
tmpStatus = tryKey(flash,area,(byte *)DEFAULT_KEY);
if (tmpStatus != flOK)
status = tmpStatus;
}
return(status);
}
/*
** protectKeyRemove
*
*
* PARAMETERS:
* flash : Pointer identifying drive
* area : indicated which protection area to work on. 0 or 1.
*
* DESCRIPTION: Removes protection key
*
* RETURNS:
* Return flOK
*
*/
FLStatus protectionKeyRemove(FLFlash * flash, byte area)
{
byte tmpKey[8];
byte floor;
FLStatus status;
for (floor = 0;floor < flash->noOfFloors;floor++)
{
setFloor(flash,floor);
status = tryKey(flash,area,tmpKey);
if (status == flOK) /* Unfortunatly the key was fine */
{
tmpKey[0]++;
status = tryKey(flash,area,tmpKey);
}
}
return flOK;
}
/*
** protectType
*
*
* PARAMETERS:
* flash : Pointer identifying drive.
* area : indicated which protection area to work on. 0 or 1.
* flag : returns any combination of
* LOCK_ENABLED - The LOCK signal is enabled.
* LOCK_ASSERTED - The LOCK signal input pin is asserted.
* KEY_INSERTED - The key has been correctly written
* READ_PROTECTED - The area is protected against read operations
* WRITE_PROTECTED - The area is protected against write operations
*
* DESCRIPTION: Gets protection type
*
* NOTE: The type is checked for all floors. The attributes are ored
* giving the harshest protection attributes.
*
* RETURNS:
* flOK on success
*/
FLStatus protectionType(FLFlash * flash, byte area, word* flag)
{
volatile Reg8bitType protectData;
byte floor;
FLBoolean curFlag; /* Indicated if the floor has r/w protection */
CardAddress addressLow,addressHigh;
FLStatus status;
status = chkASICmode(flash);
if(status != flOK)
return status;
*flag = KEY_INSERTED | LOCK_ASSERTED; /* initiate the flags */
for (floor = 0;floor < flash->noOfFloors;floor++)
{
setFloor(flash,floor);
/* read data protect structure status */
switch (area)
{
case 0: /* data protect structure 0 */
protectData = flRead8bitRegPlus(flash,NdataProtect0Status) ;
break;
case 1: /* data protect structure 1 */
protectData = flRead8bitRegPlus(flash,NdataProtect1Status) ;
*flag |= CHANGEABLE_PROTECTION;
break;
default: /* No such protection area */
return flGeneralFailure;
}
curFlag = FALSE;
/* Check if area is write protected */
if((protectData & PROTECT_STAT_WP_MASK) ==PROTECT_STAT_WP_MASK)
{
status = protectionBoundries(flash, area, &addressLow,
&addressHigh, floor);
if(status != flOK)
return status;
if ((addressLow != addressHigh) ||
(addressLow != ((CardAddress)(area + 1)<<flash->erasableBlockSizeBits)))
{
*flag |= WRITE_PROTECTED;
curFlag = TRUE;
}
}
/* Check if area is read protected */
if((protectData & PROTECT_STAT_RP_MASK) ==PROTECT_STAT_RP_MASK)
{
*flag |= READ_PROTECTED;
curFlag = TRUE;
}
/* Check if key is corrently inserted */
if(((protectData & PROTECT_STAT_KEY_OK_MASK) !=
PROTECT_STAT_KEY_OK_MASK) && (curFlag == TRUE))
*flag &= ~KEY_INSERTED;
/* Check if HW signal is enabled */
if((protectData & PROTECT_STAT_LOCK_MASK) == PROTECT_STAT_LOCK_MASK)
*flag |=LOCK_ENABLED ;
/* Check if HW signal is asserted */
if((flRead8bitRegPlus(flash,NprotectionStatus) &
PROTECT_STAT_LOCK_INPUT_MASK) == PROTECT_STAT_LOCK_INPUT_MASK)
*flag &= ~LOCK_ASSERTED;
}
return(flOK);
}
#ifndef FL_READ_ONLY
static byte findChecksum(byte * buffer, word size)
{
register int i;
byte answer;
answer = 0xff;
for(i=0 ; i<size ; i++)
answer -= buffer[i];
return answer;
}
/*
** SetProtection
*
*
* PARAMETERS:
* flash : Pointer identifying drive
* area : indicated which protection area to work on. 0 or 1.
* AddressLow : sets address of lower boundary of protected area. 0 - floor size.
* AddressHigh : sets address of upper boundary of protected area. AddressLow - floor size.
* Key : an 8 byte long array containing the protection password.
* flag : any combination of the following flags:
* LOCK_ENABLED - The LOCK signal is enabled.
* READ_PROTECTED - The area is protected against read operations
* WRITE_PROTECTED - The area is protected against write operations
* modes : Either COMMIT_PROTECTION will cause the new values to
* take affect immidiatly or DO_NOT_COMMIT_PROTECTION for
* delaying the new values to take affect only after the
* next reset.
*
* DESCRIPTION: Sets the definitions of a protected area: location, key and protection type
*
* RETURNS:
* flOK - success
* FlWriteProtect - protection violetion,
* FlReadProtect - protection violetion.
* FlDataError - any other read failure.
* FlWriteFault - any other write error.
* flBadLength - if the length of the protected area exceeds
* allowed length
*/
FLStatus protectionSet ( FLFlash * flash, byte area, word flag,
CardAddress addressLow, CardAddress addressHigh,
byte FAR1* key , byte modes, byte floorNo)
{
FLBoolean restoreInterleave = FALSE;
byte downloadStatus;
DPSStruct dps;
dword floorInc = floorNo * NFDC21thisVars->floorSize;
word goodUnit,redundantUnit;
dword goodDPS,redundantDPS;
FLStatus status;
dword goodIPL = 0; /* Initialized to remove warrnings */
dword redundantIPL = 0; /* Initialized to remove warrnings */
dword copyOffset; /* Offset to redundant DPS unit */
dword ipl0Copy0; /* Offset to IPL second 512 bytes copy 0 */
dword dps1Copy0; /* Offset to DPS1 copy 0 */
word dps1UnitNo; /* Offset to redundant DPS unit */
status = chkASICmode(flash);
if(status != flOK)
return status;
/* check if exceeds the size */
if( (addressLow > addressHigh) ||
(addressHigh - addressLow >= (dword)NFDC21thisVars->floorSize))
return( flBadLength );
/* change to interleave 1 */
if ( flash->interleaving == 2)
{
restoreInterleave = TRUE;
status = changeInterleave(flash,1);
if(status != flOK)
return status;
}
if(flash->mediaType == MDOCP_TYPE) /* DiskOnChip Millennium Plus 32MB */
{
copyOffset = flash->chipSize>>1; /* The chips are consequtive */
dps1Copy0 = DPS1_COPY0_32;
dps1UnitNo = DPS1_UNIT_NO_32;
ipl0Copy0 = IPL0_COPY0_32;
}
else
{
copyOffset = flash->chipSize>>1; /* The chips are consequtive */
dps1Copy0 = DPS1_COPY0_16;
dps1UnitNo = DPS1_UNIT_NO_16;
ipl0Copy0 = IPL0_COPY0_16;
}
/* find if previous download */
downloadStatus = flRead8bitRegPlus(flash,NdownloadStatus);
/* prepare buffer */
switch (area)
{
case 0: /* data protect structure 0 */
switch (downloadStatus & DWN_STAT_DPS0_ERR)
{
case DWN_STAT_DPS01_ERR: /* Both are bad */
return flBadDownload;
case DWN_STAT_DPS00_ERR: /* First is bad */
redundantUnit = (word)(DPS0_UNIT_NO + floorNo * (NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
goodUnit = (word)(redundantUnit + (copyOffset>>flash->erasableBlockSizeBits));
goodDPS = DPS0_COPY0+floorInc + copyOffset;
redundantDPS = DPS0_COPY0+floorInc;
break;
default: /* Both copies are good */
goodUnit = (word)(DPS0_UNIT_NO + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
redundantUnit = (word)(goodUnit + (copyOffset>>flash->erasableBlockSizeBits));
goodDPS = DPS0_COPY0+floorInc;
redundantDPS = DPS0_COPY0+floorInc + copyOffset;
}
break;
case 1: /* data protect structure 0 */
switch (downloadStatus & DWN_STAT_DPS1_ERR)
{
case DWN_STAT_DPS11_ERR: /* Both are bad */
return flBadDownload;
case DWN_STAT_DPS10_ERR: /* First is bad */
redundantUnit = (word)(dps1UnitNo + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
goodUnit = (word)(redundantUnit + (copyOffset>>flash->erasableBlockSizeBits));
goodDPS = dps1Copy0+floorInc + copyOffset;
redundantDPS = dps1Copy0+floorInc;
redundantIPL = ipl0Copy0 + floorInc;
goodIPL = redundantIPL + copyOffset;
break;
default : /* First is good */
goodUnit = (word)(dps1UnitNo + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
redundantUnit = (word)(goodUnit + (copyOffset>>flash->erasableBlockSizeBits));
goodDPS = dps1Copy0+floorInc;
redundantDPS = dps1Copy0+floorInc + copyOffset;
goodIPL = ipl0Copy0 + floorInc;
redundantIPL = goodIPL + copyOffset;
}
break;
default: /* No such protection area */
return flGeneralFailure;
}
/* Build new DPS */
if (key==NULL) /* key must be retreaved from previous structure */
{
status = flash->read(flash,goodDPS,(void FAR1 *)&dps,SIZE_OF_DPS,0);
if(status!=flOK) goto END_WRITE_DPS;
if(findChecksum((byte *)&dps,SIZE_OF_DPS)!=0) /* bad copy */
status = flash->read(flash,goodDPS+REDUNDANT_DPS_OFFSET,
(void FAR1*)&dps,SIZE_OF_DPS,0);
makeDPS(addressLow,addressHigh,(byte FAR1*)(dps.key),flag,(byte *)&dps);
}
else /* key is given as a parameter */
{
makeDPS(addressLow,addressHigh,(byte FAR1*)key,flag,(byte *)&dps);
}
/* Erase redundant unit */
status = flash->erase(flash,redundantUnit,1);
if(status!=flOK) goto END_WRITE_DPS;
/* Write new DPS */
status = flash->write(flash,redundantDPS,&dps,SIZE_OF_DPS,0);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,redundantDPS + REDUNDANT_DPS_OFFSET,
&dps,SIZE_OF_DPS,0);
if(status!=flOK) goto END_WRITE_DPS;
if (area == 1) /* copy the IPL */
{
#ifndef MTD_STANDALONE
/* Force remapping of internal catched sector */
flash->socket->remapped = TRUE;
#endif /* MTD_STANDALONE */
/* Read first 512 bytes IPL */
status = flash->read(flash,goodIPL,NFDC21thisBuffer,SECTOR_SIZE,0);
if(status!=flOK) goto END_WRITE_DPS;
/* Write first 512 bytes IPL */
status = flash->write(flash,redundantIPL,NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,redundantIPL + SECTOR_SIZE,
NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
/* Read second 512 bytes IPL */
status = flash->read(flash,goodIPL + IPL_HIGH_SECTOR,
NFDC21thisBuffer,SECTOR_SIZE,0);
if(status!=flOK) goto END_WRITE_DPS;
/* Write second 512 bytes IPL */
status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR,
NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR +
SECTOR_SIZE, NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
/* Read Srong Arm mark */
status = flash->read(flash,goodIPL + IPL_HIGH_SECTOR + 8,
NFDC21thisBuffer,1,EXTRA);
if(status!=flOK) goto END_WRITE_DPS;
/* Write Srong Arm mark */
status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + 8 +
SECTOR_SIZE, NFDC21thisBuffer,1,EXTRA);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + 8,
NFDC21thisBuffer,1,EXTRA);
if(status!=flOK) goto END_WRITE_DPS;
}
/* Erase good unit */
status = flash->erase(flash,goodUnit,1);
if(status!=flOK) goto END_WRITE_DPS;
/* Write over previous DPS */
status = flash->write(flash,goodDPS,&dps,SIZE_OF_DPS,0);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,goodDPS + REDUNDANT_DPS_OFFSET,
&dps,SIZE_OF_DPS,0);
if(status!=flOK) goto END_WRITE_DPS;
if (area == 1) /* copy the IPL */
{
/* Read first 512 bytes IPL */
status = flash->read(flash,redundantIPL,NFDC21thisBuffer,SECTOR_SIZE,0);
if(status!=flOK) goto END_WRITE_DPS;
/* Write first 512 bytes IPL */
status = flash->write(flash,goodIPL,NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,goodIPL + SECTOR_SIZE,
NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
/* Read second 512 bytes IPL */
status = flash->read(flash,redundantIPL + IPL_HIGH_SECTOR,
NFDC21thisBuffer,SECTOR_SIZE,0);
if(status!=flOK) goto END_WRITE_DPS;
/* Write second 512 bytes IPL */
status = flash->write(flash,goodIPL + IPL_HIGH_SECTOR,
NFDC21thisBuffer,SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
status = flash->write(flash,goodIPL + IPL_HIGH_SECTOR +
SECTOR_SIZE, NFDC21thisBuffer,
SECTOR_SIZE,EDC);
if(status!=flOK) goto END_WRITE_DPS;
}
END_WRITE_DPS:
if ( restoreInterleave == TRUE)
{
FLStatus status2;
chkASICmode(flash); /* Release posible access error */
status2 = changeInterleave(flash, 2); /* change back to interleave 2 */
if(status2 != flOK)
return status2;
}
if (status == flOK)
{
if ((modes & COMMIT_PROTECTION) && /* The new values will take affect now */
(flash->download != NULL))
status = flash->download(flash);
}
return status;
}
/*
** makeDataProtectStruct
*
*
* PARAMETERS:
* AddressLow : sets address of lower boundary of protected area
* AddressHigh: sets address of upper boundary of protected area
* Key : an 8 byte long array containing the protection password.
* flag : any combination of the following flags:
* LOCK_ENABLED - The LOCK signal is enabled.
* READ_PROTECTED - The area is protected against read operations
* WRITE_PROTECTED - The area is protected against write operations
* buffer - buffer pointer of the returned structure.
*
* DESCRIPTION: Sets the definitions of a protected structure: location, key and protection type
*
* RETURNS:
*
*/
static void makeDPS(CardAddress addressLow, CardAddress addressHigh,
byte FAR1* key , word flag, byte* buffer)
{
int i;
DPSStruct* dps = (DPSStruct *)buffer;
/* convert to little endien and store */
toLE4(dps->addressLow,addressLow >>10);
toLE4(dps->addressHigh,addressHigh >>10);
/*insert protection key */
for(i=0; i<PROTECTION_KEY_LENGTH; i++)
dps->key[i] = key[i];
/* insert flags */
dps->protectionType = 0;
if((flag & LOCK_ENABLED)==LOCK_ENABLED)
dps->protectionType |= DPS_LOCK_ENABLED;
if((flag & READ_PROTECTED)==READ_PROTECTED)
dps->protectionType |= DPS_READ_PROTECTED;
if((flag & WRITE_PROTECTED)==WRITE_PROTECTED)
dps->protectionType |= DPS_WRITE_PROTECTED;
/* calculate and store checksum */
dps->checksum = findChecksum(buffer,SIZE_OF_DPS-1);
}
#endif /* FL_READ_ONLY */
#endif /* HW_PROTECTION */