Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

810 lines
27 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/PROTECTP.C_V $
  3. *
  4. * Rev 1.18 Apr 15 2002 07:38:44 oris
  5. * Added static qualifier for private functions (findChecksum and makeDPS).
  6. * Removed readDPS and writeDPS routine prototypes (no longer exist).
  7. * Added setStickyBit routine for DiskOnChip Plus 128Mbit.
  8. *
  9. * Rev 1.17 Jan 28 2002 21:26:24 oris
  10. * Removed the use of back-slashes in macro definitions.
  11. *
  12. * Rev 1.16 Jan 17 2002 23:04:54 oris
  13. * Replaced docsysp include directive with docsys.
  14. * Changed the use of vol (macro *pVol) to *flash.
  15. * Add support for DiskOnChip Millennium Plus 16MB :
  16. * - Copy extra area of IPL independently of the EDC to copy Strong arm mark.
  17. * - DPS 0 and 1 location where changed - affects protectionSet routine.
  18. * Bug fix - Wrong usage of findChecksum, caused the use of the second copy of the DPS instead of the first.
  19. *
  20. * Rev 1.15 Sep 24 2001 18:24:18 oris
  21. * removed ifdef and forced using flRead8bitRegPlus instead of reading with flRead16bitRegPlus.
  22. *
  23. * Rev 1.14 Sep 15 2001 23:47:56 oris
  24. * Remove all 8-bit access to uneven addresses.
  25. *
  26. * Rev 1.13 Jul 16 2001 17:41:54 oris
  27. * Ignore write protection of the DPSs.
  28. *
  29. * Rev 1.12 Jul 13 2001 01:09:26 oris
  30. * Bug fix for protection boundaries when using Millennium Plus devices that can not access a single byte.
  31. * Added send default key before trying a protection violation command.
  32. * Bug fix - bad IPL second copy offset.
  33. *
  34. * Rev 1.11 May 16 2001 21:21:42 oris
  35. * Removed warnings.
  36. *
  37. * Rev 1.10 May 09 2001 00:35:48 oris
  38. * Bug fix - Lock asserted was reported opposite of the real state.
  39. * Bug fix - Make sure to return "key inserted" if the partition is not read\write protected.
  40. * This is to enable a partition that does not span over all of the media floors to return "key inserted".
  41. *
  42. * Rev 1.9 May 06 2001 22:42:18 oris
  43. * Bug fix - insert key does not try to insert key to a floor that is not read\write protected.
  44. * Bug fix - protection type does not return key inserted is one of the floors key is not inserted.
  45. * Bug fix - set protection no longer clears the IPL.
  46. * redundant was misspelled.
  47. *
  48. * Rev 1.8 May 01 2001 14:24:56 oris
  49. * Bug fix - CHANGEABLE_PRTOECTION was never reported.
  50. *
  51. * Rev 1.7 Apr 18 2001 17:19:02 oris
  52. * Bug fix - bad status code returned by protection set routine du to calling changaInterleave while in access error.
  53. *
  54. * Rev 1.6 Apr 18 2001 09:29:32 oris
  55. * Bug fix - remove key routine always return bad status code.
  56. *
  57. * Rev 1.5 Apr 16 2001 13:58:28 oris
  58. * Removed warrnings.
  59. *
  60. * Rev 1.4 Apr 12 2001 06:52:32 oris
  61. * Changed protectionBounries and protectionSet routine to be floor specific.
  62. *
  63. * Rev 1.3 Apr 10 2001 23:56:30 oris
  64. * Bug fix - protectionBounries routine - floor did not change.
  65. * Bug fix - protectionSet routine - floors with no protected areas were not updated.
  66. * Bug fix - protectionBounries routine - bad paranthesis in MAX calculation.
  67. *
  68. * Rev 1.2 Apr 09 2001 19:04:24 oris
  69. * Removed warrnings.
  70. *
  71. */
  72. /*******************************************************************
  73. *
  74. * DESCRIPTION: MTD protection mechanism routines for the MDOC32
  75. *
  76. * AUTHOR: arie tamam
  77. *
  78. * HISTORY: created november 14, 2000
  79. *
  80. *******************************************************************/
  81. /** include files **/
  82. #include "mdocplus.h"
  83. #include "protectp.h"
  84. #include "docsys.h"
  85. /** local definitions **/
  86. /* default settings */
  87. /** external functions **/
  88. /** external data **/
  89. /** internal functions **/
  90. static byte findChecksum(byte * buffer, word size);
  91. static void makeDPS(CardAddress addressLow, CardAddress addressHigh,
  92. byte FAR1* key , word flag, byte* buffer);
  93. #define MINUS_FLOORSIZE(arg) ((arg > NFDC21thisVars->floorSize) ? arg - NFDC21thisVars->floorSize : 0)
  94. /** public data **/
  95. /** private data **/
  96. /** public functions **/
  97. #ifdef HW_PROTECTION
  98. /**********/
  99. /* Macros */
  100. /**********/
  101. /* check if key is correct */
  102. #define isArea0Protected(flash) (((flRead8bitRegPlus(flash,NdataProtect0Status) & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) ? TRUE : FALSE)
  103. #define isArea1Protected(flash) (((flRead8bitRegPlus(flash,NdataProtect1Status) & PROTECT_STAT_KEY_OK_MASK) != PROTECT_STAT_KEY_OK_MASK) ? TRUE : FALSE)
  104. /*----------------------------------------------------------------------*/
  105. /* s e t S t i c k y B i t */
  106. /* */
  107. /* Set the sticky bit to prevent the insertion of the protection key. */
  108. /* */
  109. /* Parameters: */
  110. /* flash : Pointer identifying drive. */
  111. /* */
  112. /* Returns: */
  113. /* flOK on success, none zero otherwise. */
  114. /*----------------------------------------------------------------------*/
  115. FLStatus setStickyBit(FLFlash * flash)
  116. {
  117. volatile Reg8bitType val;
  118. register int i;
  119. /* Raise the sticky bit, while keeping the other bits of the register */
  120. for(i=0;i<flash->noOfFloors;i++)
  121. {
  122. /* Remove last bit */
  123. val = flRead8bitRegPlus(flash, NoutputControl) |
  124. OUT_CNTRL_STICKY_BIT_ENABLE;
  125. flWrite8bitRegPlus(flash, NoutputControl, val);
  126. }
  127. return flOK;
  128. }
  129. /*
  130. ** protectBoundries
  131. *
  132. *
  133. * PARAMETERS:
  134. * flash : Pointer identifying drive
  135. * area : indicated which protection area to work on. 0 or 1.
  136. * AddressLow : address of lower boundary of protected area
  137. * AddressHigh : address of upper boundary of protected area
  138. *
  139. * DESCRIPTION: Gets protection boundaries from registers
  140. *
  141. * NOTE : protection areas are assumed to be consequtive although they
  142. * may skip DPS , OTP and header units.
  143. *
  144. * RETURNS:
  145. * flOK on success
  146. *
  147. */
  148. FLStatus protectionBoundries(FLFlash * flash, byte area,CardAddress* addressLow,
  149. CardAddress* addressHigh, byte floorNo)
  150. {
  151. /* Check mode of ASIC and set to NORMAL.*/
  152. FLStatus status = chkASICmode(flash);
  153. if(status != flOK)
  154. return status;
  155. setFloor(flash,floorNo);
  156. switch (area)
  157. {
  158. case 0: /* data protect structure 0 */
  159. /* read the data protect 0 addresses */
  160. *addressLow = ((dword)flRead8bitRegPlus(flash,NdataProtect0LowAddr) << 10)| /* ADDR_1 */
  161. ((dword)flRead8bitRegPlus(flash,NdataProtect0LowAddr+1) << 18); /* ADDR_2 */
  162. *addressHigh = ((dword)flRead8bitRegPlus(flash,NdataProtect0UpAddr) << 10)| /* ADDR_1 */
  163. ((dword)flRead8bitRegPlus(flash,NdataProtect0UpAddr+1) << 18); /* ADDR_2 */
  164. break;
  165. case 1: /* data protect structure 1 */
  166. /* read the data protect 1 addresses */
  167. *addressLow = ((dword)flRead8bitRegPlus(flash,NdataProtect1LowAddr) << 10)| /* ADDR_1 */
  168. ((dword)flRead8bitRegPlus(flash,NdataProtect1LowAddr+1) << 18); /* ADDR_2 */
  169. *addressHigh = ((dword)flRead8bitRegPlus(flash,NdataProtect1UpAddr) << 10)| /* ADDR_1 */
  170. ((dword)flRead8bitRegPlus(flash,NdataProtect1UpAddr+1) << 18); /* ADDR_2 */
  171. break;
  172. default: /* No such protection area */
  173. return flGeneralFailure;
  174. }
  175. return(flOK);
  176. }
  177. /*
  178. ** tryKey
  179. *
  180. *
  181. * PARAMETERS:
  182. * flash : Pointer identifying drive
  183. * area : indicated which protection area to work on. 0 or 1.
  184. * Key : an 8 byte long array containing the protection password.
  185. * unsigned char * is an 8 bytes unsigned char array
  186. *
  187. * DESCRIPTION: Sends protection key
  188. *
  189. * RETURNS:
  190. * flOK on success otherwise flWrongKey
  191. *
  192. */
  193. FLStatus tryKey(FLFlash * flash, byte area, unsigned char FAR1* key)
  194. {
  195. int i;
  196. switch (area)
  197. {
  198. case 0: /* data protect structure 0 */
  199. for(i=0; i<PROTECTION_KEY_LENGTH; i++) /* Send key */
  200. flWrite8bitRegPlus(flash,NdataProtect0Key, key[i]);
  201. /* check if key is valid */
  202. if (isArea0Protected(flash) == TRUE)
  203. {
  204. return flWrongKey;
  205. }
  206. else
  207. {
  208. return flOK;
  209. }
  210. case 1: /* data protect structure 0 */
  211. for(i=0; i<PROTECTION_KEY_LENGTH; i++) /* Send key */
  212. flWrite8bitRegPlus(flash,NdataProtect1Key, key[i]);
  213. /* check if key is valid */
  214. if (isArea1Protected(flash) == TRUE)
  215. {
  216. return flWrongKey;
  217. }
  218. else
  219. {
  220. return flOK;
  221. }
  222. default: /* No such protection area */
  223. return flGeneralFailure;
  224. }
  225. }
  226. /*
  227. ** protectKeyInsert
  228. *
  229. *
  230. * PARAMETERS:
  231. * flash : Pointer identifying drive
  232. * area : indicated which protection area to work on. 0 or 1.
  233. * Key : an 8 byte long array containing the protection password.
  234. * unsigned char * is an 8 bytes unsigned char array
  235. *
  236. * DESCRIPTION: Sends protection key only to protected areas.
  237. *
  238. * NOTE : If key is already inserted the given key will not be sent.
  239. * NOTE : The key will be sent to all the devices floors even if a key
  240. * did not fit one of them.
  241. * NOTE : This 2 notes above allow inserting diffrent key to
  242. * diffrent floors in the case of power failure while formmating
  243. * the device.
  244. *
  245. * RETURNS:
  246. * flOK on success otherwise flWrongKey
  247. *
  248. */
  249. FLStatus protectionKeyInsert(FLFlash * flash, byte area, unsigned char FAR1* key)
  250. {
  251. byte floor;
  252. FLStatus status;
  253. FLStatus tmpStatus;
  254. /* Check mode of ASIC and set to NORMAL.*/
  255. status = chkASICmode(flash);
  256. if(status != flOK)
  257. return status;
  258. /* Send key to all floors */
  259. for (floor = 0;floor<flash->noOfFloors;floor++)
  260. {
  261. setFloor(flash,floor);
  262. switch (area)
  263. {
  264. case 0: /* data protect structure 0 */
  265. /* check if key is already inserted */
  266. if ((isArea0Protected(flash) == FALSE) || /* Key is in */
  267. ((flRead8bitRegPlus(flash,NdataProtect0Status) & /* Or not protected */
  268. (PROTECT_STAT_WP_MASK | PROTECT_STAT_RP_MASK)) == 0))
  269. continue;
  270. break;
  271. case 1: /* data protect structure 1 */
  272. /* check if key is already inserted */
  273. if ((isArea1Protected(flash) == FALSE) || /* Key is in */
  274. ((flRead8bitRegPlus(flash,NdataProtect1Status) & /* Or not protected */
  275. (PROTECT_STAT_WP_MASK | PROTECT_STAT_RP_MASK)) == 0))
  276. continue;
  277. break;
  278. default: /* No such protection area */
  279. return flGeneralFailure;
  280. }
  281. tmpStatus = tryKey(flash,area,key);
  282. if (tmpStatus == flOK)
  283. continue;
  284. /* Try default key */
  285. tmpStatus = tryKey(flash,area,(byte *)DEFAULT_KEY);
  286. if (tmpStatus != flOK)
  287. status = tmpStatus;
  288. }
  289. return(status);
  290. }
  291. /*
  292. ** protectKeyRemove
  293. *
  294. *
  295. * PARAMETERS:
  296. * flash : Pointer identifying drive
  297. * area : indicated which protection area to work on. 0 or 1.
  298. *
  299. * DESCRIPTION: Removes protection key
  300. *
  301. * RETURNS:
  302. * Return flOK
  303. *
  304. */
  305. FLStatus protectionKeyRemove(FLFlash * flash, byte area)
  306. {
  307. byte tmpKey[8];
  308. byte floor;
  309. FLStatus status;
  310. for (floor = 0;floor < flash->noOfFloors;floor++)
  311. {
  312. setFloor(flash,floor);
  313. status = tryKey(flash,area,tmpKey);
  314. if (status == flOK) /* Unfortunatly the key was fine */
  315. {
  316. tmpKey[0]++;
  317. status = tryKey(flash,area,tmpKey);
  318. }
  319. }
  320. return flOK;
  321. }
  322. /*
  323. ** protectType
  324. *
  325. *
  326. * PARAMETERS:
  327. * flash : Pointer identifying drive.
  328. * area : indicated which protection area to work on. 0 or 1.
  329. * flag : returns any combination of
  330. * LOCK_ENABLED - The LOCK signal is enabled.
  331. * LOCK_ASSERTED - The LOCK signal input pin is asserted.
  332. * KEY_INSERTED - The key has been correctly written
  333. * READ_PROTECTED - The area is protected against read operations
  334. * WRITE_PROTECTED - The area is protected against write operations
  335. *
  336. * DESCRIPTION: Gets protection type
  337. *
  338. * NOTE: The type is checked for all floors. The attributes are ored
  339. * giving the harshest protection attributes.
  340. *
  341. * RETURNS:
  342. * flOK on success
  343. */
  344. FLStatus protectionType(FLFlash * flash, byte area, word* flag)
  345. {
  346. volatile Reg8bitType protectData;
  347. byte floor;
  348. FLBoolean curFlag; /* Indicated if the floor has r/w protection */
  349. CardAddress addressLow,addressHigh;
  350. FLStatus status;
  351. status = chkASICmode(flash);
  352. if(status != flOK)
  353. return status;
  354. *flag = KEY_INSERTED | LOCK_ASSERTED; /* initiate the flags */
  355. for (floor = 0;floor < flash->noOfFloors;floor++)
  356. {
  357. setFloor(flash,floor);
  358. /* read data protect structure status */
  359. switch (area)
  360. {
  361. case 0: /* data protect structure 0 */
  362. protectData = flRead8bitRegPlus(flash,NdataProtect0Status) ;
  363. break;
  364. case 1: /* data protect structure 1 */
  365. protectData = flRead8bitRegPlus(flash,NdataProtect1Status) ;
  366. *flag |= CHANGEABLE_PROTECTION;
  367. break;
  368. default: /* No such protection area */
  369. return flGeneralFailure;
  370. }
  371. curFlag = FALSE;
  372. /* Check if area is write protected */
  373. if((protectData & PROTECT_STAT_WP_MASK) ==PROTECT_STAT_WP_MASK)
  374. {
  375. status = protectionBoundries(flash, area, &addressLow,
  376. &addressHigh, floor);
  377. if(status != flOK)
  378. return status;
  379. if ((addressLow != addressHigh) ||
  380. (addressLow != ((CardAddress)(area + 1)<<flash->erasableBlockSizeBits)))
  381. {
  382. *flag |= WRITE_PROTECTED;
  383. curFlag = TRUE;
  384. }
  385. }
  386. /* Check if area is read protected */
  387. if((protectData & PROTECT_STAT_RP_MASK) ==PROTECT_STAT_RP_MASK)
  388. {
  389. *flag |= READ_PROTECTED;
  390. curFlag = TRUE;
  391. }
  392. /* Check if key is corrently inserted */
  393. if(((protectData & PROTECT_STAT_KEY_OK_MASK) !=
  394. PROTECT_STAT_KEY_OK_MASK) && (curFlag == TRUE))
  395. *flag &= ~KEY_INSERTED;
  396. /* Check if HW signal is enabled */
  397. if((protectData & PROTECT_STAT_LOCK_MASK) == PROTECT_STAT_LOCK_MASK)
  398. *flag |=LOCK_ENABLED ;
  399. /* Check if HW signal is asserted */
  400. if((flRead8bitRegPlus(flash,NprotectionStatus) &
  401. PROTECT_STAT_LOCK_INPUT_MASK) == PROTECT_STAT_LOCK_INPUT_MASK)
  402. *flag &= ~LOCK_ASSERTED;
  403. }
  404. return(flOK);
  405. }
  406. #ifndef FL_READ_ONLY
  407. static byte findChecksum(byte * buffer, word size)
  408. {
  409. register int i;
  410. byte answer;
  411. answer = 0xff;
  412. for(i=0 ; i<size ; i++)
  413. answer -= buffer[i];
  414. return answer;
  415. }
  416. /*
  417. ** SetProtection
  418. *
  419. *
  420. * PARAMETERS:
  421. * flash : Pointer identifying drive
  422. * area : indicated which protection area to work on. 0 or 1.
  423. * AddressLow : sets address of lower boundary of protected area. 0 - floor size.
  424. * AddressHigh : sets address of upper boundary of protected area. AddressLow - floor size.
  425. * Key : an 8 byte long array containing the protection password.
  426. * flag : any combination of the following flags:
  427. * LOCK_ENABLED - The LOCK signal is enabled.
  428. * READ_PROTECTED - The area is protected against read operations
  429. * WRITE_PROTECTED - The area is protected against write operations
  430. * modes : Either COMMIT_PROTECTION will cause the new values to
  431. * take affect immidiatly or DO_NOT_COMMIT_PROTECTION for
  432. * delaying the new values to take affect only after the
  433. * next reset.
  434. *
  435. * DESCRIPTION: Sets the definitions of a protected area: location, key and protection type
  436. *
  437. * RETURNS:
  438. * flOK - success
  439. * FlWriteProtect - protection violetion,
  440. * FlReadProtect - protection violetion.
  441. * FlDataError - any other read failure.
  442. * FlWriteFault - any other write error.
  443. * flBadLength - if the length of the protected area exceeds
  444. * allowed length
  445. */
  446. FLStatus protectionSet ( FLFlash * flash, byte area, word flag,
  447. CardAddress addressLow, CardAddress addressHigh,
  448. byte FAR1* key , byte modes, byte floorNo)
  449. {
  450. FLBoolean restoreInterleave = FALSE;
  451. byte downloadStatus;
  452. DPSStruct dps;
  453. dword floorInc = floorNo * NFDC21thisVars->floorSize;
  454. word goodUnit,redundantUnit;
  455. dword goodDPS,redundantDPS;
  456. FLStatus status;
  457. dword goodIPL = 0; /* Initialized to remove warrnings */
  458. dword redundantIPL = 0; /* Initialized to remove warrnings */
  459. dword copyOffset; /* Offset to redundant DPS unit */
  460. dword ipl0Copy0; /* Offset to IPL second 512 bytes copy 0 */
  461. dword dps1Copy0; /* Offset to DPS1 copy 0 */
  462. word dps1UnitNo; /* Offset to redundant DPS unit */
  463. status = chkASICmode(flash);
  464. if(status != flOK)
  465. return status;
  466. /* check if exceeds the size */
  467. if( (addressLow > addressHigh) ||
  468. (addressHigh - addressLow >= (dword)NFDC21thisVars->floorSize))
  469. return( flBadLength );
  470. /* change to interleave 1 */
  471. if ( flash->interleaving == 2)
  472. {
  473. restoreInterleave = TRUE;
  474. status = changeInterleave(flash,1);
  475. if(status != flOK)
  476. return status;
  477. }
  478. if(flash->mediaType == MDOCP_TYPE) /* DiskOnChip Millennium Plus 32MB */
  479. {
  480. copyOffset = flash->chipSize>>1; /* The chips are consequtive */
  481. dps1Copy0 = DPS1_COPY0_32;
  482. dps1UnitNo = DPS1_UNIT_NO_32;
  483. ipl0Copy0 = IPL0_COPY0_32;
  484. }
  485. else
  486. {
  487. copyOffset = flash->chipSize>>1; /* The chips are consequtive */
  488. dps1Copy0 = DPS1_COPY0_16;
  489. dps1UnitNo = DPS1_UNIT_NO_16;
  490. ipl0Copy0 = IPL0_COPY0_16;
  491. }
  492. /* find if previous download */
  493. downloadStatus = flRead8bitRegPlus(flash,NdownloadStatus);
  494. /* prepare buffer */
  495. switch (area)
  496. {
  497. case 0: /* data protect structure 0 */
  498. switch (downloadStatus & DWN_STAT_DPS0_ERR)
  499. {
  500. case DWN_STAT_DPS01_ERR: /* Both are bad */
  501. return flBadDownload;
  502. case DWN_STAT_DPS00_ERR: /* First is bad */
  503. redundantUnit = (word)(DPS0_UNIT_NO + floorNo * (NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
  504. goodUnit = (word)(redundantUnit + (copyOffset>>flash->erasableBlockSizeBits));
  505. goodDPS = DPS0_COPY0+floorInc + copyOffset;
  506. redundantDPS = DPS0_COPY0+floorInc;
  507. break;
  508. default: /* Both copies are good */
  509. goodUnit = (word)(DPS0_UNIT_NO + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
  510. redundantUnit = (word)(goodUnit + (copyOffset>>flash->erasableBlockSizeBits));
  511. goodDPS = DPS0_COPY0+floorInc;
  512. redundantDPS = DPS0_COPY0+floorInc + copyOffset;
  513. }
  514. break;
  515. case 1: /* data protect structure 0 */
  516. switch (downloadStatus & DWN_STAT_DPS1_ERR)
  517. {
  518. case DWN_STAT_DPS11_ERR: /* Both are bad */
  519. return flBadDownload;
  520. case DWN_STAT_DPS10_ERR: /* First is bad */
  521. redundantUnit = (word)(dps1UnitNo + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
  522. goodUnit = (word)(redundantUnit + (copyOffset>>flash->erasableBlockSizeBits));
  523. goodDPS = dps1Copy0+floorInc + copyOffset;
  524. redundantDPS = dps1Copy0+floorInc;
  525. redundantIPL = ipl0Copy0 + floorInc;
  526. goodIPL = redundantIPL + copyOffset;
  527. break;
  528. default : /* First is good */
  529. goodUnit = (word)(dps1UnitNo + floorNo*(NFDC21thisVars->floorSize>>flash->erasableBlockSizeBits));
  530. redundantUnit = (word)(goodUnit + (copyOffset>>flash->erasableBlockSizeBits));
  531. goodDPS = dps1Copy0+floorInc;
  532. redundantDPS = dps1Copy0+floorInc + copyOffset;
  533. goodIPL = ipl0Copy0 + floorInc;
  534. redundantIPL = goodIPL + copyOffset;
  535. }
  536. break;
  537. default: /* No such protection area */
  538. return flGeneralFailure;
  539. }
  540. /* Build new DPS */
  541. if (key==NULL) /* key must be retreaved from previous structure */
  542. {
  543. status = flash->read(flash,goodDPS,(void FAR1 *)&dps,SIZE_OF_DPS,0);
  544. if(status!=flOK) goto END_WRITE_DPS;
  545. if(findChecksum((byte *)&dps,SIZE_OF_DPS)!=0) /* bad copy */
  546. status = flash->read(flash,goodDPS+REDUNDANT_DPS_OFFSET,
  547. (void FAR1*)&dps,SIZE_OF_DPS,0);
  548. makeDPS(addressLow,addressHigh,(byte FAR1*)(dps.key),flag,(byte *)&dps);
  549. }
  550. else /* key is given as a parameter */
  551. {
  552. makeDPS(addressLow,addressHigh,(byte FAR1*)key,flag,(byte *)&dps);
  553. }
  554. /* Erase redundant unit */
  555. status = flash->erase(flash,redundantUnit,1);
  556. if(status!=flOK) goto END_WRITE_DPS;
  557. /* Write new DPS */
  558. status = flash->write(flash,redundantDPS,&dps,SIZE_OF_DPS,0);
  559. if(status!=flOK) goto END_WRITE_DPS;
  560. status = flash->write(flash,redundantDPS + REDUNDANT_DPS_OFFSET,
  561. &dps,SIZE_OF_DPS,0);
  562. if(status!=flOK) goto END_WRITE_DPS;
  563. if (area == 1) /* copy the IPL */
  564. {
  565. #ifndef MTD_STANDALONE
  566. /* Force remapping of internal catched sector */
  567. flash->socket->remapped = TRUE;
  568. #endif /* MTD_STANDALONE */
  569. /* Read first 512 bytes IPL */
  570. status = flash->read(flash,goodIPL,NFDC21thisBuffer,SECTOR_SIZE,0);
  571. if(status!=flOK) goto END_WRITE_DPS;
  572. /* Write first 512 bytes IPL */
  573. status = flash->write(flash,redundantIPL,NFDC21thisBuffer,SECTOR_SIZE,EDC);
  574. if(status!=flOK) goto END_WRITE_DPS;
  575. status = flash->write(flash,redundantIPL + SECTOR_SIZE,
  576. NFDC21thisBuffer,SECTOR_SIZE,EDC);
  577. if(status!=flOK) goto END_WRITE_DPS;
  578. /* Read second 512 bytes IPL */
  579. status = flash->read(flash,goodIPL + IPL_HIGH_SECTOR,
  580. NFDC21thisBuffer,SECTOR_SIZE,0);
  581. if(status!=flOK) goto END_WRITE_DPS;
  582. /* Write second 512 bytes IPL */
  583. status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR,
  584. NFDC21thisBuffer,SECTOR_SIZE,EDC);
  585. if(status!=flOK) goto END_WRITE_DPS;
  586. status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR +
  587. SECTOR_SIZE, NFDC21thisBuffer,SECTOR_SIZE,EDC);
  588. if(status!=flOK) goto END_WRITE_DPS;
  589. /* Read Srong Arm mark */
  590. status = flash->read(flash,goodIPL + IPL_HIGH_SECTOR + 8,
  591. NFDC21thisBuffer,1,EXTRA);
  592. if(status!=flOK) goto END_WRITE_DPS;
  593. /* Write Srong Arm mark */
  594. status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + 8 +
  595. SECTOR_SIZE, NFDC21thisBuffer,1,EXTRA);
  596. if(status!=flOK) goto END_WRITE_DPS;
  597. status = flash->write(flash,redundantIPL + IPL_HIGH_SECTOR + 8,
  598. NFDC21thisBuffer,1,EXTRA);
  599. if(status!=flOK) goto END_WRITE_DPS;
  600. }
  601. /* Erase good unit */
  602. status = flash->erase(flash,goodUnit,1);
  603. if(status!=flOK) goto END_WRITE_DPS;
  604. /* Write over previous DPS */
  605. status = flash->write(flash,goodDPS,&dps,SIZE_OF_DPS,0);
  606. if(status!=flOK) goto END_WRITE_DPS;
  607. status = flash->write(flash,goodDPS + REDUNDANT_DPS_OFFSET,
  608. &dps,SIZE_OF_DPS,0);
  609. if(status!=flOK) goto END_WRITE_DPS;
  610. if (area == 1) /* copy the IPL */
  611. {
  612. /* Read first 512 bytes IPL */
  613. status = flash->read(flash,redundantIPL,NFDC21thisBuffer,SECTOR_SIZE,0);
  614. if(status!=flOK) goto END_WRITE_DPS;
  615. /* Write first 512 bytes IPL */
  616. status = flash->write(flash,goodIPL,NFDC21thisBuffer,SECTOR_SIZE,EDC);
  617. if(status!=flOK) goto END_WRITE_DPS;
  618. status = flash->write(flash,goodIPL + SECTOR_SIZE,
  619. NFDC21thisBuffer,SECTOR_SIZE,EDC);
  620. if(status!=flOK) goto END_WRITE_DPS;
  621. /* Read second 512 bytes IPL */
  622. status = flash->read(flash,redundantIPL + IPL_HIGH_SECTOR,
  623. NFDC21thisBuffer,SECTOR_SIZE,0);
  624. if(status!=flOK) goto END_WRITE_DPS;
  625. /* Write second 512 bytes IPL */
  626. status = flash->write(flash,goodIPL + IPL_HIGH_SECTOR,
  627. NFDC21thisBuffer,SECTOR_SIZE,EDC);
  628. if(status!=flOK) goto END_WRITE_DPS;
  629. status = flash->write(flash,goodIPL + IPL_HIGH_SECTOR +
  630. SECTOR_SIZE, NFDC21thisBuffer,
  631. SECTOR_SIZE,EDC);
  632. if(status!=flOK) goto END_WRITE_DPS;
  633. }
  634. END_WRITE_DPS:
  635. if ( restoreInterleave == TRUE)
  636. {
  637. FLStatus status2;
  638. chkASICmode(flash); /* Release posible access error */
  639. status2 = changeInterleave(flash, 2); /* change back to interleave 2 */
  640. if(status2 != flOK)
  641. return status2;
  642. }
  643. if (status == flOK)
  644. {
  645. if ((modes & COMMIT_PROTECTION) && /* The new values will take affect now */
  646. (flash->download != NULL))
  647. status = flash->download(flash);
  648. }
  649. return status;
  650. }
  651. /*
  652. ** makeDataProtectStruct
  653. *
  654. *
  655. * PARAMETERS:
  656. * AddressLow : sets address of lower boundary of protected area
  657. * AddressHigh: sets address of upper boundary of protected area
  658. * Key : an 8 byte long array containing the protection password.
  659. * flag : any combination of the following flags:
  660. * LOCK_ENABLED - The LOCK signal is enabled.
  661. * READ_PROTECTED - The area is protected against read operations
  662. * WRITE_PROTECTED - The area is protected against write operations
  663. * buffer - buffer pointer of the returned structure.
  664. *
  665. * DESCRIPTION: Sets the definitions of a protected structure: location, key and protection type
  666. *
  667. * RETURNS:
  668. *
  669. */
  670. static void makeDPS(CardAddress addressLow, CardAddress addressHigh,
  671. byte FAR1* key , word flag, byte* buffer)
  672. {
  673. int i;
  674. DPSStruct* dps = (DPSStruct *)buffer;
  675. /* convert to little endien and store */
  676. toLE4(dps->addressLow,addressLow >>10);
  677. toLE4(dps->addressHigh,addressHigh >>10);
  678. /*insert protection key */
  679. for(i=0; i<PROTECTION_KEY_LENGTH; i++)
  680. dps->key[i] = key[i];
  681. /* insert flags */
  682. dps->protectionType = 0;
  683. if((flag & LOCK_ENABLED)==LOCK_ENABLED)
  684. dps->protectionType |= DPS_LOCK_ENABLED;
  685. if((flag & READ_PROTECTED)==READ_PROTECTED)
  686. dps->protectionType |= DPS_READ_PROTECTED;
  687. if((flag & WRITE_PROTECTED)==WRITE_PROTECTED)
  688. dps->protectionType |= DPS_WRITE_PROTECTED;
  689. /* calculate and store checksum */
  690. dps->checksum = findChecksum(buffer,SIZE_OF_DPS-1);
  691. }
  692. #endif /* FL_READ_ONLY */
  693. #endif /* HW_PROTECTION */