Source code of Windows XP (NT5)
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.

3762 lines
142 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/BLOCKDEV.C_V $
  3. *
  4. * Rev 1.43 Apr 15 2002 20:14:20 oris
  5. * Prevent any change to the flPolicy environment variable. It must be set to FL_DEFAULT_POLICY.
  6. *
  7. * Rev 1.42 Apr 15 2002 07:33:56 oris
  8. * Moved doc2exb functions declaration to blockdev.c
  9. * Moved bdkCall function declaration to docbdk.h
  10. * Bug fix - Bad arguments sanity check for FL_MTD_BUS_ACCESS_TYPE.
  11. * Bug fix - Missing initialization of global variables:
  12. * - bus access in flSetDocBusRoutine() and flGetDocBusRoutine() and when ENVIRONMENT_VARS compilation flag is not defined.
  13. * - verify write when ENVIRONMENT_VARS compilation flag is not defined.
  14. * - All global (for all sockets and volumes) environment variables where not reinitialized after flExit call.
  15. * - Renamed initEnvVarsDone to initGlobalVarsDone.
  16. * - Renamed flInitEnvVars() to flInitGlobalVars().
  17. * Changed flBusConfig environment array to dword variables instead of single byte.
  18. * Added support for VERIFY_ERASED_SECTOR compilation flag.
  19. * Placed multi-doc environment variable under the MULTI_DOC compilation flag.
  20. * VolumeInfo routine - remove warning by placing eraseCyclesPerUnit variable under FL_LOW_LEVEL compilation flag.
  21. *
  22. * Rev 1.41 Feb 19 2002 20:58:08 oris
  23. * Moved include directives to blockdev.h file.
  24. * Bug fix - findFreeVolume routine did not initialize flfash records of the volume. It caused exception when formatting a DiskOnChip with more then 1 partition.
  25. * Compilation error missing ifdef EXIT.
  26. * Convert TL_LEAVE_BINARY_AREA to FL_LEAVE_BINARY_AREA before sending it to the TL.
  27. * Bug fix - volumeInfo routine might cause exception if osak version or driver version is larger the designated field.
  28. * use intermediate variable before sending irFlags to otpSize routine.
  29. *
  30. * Rev 1.40 Jan 29 2002 20:07:42 oris
  31. * Added NAMING_CONVENTION prefix and extern "C" for cpp files to all public routines:
  32. * flSetEnvVolume, flSetEnvSocket , flSetEnvAll , flSetDocBusRoutine , flGetDocBusRoutine, flBuildGeometry , bdCall and flExit
  33. * Changed LOW_LEVEL compilation flag with FL_LOW_LEVEL to prevent definition clashes.
  34. * Removed warnings.
  35. * Moved writeIPL sanity check to MTD level.
  36. * Removed download operation after writeIPL call (it is now one of the routines parameters).
  37. * Added sanity check (null pointer passed) to flSetEnvVolume, flSetDocBusRoutine and flGetDocBusRoutine.
  38. *
  39. * Rev 1.39 Jan 28 2002 21:23:32 oris
  40. * Bug fix - initialization of flPolicy variable caused a memory lick (set max unit chain to 0).
  41. * Changed FL_NFTL_CACHE_ENABLED to FL_TL_CACHE_ENABLED.
  42. * Changed flSetDocBusRoutine interface and added flGetDocBusRoutine.
  43. * Added FL_IPL_DOWNLOAD flag to writeIPL routine in order to control whether the IPL will be reloaded after the update.
  44. *
  45. * Rev 1.38 Jan 23 2002 23:30:46 oris
  46. * Added a call to flExit() in case flSuspend was restored to FL_OFF.
  47. * Moved Alon based DiskOnChip write IPL routine from blockdev, to diskonc.
  48. * Added sanity check to flCheckVolume() - Make sure irData is NULL and irLength is set to 0.
  49. *
  50. * Rev 1.37 Jan 21 2002 20:43:36 oris
  51. * Bug fix - Missing\bad support for FL_SECTORS_VERIFIED_PER_FOLDING and FL_VERIFY_WRITE_BDTL environment variables.
  52. *
  53. * Rev 1.36 Jan 20 2002 20:40:20 oris
  54. * Improved documentation of bdFormatPhisycalDrive - Added TL_NORMAL_FORMAT flag was added.
  55. * Removed ifdef NO_PHYSICAL_IO from flGetBPB routine.
  56. *
  57. * Rev 1.35 Jan 17 2002 22:56:22 oris
  58. * Placed docbdk.h under BDK_ACCESS ifdef
  59. * Added include directive to docsys.h
  60. * Removed function prototypes from header.
  61. * Changed FLFlash record in the volume structure into a pointer
  62. * Added flBusConfig variable and flSetDocBusRoutine() routine for runtime control over memory access routines - under the FL_NO_USE_FUNC definition.
  63. * Added flSectorsVerfiedPerFolding environment variable was added
  64. * Added flSuspendMode environment variable was added.
  65. * Changed flVerifyWrite environment variable : 4 for Disk partitions 3 for Binary and 1 for the rest.
  66. * Changed flPolicy to be partition specific.
  67. * Changed flSetEnv() routine was changed into 3 different routines: flSetEnvVolume / flSetEnvSocket / flSetEnvAll
  68. * Variables types for environment variables were changed to the minimal size needed.
  69. * Added flInitEnvVars() routine for setting default values to environment variables.
  70. * Use single FLFlash record for each volume - (change vol.flash to a pointer instead of the record itself).
  71. * Added \r to all DEBUG_PRINT routines.
  72. * Removed SINGLE_BUFFER ifdef.
  73. * Added volume verification after format for faster write performance with FL_OFF.
  74. * Removed FLFlash parameter to all TL calls (flMount / flFormat / flPreMount )
  75. * Added support for firmware other then the 3 defaults (getExbInfo additional parameter)
  76. * Added support for M+ 16MB
  77. * Added partition parameter to setBusy - Stores current partition in the socket record for the use of lower TrueFFS layers .
  78. * Changed tffsmin to TFFSMIN
  79. * Added FL_VERIFY_VOLUME functionNo.
  80. * Made sure flInit() initializes all sockets and flashes volumes
  81. * Added flClearQuickMountInfo() routine (FL_CLEAR_QUICK_MOUNT_INFO)
  82. * readIPL routine now supports all DiskOnChip
  83. *
  84. * Rev 1.34 Nov 29 2001 20:53:44 oris
  85. * Bug fix - flInquireCapabilities() returned bad status for SUPPORT_WRITE_IPL_ROUTINE.
  86. *
  87. * Rev 1.33 Nov 21 2001 11:40:44 oris
  88. * Changed FL_MULTI_DOC_NOT_ACTIVE to FL_OFF, FL_VERIFY_WRITE_MODE to FL_MTD_VERIFY_WRITE , FL_WITHOUT_VERIFY_WRITE to FL_OFF , FL_MARK_DELETE to FL_ON.
  89. *
  90. * Rev 1.32 Nov 08 2001 10:44:04 oris
  91. * Added flVerifyWrite environment variable that controls the verify write mode at run-time.
  92. * Added support for large DiskOnChip in flBuildGeometry.
  93. * Remove s/w protection from binary partition.
  94. * Placed flAbsMount under ABS_READ_WRITE compilation flag.
  95. *
  96. * Rev 1.31 Sep 24 2001 18:23:04 oris
  97. * Removed warnings.
  98. *
  99. * Rev 1.30 Sep 15 2001 23:44:22 oris
  100. * Changed BIG_ENDIAN to FL_BIG_ENDIAN
  101. *
  102. * Rev 1.29 Aug 02 2001 20:04:04 oris
  103. * Added support for 1k IPL for DiskOnChip 2000 TSOP - writeIPL()
  104. *
  105. * Rev 1.28 Jul 29 2001 19:14:24 oris
  106. * Bug fix for TrueFFS internal mutex when using multi-doc and environment variables (when no multi-doc feature is disbaled)
  107. *
  108. * Rev 1.27 Jul 13 2001 00:59:28 oris
  109. * Changed flash lifetime calculation according to specific flash.
  110. *
  111. * Rev 1.26 Jun 17 2001 08:16:50 oris
  112. * Added NO_PHISICAL_IO compilation flag to reduce code size.
  113. * Added NO_READ_BBT_CODE compilation flag to reduce code size.
  114. * Changed placeExbByBuffer exbflags argument to word instead of byte to support /empty flag.
  115. * Deleted redundent #ifdef MULTI_DOC in flInit().
  116. *
  117. * Rev 1.25 May 31 2001 18:11:52 oris
  118. * Removed readBBT routine from under the #ifndef FL_READ_ONLY.
  119. *
  120. * Rev 1.24 May 16 2001 21:16:08 oris
  121. * Changed the Binary state (0,1) of the environment variables to meaningful definitions.
  122. * Added flMtlDefragMode environment variable.
  123. * Added the FL_ prefix to the following defines: ON, OFF
  124. * Bug fix - One of the "ifndef" statement of NO_IPL_CODE was coded as "ifdef"
  125. * Change "data" named variables to flData to avoid name clashes.
  126. *
  127. * Rev 1.23 May 09 2001 00:31:00 oris
  128. * Added NO_PHYSICAL_IO , NO_IPL_CODE and NO_INQUIRE_CAPABILITY compilation flags to reduce code size.
  129. *
  130. * Rev 1.22 May 06 2001 22:41:04 oris
  131. * Bug fix - flInquireCapabilities routine did not return the correct value when capability was not supported.
  132. * Added SUPPORT_WRITE_IPL_ROUTIN capability.
  133. * Removed warnings.
  134. *
  135. * Rev 1.21 May 01 2001 17:05:10 oris
  136. * Bug fix - bad argument check in flSetEnv routine.
  137. *
  138. * Rev 1.20 Apr 30 2001 17:57:00 oris
  139. * Added new environment variable flMarkDeleteOnFlash.
  140. *
  141. * Rev 1.19 Apr 24 2001 17:05:38 oris
  142. * Bug fix flMoutVolume routine return the correct hidden sectors even if high level mount fails.
  143. * Bug fix Write IPL routine supports Doc2000 TSOP as well as Millennium Plus.
  144. * Support readBBT new interface.
  145. *
  146. * Rev 1.18 Apr 18 2001 20:43:00 oris
  147. * Added force download call after writing IPL.
  148. *
  149. * Rev 1.17 Apr 18 2001 19:14:24 oris
  150. * Bug fix - binary partition insert and remove key routine no longer stop the place exb proccess.
  151. *
  152. * Rev 1.16 Apr 18 2001 09:26:22 oris
  153. * noOfDrives variable was changed to unsigned. This is a bug fix for vxWorks boot code.
  154. * Make sure blockdev does not try to mount more volumes then the VOLUMES definition.
  155. *
  156. * Rev 1.15 Apr 16 2001 13:02:38 oris
  157. * Removed warrnings.
  158. *
  159. * Rev 1.14 Apr 12 2001 06:48:22 oris
  160. * Added call to download routine after physical format in order
  161. * to load new IPL and to initialize new protection information.
  162. * Removed warnings.
  163. *
  164. * Rev 1.13 Apr 03 2001 16:33:10 oris
  165. * Removed unused variables.
  166. * Added proper casting in otpSize call.
  167. *
  168. * Rev 1.12 Apr 03 2001 14:33:16 oris
  169. * Bug fix in absRead sectors when reading multiple sectors.
  170. *
  171. * Rev 1.11 Apr 01 2001 14:57:58 oris
  172. * Bug fix in read multiple sectors.
  173. *
  174. * Rev 1.10 Mar 28 2001 06:19:12 oris
  175. * Removed flChangeEnvVar prototype.
  176. * Left alligned all # directives.
  177. * Bug fix in flSetEnv ((value !=0)||(value!=1)) => ((value !=0)&&(value!=1)) + downcast for given argument + add return status code
  178. * Removed unused variables.
  179. * Remove casting warnnings.
  180. * Add arg check in bdFormatPhysicalDrive for BDTLPartitionInfo != NULL.
  181. * Bug fix for absWrite - multi-secotr write should be initialized with zeros to prevent sector found return code.
  182. * Replaced the numbers in writeProtect routine to defines (moved from ioctl.h to blockdev.h).
  183. * Add break for mdocp identification in getPhysicalInfo.
  184. * Added readIPL routine.
  185. * Added LOG_FILE compilation flag for EDC errors for mdocp.
  186. * Added initialization of tl table in flInit.
  187. * flExit mutex bug fix.
  188. *
  189. * Rev 1.9 Mar 05 2001 21:00:34 oris
  190. * Bug fix - initialize exbLen argument in bdFormatVolume.
  191. * Bug fix - initialize bdtlFp flags fiels in bdFormatVolume.
  192. * Restored the flExit pragma under __BORLANDC__ compilation flag
  193. *
  194. * Rev 1.8 Feb 22 2001 20:21:34 oris
  195. * Bug fix in flExit with multi-doc release uncreated mutxe.
  196. *
  197. * Rev 1.7 Feb 20 2001 15:44:58 oris
  198. * Bug fix for mutex initialization in flInit.
  199. *
  200. * Rev 1.6 Feb 18 2001 23:29:28 oris
  201. * Bug fix - Added findFreeVolume call in flFormatPhysicalDrive.
  202. * bug fix - Added partition sanity check in bdcall entrence.
  203. * bug fix - Increamented pVol before entering loop in flExit.
  204. *
  205. * Rev 1.5 Feb 18 2001 14:13:22 oris
  206. * Restored FL_BACKGROUND.
  207. * Place bdkCall extern prototype under BDK_ACCESS compilation flag.
  208. * Changed multiple volume mechanism - Replaced removeVolumeHandles and
  209. * flConvertDriveHandle routines with flInit + findFreeVolume and changed
  210. * dismountPhysicalDrive + flEacit to comply.
  211. * Changed bdcall volume validity check.
  212. * Added new volume flag VOLUME_ACCUPIED.
  213. * Moved all the new environment variable (flPolicy,flUseMultiDoc and flMaxUnitChain)
  214. * from flcustom.c in order to allow backwards competability.
  215. * Removed globalMutex (for now).
  216. * Allocate only 1 mutex when multi-doc is registered therfore setBusy takes only 1 mutex .
  217. * Bug fix - absRead and absWrite add bootSectors to the given sectors.
  218. * Bug fix - INVALID_VOLUME_HANDLE changed to INVALID_VOLUME_NUMBER.
  219. * Bug fix - Added (byte FAR1 *) casting in readBBT call.
  220. * Bug fix - Added (FLCapability FAR2 *) casting in inquire capability call.
  221. *
  222. * Rev 1.4 Feb 14 2001 01:51:32 oris
  223. * Completly revised flInquireCapabilities routine.
  224. * Added oldFormat flag to flBuildGeometry routine.
  225. * Remove FL_BACKGROUND compilation flag.
  226. * Added arg check for flSetEnv + new FL_SET_MAX_CHAIN.
  227. * Changed FL_COMPLETE_ASAP_POLICY to FL_SET_POLICY.
  228. * Moved argument check in flFormatPhysicalDrive to fltl.c.
  229. * Moved readBBT routine inside bdcall.
  230. * Placed volumeInfo C\H\S data under ABS_READ_WRITE.
  231. *
  232. * Rev 1.3 Feb 13 2001 02:10:48 oris
  233. * Changed flChangeEnvVar routine name to flSetEnv
  234. *
  235. * Rev 1.2 Feb 12 2001 11:51:12 oris
  236. * Added function prototype in begining of the file.
  237. * Change routine order in the file.
  238. * Added mutex support for TrueFFS 5.0 partitions while changing bdcall order.
  239. * flMountVolume returns the number of boot sectors.
  240. * Moved the writeBBT routine to FLTL.C.
  241. * Added static before changePassword.
  242. * Added static before writeProtect.
  243. * Added static before dismountLowLevel.
  244. * Added static before writeIPL.
  245. * Added static before inquireCapabilities.
  246. * window base is returned by getPhysicalInfo in irLength.
  247. * Added MULTI_DOC compliation flag.
  248. *
  249. * Rev 1.1 Feb 07 2001 17:55:06 oris
  250. * Buf fix for writeBBT of no bad blocks
  251. * Moved readBBT routine from under the fl_read_only define
  252. * Added casting in calls to readBBT and writeBBT
  253. * Added checkStatus check for flAbsWrite and flAbsRead routines
  254. * Added initialization of noOfMTDs and noOfSockets in flInit
  255. *
  256. * Rev 1.0 Feb 04 2001 18:53:04 oris
  257. * Initial revision.
  258. *
  259. */
  260. /*************************************************************************/
  261. /* M-Systems Confidential */
  262. /* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
  263. /* All Rights Reserved */
  264. /*************************************************************************/
  265. /* NOTICE OF M-SYSTEMS OEM */
  266. /* SOFTWARE LICENSE AGREEMENT */
  267. /* */
  268. /* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
  269. /* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
  270. /* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
  271. /* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
  272. /* E-MAIL = [email protected] */
  273. /*************************************************************************/
  274. #include "bddefs.h"
  275. #include "blockdev.h"
  276. #ifdef FL_BACKGROUND
  277. #include "backgrnd.h"
  278. #endif
  279. /********************* Extern Function Prototype Start *******************/
  280. #ifdef WRITE_EXB_IMAGE
  281. extern FLStatus getExbInfo(Volume vol, void FAR1 * buf, dword bufLen, word exbFlags);
  282. extern FLStatus placeExbByBuffer(Volume vol, byte FAR1 * buf, dword bufLen,
  283. word windowBase,word exbFlags);
  284. #endif /* WRITE_EXB_IMAGE */
  285. #if (defined(FORMAT_VOLUME) && defined(COMPRESSION))
  286. extern FLStatus flFormatZIP(unsigned volNo, TL *baseTL , FLFlash * flash);
  287. #endif
  288. #if defined(FILES) && FILES > 0
  289. extern File fileTable[FILES]; /* the file table */
  290. extern FLStatus flushBuffer(Volume vol);
  291. extern FLStatus openFile(Volume vol, IOreq FAR2 *ioreq);
  292. extern FLStatus closeFile(File *file);
  293. extern FLStatus joinFile (File *file, IOreq FAR2 *ioreq);
  294. extern FLStatus splitFile (File *file, IOreq FAR2 *ioreq);
  295. extern FLStatus readFile(File *file,IOreq FAR2 *ioreq);
  296. extern FLStatus writeFile(File *file, IOreq FAR2 *ioreq);
  297. extern FLStatus seekFile(File *file, IOreq FAR2 *ioreq);
  298. extern FLStatus findFile(Volume vol, File *file, IOreq FAR2 *ioreq);
  299. extern FLStatus findFirstFile(Volume vol, IOreq FAR2 *ioreq);
  300. extern FLStatus findNextFile(File *file, IOreq FAR2 *ioreq);
  301. extern FLStatus getDiskInfo(Volume vol, IOreq FAR2 *ioreq);
  302. extern FLStatus deleteFile(Volume vol, IOreq FAR2 *ioreq,
  303. FLBoolean isDirectory);
  304. extern FLStatus renameFile(Volume vol, IOreq FAR2 *ioreq);
  305. extern FLStatus makeDir(Volume vol, IOreq FAR2 *ioreq);
  306. #endif /* FILES > 0 */
  307. /********************* Extern Function Prototype End *******************/
  308. /********************* Internal Function Prototype Start ***************/
  309. void flInitGlobalVars(void);
  310. /********************* Internal Function Prototype End *****************/
  311. /********************* Global variables Start **************************/
  312. Volume vols[VOLUMES];
  313. FLMutex flMutex[SOCKETS];
  314. byte handleConversionTable[SOCKETS][MAX_TL_PARTITIONS];
  315. FLBoolean initDone = FALSE; /* Initialization not done yet */
  316. FLBoolean initGlobalVarsDone = FALSE; /* Initialization of environment */
  317. /* and access type variables not */
  318. /* done yet. */
  319. unsigned noOfDrives;
  320. dword flMsecCounter = 0;
  321. /* bus configuration
  322. *
  323. * DiskOnChip minimal bus width
  324. */
  325. #ifndef FL_NO_USE_FUNC
  326. dword flBusConfig[SOCKETS];
  327. #endif /* FL_NO_USE_FUNC */
  328. /* Verify write state
  329. *
  330. * BDTL partitions : 0-(MAX_TL_PARTITIONS-1)
  331. * Binary partitions : MAX_TL_PARTITIONS - (2*MAX_TL_PARTITIONS-2)
  332. * Last : 2*MAX_TL_PARTITIONS-1
  333. */
  334. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  335. byte flVerifyWrite[SOCKETS][MAX_TL_PARTITIONS<<1];
  336. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  337. #ifdef ENVIRONMENT_VARS
  338. cpyBuffer tffscpy; /* Pointer to memory copy routine */
  339. cmpBuffer tffscmp; /* Pointer to memory compare routine */
  340. setBuffer tffsset; /* Pointer to memory set routine */
  341. /********************************************/
  342. /* default values for environment variables */
  343. /********************************************/
  344. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  345. /* Max sectors verified per write operation (must be even number) */
  346. dword flSectorsVerifiedPerFolding = 64;
  347. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  348. #ifdef MULTI_DOC
  349. /* No multi-doc (MTL) */
  350. byte flUseMultiDoc;
  351. /* MTL defragmentaion mode (0 - standard) */
  352. byte flMTLdefragMode;
  353. #endif /* MULTI_DOC */
  354. /* Set the TL operation policy */
  355. byte flPolicy[SOCKETS][MAX_TL_PARTITIONS];
  356. /* Maximum chain length */
  357. byte flMaxUnitChain;
  358. /* Mark the delete sector on the flash */
  359. byte flMarkDeleteOnFlash;
  360. /* Read Only mode */
  361. byte flSuspendMode;
  362. /********************* Global variables End *****************************/
  363. /*----------------------------------------------------------------------*/
  364. /* f l S e t E n v V o l u m e */
  365. /* */
  366. /* Change one of TrueFFS environment variables for a specific partition */
  367. /* */
  368. /* Note : This routine is used by all other flSetEnv routines. */
  369. /* In order to effect variables that are common to several */
  370. /* sockets or volumes use INVALID_VOLUME_NUMBER */
  371. /* */
  372. /* Parameters: */
  373. /* variableType : variable type to cahnge */
  374. /* socket : Associated socket */
  375. /* volume : Associated volume (partition) */
  376. /* value : varaible value */
  377. /* */
  378. /* Note: Variables common to al sockets must be addressed using socket */
  379. /* 0 and volume 0. */
  380. /* */
  381. /* Returns: */
  382. /* FLStatus : 0 on success, otherwise failed */
  383. /* prevValue : The previous value of the variable */
  384. /*----------------------------------------------------------------------*/
  385. FLStatus NAMING_CONVENTION flSetEnvVolume(FLEnvVars variableType ,
  386. byte socket,byte volume ,
  387. dword value, dword FAR2 *prevValue)
  388. {
  389. /* Arg sanity check */
  390. if(prevValue == NULL)
  391. {
  392. DEBUG_PRINT(("ERROR - prevValue argument is NULL.\r\n"));
  393. return flBadParameter;
  394. }
  395. switch (variableType) /* Check value argument is a valid mode */
  396. {
  397. case FL_SET_MAX_CHAIN:
  398. if ((value > 31) || (value < 1))
  399. {
  400. DEBUG_PRINT(("Debug: Error - Chains length must between 0 and 32.\r\n"));
  401. return flBadParameter;
  402. }
  403. break;
  404. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  405. case FL_SECTORS_VERIFIED_PER_FOLDING:
  406. if (value & 1) /* odd number */
  407. {
  408. DEBUG_PRINT(("Debug: Error - sector verification numbr must be even.\r\n"));
  409. return flBadParameter;
  410. }
  411. break;
  412. case FL_VERIFY_WRITE_BDTL:
  413. if ((value != FL_UPS) && (value != FL_OFF) && (value != FL_ON))
  414. {
  415. DEBUG_PRINT(("Debug: Error - verify write of BDTL can not accept this value.\r\n"));
  416. return flBadParameter;
  417. }
  418. break;
  419. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  420. case FL_SUSPEND_MODE:
  421. if((value != FL_OFF) &&
  422. (value != FL_SUSPEND_WRITE) &&
  423. (value != FL_SUSPEND_IO) )
  424. {
  425. DEBUG_PRINT(("Debug: Error - verify write of BDTL can not accept this value.\r\n"));
  426. return flBadParameter;
  427. }
  428. break;
  429. #ifndef FL_NO_USE_FUNC
  430. case FL_MTD_BUS_ACCESS_TYPE:
  431. break;
  432. #endif /* FL_NO_USE_FUNC */
  433. default:
  434. if ((value != FL_ON)&&(value!=FL_OFF))
  435. {
  436. DEBUG_PRINT(("Debug: Error - Value must be either FL_ON (1) or FL_OFF(0).\r\n"));
  437. return flBadParameter;
  438. }
  439. }
  440. switch (variableType) /* Check volume and socket sanity */
  441. {
  442. /* Volume specfic variables */
  443. case FL_SET_POLICY:
  444. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  445. case FL_VERIFY_WRITE_BDTL:
  446. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  447. #ifdef VERIFY_WRITE
  448. case FL_VERIFY_WRITE_BINARY:
  449. #endif /* VERIFY_WRITE */
  450. if (( volume >= MAX_TL_PARTITIONS ) ||
  451. ((variableType == FL_VERIFY_WRITE_BINARY) &&
  452. (volume == MAX_TL_PARTITIONS - 1 ) ) )
  453. {
  454. DEBUG_PRINT(("Debug: Error - No such volume, therefore can not change environment variable.\r\n"));
  455. return flBadParameter;
  456. }
  457. if (socket>=SOCKETS)
  458. {
  459. DEBUG_PRINT(("Debug: Error - No such socket, therefore can not change environment variable.\r\n"));
  460. return flBadParameter;
  461. }
  462. break;
  463. /* Socket specfic variables */
  464. #ifdef VERIFY_WRITE
  465. case FL_VERIFY_WRITE_OTHER:
  466. #endif /* VERIFY_WRITE */
  467. case FL_MTD_BUS_ACCESS_TYPE:
  468. if (socket>=SOCKETS)
  469. {
  470. DEBUG_PRINT(("Debug: Error - No such socket, therefore can not change environment variable.\r\n"));
  471. return flBadParameter;
  472. }
  473. if (volume!=INVALID_VOLUME_NUMBER)
  474. {
  475. DEBUG_PRINT(("Debug: Error - This global variable is common to all volumes.\r\n"));
  476. return flBadParameter;
  477. }
  478. break;
  479. /* Global variables for all sockets and volumes */
  480. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  481. case FL_SECTORS_VERIFIED_PER_FOLDING:
  482. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  483. case FL_IS_RAM_CHECK_ENABLED:
  484. case FL_TL_CACHE_ENABLED:
  485. case FL_DOC_8BIT_ACCESS:
  486. case FL_MULTI_DOC_ENABLED:
  487. case FL_SET_MAX_CHAIN:
  488. case FL_MARK_DELETE_ON_FLASH:
  489. case FL_SUSPEND_MODE:
  490. case FL_MTL_POLICY:
  491. if ((socket!=INVALID_VOLUME_NUMBER) || (volume!=INVALID_VOLUME_NUMBER))
  492. {
  493. DEBUG_PRINT(("Debug: Error - This global variable is common to all sockets and volumes.\r\n"));
  494. return flBadParameter;
  495. }
  496. break;
  497. default:
  498. DEBUG_PRINT(("Debug: Unknown variable type.\r\n"));
  499. return flFeatureNotSupported;
  500. }
  501. /* Make sure environement variables are */
  502. /* initialized to their default values */
  503. flInitGlobalVars();
  504. /***************************************************/
  505. /* Arguments have been checked now change variable */
  506. /* and report the previous value. */
  507. /***************************************************/
  508. switch (variableType)
  509. {
  510. case FL_IS_RAM_CHECK_ENABLED:
  511. *prevValue = (dword)flUseisRAM;
  512. flUseisRAM = (byte)value;
  513. break;
  514. case FL_TL_CACHE_ENABLED:
  515. *prevValue = (dword)flUseNFTLCache;
  516. flUseNFTLCache = (byte)value;
  517. break;
  518. case FL_DOC_8BIT_ACCESS:
  519. *prevValue = (dword)flUse8Bit;
  520. flUse8Bit = (byte)value;
  521. break;
  522. case FL_SET_MAX_CHAIN:
  523. *prevValue = (dword)flMaxUnitChain;
  524. flMaxUnitChain = (byte)value;
  525. break;
  526. case FL_MARK_DELETE_ON_FLASH:
  527. *prevValue = (dword)flMarkDeleteOnFlash;
  528. flMarkDeleteOnFlash = (byte)value;
  529. break;
  530. #ifdef MULTI_DOC
  531. case FL_MULTI_DOC_ENABLED:
  532. *prevValue = (dword)flUseMultiDoc;
  533. flUseMultiDoc = (byte)value;
  534. break;
  535. case FL_MTL_POLICY:
  536. *prevValue = (dword)flMTLdefragMode;
  537. flMTLdefragMode = (byte)value;
  538. break;
  539. #endif /* MULTI_DOC */
  540. case FL_SUSPEND_MODE:
  541. if((value == FL_OFF) && (flSuspendMode != FL_OFF))
  542. #ifdef EXIT
  543. flExit();
  544. #endif /* EXIT */
  545. *prevValue = (dword)flSuspendMode;
  546. flSuspendMode = (byte)value;
  547. break;
  548. case FL_SET_POLICY:
  549. *prevValue = (dword)flPolicy[socket][volume];
  550. /* flPolicy[socket][volume] = (byte)value; */
  551. break;
  552. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  553. case FL_SECTORS_VERIFIED_PER_FOLDING:
  554. *prevValue = flSectorsVerifiedPerFolding;
  555. flSectorsVerifiedPerFolding = value;
  556. break;
  557. case FL_VERIFY_WRITE_BDTL:
  558. *prevValue = (dword)flVerifyWrite[socket][volume];
  559. flVerifyWrite[socket][volume] = (byte)value;
  560. break;
  561. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  562. #ifdef VERIFY_WRITE
  563. case FL_VERIFY_WRITE_BINARY:
  564. *prevValue = (dword)flVerifyWrite[socket][volume+MAX_TL_PARTITIONS];
  565. flVerifyWrite[socket][volume+MAX_TL_PARTITIONS] = (byte)value;
  566. break;
  567. case FL_VERIFY_WRITE_OTHER:
  568. *prevValue = (dword)flVerifyWrite[socket][(MAX_TL_PARTITIONS<<1)-1];
  569. flVerifyWrite[socket][(MAX_TL_PARTITIONS<<1)-1] = (byte)value;
  570. break;
  571. #endif /* VERIFY_WRITE */
  572. default: /* FL_MTD_BUS_ACCESS_TYPE */
  573. #ifndef FL_NO_USE_FUNC
  574. *prevValue = flBusConfig[socket];
  575. flBusConfig[socket] = (dword)value;
  576. #endif /* FL_NO_USE_FUNC */
  577. break;
  578. }
  579. return flOK;
  580. }
  581. /*----------------------------------------------------------------------*/
  582. /* f l S e t E n v S o c k e t */
  583. /* */
  584. /* Change one of TrueFFS environment variables for a specific sockets. */
  585. /* */
  586. /* Parameters: */
  587. /* variableType : variable type to cahnge */
  588. /* socket : socket number */
  589. /* value : varaible value */
  590. /* */
  591. /* Returns: */
  592. /* FLStatus : 0 on success, otherwise failed */
  593. /* prevValue : The previous value of the variable */
  594. /* if there are more then 1 partition in that */
  595. /* socket , the first partition value is returned*/
  596. /*----------------------------------------------------------------------*/
  597. FLStatus NAMING_CONVENTION flSetEnvSocket(FLEnvVars variableType , byte socket , dword value, dword FAR2 *prevValue)
  598. {
  599. FLStatus status = flOK;
  600. byte volume = 0;
  601. switch (variableType) /* Check volume and socket sanity */
  602. {
  603. /* Volume specific variables */
  604. case FL_SET_POLICY:
  605. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  606. case FL_VERIFY_WRITE_BDTL:
  607. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  608. status = flSetEnvVolume(variableType,socket,MAX_TL_PARTITIONS-1,value,prevValue);
  609. #ifdef VERIFY_WRITE
  610. case FL_VERIFY_WRITE_BINARY:
  611. #endif /* VERIFY_WRITE */
  612. for (;(volume<MAX_TL_PARTITIONS-1)&&(status == flOK);volume++)
  613. status = flSetEnvVolume(variableType,socket,volume,value,prevValue);
  614. break;
  615. /* Socket specific variables */
  616. #ifdef VERIFY_WRITE
  617. case FL_VERIFY_WRITE_OTHER:
  618. #endif /* VERIFY_WRITE */
  619. #ifndef FL_NO_USE_FUNC
  620. case FL_MTD_BUS_ACCESS_TYPE:
  621. #endif /* FL_NO_USE_FUNC */
  622. #if (defined(VERIFY_WRITE) || !defined(FL_NO_USE_FUNC))
  623. status = flSetEnvVolume(variableType,socket,INVALID_VOLUME_NUMBER,value,prevValue);
  624. break;
  625. #endif /* not FL_NO_USE_FUNC || VERIFY_WRITE */
  626. /* Either global variables , or unknown */
  627. default:
  628. if(socket != INVALID_VOLUME_NUMBER) /* Was not called from flSetEnv */
  629. {
  630. DEBUG_PRINT(("Debug: Variable type is either unknown or not socket related.\r\n"));
  631. return flBadParameter;
  632. }
  633. status = flSetEnvVolume(variableType,INVALID_VOLUME_NUMBER,INVALID_VOLUME_NUMBER,value,prevValue);
  634. break;
  635. }
  636. return status;
  637. }
  638. /*----------------------------------------------------------------------*/
  639. /* f l S e t E n v All */
  640. /* */
  641. /* Change one of TrueFFS environment variables for all systems, sockets */
  642. /* and partitions. */
  643. /* */
  644. /* Parameters: */
  645. /* variableType : variable type to cahnge */
  646. /* value : varaible value */
  647. /* */
  648. /* Returns: */
  649. /* FLStatus : 0 on success, otherwise failed */
  650. /* prevValue : The previous value of the variable */
  651. /*----------------------------------------------------------------------*/
  652. FLStatus NAMING_CONVENTION flSetEnvAll(FLEnvVars variableType , dword value, dword FAR2 *prevValue)
  653. {
  654. FLStatus status = flOK;
  655. byte socket;
  656. switch (variableType) /* Check volume and socket sanity */
  657. {
  658. case FL_SET_POLICY: /* Per volume */
  659. case FL_VERIFY_WRITE_BDTL: /* Per volume */
  660. case FL_VERIFY_WRITE_BINARY: /* Per volume */
  661. case FL_VERIFY_WRITE_OTHER: /* Per socket */
  662. case FL_MTD_BUS_ACCESS_TYPE: /* Per socket */
  663. for (socket=0;(socket<SOCKETS)&&(status == flOK);socket++)
  664. status = flSetEnvSocket(variableType,socket,value,prevValue);
  665. return status;
  666. default:
  667. return flSetEnvVolume(variableType,INVALID_VOLUME_NUMBER,INVALID_VOLUME_NUMBER,value,prevValue);
  668. }
  669. }
  670. #endif /* ENVIRONMENT_VARS */
  671. #ifndef FL_NO_USE_FUNC
  672. /*----------------------------------------------------------------------*/
  673. /* f l S e t D o c B u s R o u t i n e */
  674. /* */
  675. /* Set user defined memory acces routines for DiskOnChip. */
  676. /* */
  677. /* Parameters: */
  678. /* socket : Socket number to install routine for. */
  679. /* structPtr : Pointer to function structure. */
  680. /* */
  681. /* Returns: */
  682. /* FLStatus : 0 on success, otherwise failed */
  683. /*----------------------------------------------------------------------*/
  684. FLStatus NAMING_CONVENTION flSetDocBusRoutine(byte socket, FLAccessStruct FAR1 * structPtr)
  685. {
  686. FLFlash* flash;
  687. /* Arg sanity check */
  688. if (socket >= SOCKETS)
  689. {
  690. DEBUG_PRINT(("Error : change SOCKETS definition in flcustom.h to support that many sockets.\r\n"));
  691. return flFeatureNotSupported;
  692. }
  693. if(structPtr == NULL)
  694. {
  695. DEBUG_PRINT(("ERROR - structPtr argument is NULL.\r\n"));
  696. return flBadParameter;
  697. }
  698. /* Make sure global variables are initialized to their default values */
  699. flInitGlobalVars();
  700. flash = flFlashOf(socket);
  701. flash->memWindowSize = structPtr->memWindowSize;
  702. flash->memRead = structPtr->memRead;
  703. flash->memWrite = structPtr->memWrite;
  704. flash->memSet = structPtr->memSet;
  705. flash->memRead8bit = structPtr->memRead8bit;
  706. flash->memRead16bit = structPtr->memRead16bit;
  707. flash->memWrite8bit = structPtr->memWrite8bit;
  708. flash->memWrite16bit = structPtr->memWrite16bit;
  709. flBusConfig[socket] = FL_ACCESS_USER_DEFINED;
  710. return flOK;
  711. }
  712. /*----------------------------------------------------------------------*/
  713. /* f l G e t D o c B u s R o u t i n e */
  714. /* */
  715. /* Get currently installed memory access routines for DiskOnChip. */
  716. /* */
  717. /* Parameters: */
  718. /* socket : Socket number to install routine for. */
  719. /* structPtr : Pointer to function structure. */
  720. /* */
  721. /* Returns: */
  722. /* FLStatus : 0 on success, otherwise failed */
  723. /*----------------------------------------------------------------------*/
  724. FLStatus NAMING_CONVENTION flGetDocBusRoutine(byte socket, FLAccessStruct FAR1 * structPtr)
  725. {
  726. FLFlash* flash;
  727. /* Arg sanity check */
  728. if (socket >= SOCKETS)
  729. {
  730. DEBUG_PRINT(("Error : change SOCKETS definition in flcustom.h to support that many sockets.\r\n"));
  731. return flFeatureNotSupported;
  732. }
  733. if(structPtr == NULL)
  734. {
  735. DEBUG_PRINT(("ERROR - structPtr argument is NULL.\r\n"));
  736. return flBadParameter;
  737. }
  738. /* Make sure global variables are initialized to their default values */
  739. flInitGlobalVars();
  740. flash = flFlashOf(socket);
  741. structPtr->memWindowSize = flash->memWindowSize;
  742. structPtr->memRead = flash->memRead;
  743. structPtr->memWrite = flash->memWrite;
  744. structPtr->memSet = flash->memSet;
  745. structPtr->memRead8bit = flash->memRead8bit;
  746. structPtr->memRead16bit = flash->memRead16bit;
  747. structPtr->memWrite8bit = flash->memWrite8bit;
  748. structPtr->memWrite16bit = flash->memWrite16bit;
  749. structPtr->access = flBusConfig[socket];
  750. return flOK;
  751. }
  752. #endif /* FL_NO_USE_FUNC */
  753. /*----------------------------------------------------------------------*/
  754. /* f l I n i t G l o b a l V a r s */
  755. /* */
  756. /* Initializes the FLite system, environment and access type variables. */
  757. /* */
  758. /* Parameters: */
  759. /* None */
  760. /* */
  761. /* Returns: */
  762. /* None */
  763. /*----------------------------------------------------------------------*/
  764. void flInitGlobalVars(void)
  765. {
  766. int i;
  767. #ifdef ENVIRONMENT_VARS
  768. int j;
  769. #endif /* ENVIRONMENT_VARS */
  770. if(initGlobalVarsDone == TRUE)
  771. return;
  772. /* Do not initialize variables on next call */
  773. initGlobalVarsDone = TRUE;
  774. /*
  775. * Set default values to per socket/volume variables
  776. */
  777. for(i=0;i<SOCKETS;i++)
  778. {
  779. #ifndef FL_NO_USE_FUNC
  780. flBusConfig[i] = FL_NO_ADDR_SHIFT |
  781. FL_BUS_HAS_8BIT_ACCESS |
  782. FL_BUS_HAS_16BIT_ACCESS |
  783. FL_BUS_HAS_32BIT_ACCESS;
  784. #endif /* FL_NO_USE_FUNC */
  785. #ifdef ENVIRONMENT_VARS
  786. for (j=0;j<MAX_TL_PARTITIONS;j++)
  787. {
  788. flPolicy[i][j] = FL_DEFAULT_POLICY; /* FL_COMPLETE_ASAP */
  789. }
  790. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  791. for (j=0;j<MAX_TL_PARTITIONS<<1;j++)
  792. {
  793. flVerifyWrite[i][j] = FL_OFF; /* FL_ON , FL_UPS */
  794. }
  795. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  796. #endif /* ENVIRONMENT_VARS */
  797. }
  798. /*
  799. * Set default values to per platform variables
  800. */
  801. #ifdef ENVIRONMENT_VARS
  802. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  803. /* Max sectors verified per write operation (must be even number) */
  804. flSectorsVerifiedPerFolding = 64;
  805. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  806. #ifdef MULTI_DOC
  807. /* No multi-doc (MTL) */
  808. flUseMultiDoc = FL_OFF;
  809. /* MTL defragmentaion mode (0 - standard) */
  810. flMTLdefragMode = FL_MTL_DEFRAGMENT_ALL_DEVICES;
  811. #endif /* MULTI_DOC */
  812. /* Maximum chain length */
  813. flMaxUnitChain = 20;
  814. /* Mark the delete sector on the flash */
  815. flMarkDeleteOnFlash = FL_ON;
  816. /* Read Only mode */
  817. flSuspendMode = FL_OFF;
  818. #endif /* ENVIRONMENT_VARS */
  819. }
  820. /*----------------------------------------------------------------------*/
  821. /* m o u n t L o w L e v e l */
  822. /* */
  823. /* Mount a volume for low level operations. If a low level routine is */
  824. /* called and the volume is not mounted for low level operations, this */
  825. /* routine is called atomatically. */
  826. /* */
  827. /* Parameters: */
  828. /* vol : Pointer identifying drive */
  829. /* */
  830. /* Returns: */
  831. /* FLStatus : 0 on success, otherwise failed */
  832. /*----------------------------------------------------------------------*/
  833. static FLStatus mountLowLevel(Volume vol)
  834. {
  835. checkStatus(flIdentifyFlash(vol.socket,vol.flash));
  836. vol.flash->setPowerOnCallback(vol.flash);
  837. vol.flags |= VOLUME_LOW_LVL_MOUNTED;
  838. return flOK;
  839. }
  840. /*----------------------------------------------------------------------*/
  841. /* d i s m o u n t L o w L e v e l */
  842. /* */
  843. /* Dismount the volume for low level operations. */
  844. /* */
  845. /* Parameters: */
  846. /* vol : Pointer identifying drive */
  847. /* */
  848. /*----------------------------------------------------------------------*/
  849. static void dismountLowLevel(Volume vol)
  850. {
  851. /* mark the volume as unmounted for low level operations.
  852. And does not change any of the other flags */
  853. vol.flags &= ~VOLUME_LOW_LVL_MOUNTED;
  854. }
  855. #ifdef FORMAT_VOLUME
  856. /*----------------------------------------------------------------------*/
  857. /* f i n d F r e e V o l u m e */
  858. /* */
  859. /* Search the vols array for an empty cell to hold the new volume . */
  860. /* */
  861. /* Parameters: */
  862. /* socket : Socket number for the new volume. */
  863. /* partition : Partition number of the new volume. */
  864. /* */
  865. /* Returns: */
  866. /* FLStatus : 0 on success, flGeneralFailure if no more */
  867. /* volumes left. */
  868. /*----------------------------------------------------------------------*/
  869. static FLStatus findFreeVolume(byte socket, byte partition)
  870. {
  871. byte volNo;
  872. for (volNo = noOfSockets;volNo < VOLUMES;volNo++)
  873. {
  874. if ((vols[volNo].flags & VOLUME_ACCUPIED) == 0)
  875. break;
  876. }
  877. if (volNo == VOLUMES)
  878. return flGeneralFailure;
  879. handleConversionTable[socket][partition] = volNo;
  880. vols[volNo].volExecInProgress = &flMutex[socket];
  881. vols[volNo].socket = vols[socket].socket;
  882. vols[volNo].flash = vols[socket].flash;
  883. vols[volNo].tl.socketNo = socket;
  884. vols[volNo].tl.partitionNo = partition;
  885. vols[volNo].flags = VOLUME_ACCUPIED;
  886. return flOK;
  887. }
  888. /*----------------------------------------------------------------------*/
  889. /* d i s m o u n t P h y s i c a l D r i v e */
  890. /* */
  891. /* Dismounts all the volumes on a specfic socket, closing all files. */
  892. /* This call is not normally necessary, unless it is known the volume */
  893. /* will soon be removed. The routine also clears the volumes entries in */
  894. /* the volume convertion table, except for partition 0 */
  895. /* */
  896. /* Parameters: */
  897. /* socketNo : Socket number to dismount. */
  898. /* */
  899. /* Returns: */
  900. /* FLStatus : 0 on success, otherwise failed */
  901. /*----------------------------------------------------------------------*/
  902. static FLStatus dismountPhysicalDrive(byte socketNo)
  903. {
  904. byte volNo;
  905. byte partition;
  906. /* Dismount all physical drive volumes */
  907. checkStatus(dismountVolume(&vols[socketNo]));
  908. for(partition = 1;partition < MAX_TL_PARTITIONS; partition++)
  909. {
  910. volNo = handleConversionTable[socketNo][partition];
  911. if (volNo != INVALID_VOLUME_NUMBER)
  912. {
  913. checkStatus(dismountVolume(&vols[volNo]));
  914. handleConversionTable[socketNo][partition]=INVALID_VOLUME_NUMBER;
  915. vols[volNo].flags = 0;
  916. }
  917. }
  918. return flOK;
  919. }
  920. #endif /* FORMAT_VOLUME */
  921. /*----------------------------------------------------------------------*/
  922. /* d i s m o u n t V o l u m e */
  923. /* */
  924. /* Dismounts the volume, closing all files. */
  925. /* This call is not normally necessary, unless it is known the volume */
  926. /* will soon be removed. */
  927. /* */
  928. /* Parameters: */
  929. /* vol : Pointer identifying drive */
  930. /* */
  931. /* Returns: */
  932. /* FLStatus : 0 on success, otherwise failed */
  933. /*----------------------------------------------------------------------*/
  934. FLStatus dismountVolume(Volume vol)
  935. {
  936. if (vol.flags & VOLUME_ABS_MOUNTED)
  937. {
  938. FLStatus status = flOK;
  939. #ifndef FIXED_MEDIA
  940. status = flMediaCheck(vol.socket);
  941. #endif
  942. if (status != flOK)
  943. vol.flags = 0;
  944. #if FILES>0
  945. status = dismountFS(&vol,status);
  946. #endif
  947. vol.tl.dismount(vol.tl.rec);
  948. }
  949. vol.flags = VOLUME_ACCUPIED; /* mark volume unmounted */
  950. return flOK;
  951. }
  952. /*----------------------------------------------------------------------*/
  953. /* s e t B u s y */
  954. /* */
  955. /* Notifies the start and end of a file-system operation. */
  956. /* */
  957. /* Parameters: */
  958. /* vol : Pointer identifying drive */
  959. /* state : FL_ON (1) = operation entry */
  960. /* FL_OFF(0) = operation exit */
  961. /* partition : Partition number of the drive */
  962. /* */
  963. /*----------------------------------------------------------------------*/
  964. FLStatus setBusy(Volume vol, FLBoolean state, byte partition)
  965. {
  966. FLStatus status = flOK;
  967. if (state == FL_ON) {
  968. if (!flTakeMutex(execInProgress))
  969. return flDriveNotAvailable;
  970. /* Mark current partition for MTD verify write */
  971. vol.socket->curPartition = partition;
  972. flSocketSetBusy(vol.socket,FL_ON);
  973. flNeedVcc(vol.socket);
  974. if (vol.flags & VOLUME_ABS_MOUNTED)
  975. status = vol.tl.tlSetBusy(vol.tl.rec,FL_ON);
  976. }
  977. else {
  978. if (vol.flags & VOLUME_ABS_MOUNTED)
  979. status = vol.tl.tlSetBusy(vol.tl.rec,FL_OFF);
  980. flDontNeedVcc(vol.socket);
  981. flSocketSetBusy(vol.socket,FL_OFF);
  982. flFreeMutex(execInProgress);
  983. }
  984. return status;
  985. }
  986. /*----------------------------------------------------------------------*/
  987. /* f i n d S e c t o r */
  988. /* */
  989. /* Locates a sector in the buffer or maps it */
  990. /* */
  991. /* Parameters: */
  992. /* vol : Pointer identifying drive */
  993. /* sectorNo : Sector no. to locate */
  994. /* */
  995. /*----------------------------------------------------------------------*/
  996. const void FAR0 *findSector(Volume vol, SectorNo sectorNo)
  997. {
  998. return
  999. #if FILES > 0
  1000. (sectorNo == vol.volBuffer.sectorNo && &vol == vol.volBuffer.owner) ?
  1001. vol.volBuffer.flData :
  1002. #endif
  1003. vol.tl.mapSector(vol.tl.rec,sectorNo,NULL);
  1004. }
  1005. /*----------------------------------------------------------------------*/
  1006. /* a b s M o u n t V o l u m e */
  1007. /* */
  1008. /* Mounts the Flash volume and assume that volume has no FAT */
  1009. /* */
  1010. /* In case the inserted volume has changed, or on the first access to */
  1011. /* the file system, it should be mounted before file operations can be */
  1012. /* done on it. */
  1013. /* Mounting a volume has the effect of discarding all open files (the */
  1014. /* files cannot be properly closed since the original volume is gone), */
  1015. /* and turning off the media-change indication to allow file processing */
  1016. /* calls. */
  1017. /* */
  1018. /* The volume automatically becomes unmounted if it is removed or */
  1019. /* changed. */
  1020. /* */
  1021. /* Parameters: */
  1022. /* vol : Pointer identifying drive */
  1023. /* */
  1024. /* Returns: */
  1025. /* FLStatus : 0 on success, otherwise failed */
  1026. /*----------------------------------------------------------------------*/
  1027. FLStatus absMountVolume(Volume vol)
  1028. {
  1029. unsigned volNo = (unsigned)(&vol - vols);
  1030. #ifdef WRITE_PROTECTION
  1031. PartitionTable FAR0 *partitionTable;
  1032. #endif
  1033. checkStatus(dismountVolume(&vol));
  1034. /* Try to mount translation layer */
  1035. checkStatus(flMount(volNo,vol.tl.socketNo,&vol.tl,TRUE,vol.flash));
  1036. vol.bootSectorNo = 0; /* assume sector 0 is DOS boot block */
  1037. #ifdef WRITE_PROTECTION
  1038. partitionTable = (PartitionTable FAR0 *) findSector(&vol,0);
  1039. if((partitionTable == NULL)||
  1040. (partitionTable==dataErrorToken)||
  1041. (LE2(partitionTable->signature) != PARTITION_SIGNATURE))
  1042. vol.password[0] = vol.password[1] = 0;
  1043. else
  1044. {
  1045. vol.password[0] = vol.password[1] = 0;
  1046. if (UNAL4(partitionTable->passwordInfo[0]) == 0 &&
  1047. (UNAL4(partitionTable->passwordInfo[1]) != 0 ||
  1048. UNAL4(partitionTable->passwordInfo[2]) != 0)) {
  1049. vol.password[0] = UNAL4(partitionTable->passwordInfo[1]);
  1050. vol.password[1] = UNAL4(partitionTable->passwordInfo[2]);
  1051. vol.flags |= VOLUME_WRITE_PROTECTED;
  1052. }
  1053. }
  1054. #endif /* WRITE_PROTECTION */
  1055. /* Disable FAT monitoring */
  1056. vol.firstFATSectorNo = vol.secondFATSectorNo = 0;
  1057. vol.flags |= VOLUME_ABS_MOUNTED; /* Enough to do abs operations */
  1058. return flOK;
  1059. }
  1060. /*----------------------------------------------------------------------*/
  1061. /* m o u n t V o l u m e */
  1062. /* */
  1063. /* Mounts the Flash volume. */
  1064. /* */
  1065. /* In case the inserted volume has changed, or on the first access to */
  1066. /* the file system, it should be mounted before file operations can be */
  1067. /* done on it. */
  1068. /* Mounting a volume has the effect of discarding all open files (the */
  1069. /* files cannot be properly closed since the original volume is gone), */
  1070. /* and turning off the media-change indication to allow file processing */
  1071. /* calls. */
  1072. /* */
  1073. /* The volume automatically becomes unmounted if it is removed or */
  1074. /* changed. */
  1075. /* */
  1076. /* Parameters: */
  1077. /* vol : Pointer identifying drive */
  1078. /* */
  1079. /* Returns: */
  1080. /* FLStatus : 0 on success, otherwise failed */
  1081. /* bootSectors : Returns the number of sectors, flMountVolume */
  1082. /* skipps. */
  1083. /*----------------------------------------------------------------------*/
  1084. static FLStatus mountVolume(Volume vol,unsigned FAR2* bootSectors)
  1085. {
  1086. SectorNo noOfSectors;
  1087. PartitionTable FAR0 *partitionTable;
  1088. Partition ptEntry;
  1089. DOSBootSector FAR0 *bootSector;
  1090. unsigned ptCount,extended_depth,ptSector;
  1091. FLBoolean primaryPtFound = FALSE, extendedPtFound = TRUE;
  1092. *bootSectors=0;
  1093. checkStatus(absMountVolume(&vol));
  1094. for(extended_depth = 0,ptSector = 0;
  1095. (extended_depth<MAX_PARTITION_DEPTH) &&
  1096. (primaryPtFound==FALSE) &&
  1097. (extendedPtFound==TRUE);
  1098. extended_depth++) {
  1099. extendedPtFound=FALSE;
  1100. /* Read in paritition table */
  1101. partitionTable = (PartitionTable FAR0 *) findSector(&vol,ptSector);
  1102. if(partitionTable == NULL) {
  1103. vol.tl.dismount(vol.tl.rec);
  1104. return flSectorNotFound;
  1105. }
  1106. if(partitionTable==dataErrorToken) {
  1107. vol.tl.dismount(vol.tl.rec);
  1108. return flDataError;
  1109. }
  1110. if (LE2(partitionTable->signature) != PARTITION_SIGNATURE)
  1111. break;
  1112. for(ptCount=0;
  1113. (ptCount<4) && (primaryPtFound==FALSE) && (extendedPtFound==FALSE);
  1114. ptCount++) {
  1115. ptEntry = partitionTable->ptEntry[ptCount];
  1116. switch (ptEntry.type) {
  1117. case FAT12_PARTIT:
  1118. case FAT16_PARTIT:
  1119. case DOS4_PARTIT:
  1120. primaryPtFound = TRUE;
  1121. vol.bootSectorNo =
  1122. (unsigned) UNAL4(ptEntry.startingSectorOfPartition);
  1123. *bootSectors=vol.bootSectorNo;
  1124. break;
  1125. case EX_PARTIT:
  1126. extendedPtFound = TRUE;
  1127. ptSector = (unsigned)UNAL4(ptEntry.startingSectorOfPartition);
  1128. break;
  1129. default:
  1130. break;
  1131. }
  1132. }
  1133. }
  1134. bootSector = (DOSBootSector FAR0 *) findSector(&vol,vol.bootSectorNo);
  1135. if(bootSector == NULL)
  1136. return flSectorNotFound;
  1137. if(bootSector==dataErrorToken)
  1138. return flDataError;
  1139. /* Do the customary sanity checks */
  1140. if (!(bootSector->bpb.jumpInstruction[0] == 0xe9 ||
  1141. (bootSector->bpb.jumpInstruction[0] == 0xeb &&
  1142. bootSector->bpb.jumpInstruction[2] == 0x90))) {
  1143. DEBUG_PRINT(("Debug: did not recognize format.\r\n"));
  1144. return flNonFATformat;
  1145. }
  1146. /* See if we handle this sector size */
  1147. if (UNAL2(bootSector->bpb.bytesPerSector) != SECTOR_SIZE)
  1148. return flFormatNotSupported;
  1149. vol.sectorsPerCluster = bootSector->bpb.sectorsPerCluster;
  1150. vol.numberOfFATS = bootSector->bpb.noOfFATS;
  1151. vol.sectorsPerFAT = LE2(bootSector->bpb.sectorsPerFAT);
  1152. vol.firstFATSectorNo = vol.bootSectorNo +
  1153. LE2(bootSector->bpb.reservedSectors);
  1154. vol.secondFATSectorNo = vol.firstFATSectorNo +
  1155. LE2(bootSector->bpb.sectorsPerFAT);
  1156. vol.rootDirectorySectorNo = vol.firstFATSectorNo +
  1157. bootSector->bpb.noOfFATS * LE2(bootSector->bpb.sectorsPerFAT);
  1158. vol.sectorsInRootDirectory =
  1159. (UNAL2(bootSector->bpb.rootDirectoryEntries) * DIRECTORY_ENTRY_SIZE - 1) /
  1160. SECTOR_SIZE + 1;
  1161. vol.firstDataSectorNo = vol.rootDirectorySectorNo +
  1162. vol.sectorsInRootDirectory;
  1163. noOfSectors = UNAL2(bootSector->bpb.totalSectorsInVolumeDOS3);
  1164. if (noOfSectors == 0)
  1165. noOfSectors = (SectorNo) LE4(bootSector->bpb.totalSectorsInVolume);
  1166. vol.maxCluster = (unsigned) ((noOfSectors + vol.bootSectorNo - vol.firstDataSectorNo) /
  1167. vol.sectorsPerCluster) + 1;
  1168. if (vol.maxCluster < 4085) {
  1169. #ifdef FAT_12BIT
  1170. vol.flags |= VOLUME_12BIT_FAT; /* 12-bit FAT */
  1171. #else
  1172. DEBUG_PRINT(("Debug: FAT_12BIT must be defined.\r\n"));
  1173. return flFormatNotSupported;
  1174. #endif
  1175. }
  1176. vol.bytesPerCluster = vol.sectorsPerCluster * SECTOR_SIZE;
  1177. vol.allocationRover = 2; /* Set rover at first cluster */
  1178. vol.flags |= VOLUME_MOUNTED; /* That's it */
  1179. return flOK;
  1180. }
  1181. #ifndef FL_READ_ONLY
  1182. #ifdef DEFRAGMENT_VOLUME
  1183. /*----------------------------------------------------------------------*/
  1184. /* d e f r a g m e n t V o l u m e */
  1185. /* */
  1186. /* Performs a general defragmentation and recycling of non-writable */
  1187. /* Flash areas, to achieve optimal write speed. */
  1188. /* */
  1189. /* NOTE: The required number of sectors (in irLength) may be changed */
  1190. /* (from another execution thread) while defragmentation is active. In */
  1191. /* particular, the defragmentation may be cut short after it began by */
  1192. /* modifying the irLength field to 0. */
  1193. /* */
  1194. /* Parameters: */
  1195. /* vol : Pointer identifying drive */
  1196. /* ioreq->irLength : Minimum number of sectors to make available */
  1197. /* for writes. */
  1198. /* */
  1199. /* Returns: */
  1200. /* ioreq->irLength : Actual number of sectors available for writes */
  1201. /* FLStatus : 0 on success, otherwise failed */
  1202. /*----------------------------------------------------------------------*/
  1203. static FLStatus defragmentVolume(Volume vol, IOreq FAR2 *ioreq)
  1204. {
  1205. return vol.tl.defragment(vol.tl.rec,&ioreq->irLength);
  1206. }
  1207. #endif /* DEFRAGMENT_VOLUME */
  1208. #ifdef FORMAT_VOLUME
  1209. /*-----------------------------------------------------------------------*/
  1210. /* f l F o r m a t V o l u m e */
  1211. /* */
  1212. /* Formats a volume, writing a new and empty file-system. All existing */
  1213. /* data is destroyed. Optionally, a low-level FTL formatting is also */
  1214. /* done. */
  1215. /* Formatting leaves the volume in the dismounted state, so that a */
  1216. /* flMountVolume call is necessary after it. */
  1217. /* */
  1218. /* Note: This routine was left for backwards compatibility with OSAK 4.2 */
  1219. /* and down therfore it is strongly recommended to use the */
  1220. /* flFormatPhysicalDrive routine instead. */
  1221. /* */
  1222. /* Parameters: */
  1223. /* vol : Pointer identifying drive */
  1224. /* irHandle : Drive number (0, 1, ...) */
  1225. /* irFlags : FAT_ONLY_FORMAT : Do FAT formatting only */
  1226. /* TL_FORMAT_ONLY : Do TL format only */
  1227. /* TL_FORMAT : Translation layer + FAT */
  1228. /* TL_FORMAT_IF_NEEDED: Do TL formatting only if */
  1229. /* current format is invalid */
  1230. /* but perform FAT anyway */
  1231. /* irData : Address of FormatParams structure to use */
  1232. /* (defined in flformat.h) */
  1233. /* */
  1234. /* Returns: */
  1235. /* FLStatus : 0 on success, otherwise failed */
  1236. /*-----------------------------------------------------------------------*/
  1237. static FLStatus bdFormatVolume(Volume vol, IOreq FAR2 *ioreq)
  1238. {
  1239. FormatParams FAR2 *userFp = (FormatParams FAR2 *) ioreq->irData;
  1240. BDTLPartitionFormatParams bdtlFp;
  1241. TLFormatParams tlFp;
  1242. FLBoolean mountOK = FALSE;
  1243. FLStatus status;
  1244. byte socket = FL_GET_SOCKET_FROM_HANDLE(ioreq);
  1245. /* Convert argument to TLFormatParmas */
  1246. tlFp.noOfBinaryPartitions = 0;
  1247. tlFp.noOfBDTLPartitions = 1;
  1248. tlFp.BDTLPartitionInfo = NULL;
  1249. tlFp.binaryPartitionInfo = NULL;
  1250. tlFp.bootImageLen = userFp->bootImageLen;
  1251. tlFp.percentUse = (byte)userFp->percentUse;
  1252. tlFp.noOfSpareUnits = (byte)userFp->noOfSpareUnits;
  1253. tlFp.noOfCascadedDevices = 0;
  1254. tlFp.progressCallback = userFp->progressCallback;
  1255. tlFp.vmAddressingLimit = userFp->vmAddressingLimit;
  1256. tlFp.embeddedCISlength = (word)userFp->embeddedCISlength;
  1257. tlFp.embeddedCIS = (byte FAR1 *)userFp->embeddedCIS;
  1258. tlFp.flags = FL_LEAVE_BINARY_AREA;
  1259. #ifdef WRITE_EXB_IMAGE
  1260. tlFp.exbLen = 0;
  1261. #endif /* WRITE_EXB_IMAGE */
  1262. #ifdef HW_PROTECTION
  1263. /* protectionKey[8]; */
  1264. tlFp.protectionType = 0;
  1265. #endif /* HW_PROTECTION */
  1266. /* Dismount all physical drive volumes and set handle to the first */
  1267. checkStatus(dismountPhysicalDrive(socket));
  1268. pVol = &vols[socket];
  1269. /* Format according to the irFlags argument */
  1270. if ((ioreq->irFlags & TL_FORMAT)||(ioreq->irFlags & TL_FORMAT_ONLY))
  1271. {
  1272. checkStatus(flFormat(socket,&tlFp,vol.flash));
  1273. }
  1274. else
  1275. {
  1276. status = flMount(socket,socket,&vol.tl,FALSE,vol.flash); /* Try to mount translation layer */
  1277. mountOK = TRUE;
  1278. if ((status == flUnknownMedia || status == flBadFormat) &&
  1279. (ioreq->irFlags & TL_FORMAT_IF_NEEDED))
  1280. {
  1281. status = flFormat(socket,&tlFp,vol.flash);
  1282. mountOK = FALSE;
  1283. }
  1284. else
  1285. {
  1286. /* assume sector 0 is DOS boot block */
  1287. vol.bootSectorNo = 0;
  1288. /* Disable FAT monitoring */
  1289. vol.firstFATSectorNo = vol.secondFATSectorNo = 0;
  1290. /* Enough to do abs operations */
  1291. vol.flags |= VOLUME_ABS_MOUNTED;
  1292. }
  1293. if (status != flOK)
  1294. return status;
  1295. }
  1296. if (!mountOK)
  1297. checkStatus(absMountVolume(&vol)); /* Mount the first partition */
  1298. #if (defined(VERIFY_WRITE) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  1299. if(vol.tl.checkVolume != NULL)
  1300. checkStatus(vol.tl.checkVolume(vol.tl.rec));
  1301. #endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
  1302. if(!(ioreq->irFlags & TL_FORMAT_ONLY))
  1303. {
  1304. /* build BDTL record for dos format routine */
  1305. tffscpy(bdtlFp.volumeId,userFp->volumeId,4);
  1306. bdtlFp.volumeLabel = (byte FAR1 *)userFp->volumeLabel;
  1307. bdtlFp.noOfFATcopies = (byte)userFp->noOfFATcopies;
  1308. bdtlFp.flags = TL_FORMAT_FAT;
  1309. checkStatus(flDosFormat(&vol.tl,&bdtlFp));
  1310. }
  1311. return flOK;
  1312. }
  1313. /*----------------------------------------------------------------------*/
  1314. /* f l F o r m a t P h y s i c a l D r i v e */
  1315. /* */
  1316. /* Low Level formats the media while partitioning it. */
  1317. /* optionaly the followng additional formats are placed */
  1318. /* 1) writing a new and empty file-system */
  1319. /* 2) Compressed media format */
  1320. /* 3) Quick Mount format */
  1321. /* */
  1322. /* 4) Place M-systems EXB file on the media */
  1323. /* All existing data is destroyed. */
  1324. /* Formatting leaves the volume in the dismounted state, so that a */
  1325. /* flMountVolume call is necessary after it. */
  1326. /* */
  1327. /* Parameters: */
  1328. /* vol : Pointer identifying drive */
  1329. /* irHandle : Drive number (0, 1, ...) */
  1330. /* irFlags : */
  1331. /* TL_NORMAL_FORMAT : Normal format */
  1332. /* TL_LEAVE_BINARY_AREA : Leave binary area unchanged */
  1333. /* */
  1334. /* irData : Address of FormatParams2 structure to use */
  1335. /* (defined in flformat.h) */
  1336. /* */
  1337. /* Returns: */
  1338. /* FLStatus : 0 on success, otherwise failed */
  1339. /*----------------------------------------------------------------------*/
  1340. static FLStatus bdFormatPhysicalDrive(Volume vol, IOreq FAR2 *ioreq)
  1341. {
  1342. FormatParams2 FAR2* userFp = (FormatParams2 FAR2 *) ioreq->irData;
  1343. BDTLPartitionFormatParams FAR2* bdtl;
  1344. TLFormatParams tlFp;
  1345. byte socket = FL_GET_SOCKET_FROM_HANDLE(ioreq);
  1346. byte partition;
  1347. byte volNo;
  1348. #ifdef COMPRESSION
  1349. FLStatus status;
  1350. #endif /* COMPRESSION */
  1351. /***********************************************/
  1352. /* Convert format parameters to TLFormatParams */
  1353. /***********************************************/
  1354. if (userFp->BDTLPartitionInfo == NULL)
  1355. return flBadParameter;
  1356. /* Note that the the BDTL partition are shiftet so that the second
  1357. becomes the first ... . This is for backwards compatibility with
  1358. FTP \ NFTL where the first partition is not given as an array */
  1359. tlFp.bootImageLen = -1; /* either all or nothing */
  1360. tlFp.percentUse = userFp->percentUse;
  1361. tlFp.noOfBDTLPartitions = userFp->noOfBDTLPartitions;
  1362. tlFp.noOfBinaryPartitions = userFp->noOfBinaryPartitions;
  1363. tlFp.BDTLPartitionInfo = userFp->BDTLPartitionInfo;
  1364. tlFp.binaryPartitionInfo = userFp->binaryPartitionInfo;
  1365. tlFp.progressCallback = userFp->progressCallback;
  1366. tlFp.vmAddressingLimit = userFp->vmAddressingLimit;
  1367. tlFp.embeddedCISlength = userFp->embeddedCISlength;
  1368. tlFp.embeddedCIS = userFp->embeddedCIS;
  1369. tlFp.cascadedDeviceNo = userFp->cascadedDeviceNo;
  1370. tlFp.noOfCascadedDevices = userFp->noOfCascadedDevices;
  1371. tlFp.flags = (byte)ioreq->irFlags;
  1372. /* Convert last partition arguments from array to dedicated fields */
  1373. bdtl = userFp->BDTLPartitionInfo;
  1374. bdtl += (userFp->noOfBDTLPartitions - 1);
  1375. tffscpy(tlFp.volumeId,bdtl->volumeId,4);
  1376. tlFp.noOfSpareUnits = (byte)bdtl->noOfSpareUnits;
  1377. tlFp.volumeLabel = bdtl->volumeLabel;
  1378. tlFp.noOfFATcopies = bdtl->noOfFATcopies;
  1379. #ifdef HW_PROTECTION
  1380. tffscpy(tlFp.protectionKey,bdtl->protectionKey,PROTECTION_KEY_LENGTH);
  1381. tlFp.protectionType = bdtl->protectionType;
  1382. #endif /* HW_PROTECTION */
  1383. /* Dismount all physical drive volumes */
  1384. checkStatus(dismountPhysicalDrive(socket));
  1385. /**********************/
  1386. /* Analize EXB buffer */
  1387. /**********************/
  1388. pVol = &vols[socket];
  1389. #ifdef WRITE_EXB_IMAGE
  1390. if ((ioreq->irFlags & TL_LEAVE_BINARY_AREA) ||
  1391. ((userFp->exbBufferLen <= 0) && (userFp->exbLen == 0)))
  1392. {
  1393. tlFp.exbLen = 0;
  1394. }
  1395. else
  1396. {
  1397. if (userFp->exbLen <= 0)
  1398. {
  1399. checkStatus(getExbInfo(&vol, userFp->exbBuffer,
  1400. userFp->exbBufferLen,
  1401. userFp->exbFlags));
  1402. tlFp.exbLen = vol.binaryLength;
  1403. }
  1404. else
  1405. {
  1406. tlFp.exbLen = userFp->exbLen;
  1407. }
  1408. }
  1409. #endif /* WRITE_EXB_IMAGE */
  1410. /*************************************************/
  1411. /* Perform low level format and write EXB buffer */
  1412. /*************************************************/
  1413. checkStatus(flFormat(socket,&tlFp,vol.flash));
  1414. /****************************************/
  1415. /* perform FAT and ZIP format if needed */
  1416. /****************************************/
  1417. for(partition=0, bdtl = userFp->BDTLPartitionInfo;
  1418. partition<userFp->noOfBDTLPartitions;
  1419. partition++,bdtl++)
  1420. {
  1421. if ( partition > 0)
  1422. checkStatus(findFreeVolume(socket,partition));
  1423. volNo = handleConversionTable[socket][partition];
  1424. pVol = &vols[volNo];
  1425. #ifdef COMPRESSION
  1426. if(bdtl->flags & TL_FORMAT_COMPRESSED)
  1427. {
  1428. checkStatus(flMount(volNo,socket,&(vol.tl),FALSE,vol.flash));
  1429. status = flFormatZIP(volNo,&vol.tl);
  1430. vol.tl.dismount(vol.tl.rec);
  1431. if(status!=flOK)
  1432. return status;
  1433. }
  1434. #endif /* COMPRESSION */
  1435. checkStatus(absMountVolume(&vol));
  1436. #if (defined(VERIFY_WRITE) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  1437. if(vol.tl.checkVolume != NULL)
  1438. checkStatus(vol.tl.checkVolume(vol.tl.rec));
  1439. #endif /* VERIFY_WRITE || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
  1440. if(bdtl->flags & TL_FORMAT_FAT) /* perform FAT format as well */
  1441. checkStatus(flDosFormat(&vol.tl,bdtl));
  1442. checkStatus(dismountVolume(&vol));
  1443. }
  1444. #ifdef WRITE_EXB_IMAGE
  1445. if (userFp->exbBufferLen > 0 )
  1446. {
  1447. pVol = &vols[socket];
  1448. checkStatus(placeExbByBuffer(&vol,(byte FAR1 *)userFp->exbBuffer,
  1449. userFp->exbBufferLen,userFp->exbWindow,userFp->exbFlags));
  1450. }
  1451. #endif /* WRITE_EXB_IMAGE */
  1452. checkStatus(mountLowLevel(&vol));
  1453. if (vol.flash->download!=NULL)
  1454. {
  1455. return vol.flash->download(vol.flash); /* download IPL */
  1456. }
  1457. return flOK;
  1458. }
  1459. /*-----------------------------------------------------------------------*/
  1460. /* f l F o r m a t L o g i c a l D r i v e */
  1461. /* */
  1462. /* Formats a logical drive, optionaly writing a new and empty */
  1463. /* file-system and or a compressed format. All existing */
  1464. /* data is destroyed. */
  1465. /* Formatting leaves the volume in the dismounted state, so that a */
  1466. /* flMountVolume call is necessary after it. */
  1467. /* */
  1468. /* Parameters: */
  1469. /* vol : Pointer identifying drive */
  1470. /* irHandle : Drive number (0, 1, ...) */
  1471. /* irData : Address of BDTLPartitionFormatParams to use */
  1472. /* (defined in flformat.h) */
  1473. /* */
  1474. /* Returns: */
  1475. /* FLStatus : 0 on success, otherwise failed */
  1476. /*-----------------------------------------------------------------------*/
  1477. static FLStatus bdFormatLogicalDrive(Volume vol, IOreq FAR2 *ioreq)
  1478. {
  1479. BDTLPartitionFormatParams FAR2 *userFp =
  1480. (BDTLPartitionFormatParams FAR2 *) ioreq->irData;
  1481. byte volNo = (byte)(&vol-vols);
  1482. #ifdef COMPRESSION
  1483. FLStatus status;
  1484. #endif /* COMPRESSION */
  1485. checkStatus(flMount(volNo,vol.tl.socketNo,&(vol.tl),FALSE,vol.flash));
  1486. /* assume sector 0 is DOS boot block */
  1487. vol.bootSectorNo = 0;
  1488. /* Disable FAT monitoring */
  1489. vol.firstFATSectorNo = vol.secondFATSectorNo = 0;
  1490. /* Enough to do abs operations */
  1491. vol.flags |= VOLUME_ABS_MOUNTED;
  1492. #ifdef COMPRESSION
  1493. if(userFp->flags & TL_FORMAT_COMPRESSED)
  1494. {
  1495. status = flFormatZIP(volNo,&vol.tl,vol.flash);
  1496. vol.tl.dismount(vol.tl.rec);
  1497. if(status!=flOK)
  1498. return status;
  1499. }
  1500. #endif /* COMPRESSION */
  1501. if(userFp->flags & TL_FORMAT_FAT) /* perform FAT format as well */
  1502. {
  1503. checkStatus(absMountVolume(&vol));
  1504. checkStatus(flDosFormat(&vol.tl,userFp));
  1505. checkStatus(dismountVolume(&vol));
  1506. }
  1507. return flOK;
  1508. }
  1509. #endif /* FORMAT_VOLUME */
  1510. #endif /* FL_READ_ONLY */
  1511. /*----------------------------------------------------------------------*/
  1512. /* s e c t o r s I n V o l u m e */
  1513. /* */
  1514. /* Defines actual number of virtual sectors according to the low-level */
  1515. /* format of the media. */
  1516. /* */
  1517. /* Returns: */
  1518. /* vol : Pointer identifying drive */
  1519. /* ioreq->irLength : Actual number of virtual sectors in volume */
  1520. /* FLStatus : 0 on success, otherwise failed */
  1521. /*----------------------------------------------------------------------*/
  1522. static FLStatus sectorsInVolume(Volume vol, IOreq FAR2 *ioreq)
  1523. {
  1524. dword sectorsInVol = vol.tl.sectorsInVolume(vol.tl.rec);
  1525. if(sectorsInVol<=vol.bootSectorNo) {
  1526. ioreq->irLength = 0;
  1527. return flGeneralFailure;
  1528. }
  1529. ioreq->irLength = sectorsInVol-vol.bootSectorNo;
  1530. return flOK;
  1531. }
  1532. #ifdef ABS_READ_WRITE
  1533. /*----------------------------------------------------------------------*/
  1534. /* a b s R e a d */
  1535. /* */
  1536. /* Reads absolute sectors by sector no. */
  1537. /* */
  1538. /* Note that if readSecots is not implemented irSectoCount will not */
  1539. /* return the actual number of sectors written in case the operation */
  1540. /* failed in the middle. */
  1541. /* */
  1542. /* Parameters: */
  1543. /* vol : Pointer identifying drive */
  1544. /* irHandle : Drive number (0, 1, ...) */
  1545. /* irData : Address of user buffer to read into */
  1546. /* irSectorNo : First sector no. to read (sector 0 is the */
  1547. /* DOS boot sector). */
  1548. /* irSectorCount : Number of consectutive sectors to read */
  1549. /* */
  1550. /* Returns: */
  1551. /* FLStatus : 0 on success, otherwise failed */
  1552. /* irSectorCount : Number of sectors actually read */
  1553. /*----------------------------------------------------------------------*/
  1554. static FLStatus absRead(Volume vol, IOreq FAR2 *ioreq)
  1555. {
  1556. char FAR1 *userBuffer = (char FAR1 *) ioreq->irData;
  1557. SectorNo currSector = vol.bootSectorNo + ioreq->irSectorNo;
  1558. void FAR0 *mappedSector;
  1559. FLStatus status;
  1560. if (vol.tl.readSectors != NULL)
  1561. {
  1562. status = vol.tl.readSectors(vol.tl.rec , currSector,
  1563. (byte FAR1* )ioreq->irData , ioreq->irSectorCount);
  1564. if (status == flSectorNotFound)
  1565. {
  1566. /* Do not report unassigned sectors. Simply report all 0's */
  1567. if(vol.tl.sectorsInVolume(vol.tl.rec) >=
  1568. (currSector+ioreq->irSectorCount))
  1569. return flOK;
  1570. }
  1571. return status;
  1572. }
  1573. else
  1574. {
  1575. SectorNo sectorCount = (SectorNo)ioreq->irSectorCount;
  1576. for (ioreq->irSectorCount = 0;
  1577. (SectorNo)(ioreq->irSectorCount) < sectorCount;
  1578. ioreq->irSectorCount++, currSector++, userBuffer += SECTOR_SIZE)
  1579. {
  1580. #ifdef SCATTER_GATHER
  1581. userBuffer = *((char FAR1 **)(ioreq->irData) +
  1582. (int)(ioreq->irSectorCount));
  1583. #endif
  1584. mappedSector = (void FAR0 *)findSector(&vol,currSector);
  1585. if (mappedSector)
  1586. {
  1587. if(mappedSector==dataErrorToken)
  1588. return flDataError;
  1589. tffscpy(userBuffer,mappedSector,SECTOR_SIZE);
  1590. }
  1591. else
  1592. {
  1593. if(vol.tl.sectorsInVolume(vol.tl.rec)<=(currSector))
  1594. return flSectorNotFound;
  1595. tffsset(userBuffer,0,SECTOR_SIZE);
  1596. }
  1597. }
  1598. }
  1599. return flOK;
  1600. }
  1601. #ifndef FL_READ_ONLY
  1602. /*----------------------------------------------------------------------*/
  1603. /* r e p l a c e F A T s e c t o r */
  1604. /* */
  1605. /* Monitors sector deletions in the FAT. */
  1606. /* */
  1607. /* When a FAT block is about to be written by an absolute write, this */
  1608. /* routine will first scan whether any sectors are being logically */
  1609. /* deleted by this FAT update, and if so, it will delete-sector them */
  1610. /* before the actual FAT update takes place. */
  1611. /* */
  1612. /* Parameters: */
  1613. /* vol : Pointer identifying drive */
  1614. /* sectorNo : FAT Sector no. about to be written */
  1615. /* newFATsector : Address of FAT sector about to be written */
  1616. /* */
  1617. /* Returns: */
  1618. /* FLStatus : 0 on success, otherwise failed */
  1619. /*----------------------------------------------------------------------*/
  1620. FLStatus replaceFATsector(Volume vol,
  1621. SectorNo sectorNo,
  1622. const char FAR1 *newFATsector)
  1623. {
  1624. const char FAR0 *oldFATsector = (const char FAR0 *)findSector(&vol,sectorNo);
  1625. SectorNo firstSector;
  1626. unsigned firstCluster;
  1627. #ifdef FAT_12BIT
  1628. word FAThalfBytes;
  1629. word halfByteOffset;
  1630. #else
  1631. word byteOffset;
  1632. #endif
  1633. if((oldFATsector==NULL) || oldFATsector==dataErrorToken)
  1634. return flOK;
  1635. #ifdef FAT_12BIT
  1636. FAThalfBytes = vol.flags & VOLUME_12BIT_FAT ? 3 : 4;
  1637. firstCluster = (FAThalfBytes == 3) ?
  1638. (((unsigned) (sectorNo - vol.firstFATSectorNo) * (2 * SECTOR_SIZE) + 2) / 3) :
  1639. ((unsigned) (sectorNo - vol.firstFATSectorNo) * (SECTOR_SIZE>>1));
  1640. firstSector = ((SectorNo) firstCluster - 2) *
  1641. vol.sectorsPerCluster + vol.firstDataSectorNo;
  1642. halfByteOffset = (firstCluster * FAThalfBytes) & ((SECTOR_SIZE<<1) - 1);
  1643. /* Find if any clusters were logically deleted, and if so, delete them */
  1644. /* NOTE: We are skipping over 12-bit FAT entries which span more than */
  1645. /* one sector. Nobody's perfect anyway. */
  1646. for (; halfByteOffset < ((SECTOR_SIZE<<1) - 2);
  1647. firstSector += vol.sectorsPerCluster,
  1648. halfByteOffset += FAThalfBytes)
  1649. {
  1650. unsigned short oldFATentry, newFATentry;
  1651. #ifdef FL_BIG_ENDIAN
  1652. oldFATentry = LE2(*(LEushort FAR0 *)(oldFATsector + (halfByteOffset>>1)));
  1653. newFATentry = LE2(*(LEushort FAR1 *)(newFATsector + (halfByteOffset>>1)));
  1654. #else
  1655. oldFATentry = UNAL2(*(Unaligned FAR0 *)(oldFATsector + (halfByteOffset / 2)));
  1656. newFATentry = UNAL2(*(Unaligned FAR1 *)(newFATsector + (halfByteOffset / 2)));
  1657. #endif
  1658. if (halfByteOffset & 1) {
  1659. oldFATentry >>= 4;
  1660. newFATentry >>= 4;
  1661. }
  1662. else if (FAThalfBytes == 3) {
  1663. oldFATentry &= 0xfff;
  1664. newFATentry &= 0xfff;
  1665. }
  1666. #else
  1667. firstCluster = ((unsigned) (sectorNo - vol.firstFATSectorNo) << (SECTOR_SIZE_BITS-1));
  1668. firstSector = ((SectorNo) firstCluster - 2) * vol.sectorsPerCluster +
  1669. vol.firstDataSectorNo;
  1670. /* Find if any clusters were logically deleted, and if so, delete them */
  1671. for (byteOffset = 0; byteOffset < SECTOR_SIZE;
  1672. firstSector += vol.sectorsPerCluster, byteOffset += 2) {
  1673. unsigned short oldFATentry = LE2(*(LEushort FAR0 *)(oldFATsector + byteOffset));
  1674. unsigned short newFATentry = LE2(*(LEushort FAR1 *)(newFATsector + byteOffset));
  1675. #endif
  1676. if (oldFATentry != FAT_FREE && newFATentry == FAT_FREE)
  1677. checkStatus(vol.tl.deleteSector(vol.tl.rec,firstSector,vol.sectorsPerCluster));
  1678. /* make sure sector is still there */
  1679. oldFATsector = (const char FAR0 *) findSector(&vol,sectorNo);
  1680. }
  1681. return flOK;
  1682. }
  1683. /*----------------------------------------------------------------------*/
  1684. /* a b s W r i t e */
  1685. /* */
  1686. /* Writes absolute sectors by sector no. */
  1687. /* */
  1688. /* Parameters: */
  1689. /* vol : Pointer identifying drive */
  1690. /* irHandle : Drive number (0, 1, ...) */
  1691. /* irData : Address of user buffer to write from */
  1692. /* irSectorNo : First sector no. to write (sector 0 is the */
  1693. /* DOS boot sector). */
  1694. /* irSectorCount : Number of consectutive sectors to write */
  1695. /* */
  1696. /* Returns: */
  1697. /* FLStatus : 0 on success, otherwise failed */
  1698. /* irSectorCount : Number of sectors actually written */
  1699. /*----------------------------------------------------------------------*/
  1700. static FLStatus absWrite(Volume vol, IOreq FAR2 *ioreq)
  1701. {
  1702. char FAR1 *userBuffer = (char FAR1 *) ioreq->irData;
  1703. SectorNo currSector = vol.bootSectorNo + ioreq->irSectorNo;
  1704. SectorNo sectorCount = (SectorNo)ioreq->irSectorCount;
  1705. if (currSector < vol.secondFATSectorNo &&
  1706. currSector + sectorCount > vol.firstFATSectorNo) {
  1707. SectorNo iSector;
  1708. for (iSector = 0; iSector < sectorCount;
  1709. iSector++, currSector++, userBuffer += SECTOR_SIZE) {
  1710. if (currSector >= vol.firstFATSectorNo &&
  1711. currSector < vol.secondFATSectorNo)
  1712. replaceFATsector(&vol,currSector,userBuffer);
  1713. }
  1714. userBuffer = (char FAR1 *) ioreq->irData;
  1715. currSector = (SectorNo)vol.bootSectorNo + (SectorNo)ioreq->irSectorNo;
  1716. }
  1717. if (vol.tl.writeMultiSector != NULL)
  1718. {
  1719. checkStatus(vol.tl.writeMultiSector(vol.tl.rec, currSector,
  1720. ioreq->irData,ioreq->irSectorCount));
  1721. }
  1722. else
  1723. {
  1724. for (ioreq->irSectorCount = 0;
  1725. (SectorNo)(ioreq->irSectorCount) < sectorCount;
  1726. ioreq->irSectorCount++, currSector++, userBuffer += SECTOR_SIZE)
  1727. {
  1728. #if FILES>0
  1729. if ((currSector == vol.volBuffer.sectorNo) &&
  1730. (&vol == vol.volBuffer.owner))
  1731. {
  1732. vol.volBuffer.sectorNo = UNASSIGNED_SECTOR; /* no longer valid */
  1733. vol.volBuffer.dirty = vol.volBuffer.checkPoint = FALSE;
  1734. }
  1735. #endif
  1736. #ifdef SCATTER_GATHER
  1737. userBuffer = *((char FAR1 **)(ioreq->irData)+(int)(ioreq->irSectorCount));
  1738. #endif
  1739. checkStatus(vol.tl.writeSector(vol.tl.rec,currSector,userBuffer));
  1740. }
  1741. }
  1742. return flOK;
  1743. }
  1744. /*----------------------------------------------------------------------*/
  1745. /* a b s D e l e t e */
  1746. /* */
  1747. /* Marks absolute sectors by sector no. as deleted. */
  1748. /* */
  1749. /* Parameters: */
  1750. /* vol : Pointer identifying drive */
  1751. /* irHandle : Drive number (0, 1, ...) */
  1752. /* irSectorNo : First sector no. to write (sector 0 is the */
  1753. /* DOS boot sector). */
  1754. /* irSectorCount : Number of consectutive sectors to delete */
  1755. /* */
  1756. /* Returns: */
  1757. /* FLStatus : 0 on success, otherwise failed */
  1758. /*----------------------------------------------------------------------*/
  1759. static FLStatus absDelete(Volume vol, IOreq FAR2 *ioreq)
  1760. {
  1761. SectorNo first;
  1762. first = (SectorNo)(vol.bootSectorNo + ioreq->irSectorNo);
  1763. return vol.tl.deleteSector(vol.tl.rec,first,(SectorNo)ioreq->irSectorCount);
  1764. }
  1765. #endif /* FL_READ_ONLY */
  1766. #ifndef NO_PHYSICAL_IO
  1767. /*----------------------------------------------------------------------*/
  1768. /* f l A b s A d d r e s s */
  1769. /* */
  1770. /* Returns the current physical media offset of an absolute sector by */
  1771. /* sector no. */
  1772. /* */
  1773. /* Parameters: */
  1774. /* vol : Pointer identifying drive */
  1775. /* irHandle : Drive number (0, 1, ...) */
  1776. /* irSectorNo : Sector no. to address (sector 0 is the DOS */
  1777. /* boot sector) */
  1778. /* */
  1779. /* Returns: */
  1780. /* FLStatus : 0 on success, otherwise failed */
  1781. /* irCount : Offset of the sector on the physical media */
  1782. /*----------------------------------------------------------------------*/
  1783. static FLStatus absAddress(Volume vol, IOreq FAR2 *ioreq)
  1784. {
  1785. CardAddress cardOffset;
  1786. const void FAR0 * sectorData =
  1787. vol.tl.mapSector(vol.tl.rec,vol.bootSectorNo + ioreq->irSectorNo,&cardOffset);
  1788. if (sectorData) {
  1789. if(sectorData==dataErrorToken)
  1790. return flDataError;
  1791. ioreq->irCount = cardOffset;
  1792. return flOK;
  1793. }
  1794. else
  1795. return flSectorNotFound;
  1796. }
  1797. #endif /* NO_PHYSICAL_IO */
  1798. /*----------------------------------------------------------------------*/
  1799. /* g e t B P B */
  1800. /* */
  1801. /* Reads the BIOS Parameter Block from the boot sector */
  1802. /* */
  1803. /* Parameters: */
  1804. /* vol : Pointer identifying drive */
  1805. /* irHandle : Drive number (0, 1, ...) */
  1806. /* irData : Address of user buffer to read BPB into */
  1807. /* */
  1808. /* Returns: */
  1809. /* FLStatus : 0 on success, otherwise failed */
  1810. /*----------------------------------------------------------------------*/
  1811. static FLStatus getBPB(Volume vol, IOreq FAR2 *ioreq)
  1812. {
  1813. BPB FAR1 *userBPB = (BPB FAR1 *) ioreq->irData;
  1814. DOSBootSector FAR0 *bootSector;
  1815. bootSector = (DOSBootSector FAR0 *) findSector(&vol,vol.bootSectorNo);
  1816. if(bootSector == NULL)
  1817. return flSectorNotFound;
  1818. if(bootSector==dataErrorToken)
  1819. return flDataError;
  1820. *userBPB = bootSector->bpb;
  1821. return flOK;
  1822. }
  1823. #ifndef FL_READ_ONLY
  1824. #ifdef WRITE_PROTECTION
  1825. /*----------------------------------------------------------------------*/
  1826. /* c h a n g e P a s s w o r d */
  1827. /* */
  1828. /* Change password for write protectipon. */
  1829. /* */
  1830. /* Parameters: */
  1831. /* vol : Pointer identifying drive */
  1832. /* */
  1833. /* Returns: */
  1834. /* FLStatus : 0 on success, otherwise failed */
  1835. /*----------------------------------------------------------------------*/
  1836. static FLStatus changePassword(Volume vol)
  1837. {
  1838. PartitionTable partitionTable;
  1839. IOreq ioreq;
  1840. FLStatus status;
  1841. #ifdef SCATTER_GATHER
  1842. void FAR1 *iovec[1];
  1843. #endif
  1844. ioreq.irHandle=(unsigned)(&vol-vols);
  1845. ioreq.irSectorNo=0-(int)vol.bootSectorNo;
  1846. ioreq.irSectorCount=1;
  1847. #ifdef SCATTER_GATHER
  1848. iovec[0] = (void FAR1 *) &partitionTable;
  1849. ioreq.irData = (void FAR1 *) iovec;
  1850. #else
  1851. ioreq.irData=&partitionTable;
  1852. #endif
  1853. if((status=absRead(&vol,&ioreq))!=flOK)
  1854. return status;
  1855. toUNAL4(partitionTable.passwordInfo[0], 0);
  1856. toUNAL4(partitionTable.passwordInfo[1],vol.password[0]);
  1857. toUNAL4(partitionTable.passwordInfo[2],vol.password[1]);
  1858. vol.flags &= ~VOLUME_WRITE_PROTECTED;
  1859. return absWrite(&vol,&ioreq);
  1860. }
  1861. /*----------------------------------------------------------------------*/
  1862. /* w r i t e P r o t e c t */
  1863. /* */
  1864. /* Put and remove write protection from the volume */
  1865. /* */
  1866. /* Parameters: */
  1867. /* vol : Pointer identifying drive */
  1868. /* irHandle : Drive number ( 0,1,2... ) */
  1869. /* irFlags : FL_PROTECT = place protection */
  1870. /* FL_UNPROTECT = remove protection */
  1871. /* FL_UNLOCK = remove protection until next dismount */
  1872. /* irData : password (8 bytes) */
  1873. /* */
  1874. /* Returns: */
  1875. /* FLStatus : 0 on success, otherwise failed */
  1876. /*----------------------------------------------------------------------*/
  1877. static FLStatus writeProtect(Volume vol,IOreq FAR2*ioreq)
  1878. {
  1879. FLStatus status=flWriteProtect;
  1880. dword *flData=(dword *)ioreq->irData;
  1881. dword passCode1 = flData[0] ^ SCRAMBLE_KEY_1;
  1882. dword passCode2 = flData[1] ^ SCRAMBLE_KEY_2;
  1883. switch (ioreq->irFlags) {
  1884. case FL_UNLOCK: /* unlock volume */
  1885. if((vol.password[0] == passCode1 && vol.password[1] == passCode2)||
  1886. (vol.password[0] == 0 && vol.password[1] == 0))
  1887. {
  1888. vol.flags &= ~VOLUME_WRITE_PROTECTED;
  1889. status=flOK;
  1890. }
  1891. else
  1892. status=flWriteProtect;
  1893. break;
  1894. case FL_UNPROTECT: /* remove password */
  1895. if(vol.password[0] == passCode1 && vol.password[1] == passCode2)
  1896. {
  1897. vol.password[0] = vol.password[1] = 0;
  1898. status = changePassword(&vol);
  1899. }
  1900. else
  1901. status=flWriteProtect;
  1902. break;
  1903. case FL_PROTECT: /* set password */
  1904. if(vol.password[0] == 0 && vol.password[1] == 0)
  1905. {
  1906. vol.password[0] = passCode1;
  1907. vol.password[1] = passCode2;
  1908. status = changePassword(&vol);
  1909. vol.flags|=VOLUME_WRITE_PROTECTED;
  1910. }
  1911. else
  1912. status=flWriteProtect;
  1913. break;
  1914. default:
  1915. status = flGeneralFailure;
  1916. }
  1917. return status;
  1918. }
  1919. #endif /* WRITE_PROTECTION */
  1920. #endif /* FL_READ_ONLY */
  1921. #endif /* ABS_READ_WRITE */
  1922. /*----------------------------------------------------------------------*/
  1923. /* s o c k e t I n f o */
  1924. /* */
  1925. /* Get socket Information (window base address) */
  1926. /* */
  1927. /* Parameters: */
  1928. /* vol : Pointer identifying drive */
  1929. /* baseAddress : pointer to receive window base address */
  1930. /* */
  1931. /* Returns: */
  1932. /* FLStatus : 0 on success, otherwise failed */
  1933. /*----------------------------------------------------------------------*/
  1934. static FLStatus socketInfo(Volume vol, dword FAR2 *baseAddress)
  1935. {
  1936. *baseAddress = (long)(vol.socket->window.baseAddress) << 12;
  1937. return flOK;
  1938. }
  1939. #ifdef FL_LOW_LEVEL
  1940. /*----------------------------------------------------------------------*/
  1941. /* g e t P h y s i c a l I n f o */
  1942. /* */
  1943. /* Get physical information of the media. The information includes */
  1944. /* JEDEC ID, unit size and media size. */
  1945. /* */
  1946. /* Parameters: */
  1947. /* vol : Pointer identifying drive */
  1948. /* irData : Address of user buffer to read physical */
  1949. /* information into. */
  1950. /* */
  1951. /* Returns: */
  1952. /* FLStatus : 0 on success, otherwise failed */
  1953. /* irLength : Physical base address of device */
  1954. /*----------------------------------------------------------------------*/
  1955. static FLStatus getPhysicalInfo(Volume vol, IOreq FAR2 *ioreq)
  1956. {
  1957. PhysicalInfo FAR2 *physicalInfo = (PhysicalInfo FAR2 *)ioreq->irData;
  1958. physicalInfo->type = vol.flash->type;
  1959. physicalInfo->unitSize = vol.flash->erasableBlockSize;
  1960. physicalInfo->mediaSize = vol.flash->chipSize * vol.flash->noOfChips;
  1961. physicalInfo->chipSize = vol.flash->chipSize;
  1962. physicalInfo->interleaving = vol.flash->interleaving;
  1963. switch(vol.flash->mediaType) {
  1964. case NOT_DOC_TYPE:
  1965. physicalInfo->mediaType = FL_NOT_DOC;
  1966. break;
  1967. case DOC_TYPE :
  1968. physicalInfo->mediaType = FL_DOC;
  1969. break;
  1970. case MDOC_TYPE :
  1971. physicalInfo->mediaType = FL_MDOC;
  1972. break;
  1973. case MDOCP_TYPE :
  1974. physicalInfo->mediaType = FL_MDOCP;
  1975. break;
  1976. case DOC2000TSOP_TYPE :
  1977. physicalInfo->mediaType = FL_DOC2000TSOP;
  1978. break;
  1979. case MDOCP_16_TYPE :
  1980. physicalInfo->mediaType = FL_MDOCP_16;
  1981. break;
  1982. }
  1983. socketInfo(&vol,(dword FAR2 *) &(ioreq->irLength));
  1984. return flOK;
  1985. }
  1986. #ifndef NO_PHYSICAL_IO
  1987. /*----------------------------------------------------------------------*/
  1988. /* p h y s i c a l R e a d */
  1989. /* */
  1990. /* Read from a physical address. */
  1991. /* */
  1992. /* Parameters: */
  1993. /* vol : Pointer identifying drive */
  1994. /* irAddress : Physical address to read from. */
  1995. /* irByteCount : Number of bytes to read. */
  1996. /* irData : Address of user buffer to read into. */
  1997. /* irFlags : Mode of the operation. */
  1998. /* */
  1999. /* Returns: */
  2000. /* FLStatus : 0 on success, otherwise failed */
  2001. /*----------------------------------------------------------------------*/
  2002. static FLStatus physicalRead(Volume vol, IOreq FAR2 *ioreq)
  2003. {
  2004. /* check that we are reading whithin the media boundaries */
  2005. if (ioreq->irAddress + (long)ioreq->irByteCount > (long)vol.flash->chipSize *
  2006. vol.flash->noOfChips)
  2007. return flBadParameter;
  2008. /* We don't read accross a unit boundary */
  2009. if ((long)ioreq->irByteCount > (long)(vol.flash->erasableBlockSize -
  2010. (ioreq->irAddress % vol.flash->erasableBlockSize)))
  2011. return flBadParameter;
  2012. checkStatus(vol.flash->read(vol.flash, ioreq->irAddress, ioreq->irData,
  2013. (word)ioreq->irByteCount, (word)ioreq->irFlags));
  2014. return flOK;
  2015. }
  2016. #ifndef FL_READ_ONLY
  2017. /*----------------------------------------------------------------------*/
  2018. /* p h y s i c a l W r i t e */
  2019. /* */
  2020. /* Write to a physical address. */
  2021. /* */
  2022. /* Parameters: */
  2023. /* vol : Pointer identifying drive */
  2024. /* irAddress : Physical address to write to. */
  2025. /* irByteCount : Number of bytes to write. */
  2026. /* irData : Address of user buffer to write from. */
  2027. /* irFlags : Mode of the operation. */
  2028. /* */
  2029. /* Returns: */
  2030. /* FLStatus : 0 on success, otherwise failed */
  2031. /*----------------------------------------------------------------------*/
  2032. static FLStatus physicalWrite(Volume vol, IOreq FAR2 *ioreq)
  2033. {
  2034. /* check that we are writing whithin the media boundaries */
  2035. if (ioreq->irAddress + (long)ioreq->irByteCount > (long)(vol.flash->chipSize *
  2036. vol.flash->noOfChips))
  2037. return flBadParameter;
  2038. /* We don't write accross a unit boundary */
  2039. if (ioreq->irByteCount > (long)(vol.flash->erasableBlockSize -
  2040. (ioreq->irAddress % vol.flash->erasableBlockSize)))
  2041. return flBadParameter;
  2042. checkStatus(vol.flash->write(vol.flash, ioreq->irAddress, ioreq->irData,
  2043. (dword)ioreq->irByteCount, (word)ioreq->irFlags));
  2044. return flOK;
  2045. }
  2046. /*----------------------------------------------------------------------*/
  2047. /* p h y s i c a l E r a s e */
  2048. /* */
  2049. /* Erase physical units. */
  2050. /* */
  2051. /* Parameters: */
  2052. /* vol : Pointer identifying drive */
  2053. /* irUnitNo : First unit to erase. */
  2054. /* irUnitCount : Number of units to erase. */
  2055. /* */
  2056. /* Returns: */
  2057. /* FLStatus : 0 on success, otherwise failed */
  2058. /*----------------------------------------------------------------------*/
  2059. static FLStatus physicalErase(Volume vol, IOreq FAR2 *ioreq)
  2060. {
  2061. if (ioreq->irUnitNo + (long)ioreq->irUnitCount > (long)
  2062. (vol.flash->chipSize * vol.flash->noOfChips / vol.flash->erasableBlockSize))
  2063. return flBadParameter;
  2064. checkStatus(vol.flash->erase(vol.flash, (word)ioreq->irUnitNo, (word)ioreq->irUnitCount));
  2065. return flOK;
  2066. }
  2067. #endif /* NO_PHYSICAL_IO */
  2068. #endif /* FL_READ_ONLY */
  2069. #ifndef NO_IPL_CODE
  2070. /*----------------------------------------------------------------------*/
  2071. /* r e a d I P L */
  2072. /* */
  2073. /* Read IPL to user buffer. */
  2074. /* */
  2075. /* Note : Read length must be a multiplication of 512 bytes */
  2076. /* Note : Causes DiskOnChip Millennium Plus to download (i,e protection */
  2077. /* key will be removed from all partitions. */
  2078. /* */
  2079. /* Parameters: */
  2080. /* flash : Pointer identifying flash medium of the volume */
  2081. /* irHandle : Socket number ( 0,1,2... ) */
  2082. /* buf : User buffer to read into */
  2083. /* bufLen : Size of user buffer */
  2084. /* */
  2085. /* Returns: */
  2086. /* FLStatus : 0 on success, otherwise failed */
  2087. /*----------------------------------------------------------------------*/
  2088. static FLStatus readIPL(FLFlash* flash, byte FAR1 * buf , dword bufLen)
  2089. {
  2090. FLStatus status;
  2091. dword secondCopyOffset = 1024;
  2092. if(bufLen & 512)
  2093. {
  2094. DEBUG_PRINT(("ERROR - Must read a multiplication of 512 bytes.\r\n"));
  2095. return flBadLength;
  2096. }
  2097. switch (flash->mediaType)
  2098. {
  2099. case MDOCP_TYPE: /* have a special place for the IPL */
  2100. case MDOCP_16_TYPE:
  2101. if (flash->readIPL != NULL)
  2102. {
  2103. checkStatus(flash->readIPL(flash,buf,(word)bufLen));
  2104. return flOK;
  2105. }
  2106. break;
  2107. case MDOC_TYPE:
  2108. if(bufLen != 512)
  2109. {
  2110. DEBUG_PRINT(("ERROR - DiskOnChip Millennium 8M has only 512 Bytes of XIP.\r\n"));
  2111. return flBadLength;
  2112. }
  2113. secondCopyOffset = 512;
  2114. case DOC2000TSOP_TYPE: /* Have a special place for the IPL */
  2115. if(bufLen > 1024)
  2116. {
  2117. DEBUG_PRINT(("ERROR - DiskOnChip 2000 TSOP has only 1024 Bytes of XIP.\r\n"));
  2118. return flBadLength;
  2119. }
  2120. if(flash->read != NULL)
  2121. {
  2122. status = flash->read(flash,0,buf,bufLen,EDC);
  2123. if(status != flOK)
  2124. return flash->read(flash,secondCopyOffset,buf,bufLen,EDC);
  2125. return status;
  2126. }
  2127. break;
  2128. default :
  2129. if(bufLen != 512)
  2130. {
  2131. DEBUG_PRINT(("ERROR - DiskOnChip 2000 has only 512 Bytes of XIP.\r\n"));
  2132. return flBadLength;
  2133. }
  2134. if(flash->win != NULL)
  2135. {
  2136. tffscpy(buf,(const void FAR1*)flash->win,bufLen);
  2137. }
  2138. break;
  2139. }
  2140. return flGeneralFailure;
  2141. }
  2142. #ifndef FL_READ_ONLY
  2143. /*----------------------------------------------------------------------*/
  2144. /* w r i t e I P L */
  2145. /* */
  2146. /* Write IPL to the proper media location */
  2147. /* */
  2148. /* Parameters: */
  2149. /* flash : Pointer identifying flash medium of the volume */
  2150. /* irHandle : Socket number ( 0,1,2... ) */
  2151. /* buf : User buffer containin data to write to the IPL */
  2152. /* bufLen : Size of user buffer */
  2153. /* flags : FL_IPL_MODE_NORMAL : None Strong Arm mode */
  2154. /* FL_IPL_DOWNLOAD : Download new IPL when done */
  2155. /* FL_IPL_MODE_SA : Strong Arm mode */
  2156. /* FL_IPL_MODE_XSCALE : X-Scale mode */
  2157. /* */
  2158. /* Returns: */
  2159. /* FLStatus : 0 on success, otherwise failed */
  2160. /*----------------------------------------------------------------------*/
  2161. static FLStatus writeIPL(FLFlash* flash, byte FAR1 * buf , dword bufLen , unsigned flags)
  2162. {
  2163. switch (flash->mediaType)
  2164. {
  2165. case DOC2000TSOP_TYPE: /* Have a special place for the IPL */
  2166. case MDOCP_TYPE :
  2167. case MDOCP_16_TYPE :
  2168. if (flash->writeIPL != NULL)
  2169. return (flash->writeIPL(flash,buf,(word)bufLen,0,flags));
  2170. DFORMAT_PRINT(("ERROR - MTD does not support write IPL (Please reconfigure MTD).\r\n"));
  2171. break;
  2172. case MDOC_TYPE:
  2173. DFORMAT_PRINT(("ERROR - DiskOnChip Millennium does not support write IPL, use the /BDFK flag.\r\n"));
  2174. break;
  2175. default :
  2176. DFORMAT_PRINT(("ERROR - DiskOnChip 2000 does not support a writiable IPL.\r\n"));
  2177. break;
  2178. }
  2179. return flFeatureNotSupported;
  2180. }
  2181. #endif /* FL_READ_ONLY */
  2182. #endif /* NO_IPL_CODE */
  2183. #ifndef NO_INQUIRE_CAPABILITIES
  2184. /*----------------------------------------------------------------------*/
  2185. /* i n q u i r e C a p a b i l i t i e s */
  2186. /* */
  2187. /* Get the specific device S/W and H/W capabilities */
  2188. /* */
  2189. /* Parameters: */
  2190. /* flash : Record discribing the media */
  2191. /* 4 LSB - Socket number */
  2192. /* capability : Enumarator representing the capability */
  2193. /* Returns: */
  2194. /* capability : CAPABILITY_SUPPORTED if the capability is */
  2195. /* supported */
  2196. /* */
  2197. /*----------------------------------------------------------------------*/
  2198. static void inquireCapabilities(FLFlash* flash , FLCapability FAR2* capability)
  2199. {
  2200. FLCapability inquiredCapability = *capability;
  2201. *capability = CAPABILITY_NOT_SUPPORTED;
  2202. switch (inquiredCapability)
  2203. {
  2204. #ifdef HW_OTP
  2205. case SUPPORT_UNERASABLE_BBT:
  2206. case SUPPORT_OTP_AREA:
  2207. if(flash->otpSize != NULL)
  2208. *capability = CAPABILITY_SUPPORTED;
  2209. break;
  2210. case SUPPORT_CUSTOMER_ID:
  2211. case SUPPORT_UNIQUE_ID:
  2212. if(flash->getUniqueId != NULL)
  2213. *capability = CAPABILITY_SUPPORTED;
  2214. break;
  2215. #endif /* HW_OTP */
  2216. case SUPPORT_MULTIPLE_BDTL_PARTITIONS:
  2217. case SUPPORT_MULTIPLE_BINARY_PARTITIONS:
  2218. if(flash->flags & INFTL_ENABLED)
  2219. *capability = CAPABILITY_SUPPORTED;
  2220. break;
  2221. #ifdef HW_PROTECTION
  2222. case SUPPORT_HW_PROTECTION:
  2223. case SUPPORT_HW_LOCK_KEY:
  2224. if(flash->protectionKeyInsert != NULL)
  2225. *capability = CAPABILITY_SUPPORTED;
  2226. break;
  2227. #endif /* HW_PROTECTION */
  2228. case SUPPORT_DEEP_POWER_DOWN_MODE:
  2229. if(flash->enterDeepPowerDownMode != NULL)
  2230. *capability = CAPABILITY_SUPPORTED;
  2231. break;
  2232. case SUPPORT_WRITE_IPL_ROUTINE:
  2233. if((flash->mediaType == DOC2000TSOP_TYPE) ||
  2234. (flash->mediaType == MDOC_TYPE))
  2235. *capability = CAPABILITY_SUPPORTED;
  2236. break;
  2237. default:
  2238. break;
  2239. }
  2240. }
  2241. #endif /* NO_INQUIRE_CAPABILITIES */
  2242. #endif /* FL_LOW_LEVEL */
  2243. /*----------------------------------------------------------------------*/
  2244. /* f l B u i l d G e o m e t r y */
  2245. /* */
  2246. /* Get C/H/S information of the disk according to number of sectors. */
  2247. /* */
  2248. /* Parameters: */
  2249. /* capacity : Number of Sectors in Volume */
  2250. /* cylinders : Pointer to Number of Cylinders */
  2251. /* heads : Pointer to Number of Heads */
  2252. /* sectors : Pointer to Number of Sectors per Track */
  2253. /* oldFormat : True for one sector per culoster */
  2254. /* */
  2255. /*----------------------------------------------------------------------*/
  2256. void NAMING_CONVENTION flBuildGeometry(dword capacity, dword FAR2 *cylinders,
  2257. dword FAR2 *heads,dword FAR2 *sectors, FLBoolean oldFormat)
  2258. {
  2259. dword temp;
  2260. *cylinders = 1024; /* Set number of cylinders to max value */
  2261. if (oldFormat == TRUE)
  2262. {
  2263. *sectors = 62L; /* Max out number of sectors per track */
  2264. temp = (*cylinders) * (*sectors); /* Compute divisor for heads */
  2265. (*heads) = capacity / temp; /* Compute value for number of heads */
  2266. if (capacity % temp) { /* If no remainder, done! */
  2267. (*heads)++; /* Else, increment number of heads */
  2268. temp = (*cylinders) * (*heads); /* Compute divisor for sectors */
  2269. (*sectors) = capacity / temp; /* Compute value for sectors per track */
  2270. if (capacity % temp) { /* If no remainder, done! */
  2271. (*sectors)++; /* Else, increment number of sectors */
  2272. temp = (*heads) * (*sectors); /* Compute divisor for cylinders */
  2273. (*cylinders) = capacity / temp; /* Compute number of cylinders */
  2274. }
  2275. }
  2276. }
  2277. else
  2278. {
  2279. *heads = 16L; /* Max out number of heads */
  2280. temp = (*cylinders) * (*heads); /* Compute divisor for heads */
  2281. *sectors = capacity / temp; /* Compute value for sectors per track */
  2282. while (*sectors > 0x3f ){ /* While number of sectors too big */
  2283. *heads *= 2; /* use one more head */
  2284. temp = (*cylinders) * (*heads); /* Recompute divisor for heads */
  2285. *sectors = capacity / temp; /* Recompute sectors per track */
  2286. }
  2287. if (capacity % temp) { /* If no remainder, done! */
  2288. (*sectors)++; /* Else, increment number of sectors */
  2289. temp = (*cylinders) * (*sectors); /* Compute divisor for heads */
  2290. *heads = capacity / temp; /* Compute value for heads */
  2291. if (capacity % temp) { /* If no remainder, done! */
  2292. (*heads)++; /* Else, increment number of heads */
  2293. temp = (*heads) * (*sectors); /* Compute divisor for cylinders */
  2294. *cylinders = (dword)(capacity / temp); /* Compute number of cylinders */
  2295. }
  2296. }
  2297. }
  2298. }
  2299. /*----------------------------------------------------------------------*/
  2300. /* v o l u m e I n f o */
  2301. /* */
  2302. /* Get general volume Information. */
  2303. /* */
  2304. /* Parameters: */
  2305. /* vol : Pointer identifying drive */
  2306. /* irHandle : Drive number (0, 1, ...) */
  2307. /* irData : pointer to VolumeInfoRecord */
  2308. /* */
  2309. /* Returns: */
  2310. /* FLStatus : 0 on success, otherwise failed */
  2311. /*----------------------------------------------------------------------*/
  2312. static FLStatus volumeInfo(Volume vol, IOreq FAR2 *ioreq)
  2313. {
  2314. VolumeInfoRecord FAR2 *info = (VolumeInfoRecord FAR2 *)(ioreq->irData);
  2315. #ifdef FL_LOW_LEVEL
  2316. IOreq ioreq2;
  2317. PhysicalInfo physicalInfo;
  2318. char wasLowLevelMounted = 1;
  2319. #endif
  2320. TLInfo tlInfo;
  2321. #ifdef FL_LOW_LEVEL
  2322. dword eraseCyclesPerUnit;
  2323. #endif /* FL_LOW_LEVEL */
  2324. #ifdef FL_LOW_LEVEL
  2325. ioreq2.irHandle = ioreq->irHandle;
  2326. if (!(vol.flags & VOLUME_LOW_LVL_MOUNTED)) {
  2327. checkStatus(mountLowLevel(&vol));
  2328. wasLowLevelMounted = 0;
  2329. }
  2330. ioreq2.irData = &physicalInfo;
  2331. checkStatus(getPhysicalInfo(&vol, &ioreq2));
  2332. info->flashType = physicalInfo.type;
  2333. info->physicalUnitSize = (unsigned short)physicalInfo.unitSize;
  2334. info->physicalSize = physicalInfo.mediaSize;
  2335. info->DOCType = physicalInfo.mediaType;
  2336. #endif /* FL_LOW_LEVEL */
  2337. tffsset(info->driverVer,0,sizeof(info->driverVer));
  2338. tffsset(info->OSAKVer,0,sizeof(info->OSAKVer));
  2339. tffscpy(info->driverVer,driverVersion,
  2340. TFFSMIN(sizeof(info->driverVer),sizeof(driverVersion)));
  2341. tffscpy(info->OSAKVer,OSAKVersion,
  2342. TFFSMIN(sizeof(info->OSAKVer),sizeof(OSAKVersion)));
  2343. checkStatus(socketInfo(&vol, &(info->baseAddress)));
  2344. checkStatus(vol.tl.getTLInfo(vol.tl.rec,&tlInfo));
  2345. info->logicalSectors = tlInfo.sectorsInVolume;
  2346. info->bootAreaSize = tlInfo.bootAreaSize;
  2347. #ifdef ABS_READ_WRITE
  2348. flBuildGeometry( tlInfo.sectorsInVolume,
  2349. (dword FAR2 *)&(info->cylinders),
  2350. (dword FAR2 *)&(info->heads),
  2351. (dword FAR2 *)&(info->sectors),FALSE);
  2352. #endif /* ABS_READ_WRITE */
  2353. #ifdef FL_LOW_LEVEL
  2354. eraseCyclesPerUnit = vol.flash->maxEraseCycles;
  2355. info->lifeTime = (char)(((tlInfo.eraseCycles /
  2356. (eraseCyclesPerUnit * (physicalInfo.mediaSize / physicalInfo.unitSize)))
  2357. % 10) + 1);
  2358. if(!wasLowLevelMounted)
  2359. dismountLowLevel(&vol);
  2360. #endif /* FL_LOW_LEVEL */
  2361. return flOK;
  2362. }
  2363. /*----------------------------------------------------------------------*/
  2364. /* b d C a l l */
  2365. /* */
  2366. /* Common entry-point to all file-system functions. Macros are */
  2367. /* to call individual function, which are separately described below. */
  2368. /* */
  2369. /* Parameters: */
  2370. /* function : file-system function code (listed below) */
  2371. /* ioreq : IOreq structure */
  2372. /* */
  2373. /* Returns: */
  2374. /* FLStatus : 0 on success, otherwise failed */
  2375. /*----------------------------------------------------------------------*/
  2376. FLStatus NAMING_CONVENTION bdCall(FLFunctionNo functionNo, IOreq FAR2 *ioreq)
  2377. {
  2378. Volume vol = NULL;
  2379. FLStatus status;
  2380. byte volNo;
  2381. #if defined(FILES) && FILES>0
  2382. File *file;
  2383. #endif
  2384. byte socket = FL_GET_SOCKET_FROM_HANDLE(ioreq);
  2385. byte partition = FL_GET_PARTITION_FROM_HANDLE(ioreq);
  2386. byte curPartitionForEnvVars;
  2387. /***********************************************/
  2388. /*** ***/
  2389. /*** find the volume record to work on ***/
  2390. /*** ***/
  2391. /***********************************************/
  2392. if (initDone == FALSE)
  2393. checkStatus(flInit());
  2394. /** ori - We are not taking mutex befre cheking fileTable */
  2395. /**************************************/
  2396. /* working with open files operations */
  2397. /**************************************/
  2398. #if defined(FILES) && FILES>0
  2399. /* Verify file handle if applicable */
  2400. if ((functionNo < INDEX_OPENFILES_END) &&
  2401. ((functionNo != FL_FIND_FILE)||(ioreq->irFlags & FIND_BY_HANDLE)))
  2402. {
  2403. if ((ioreq->irHandle < FILES) &&
  2404. (fileTable[ioreq->irHandle].flags & FILE_IS_OPEN))
  2405. {
  2406. file = fileTable + ioreq->irHandle;
  2407. pVol = file->fileVol;
  2408. socket = vol.tl.socketNo;
  2409. partition = vol.tl.partitionNo;
  2410. }
  2411. else
  2412. {
  2413. return flBadFileHandle;
  2414. }
  2415. }
  2416. #endif /* FILES>0 */
  2417. /* Set environment variable current partition. */
  2418. curPartitionForEnvVars = partition;
  2419. /****************************************************/
  2420. /* None files operations are divided into 3 groups: */
  2421. /* 1. Uses the specific partition volume record. */
  2422. /* 2. Must be called with partition number 0. */
  2423. /* 3. Must use partition number 0 and ignore */
  2424. /* the given partition (binary operations). */
  2425. /****************************************************/
  2426. if (pVol == NULL) /* irHandle is drive no. */
  2427. {
  2428. /* Handle sanity check */
  2429. if ((socket >= noOfSockets) ||
  2430. (partition >= MAX_TL_PARTITIONS))
  2431. return flBadDriveHandle;
  2432. volNo = handleConversionTable[socket][partition];
  2433. /* Some operation must not be checked ONLY for socket sanity */
  2434. if((functionNo < INDEX_BINARY_END) && /* Group 3 */
  2435. (functionNo > INDEX_BINARY_START))
  2436. {
  2437. volNo = socket;
  2438. /* Binary partitions are numbered after BDTL partitions */
  2439. curPartitionForEnvVars = (byte)(MAX_TL_PARTITIONS+partition);
  2440. }
  2441. /* The rest must be checked for socket and volume sanity */
  2442. else
  2443. {
  2444. if (volNo == INVALID_VOLUME_NUMBER) /* Group 1 + 2 */
  2445. return flBadDriveHandle;
  2446. /* Some operation must be called with partition 0 */
  2447. if ((functionNo > INDEX_NEED_PARTITION_0_START) && /* Group 2 */
  2448. (functionNo < INDEX_NEED_PARTITION_0_END))
  2449. {
  2450. if(partition != 0)
  2451. {
  2452. return flBadDriveHandle;
  2453. }
  2454. else /* Use general verify write environement variable */
  2455. {
  2456. curPartitionForEnvVars = (MAX_TL_PARTITIONS<<1)-1;
  2457. }
  2458. }
  2459. }
  2460. pVol = &vols[volNo];
  2461. }
  2462. /********************************************************************/
  2463. /*** ***/
  2464. /*** Volume record has been found. Now verify that the volume ***/
  2465. /*** record is ready for the specific operation. ***/
  2466. /*** ***/
  2467. /********************************************************************/
  2468. status = setBusy(&vol,FL_ON,curPartitionForEnvVars); /* Let everyone know we are here */
  2469. /*******************************/
  2470. /* Verify S/W write protection */
  2471. /*******************************/
  2472. #if defined(WRITE_PROTECTION)&& !defined(FL_READ_ONLY)
  2473. if(vol.flags&VOLUME_WRITE_PROTECTED)
  2474. if(
  2475. #if defined(FILES) && FILES>0
  2476. ((functionNo > INDEX_WRITE_FILE_START) &&
  2477. (functionNo < FL_LAST_FAT_FUNCTION)) ||
  2478. #endif /* FILES > 0 */
  2479. #ifdef FORMAT_VOLUME
  2480. (functionNo==BD_FORMAT_VOLUME) ||
  2481. (functionNo==BD_FORMAT_PHYSICAL_DRIVE) ||
  2482. (functionNo==BD_FORMAT_LOGICAL_DRIVE) ||
  2483. #endif /* FORMAT_VOLUME */
  2484. #ifdef WRITE_EXB_IMAGE
  2485. (functionNo==FL_PLACE_EXB) ||
  2486. #endif /* WRITE_EXB_IMAGE */
  2487. (functionNo==FL_DEFRAGMENT_VOLUME) ||
  2488. #ifdef ABS_READ_WRITE
  2489. (functionNo==FL_ABS_WRITE) ||
  2490. (functionNo==FL_ABS_DELETE) ||
  2491. #endif /* ABS_READ_WRITE */
  2492. #ifdef FL_LOW_LEVEL
  2493. (functionNo==FL_PHYSICAL_WRITE) ||
  2494. (functionNo==FL_PHYSICAL_ERASE) ||
  2495. #endif /* FL_LOW_LEVEL */
  2496. #ifdef VERIFY_VOLUME
  2497. (functionNo==FL_VERIFY_VOLUME) ||
  2498. #endif /* VERIFY_VOLUME */
  2499. 0)
  2500. {
  2501. status = flWriteProtect;
  2502. goto flCallExit;
  2503. }
  2504. #endif /* WRITE_PROTECTION && !FL_READ_ONLY */
  2505. /***********************************************/
  2506. /* Binary partition operations */
  2507. /* Low level mount and direct call the routine */
  2508. /***********************************************/
  2509. #ifdef BDK_ACCESS
  2510. if ((functionNo > INDEX_BINARY_START) &&
  2511. (functionNo < INDEX_BINARY_END ) )
  2512. {
  2513. #ifdef WRITE_EXB_IMAGE
  2514. if ((functionNo != FL_BINARY_PROTECTION_INSERT_KEY) &&
  2515. (functionNo != FL_BINARY_PROTECTION_REMOVE_KEY))
  2516. vol.moduleNo = INVALID_MODULE_NO; /* Stop place EXB operation */
  2517. #endif
  2518. /* Mount flash and call binary module to proccess request */
  2519. if (!(pVol->flags & VOLUME_LOW_LVL_MOUNTED))
  2520. status = mountLowLevel(&vol);
  2521. if (status == flOK)
  2522. status = bdkCall(functionNo,ioreq,pVol->flash);
  2523. goto flCallExit;
  2524. }
  2525. #endif /* BDK_ACCESS */
  2526. /***********************************/
  2527. /* None binary routine */
  2528. /* Nag about mounting if necessary */
  2529. /***********************************/
  2530. switch (functionNo) {
  2531. #if FILES > 0
  2532. case FL_LAST_FAT_FUNCTION:
  2533. status = flBadFunction;
  2534. goto flCallExit;
  2535. #endif
  2536. /* Pre mount routine - Make sure the volume is low level disMounted */
  2537. case FL_ABS_MOUNT:
  2538. case FL_MOUNT_VOLUME:
  2539. #ifndef FL_READ_ONLY
  2540. #ifdef FORMAT_VOLUME
  2541. case BD_FORMAT_VOLUME:
  2542. case BD_FORMAT_LOGICAL_DRIVE:
  2543. #endif /* FORMAT_VOLUME */
  2544. #endif /* FL_READ_ONLY */
  2545. #ifdef FL_LOW_LEVEL
  2546. if (vol.flags & VOLUME_LOW_LVL_MOUNTED)
  2547. dismountLowLevel(&vol); /* mutual exclusive mounting */
  2548. #endif /* FL_LOW_LEVEL */
  2549. break;
  2550. /* Physical operation must have the device low level (MTD) mounted */
  2551. /* Do not need any special operation */
  2552. case FL_UPDATE_SOCKET_PARAMS:
  2553. case FL_COUNT_VOLUMES:
  2554. #if (defined(FORMAT_VOLUME) && !defined(FL_READ_ONLY))
  2555. case FL_WRITE_BBT:
  2556. #endif
  2557. #ifdef HW_PROTECTION
  2558. case FL_PROTECTION_GET_TYPE:
  2559. case FL_PROTECTION_REMOVE_KEY:
  2560. case FL_PROTECTION_INSERT_KEY:
  2561. #ifndef FL_READ_ONLY
  2562. case FL_PROTECTION_SET_LOCK:
  2563. case FL_PROTECTION_CHANGE_KEY:
  2564. case FL_PROTECTION_CHANGE_TYPE:
  2565. #endif /* FL_READ_ONLY */
  2566. #endif /* HW_PROTECTION */
  2567. #ifdef QUICK_MOUNT_FEATURE
  2568. case FL_CLEAR_QUICK_MOUNT_INFO:
  2569. #endif /* QUICK_MOUNT_FEATURE */
  2570. break;
  2571. /* MTD must be mounted first */
  2572. #ifdef FL_LOW_LEVEL
  2573. /* Some physical operation must not be done while abs mounted */
  2574. case FL_GET_PHYSICAL_INFO:
  2575. case FL_PHYSICAL_READ:
  2576. #ifndef FL_READ_ONLY
  2577. case FL_PHYSICAL_WRITE:
  2578. case FL_PHYSICAL_ERASE:
  2579. #endif /* FL_READ_ONLY */
  2580. #ifndef BDK_ACCESS
  2581. #ifdef MULTI_DOC
  2582. #ifdef ENVIRONMENT_VARS
  2583. if (flUseMultiDoc == FL_ON)
  2584. #endif
  2585. {
  2586. volNo = handleConversionTable[0][0];
  2587. if ((volNo != INVALID_VOLUME_NUMBER) &&
  2588. (pVol[volNo].flags & VOLUME_ABS_MOUNTED))
  2589. #else
  2590. {
  2591. if(vol.flags & VOLUME_ABS_MOUNTED)
  2592. #endif
  2593. {
  2594. status = flGeneralFailure; /* mutual exclusive mounting */
  2595. goto flCallExit;
  2596. }
  2597. }
  2598. #endif /* BDK_ACCESS */
  2599. #ifndef NO_INQUIRE_CAPABILITIES
  2600. case FL_INQUIRE_CAPABILITIES:
  2601. #endif /* NO_INQUIRE_CAPABILITIES */
  2602. case FL_DEEP_POWER_DOWN_MODE:
  2603. #ifdef HW_OTP
  2604. case FL_OTP_SIZE:
  2605. case FL_OTP_READ:
  2606. #ifndef FL_READ_ONLY
  2607. case FL_OTP_WRITE:
  2608. #endif /* FL_READ_ONLY */
  2609. case FL_UNIQUE_ID:
  2610. case FL_CUSTOMER_ID:
  2611. #endif /* HW_OTP */
  2612. #ifndef NO_IPL_CODE
  2613. case FL_READ_IPL:
  2614. #ifndef FL_READ_ONLY
  2615. case FL_WRITE_IPL:
  2616. #endif /* FL_READ_ONLY */
  2617. #endif /* NO_IPL_CODE */
  2618. #ifndef FL_READ_ONLY
  2619. #ifdef WRITE_EXB_IMAGE
  2620. case FL_PLACE_EXB:
  2621. #endif /* WRITE_EXB_IMAGE */
  2622. #ifdef FORMAT_VOLUME
  2623. case BD_FORMAT_PHYSICAL_DRIVE:
  2624. #endif /* FORMAT_VOLUME */
  2625. #endif /* FL_READ_ONLY */
  2626. if (!(vol.flags & VOLUME_LOW_LVL_MOUNTED))
  2627. {
  2628. status = mountLowLevel(&vol); /* automatic low level mounting */
  2629. }
  2630. else
  2631. {
  2632. status = flOK;
  2633. #ifndef FIXED_MEDIA
  2634. status = flMediaCheck(vol.socket);
  2635. if (status == flDiskChange)
  2636. status = mountLowLevel(&vol); /* card was changed, remount */
  2637. #endif /* FIXED_MEDIA */
  2638. }
  2639. if (status != flOK)
  2640. {
  2641. dismountLowLevel(&vol);
  2642. goto flCallExit;
  2643. }
  2644. break;
  2645. #endif /* FL_LOW_LEVEL */
  2646. /* Check for abs mount */
  2647. default:
  2648. if (vol.flags & VOLUME_ABS_MOUNTED)
  2649. {
  2650. #ifndef NT5PORT
  2651. FLStatus status = flOK;
  2652. #else /*NT5PORT*/
  2653. FLStatus istatus = flOK;
  2654. #endif /*NT5PORT*/
  2655. #ifndef FIXED_MEDIA
  2656. #ifndef NT5PORT
  2657. status = flMediaCheck(vol.socket);
  2658. #else /*NT5PORT*/
  2659. istatus = flMediaCheck(vol.socket);
  2660. #endif /*NT5PORT*/
  2661. #endif /*FIXED_MEDIA*/
  2662. #ifndef NT5PORT
  2663. if (status != flOK)
  2664. #else /*NT5PORT*/
  2665. if (istatus != flOK)
  2666. #endif /*NT5PORT*/
  2667. dismountVolume(&vol);
  2668. }
  2669. if (!(vol.flags & VOLUME_ABS_MOUNTED)
  2670. #if defined(FILES) && FILES>0
  2671. && (functionNo > FL_LAST_FAT_FUNCTION)
  2672. #endif
  2673. )
  2674. {
  2675. status = flNotMounted;
  2676. goto flCallExit;
  2677. }
  2678. /* We know that the tl is abs mounted (except for files )
  2679. now check for high level mounted */
  2680. if (!( vol.flags & VOLUME_MOUNTED ) &&
  2681. ( functionNo != FL_DISMOUNT_VOLUME ) &&
  2682. ( functionNo != FL_CHECK_VOLUME ) &&
  2683. #ifndef FL_READ_ONLY
  2684. ( functionNo != FL_DEFRAGMENT_VOLUME ) &&
  2685. #endif /* FL_READ_ONLY */
  2686. #ifdef ABS_READ_WRITE
  2687. ( functionNo != FL_ABS_READ ) &&
  2688. ( functionNo != FL_ABS_ADDRESS ) &&
  2689. #ifndef FL_READ_ONLY
  2690. ( functionNo != FL_ABS_WRITE ) &&
  2691. ( functionNo != FL_ABS_DELETE ) &&
  2692. #endif /* FL_READ_ONLY */
  2693. #endif /* ABS_READ_WRITE */
  2694. #if (defined(WRITE_PROTECTION) && !defined(FL_READ_ONLY))
  2695. ( functionNo != FL_WRITE_PROTECTION ) &&
  2696. #endif /* WRITE_PROTECTION */
  2697. #ifdef VERIFY_VOLUME
  2698. ( functionNo != FL_VERIFY_VOLUME ) &&
  2699. #endif /* VERIFY_VOLUME */
  2700. ( functionNo != FL_READ_BBT ) &&
  2701. ( functionNo != FL_SECTORS_IN_VOLUME ) &&
  2702. ( functionNo != FL_VOLUME_INFO ))
  2703. {
  2704. status = flNotMounted;
  2705. goto flCallExit;
  2706. }
  2707. }
  2708. /*****************************************************/
  2709. /*** ***/
  2710. /*** The Volume record is already initialized. ***/
  2711. /*** Exceute the proper function. ***/
  2712. /*** ***/
  2713. /*****************************************************/
  2714. switch (functionNo) {
  2715. #if defined(FILES) && FILES > 0
  2716. #ifndef FL_READ_ONLY
  2717. case FL_FLUSH_BUFFER:
  2718. status = flushBuffer(&vol);
  2719. break;
  2720. #endif /* FL_READ_ONLY */
  2721. case FL_OPEN_FILE:
  2722. status = openFile(&vol,ioreq);
  2723. break;
  2724. case FL_CLOSE_FILE:
  2725. status = closeFile(file);
  2726. break;
  2727. #ifndef FL_READ_ONLY
  2728. #ifdef SPLIT_JOIN_FILE
  2729. case FL_JOIN_FILE:
  2730. status = joinFile(file, ioreq);
  2731. break;
  2732. case FL_SPLIT_FILE:
  2733. status = splitFile(file, ioreq);
  2734. break;
  2735. #endif
  2736. #endif /* FL_READ_ONLY */
  2737. case FL_READ_FILE:
  2738. status = readFile(file,ioreq);
  2739. break;
  2740. #ifndef FL_READ_ONLY
  2741. case FL_WRITE_FILE:
  2742. status = writeFile(file,ioreq);
  2743. break;
  2744. #endif
  2745. case FL_SEEK_FILE:
  2746. status = seekFile(file,ioreq);
  2747. break;
  2748. case FL_FIND_FILE:
  2749. status = findFile(&vol,file,ioreq);
  2750. break;
  2751. case FL_FIND_FIRST_FILE:
  2752. status = findFirstFile(&vol,ioreq);
  2753. break;
  2754. case FL_FIND_NEXT_FILE:
  2755. status = findNextFile(file,ioreq);
  2756. break;
  2757. case FL_GET_DISK_INFO:
  2758. status = getDiskInfo(&vol,ioreq);
  2759. break;
  2760. #ifndef FL_READ_ONLY
  2761. case FL_DELETE_FILE:
  2762. status = deleteFile(&vol,ioreq,FALSE);
  2763. break;
  2764. #ifdef RENAME_FILE
  2765. case FL_RENAME_FILE:
  2766. status = renameFile(&vol,ioreq);
  2767. break;
  2768. #endif
  2769. #ifdef SUB_DIRECTORY
  2770. case FL_MAKE_DIR:
  2771. status = makeDir(&vol,ioreq);
  2772. break;
  2773. case FL_REMOVE_DIR:
  2774. status = deleteFile(&vol,ioreq,TRUE);
  2775. break;
  2776. #endif
  2777. #endif /* FL_READ_ONLY */
  2778. #endif /* FILES > 0 */
  2779. case FL_MOUNT_VOLUME:
  2780. status = mountVolume(&vol,&(ioreq->irFlags));
  2781. break;
  2782. case FL_DISMOUNT_VOLUME:
  2783. status = dismountVolume(&vol);
  2784. break;
  2785. case FL_CHECK_VOLUME:
  2786. status = flOK; /* If we got this far */
  2787. break;
  2788. case FL_UPDATE_SOCKET_PARAMS:
  2789. status = updateSocketParameters(flSocketOf(ioreq->irHandle), ioreq->irData);
  2790. break;
  2791. #ifndef NO_READ_BBT_CODE
  2792. case FL_READ_BBT:
  2793. if(vol.tl.readBBT != NULL)
  2794. {
  2795. status = vol.tl.readBBT(vol.tl.rec,(CardAddress FAR1 *)ioreq->irData,
  2796. &(ioreq->irLength),&(ioreq->irFlags));
  2797. }
  2798. else
  2799. {
  2800. status = flFeatureNotSupported;
  2801. }
  2802. break;
  2803. #endif /* NO_READ_BBT_CODE */
  2804. #ifndef FL_READ_ONLY
  2805. #ifdef DEFRAGMENT_VOLUME
  2806. case FL_DEFRAGMENT_VOLUME:
  2807. status = defragmentVolume(&vol,ioreq);
  2808. break;
  2809. #endif /* DEFRAGMENT_VOLUME */
  2810. #if defined (FORMAT_VOLUME) && !defined(FL_READ_ONLY)
  2811. case BD_FORMAT_VOLUME:
  2812. status = bdFormatVolume(&vol,ioreq);
  2813. break;
  2814. case BD_FORMAT_PHYSICAL_DRIVE:
  2815. status = bdFormatPhysicalDrive(&vol,ioreq);
  2816. break;
  2817. case BD_FORMAT_LOGICAL_DRIVE:
  2818. status = bdFormatLogicalDrive(&vol,ioreq);
  2819. break;
  2820. #endif /* FORMAT_VOLUME AND NOT FL_READ_ONLY */
  2821. #ifdef WRITE_EXB_IMAGE
  2822. case FL_PLACE_EXB:
  2823. status = placeExbByBuffer(&vol,(byte FAR1*)ioreq->irData,
  2824. ioreq->irLength,(word)ioreq->irWindowBase ,(word)ioreq->irFlags);
  2825. break;
  2826. #endif /* WRITE_EXB_IMAGE */
  2827. #endif /* FL_READ_ONLY */
  2828. case FL_SECTORS_IN_VOLUME:
  2829. status = sectorsInVolume(&vol,ioreq);
  2830. break;
  2831. case FL_ABS_MOUNT:
  2832. status = absMountVolume(&vol);
  2833. break;
  2834. #ifdef ABS_READ_WRITE
  2835. case FL_ABS_READ:
  2836. status = absRead(&vol,ioreq);
  2837. break;
  2838. #ifndef NO_PHYSICAL_IO
  2839. case FL_ABS_ADDRESS:
  2840. status = absAddress(&vol,ioreq);
  2841. break;
  2842. #endif /* NO_PHYSICAL_IO */
  2843. #ifndef FL_READ_ONLY
  2844. case FL_ABS_DELETE:
  2845. status = absDelete(&vol,ioreq);
  2846. break;
  2847. case FL_ABS_WRITE:
  2848. status = absWrite(&vol,ioreq);
  2849. break;
  2850. #endif /* FL_READ_ONLY */
  2851. case FL_GET_BPB:
  2852. status = getBPB(&vol,ioreq);
  2853. break;
  2854. #ifndef FL_READ_ONLY
  2855. #if (defined(WRITE_PROTECTION) && !defined(FL_READ_ONLY))
  2856. case FL_WRITE_PROTECTION :
  2857. status = writeProtect(&vol,ioreq);
  2858. break;
  2859. #endif /* WRITE_PROTECTION */
  2860. #endif /* FL_READ_ONLY */
  2861. #endif /* ABS_READ_WRITE */
  2862. #ifdef VERIFY_VOLUME
  2863. case FL_VERIFY_VOLUME :
  2864. if ((vol.tl.checkVolume != NULL) &&
  2865. (ioreq->irData == NULL) &&
  2866. (ioreq->irLength == 0 ) )
  2867. {
  2868. status = vol.tl.checkVolume(vol.tl.rec);
  2869. }
  2870. else
  2871. {
  2872. status = flFeatureNotSupported;
  2873. }
  2874. break;
  2875. #endif /* VERIFY_VOLUME */
  2876. #ifdef FL_LOW_LEVEL
  2877. case FL_GET_PHYSICAL_INFO:
  2878. status = getPhysicalInfo(&vol, ioreq);
  2879. break;
  2880. #ifndef NO_PHYSICAL_IO
  2881. case FL_PHYSICAL_READ:
  2882. status = physicalRead(&vol, ioreq);
  2883. break;
  2884. #ifndef FL_READ_ONLY
  2885. case FL_PHYSICAL_WRITE:
  2886. status = physicalWrite(&vol, ioreq);
  2887. break;
  2888. case FL_PHYSICAL_ERASE:
  2889. status = physicalErase(&vol, ioreq);
  2890. break;
  2891. #endif /* FL_READ_ONLY */
  2892. #endif /* NO_PHYSICAL_IO */
  2893. /* direct calls to the MTD */
  2894. #ifdef HW_OTP
  2895. case FL_OTP_SIZE:
  2896. if (vol.flash->otpSize != NULL)
  2897. {
  2898. word tmp = (word)ioreq->irFlags;
  2899. status = vol.flash->otpSize(vol.flash, (dword FAR2 *)(&ioreq->irCount ),
  2900. (dword FAR2 *)(&ioreq->irLength),
  2901. &tmp);
  2902. ioreq->irFlags = (unsigned)tmp;
  2903. }
  2904. else
  2905. {
  2906. status = flFeatureNotSupported;
  2907. }
  2908. break;
  2909. case FL_OTP_READ:
  2910. if (vol.flash->readOTP != NULL)
  2911. {
  2912. status = vol.flash->readOTP(vol.flash, (word)ioreq->irCount,
  2913. ioreq->irData, (word)ioreq->irLength);
  2914. }
  2915. else
  2916. {
  2917. status = flFeatureNotSupported;
  2918. }
  2919. break;
  2920. #ifndef FL_READ_ONLY
  2921. case FL_OTP_WRITE:
  2922. if (vol.flash->writeOTP != NULL)
  2923. {
  2924. status = vol.flash->writeOTP(vol.flash,ioreq->irData,
  2925. (word)ioreq->irLength);
  2926. }
  2927. else
  2928. {
  2929. status = flFeatureNotSupported;
  2930. }
  2931. break;
  2932. #endif /* FL_READ_ONLY */
  2933. case FL_UNIQUE_ID:
  2934. if (vol.flash->getUniqueId !=NULL)
  2935. {
  2936. status = vol.flash->getUniqueId(vol.flash, ioreq->irData);
  2937. }
  2938. else
  2939. {
  2940. status = flFeatureNotSupported;
  2941. }
  2942. break;
  2943. case FL_CUSTOMER_ID:
  2944. if (vol.flash->getUniqueId !=NULL)
  2945. {
  2946. byte buf[UNIQUE_ID_LEN];
  2947. status = vol.flash->getUniqueId (vol.flash, buf);
  2948. tffscpy (ioreq->irData,buf,CUSTOMER_ID_LEN);
  2949. }
  2950. else
  2951. {
  2952. status = flFeatureNotSupported;
  2953. }
  2954. break;
  2955. #endif /* HW_OTP */
  2956. #ifndef NO_IPL_CODE
  2957. #ifndef FL_READ_ONLY
  2958. case FL_WRITE_IPL:
  2959. status = writeIPL(vol.flash,(byte FAR1*)ioreq->irData,ioreq->irLength,ioreq->irFlags);
  2960. break;
  2961. #endif /* FL_READ_ONLY */
  2962. case FL_READ_IPL:
  2963. status = readIPL(vol.flash,(byte FAR1*)ioreq->irData,ioreq->irLength);
  2964. break;
  2965. #endif /* NO_IPL_CODE */
  2966. case FL_DEEP_POWER_DOWN_MODE:
  2967. if (vol.flash->enterDeepPowerDownMode !=NULL)
  2968. {
  2969. vol.flash->enterDeepPowerDownMode(vol.flash,(word)ioreq->irFlags);
  2970. status = flOK;
  2971. }
  2972. else
  2973. {
  2974. status = flFeatureNotSupported;
  2975. }
  2976. break;
  2977. #ifndef NO_INQUIRE_CAPABILITIES
  2978. case FL_INQUIRE_CAPABILITIES:
  2979. inquireCapabilities(vol.flash,(FLCapability FAR2 *)&(ioreq->irLength));
  2980. break;
  2981. #endif /* NO_INQUIRE_CAPABILITIES */
  2982. #endif /* FL_LOW_LEVEL */
  2983. case FL_VOLUME_INFO:
  2984. status = volumeInfo(&vol, ioreq);
  2985. break;
  2986. /* Pre mount routines */
  2987. #if (defined(FORMAT_VOLUME) && !defined(FL_READ_ONLY))
  2988. case FL_WRITE_BBT:
  2989. #ifndef NT5PORT
  2990. checkStatus(dismountPhysicalDrive(socket));
  2991. #else /*NT5PORT*/
  2992. status = dismountPhysicalDrive(socket);
  2993. if (status != flOK)
  2994. goto flCallExit;
  2995. #endif /*NT5PORT*/
  2996. #endif
  2997. case FL_COUNT_VOLUMES:
  2998. #ifdef QUICK_MOUNT_FEATURE
  2999. case FL_CLEAR_QUICK_MOUNT_INFO:
  3000. #endif /* QUICK_MOUNT_FEATURE */
  3001. #ifdef HW_PROTECTION
  3002. case FL_PROTECTION_GET_TYPE:
  3003. case FL_PROTECTION_REMOVE_KEY:
  3004. case FL_PROTECTION_INSERT_KEY:
  3005. #ifndef FL_READ_ONLY
  3006. case FL_PROTECTION_SET_LOCK:
  3007. case FL_PROTECTION_CHANGE_KEY:
  3008. case FL_PROTECTION_CHANGE_TYPE:
  3009. #endif /* FL_READ_ONLY */
  3010. #endif /* HW_PROTECTION */
  3011. status = flPreMount(functionNo , ioreq , vol.flash);
  3012. break;
  3013. default:
  3014. status = flBadFunction;
  3015. }
  3016. #if ((defined(FILES)) && (FILES > 0) && (!defined(FL_READ_ONLY)))
  3017. if (vol.volBuffer.checkPoint)
  3018. {
  3019. FLStatus st = flushBuffer(&vol);
  3020. if (status == flOK)
  3021. status = st;
  3022. }
  3023. #endif
  3024. /*********************************************/
  3025. /* Exit nicely - Release mutex of the socket */
  3026. /*********************************************/
  3027. flCallExit:
  3028. if(status==flOK)
  3029. status = setBusy(&vol,FL_OFF,curPartitionForEnvVars);
  3030. else
  3031. setBusy(&vol,FL_OFF,curPartitionForEnvVars); /* We're leaving */
  3032. return status;
  3033. }
  3034. #if POLLING_INTERVAL != 0
  3035. /*----------------------------------------------------------------------*/
  3036. /* s o c k e t I n t e r v a l R o u t i n e */
  3037. /* */
  3038. /* Routine called by the interval timer to perform periodic socket */
  3039. /* actions and handle the watch-dog timer. */
  3040. /* */
  3041. /* Parameters: */
  3042. /* None */
  3043. /* */
  3044. /*----------------------------------------------------------------------*/
  3045. /* Routine called at time intervals to poll sockets */
  3046. static void socketIntervalRoutine(void)
  3047. {
  3048. unsigned volNo;
  3049. Volume vol = vols;
  3050. flMsecCounter += POLLING_INTERVAL;
  3051. for (volNo = 0; volNo < noOfSockets; volNo++, pVol++)
  3052. if (flTakeMutex(&flMutex[volNo])) {
  3053. #ifdef FL_BACKGROUND
  3054. if (vol.flags & VOLUME_ABS_MOUNTED)
  3055. /* Allow background operation to proceed */
  3056. vol.tl.tlSetBusy(vol.tl.rec,FL_OFF);
  3057. #endif
  3058. flIntervalRoutine(vol.socket);
  3059. flFreeMutex(&flMutex[volNo]);
  3060. }
  3061. }
  3062. #endif /* POLLING_INTERVAL != 0 */
  3063. /*----------------------------------------------------------------------*/
  3064. /* f l I n i t */
  3065. /* */
  3066. /* Initializes the FLite system, sockets and timers. */
  3067. /* */
  3068. /* Calling this function is optional. If it is not called, */
  3069. /* initialization will be done automatically on the first FLite call. */
  3070. /* This function is provided for those applications who want to */
  3071. /* explicitly initialize the system and get an initialization status. */
  3072. /* */
  3073. /* Calling flInit after initialization was done has no effect. */
  3074. /* */
  3075. /* Parameters: */
  3076. /* None */
  3077. /* */
  3078. /* Returns: */
  3079. /* FLStatus : 0 on success, otherwise failed */
  3080. /*----------------------------------------------------------------------*/
  3081. FLStatus flInit(void)
  3082. {
  3083. if (!initDone) {
  3084. FLStatus status;
  3085. unsigned volNo;
  3086. Volume vol = vols;
  3087. IOreq req;
  3088. #ifdef LOG_FILE
  3089. FILE *out;
  3090. out=FL_FOPEN("EDCerr.txt","w");
  3091. FL_FPRINTF(out,"EDC error LOG\n");
  3092. FL_FCLOSE(out);
  3093. #endif /* LOG_FILE */
  3094. flInitGlobalVars();
  3095. #ifdef ENVIRONMENT_VARS
  3096. /* Call users initialization routine for :
  3097. * flUse8Bit,flUseNFTLCache,flUseisRAM
  3098. */
  3099. flSetEnvVar();
  3100. if(flUse8Bit==1)
  3101. {
  3102. tffscpy = flmemcpy;
  3103. tffscmp = flmemcmp;
  3104. tffsset = flmemset;
  3105. }
  3106. else
  3107. {
  3108. tffscpy = flcpy;
  3109. tffsset = flset;
  3110. tffscmp = flcmp;
  3111. }
  3112. #endif /* ENVIRONMENT_VARS */
  3113. /*
  3114. * 1) Mark all the volumes as not used and free to be allocated.
  3115. * 2) Clear passowrd in order to make it invald.
  3116. */
  3117. tffsset(vols,0,sizeof(vols));
  3118. for (volNo = 0,pVol = vols; volNo < VOLUMES; volNo++,pVol++)
  3119. {
  3120. /* The actual number of sockets is not yet known and will be retreaved by
  3121. * flRegisterComponents routine by the socket componenets. For now supply
  3122. * each of the possible sockets with its buffer and socket number.
  3123. */
  3124. if ( volNo < SOCKETS)
  3125. {
  3126. vol.socket = flSocketOf(volNo);
  3127. vol.flash = flFlashOf(volNo);
  3128. tffsset(vol.socket,0,sizeof(FLSocket));
  3129. tffsset(vol.flash,0,sizeof(FLFlash));
  3130. vol.socket->volNo = volNo;
  3131. #ifdef WRITE_EXB_IMAGE
  3132. vol.moduleNo = INVALID_MODULE_NO; /* Ready for exb write operation */
  3133. #endif
  3134. }
  3135. else
  3136. {
  3137. vol.flash = NULL;
  3138. }
  3139. vol.volExecInProgress = NULL;
  3140. }
  3141. #if FILES > 0
  3142. initFS();
  3143. #endif
  3144. flSysfunInit();
  3145. #ifdef FL_BACKGROUND
  3146. flCreateBackground();
  3147. #endif
  3148. /* Initialize variales */
  3149. for (noOfTLs = 0 ;noOfTLs < TLS;noOfTLs++)
  3150. {
  3151. tlTable[noOfTLs].mountRoutine = NULL;
  3152. tlTable[noOfTLs].preMountRoutine = NULL;
  3153. tlTable[noOfTLs].formatRoutine = NULL;
  3154. }
  3155. initDone = TRUE;
  3156. noOfTLs = 0;
  3157. noOfDrives = 0;
  3158. noOfSockets = 0;
  3159. noOfMTDs = 0;
  3160. checkStatus(flRegisterComponents());
  3161. #ifdef COMPRESSION
  3162. checkStatus(flRegisterZIP());
  3163. #endif
  3164. #ifdef MULTI_DOC
  3165. #ifdef ENVIRONMENT_VARS
  3166. if(flUseMultiDoc==FL_ON)
  3167. {
  3168. checkStatus(flRegisterMTL());
  3169. }
  3170. #else
  3171. checkStatus(flRegisterMTL());
  3172. #endif /* ENVIRONMENT_VARS */
  3173. #endif /* MULT_DOC */
  3174. #ifdef BDK_ACCESS
  3175. bdkInit();
  3176. #endif
  3177. checkStatus(flInitSockets());
  3178. #if POLLING_INTERVAL > 0
  3179. checkStatus(flInstallTimer(socketIntervalRoutine,POLLING_INTERVAL));
  3180. #endif
  3181. /*
  3182. * Now that the number of actual sockets is known, create a mutex for
  3183. * each of the systems sockets. Multi-doc uses only 1 mutex.
  3184. */
  3185. #ifdef MULTI_DOC
  3186. if ((noOfSockets)
  3187. #ifdef ENVIRONMENT_VARS
  3188. &&(flUseMultiDoc == FL_ON)
  3189. #endif /* ENVIRONMENT_VARS */
  3190. )
  3191. { /* All sockets use the same mutex */
  3192. if (flCreateMutex(&flMutex[0]) != flOK)
  3193. return flGeneralFailure;
  3194. for (volNo = 0; volNo < noOfSockets ; volNo++)
  3195. {
  3196. vols[volNo].volExecInProgress = &flMutex[0];
  3197. }
  3198. }
  3199. else
  3200. #endif /* MULTI_DOC */
  3201. { /* Each socket uses a diffren mutex */
  3202. for (volNo = 0; volNo < noOfSockets ; volNo++)
  3203. {
  3204. if (flCreateMutex(&flMutex[volNo]) != flOK)
  3205. return flGeneralFailure;
  3206. vols[volNo].volExecInProgress = &flMutex[volNo];
  3207. }
  3208. }
  3209. /* Count the number of volumes on all the systems sockets and
  3210. * initialize conversion table. The table is used to convert a socket
  3211. * and a partition numbers to the correct volume index in the vols record.
  3212. * Partition 0 of each of the sockets will recieve the volume record
  3213. * indexed with the socket number in the vols array. The rest of the
  3214. * volumes will be serialy allocated. New volume records can be allocated
  3215. * By the format routine. The format and the write BBT routines clear all
  3216. * volume records taken by the sockets except for the first.
  3217. *
  3218. * The partition and socket are passed to the TL module using 2 dedicated
  3219. * fields in the TL record. Both those values are also initiaized.
  3220. * All volumes on a specific socket will share the same mutex.
  3221. */
  3222. tffsset(handleConversionTable,INVALID_VOLUME_NUMBER, /* Clear table */
  3223. sizeof(handleConversionTable));
  3224. for (pVol = vols , noOfDrives = (unsigned)noOfSockets , req.irHandle = 0;
  3225. req.irHandle < noOfSockets; req.irHandle++, pVol++)
  3226. {
  3227. /* Initialize partition 0 */
  3228. handleConversionTable[req.irHandle][0] = (byte)req.irHandle;
  3229. vol.tl.socketNo = (byte)req.irHandle;
  3230. vol.tl.partitionNo = 0;
  3231. vol.flags = VOLUME_ACCUPIED;
  3232. /* The rest of the partitions are initialzed only if multi-doc
  3233. * is not active since Multi-doc supports only the first volume
  3234. * of each socket.
  3235. */
  3236. status = flPreMount(FL_COUNT_VOLUMES , &req , vol.flash);
  3237. if (status == flOK)
  3238. {
  3239. vol.volExecInProgress = &flMutex[req.irHandle];
  3240. for(volNo = 1;(volNo < req.irFlags) && (noOfDrives < VOLUMES); volNo++,noOfDrives++)
  3241. {
  3242. handleConversionTable[req.irHandle][volNo] = (byte)noOfDrives;
  3243. vols[noOfDrives].socket = vol.socket;
  3244. vols[noOfDrives].flash = vol.flash;
  3245. vols[noOfDrives].tl.socketNo = (byte)req.irHandle;
  3246. vols[noOfDrives].tl.partitionNo = (byte)volNo;
  3247. vols[noOfDrives].volExecInProgress =
  3248. vol.volExecInProgress;
  3249. vol.flags = VOLUME_ACCUPIED;
  3250. }
  3251. }
  3252. }
  3253. }
  3254. return flOK;
  3255. }
  3256. #ifdef EXIT
  3257. /*----------------------------------------------------------------------*/
  3258. /* f l E x i t */
  3259. /* */
  3260. /* If the application ever exits, flExit should be called before exit. */
  3261. /* flExit flushes all buffers, closes all open files, powers down the */
  3262. /* sockets and removes the interval timer. */
  3263. /* */
  3264. /* Parameters: */
  3265. /* None */
  3266. /* */
  3267. /* Returns: */
  3268. /* Nothing */
  3269. /*----------------------------------------------------------------------*/
  3270. void NAMING_CONVENTION flExit(void)
  3271. {
  3272. unsigned volNo;
  3273. Volume vol = vols;
  3274. FLBoolean mutexTaken = FALSE;
  3275. if(flInit==FALSE)
  3276. return;
  3277. /* Dismount the TL and MTD */
  3278. for (volNo = 0; (volNo < VOLUMES); volNo++,pVol++)
  3279. {
  3280. if ((vol.flags & VOLUME_ACCUPIED) && (setBusy(&vol,FL_ON,vol.tl.partitionNo) == flOK))
  3281. {
  3282. dismountVolume(&vol);
  3283. #ifdef FL_LOW_LEVEL
  3284. dismountLowLevel(&vol);
  3285. #endif
  3286. setBusy(&vol,FL_OFF,vol.tl.partitionNo);
  3287. }
  3288. }
  3289. /* Dismount SOCKET */
  3290. pVol = vols;
  3291. for (volNo = 0; volNo < noOfSockets ; volNo++,pVol++)
  3292. {
  3293. #ifdef MULTI_DOC
  3294. #ifdef ENVIRONMENT_VARS
  3295. if (flUseMultiDoc == FL_ON) /* multi-doc not active */
  3296. #endif /* ENVIRONMENT_VARS */
  3297. if (volNo == 0)
  3298. #endif /* MULTI_DOC */
  3299. mutexTaken = (setBusy(&vol,FL_ON,vol.tl.partitionNo) == flOK) ? TRUE:FALSE;
  3300. if (mutexTaken == TRUE)
  3301. {
  3302. flFreeMutex(execInProgress); /* free the mutex that was taken in setBusy(FL_ON) */
  3303. /* delete mutex protecting FLite volume access */
  3304. flDeleteMutex(execInProgress);
  3305. mutexTaken = FALSE;
  3306. }
  3307. flExitSocket(vol.socket);
  3308. }
  3309. #if POLLING_INTERVAL != 0
  3310. flRemoveTimer();
  3311. #endif
  3312. #ifdef ALLOCTST
  3313. out_data_sz();
  3314. #endif
  3315. initDone = FALSE;
  3316. initGlobalVarsDone = FALSE;
  3317. pVol = NULL;
  3318. }
  3319. #ifdef __BORLANDC__
  3320. #ifdef EXIT
  3321. #pragma exit flExit
  3322. #endif /* EXIT */
  3323. #include <dos.h>
  3324. static int cdecl flBreakExit(void)
  3325. {
  3326. flExit();
  3327. return 0;
  3328. }
  3329. static void setCBreak(void)
  3330. {
  3331. ctrlbrk(flBreakExit);
  3332. }
  3333. #pragma startup setCBreak
  3334. #endif
  3335. #endif