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.

651 lines
29 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/FLSOCKET.C_V $
  3. *
  4. * Rev 1.11 Apr 15 2002 07:37:04 oris
  5. * Added support for VERIFY_ERASED_SECTOR compilation flag.
  6. *
  7. * Rev 1.10 Jan 17 2002 23:02:12 oris
  8. * Removed SINGLE_BUFFER compilation flag
  9. * Made sure buffers are allocated when VERIFY_VOLUME and MTD_RECONSTRUCT_BBT are defined
  10. * Set socket verify write mode according to environment variable
  11. * Verify write buffers are allocated according to define and not runtime variable.
  12. * Added flReadBackBufferOf returning pointer to the readback buffer.
  13. *
  14. * Rev 1.9 Nov 21 2001 11:38:42 oris
  15. * Changed FL_WITH_VERIFY_WRITE and FL_WITHOUT_VERIFY_WRITE to FL_ON and FL_OFF.
  16. *
  17. * Rev 1.8 Nov 08 2001 10:49:30 oris
  18. * Added run-time contorll over verify write mode buffers.
  19. *
  20. * Rev 1.7 Jul 13 2001 01:05:36 oris
  21. * Add allocation for read back buffer.
  22. *
  23. * Rev 1.6 May 16 2001 21:19:16 oris
  24. * Added the FL_ prefix to the following defines: ON , OFF, MALLOC and FREE.
  25. *
  26. * Rev 1.5 Apr 10 2001 16:42:16 oris
  27. * Bug fix - DiskOnChip socket routines clashed with pccards socket
  28. * routines. Moved all DiskOnChip socket routines to docsoc.c.
  29. *
  30. * Rev 1.4 Apr 09 2001 15:09:38 oris
  31. * End with an empty line.
  32. *
  33. * Rev 1.3 Apr 01 2001 07:55:04 oris
  34. * copywrite notice.
  35. * Removed defaultSocketParams routine due to a conflict in windows CE.
  36. * Aliggned left all # directives.
  37. *
  38. * Rev 1.2 Feb 14 2001 01:58:46 oris
  39. * Changed defaultUpdateSocketParameters prototype.
  40. *
  41. * Rev 1.1 Feb 12 2001 12:14:06 oris
  42. * Added support for updateSocketParams (retreave FLSocket record)
  43. *
  44. * Rev 1.0 Feb 04 2001 14:17:16 oris
  45. * Initial revision.
  46. *
  47. */
  48. /***********************************************************************************/
  49. /* M-Systems Confidential */
  50. /* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
  51. /* All Rights Reserved */
  52. /***********************************************************************************/
  53. /* NOTICE OF M-SYSTEMS OEM */
  54. /* SOFTWARE LICENSE AGREEMENT */
  55. /* */
  56. /* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
  57. /* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
  58. /* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
  59. /* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
  60. /* E-MAIL = [email protected] */
  61. /***********************************************************************************/
  62. #include "flsocket.h"
  63. byte noOfSockets = 0; /* No. of drives actually registered */
  64. static FLSocket vols[SOCKETS];
  65. #ifdef FL_MALLOC
  66. static FLBuffer *volBuffers[SOCKETS];
  67. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  68. static byte* readBackBuffer[SOCKETS];
  69. #endif /* VERIFY_WRITE || VERIFY_ERASE || VERIFY_VOLUME || MTD_RECONSTRUCT_BBT || VERIFY_ERASED_SECTOR */
  70. #else
  71. static FLBuffer volBuffers[SOCKETS];
  72. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  73. static byte readBackBuffer[SOCKETS][READ_BACK_BUFFER_SIZE];
  74. #endif /* VERIFY_WRITE || VERIFY_ERASE || VERIFY_VOLUME || MTD_RECONSTRUCT_BBT || VERIFY_ERASED_SECTOR */
  75. #endif /* FL_MALLOC */
  76. /*----------------------------------------------------------------------*/
  77. /* f l S o c k e t N o O f */
  78. /* */
  79. /* Gets the volume no. connected to a socket */
  80. /* */
  81. /* Parameters: */
  82. /* vol : Pointer identifying drive */
  83. /* */
  84. /* Returns: */
  85. /* volume no. of socket */
  86. /*----------------------------------------------------------------------*/
  87. unsigned flSocketNoOf(const FLSocket vol)
  88. {
  89. return vol.volNo;
  90. }
  91. /*----------------------------------------------------------------------*/
  92. /* f l S o c k e t O f */
  93. /* */
  94. /* Gets the socket connected to a volume no. */
  95. /* */
  96. /* Parameters: */
  97. /* volNo : Volume no. for which to get socket */
  98. /* */
  99. /* Returns: */
  100. /* socket of volume no. */
  101. /*----------------------------------------------------------------------*/
  102. FLSocket *flSocketOf(unsigned volNo)
  103. {
  104. return &vols[volNo];
  105. }
  106. /*----------------------------------------------------------------------*/
  107. /* f l B u f f e r O f */
  108. /* */
  109. /* Gets the buffer connected to a volume no. */
  110. /* */
  111. /* Parameters: */
  112. /* volNo : Volume no. for which to get socket */
  113. /* */
  114. /* Returns: */
  115. /* buffer of volume no. */
  116. /*----------------------------------------------------------------------*/
  117. FLBuffer *flBufferOf(unsigned volNo)
  118. {
  119. #ifdef FL_MALLOC
  120. return volBuffers[volNo];
  121. #else
  122. return &volBuffers[volNo];
  123. #endif
  124. }
  125. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT) || defined(VERIFY_VOLUME) || defined (VERIFY_ERASED_SECTOR))
  126. /*----------------------------------------------------------------------*/
  127. /* f l R e a d B a c k B u f f e r O f */
  128. /* */
  129. /* Gets the read back buffer connected to a volume no. */
  130. /* */
  131. /* Parameters: */
  132. /* volNo : Volume no. for which to get socket */
  133. /* */
  134. /* Returns: */
  135. /* buffer of volume no. */
  136. /*----------------------------------------------------------------------*/
  137. byte * flReadBackBufferOf(unsigned volNo)
  138. {
  139. #ifdef FL_MALLOC
  140. return readBackBuffer[volNo];
  141. #else
  142. return &(readBackBuffer[volNo][0]);
  143. #endif
  144. }
  145. #endif /* VERIFY_WRITE || VERIFY_ERASE || VERIFY_VOLUME || MTD_RECONSTRUCT_BBT || VERIFY_ERASED_SECTOR */
  146. /*----------------------------------------------------------------------*/
  147. /* f l W r i t e P r o t e c t e d */
  148. /* */
  149. /* Returns the write-protect state of the media */
  150. /* */
  151. /* Parameters: */
  152. /* vol : Pointer identifying drive */
  153. /* */
  154. /* Returns: */
  155. /* 0 = not write-protected, other = write-protected */
  156. /*----------------------------------------------------------------------*/
  157. FLBoolean flWriteProtected(FLSocket vol)
  158. {
  159. return vol.writeProtected(&vol);
  160. }
  161. #ifndef FIXED_MEDIA
  162. /*----------------------------------------------------------------------*/
  163. /* f l R e s e t C a r d C h a n g e d */
  164. /* */
  165. /* Acknowledges a media-change condition and turns off the condition. */
  166. /* */
  167. /* Parameters: */
  168. /* vol : Pointer identifying drive */
  169. /* */
  170. /*----------------------------------------------------------------------*/
  171. void flResetCardChanged(FLSocket vol)
  172. {
  173. if (vol.getAndClearCardChangeIndicator)
  174. vol.getAndClearCardChangeIndicator(&vol); /* turn off the indicator */
  175. vol.cardChanged = FALSE;
  176. }
  177. /*----------------------------------------------------------------------*/
  178. /* f l M e d i a C h e c k */
  179. /* */
  180. /* Checks the presence and change status of the media */
  181. /* */
  182. /* Parameters: */
  183. /* vol : Pointer identifying drive */
  184. /* */
  185. /* Returns: */
  186. /* flOK -> Media present and not changed */
  187. /* driveNotReady -> Media not present */
  188. /* diskChange -> Media present but changed */
  189. /*----------------------------------------------------------------------*/
  190. FLStatus flMediaCheck(FLSocket vol)
  191. {
  192. if (!vol.cardDetected(&vol)) {
  193. vol.cardChanged = TRUE;
  194. return flDriveNotReady;
  195. }
  196. if (vol.getAndClearCardChangeIndicator &&
  197. vol.getAndClearCardChangeIndicator(&vol))
  198. vol.cardChanged = TRUE;
  199. return vol.cardChanged ? flDiskChange : flOK;
  200. }
  201. #endif
  202. /*----------------------------------------------------------------------*/
  203. /* f l G e t M a p p i n g C o n t e x t */
  204. /* */
  205. /* Returns the currently mapped window page (in 4KB units) */
  206. /* */
  207. /* Parameters: */
  208. /* vol : Pointer identifying drive */
  209. /* */
  210. /* Returns: */
  211. /* unsigned int : Current mapped page no. */
  212. /*----------------------------------------------------------------------*/
  213. unsigned flGetMappingContext(FLSocket vol)
  214. {
  215. return vol.window.currentPage;
  216. }
  217. /*----------------------------------------------------------------------*/
  218. /* f l M a p */
  219. /* */
  220. /* Maps the window to a specified card address and returns a pointer to */
  221. /* that location (some offset within the window). */
  222. /* */
  223. /* NOTE: Addresses over 128M are attribute memory. On PCMCIA adapters, */
  224. /* subtract 128M from the address and map to attribute memory. */
  225. /* */
  226. /* Parameters: */
  227. /* vol : Pointer identifying drive */
  228. /* address : Byte-address on card. NOT necessarily on a */
  229. /* full-window boundary. */
  230. /* If above 128MB, address is in attribute space. */
  231. /* */
  232. /* Returns: */
  233. /* Pointer to a location within the window mapping the address. */
  234. /*----------------------------------------------------------------------*/
  235. void FAR0 *flMap(FLSocket vol, CardAddress address)
  236. {
  237. unsigned pageToMap;
  238. if (vol.window.currentPage == UNDEFINED_MAPPING)
  239. vol.setWindow(&vol);
  240. pageToMap = (unsigned) ((address & -vol.window.size) >> 12);
  241. if (vol.window.currentPage != pageToMap) {
  242. vol.setMappingContext(&vol, pageToMap);
  243. vol.window.currentPage = pageToMap;
  244. vol.remapped = TRUE; /* indicate remapping done */
  245. }
  246. return addToFarPointer(vol.window.base,address & (vol.window.size - 1));
  247. }
  248. /*----------------------------------------------------------------------*/
  249. /* f l S e t W i n d o w B u s W i d t h */
  250. /* */
  251. /* Requests to set the window bus width to 8 or 16 bits. */
  252. /* Whether the request is filled depends on hardware capabilities. */
  253. /* */
  254. /* Parameters: */
  255. /* vol : Pointer identifying drive */
  256. /* width : Requested bus width */
  257. /* */
  258. /*----------------------------------------------------------------------*/
  259. void flSetWindowBusWidth(FLSocket vol, unsigned width)
  260. {
  261. vol.window.busWidth = width;
  262. vol.window.currentPage = UNDEFINED_MAPPING; /* force remapping */
  263. }
  264. /*----------------------------------------------------------------------*/
  265. /* f l S e t W i n d o w S p e e d */
  266. /* */
  267. /* Requests to set the window speed to a specified value. */
  268. /* The window speed is set to a speed equal or slower than requested, */
  269. /* if possible in hardware. */
  270. /* */
  271. /* Parameters: */
  272. /* vol : Pointer identifying drive */
  273. /* nsec : Requested window speed in nanosec. */
  274. /* */
  275. /*----------------------------------------------------------------------*/
  276. void flSetWindowSpeed(FLSocket vol, unsigned nsec)
  277. {
  278. vol.window.speed = nsec;
  279. vol.window.currentPage = UNDEFINED_MAPPING; /* force remapping */
  280. }
  281. /*----------------------------------------------------------------------*/
  282. /* f l S e t W i n d o w S i z e */
  283. /* */
  284. /* Requests to set the window size to a specified value (power of 2). */
  285. /* The window size is set to a size equal or greater than requested, */
  286. /* if possible in hardware. */
  287. /* */
  288. /* Parameters: */
  289. /* vol : Pointer identifying drive */
  290. /* sizeIn4KBUnits : Requested window size in 4 KByte units. */
  291. /* MUST be a power of 2. */
  292. /* */
  293. /*----------------------------------------------------------------------*/
  294. void flSetWindowSize(FLSocket vol, unsigned sizeIn4KBunits)
  295. {
  296. vol.window.size = (long) (sizeIn4KBunits) * 0x1000L;
  297. /* Size may not be possible. Actual size will be set by 'setWindow' */
  298. vol.window.base = physicalToPointer((long) vol.window.baseAddress << 12,
  299. vol.window.size,vol.volNo);
  300. vol.window.currentPage = UNDEFINED_MAPPING; /* force remapping */
  301. }
  302. /*----------------------------------------------------------------------*/
  303. /* f l S o c k e t S e t B u s y */
  304. /* */
  305. /* Notifies the start and end of a file-system operation. */
  306. /* */
  307. /* Parameters: */
  308. /* vol : Pointer identifying drive */
  309. /* state : FL_ON (1) = operation entry */
  310. /* FL_OFF(0) = operation exit */
  311. /* */
  312. /*----------------------------------------------------------------------*/
  313. void flSocketSetBusy(FLSocket vol, FLBoolean state)
  314. {
  315. if (state == FL_OFF)
  316. {
  317. #if POLLING_INTERVAL == 0
  318. /* If we are not polling, activate the interval routine before exit */
  319. flIntervalRoutine(&vol);
  320. #endif
  321. }
  322. else
  323. {
  324. /* Set verify write operation to this socket */
  325. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASED_SECTOR))
  326. if(flVerifyWrite[vol.volNo][vol.curPartition] == FL_ON)
  327. {
  328. vol.verifyWrite = FL_ON;
  329. }
  330. else
  331. {
  332. vol.verifyWrite = FL_OFF;
  333. }
  334. #endif /* VERIFY_WRITE || VERIFY_ERASED_SECTOR */
  335. vol.window.currentPage = UNDEFINED_MAPPING; /* don't assume mapping still valid */
  336. #ifdef FIXED_MEDIA
  337. vol.remapped = TRUE;
  338. #endif /* FIXED_MEDIA */
  339. }
  340. }
  341. /*----------------------------------------------------------------------*/
  342. /* f l N e e d V c c */
  343. /* */
  344. /* Turns on Vcc, if not on already */
  345. /* */
  346. /* Parameters: */
  347. /* vol : Pointer identifying drive */
  348. /* */
  349. /* Returns: */
  350. /* FLStatus : 0 on success, failed otherwise */
  351. /*----------------------------------------------------------------------*/
  352. void flNeedVcc(FLSocket vol)
  353. {
  354. vol.VccUsers++;
  355. if (vol.VccState == PowerOff) {
  356. vol.VccOn(&vol);
  357. if (vol.powerOnCallback)
  358. vol.powerOnCallback(vol.flash);
  359. }
  360. vol.VccState = PowerOn;
  361. }
  362. /*----------------------------------------------------------------------*/
  363. /* f l D o n t N e e d V c c */
  364. /* */
  365. /* Notifies that Vcc is no longer needed, allowing it to be turned off. */
  366. /* */
  367. /* Parameters: */
  368. /* vol : Pointer identifying drive */
  369. /* */
  370. /*----------------------------------------------------------------------*/
  371. void flDontNeedVcc(FLSocket vol)
  372. {
  373. if (vol.VccUsers > 0)
  374. vol.VccUsers--;
  375. }
  376. #ifdef SOCKET_12_VOLTS
  377. /*----------------------------------------------------------------------*/
  378. /* f l N e e d V p p */
  379. /* */
  380. /* Turns on Vpp, if not on already */
  381. /* */
  382. /* Parameters: */
  383. /* vol : Pointer identifying drive */
  384. /* */
  385. /* Returns: */
  386. /* FLStatus : 0 on success, failed otherwise */
  387. /*----------------------------------------------------------------------*/
  388. FLStatus flNeedVpp(FLSocket vol)
  389. {
  390. vol.VppUsers++;
  391. if (vol.VppState == PowerOff)
  392. checkStatus(vol.VppOn(&vol));
  393. vol.VppState = PowerOn;
  394. return flOK;
  395. }
  396. /*----------------------------------------------------------------------*/
  397. /* f l D o n t N e e d V p p */
  398. /* */
  399. /* Notifies that Vpp is no longer needed, allowing it to be turned off. */
  400. /* */
  401. /* Parameters: */
  402. /* vol : Pointer identifying drive */
  403. /* */
  404. /*----------------------------------------------------------------------*/
  405. void flDontNeedVpp(FLSocket vol)
  406. {
  407. if (vol.VppUsers > 0)
  408. vol.VppUsers--;
  409. }
  410. #endif /* SOCKET_12_VOLTS */
  411. /*----------------------------------------------------------------------*/
  412. /* f l S e t P o w e r O n C a l l b a c k */
  413. /* */
  414. /* Sets a routine address to call when powering on the socket. */
  415. /* */
  416. /* Parameters: */
  417. /* vol : Pointer identifying drive */
  418. /* routine : Routine to call when turning on power */
  419. /* flash : Flash object of routine */
  420. /* */
  421. /*----------------------------------------------------------------------*/
  422. void flSetPowerOnCallback(FLSocket vol, void (*routine)(void *flash), void *flash)
  423. {
  424. vol.powerOnCallback = routine;
  425. vol.flash = flash;
  426. }
  427. /*----------------------------------------------------------------------*/
  428. /* f l I n t e r v a l R o u t i n e */
  429. /* */
  430. /* Performs periodic socket actions: Checks card presence, and handles */
  431. /* the Vcc & Vpp turn off mechanisms. */
  432. /* */
  433. /* The routine may be called from the interval timer or sunchronously. */
  434. /* */
  435. /* Parameters: */
  436. /* vol : Pointer identifying drive */
  437. /* */
  438. /*----------------------------------------------------------------------*/
  439. void flIntervalRoutine(FLSocket vol)
  440. {
  441. #ifndef FIXED_MEDIA
  442. if (vol.getAndClearCardChangeIndicator == NULL &&
  443. !vol.cardChanged)
  444. if (!vol.cardDetected(&vol)) /* Check that the card is still there */
  445. vol.cardChanged = TRUE;
  446. #endif
  447. if (vol.VppUsers == 0) {
  448. if (vol.VppState == PowerOn)
  449. vol.VppState = PowerGoingOff;
  450. else if (vol.VppState == PowerGoingOff) {
  451. vol.VppState = PowerOff;
  452. #ifdef SOCKET_12_VOLTS
  453. vol.VppOff(&vol);
  454. #endif
  455. }
  456. if (vol.VccUsers == 0) {
  457. if (vol.VccState == PowerOn)
  458. vol.VccState = PowerGoingOff;
  459. else if (vol.VccState == PowerGoingOff) {
  460. vol.VccState = PowerOff;
  461. vol.VccOff(&vol);
  462. }
  463. }
  464. }
  465. }
  466. /*----------------------------------------------------------------------*/
  467. /* u d a t e S o c k e t P a r a m e t e r s */
  468. /* */
  469. /* Pass socket parameters to the socket interface layer. */
  470. /* This function should be called after the socket parameters (like */
  471. /* size and base) are known. If these parameters are known at */
  472. /* registration time then there is no need to use this function, and */
  473. /* the parameters can be passed to the registration routine. */
  474. /* The structure passed in irData is specific for each socket interface.*/
  475. /* */
  476. /* Note : When using DiskOnChip this routine returns the socekt */
  477. /* parameters instead of initialiaing them. */
  478. /* */
  479. /* Parameters: */
  480. /* vol : Pointer identifying drive */
  481. /* params : Record returning (or sending) the flsocket record */
  482. /* */
  483. /* Returns: */
  484. /* FLStatus : 0 on success */
  485. /*----------------------------------------------------------------------*/
  486. FLStatus updateSocketParameters(FLSocket vol, void FAR1 *params)
  487. {
  488. if (vol.updateSocketParams)
  489. vol.updateSocketParams(&vol, params);
  490. return flOK;
  491. }
  492. #ifdef EXIT
  493. /*----------------------------------------------------------------------*/
  494. /* f l E x i t S o c k e t */
  495. /* */
  496. /* Reset the socket and free resources that were allocated for this */
  497. /* socket. */
  498. /* This function is called when FLite exits. */
  499. /* */
  500. /* Parameters: */
  501. /* vol : Pointer identifying drive */
  502. /* */
  503. /*----------------------------------------------------------------------*/
  504. void flExitSocket(FLSocket vol)
  505. {
  506. flMap(&vol, 0); /* reset the mapping register */
  507. flDontNeedVcc(&vol);
  508. flSocketSetBusy(&vol,FL_OFF);
  509. vol.freeSocket(&vol); /* free allocated resources */
  510. #ifdef FL_MALLOC
  511. FL_FREE(volBuffers[vol.volNo]);
  512. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  513. FL_FREE(readBackBuffer[vol.volNo]);
  514. #endif /* VERIFY_WRITE || VERIFY_ERASE || VERIFY_VOLUME || MTD_RECONSTRUCT_BBT || VERIFY_ERASED_SECTOR */
  515. #endif /* FL_MALLOC */
  516. }
  517. #endif /* EXIT */
  518. /*-----------------------------------------------------------------------*/
  519. /* f l I n i t S o c k e t s */
  520. /* */
  521. /* First call to this module: Initializes the controller and all sockets */
  522. /* */
  523. /* Parameters: */
  524. /* vol : Pointer identifying drive */
  525. /* */
  526. /* Returns: */
  527. /* FLStatus : 0 on success, failed otherwise */
  528. /*---_-------------------------------------------------------------------*/
  529. FLStatus flInitSockets(void)
  530. {
  531. unsigned volNo;
  532. FLSocket vol = vols;
  533. for (volNo = 0; volNo < noOfSockets; volNo++, pVol++) {
  534. flSetWindowSpeed(&vol, 250);
  535. flSetWindowBusWidth(&vol, 16);
  536. flSetWindowSize(&vol, 2); /* make it 8 KBytes */
  537. vol.cardChanged = FALSE;
  538. #ifdef FL_MALLOC
  539. /* allocate buffer for this socket */
  540. volBuffers[volNo] = (FLBuffer *)FL_MALLOC(sizeof(FLBuffer));
  541. if (volBuffers[volNo] == NULL) {
  542. DEBUG_PRINT(("Debug: failed allocating sector buffer.\r\n"));
  543. return flNotEnoughMemory;
  544. }
  545. #if (defined(VERIFY_WRITE) || defined(VERIFY_ERASE) || defined(MTD_RECONSTRUCT_BBT) || defined(VERIFY_VOLUME) || defined(VERIFY_ERASED_SECTOR))
  546. /* allocate read back buffer for this socket */
  547. readBackBuffer[volNo] = (byte *)FL_MALLOC(READ_BACK_BUFFER_SIZE);
  548. if (readBackBuffer[volNo] == NULL) {
  549. DEBUG_PRINT(("Debug: failed allocating readBack buffer.\r\n"));
  550. return flNotEnoughMemory;
  551. }
  552. #endif /* VERIFY_WRITE || VERIFY_ERASE || MTD_READ_BBT || VERIFY_VOLUME || VERIFY_ERASED_SECTOR */
  553. #endif /* FL_MALLOC */
  554. checkStatus(vol.initSocket(&vol));
  555. #ifdef SOCKET_12_VOLTS
  556. vol.VppOff(&vol);
  557. vol.VppState = PowerOff;
  558. vol.VppUsers = 0;
  559. #endif
  560. vol.VccOff(&vol);
  561. vol.VccState = PowerOff;
  562. vol.VccUsers = 0;
  563. }
  564. return flOK;
  565. }