PageRenderTime 682ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/peek-build/m23/csw-system/drv_app/ffs/board/tmffs.c

https://bitbucket.org/C0deMaver1ck/peeklinux
C | 959 lines | 698 code | 136 blank | 125 comment | 89 complexity | 6ceb05781fa1e2295df8052edcb2b2f2 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /******************************************************************************
  2. * Flash File System (ffs)
  3. * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
  4. *
  5. * ffs testmode interface
  6. *
  7. * $Id: tmffs.c 1.51 Thu, 18 Dec 2003 10:50:52 +0100 tsj $
  8. *
  9. ******************************************************************************/
  10. #ifndef TARGET
  11. #include "ffs.cfg"
  12. #endif
  13. #if (TARGET == 1)
  14. #include "etm/etm.h"
  15. #include "etm/etm_api.h"
  16. #include "ffs/board/task.h"
  17. #endif
  18. #include "ffs/board/ffstrace.h"
  19. #include "ffs/board/tmffs.h"
  20. #include "ffs/ffs_api.h"
  21. #include "ffs/pcm.h"
  22. #include "swconfig.cfg"
  23. #include <string.h>
  24. /******************************************************************************
  25. * Local globals for all protocols
  26. ******************************************************************************/
  27. static int32 bufsize, tmpsize;
  28. static uint8 stringsize;
  29. effs_t ffs_initialize(void);
  30. effs_t ffs_exit(void);
  31. #define tmffs_put8(x) *outp++ = x;
  32. #define tmffs_put16(x) *outp++ = (x & 0xff); *outp++ = (x>>8);
  33. #if (TARGET == 1)
  34. int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize);
  35. // Not in use
  36. //#define tmffs_put32(x) tmffs_put16(x); tmffs_put16(x >> 16);
  37. /******************************************************************************
  38. * TM FFS registration to ETM database
  39. *****************************************************************************/
  40. /* Callback function registered in ETM database */
  41. int etm_ffs1_pkt_receive(uint8 *data, int size)
  42. {
  43. int mid;
  44. T_ETM_PKT *pkt;
  45. ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(*, %d)" NL, size));
  46. /* Create TestMode return Packet */
  47. if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) {
  48. ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(): Limit of memory bank reached" NL));
  49. return ETM_NOMEM;
  50. }
  51. // Max packet size for TM3 is 128 bytes
  52. size = tm_ffs(pkt->data, TM3_PACKET_SIZE, data, size);
  53. pkt->size = size;
  54. pkt->status = ETM_OK;
  55. pkt->mid = ETM_FFS1;
  56. etm_pkt_send(pkt);
  57. target_free(pkt);
  58. return ETM_OK;
  59. }
  60. /* Callback function registered in ETM database */
  61. int etm_ffs2_pkt_receive(uint8 *data, int size)
  62. {
  63. int status;
  64. T_ETM_PKT *pkt = NULL;
  65. ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(*, %d)" NL, size));
  66. /* Create TestMode return Packet */
  67. if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) {
  68. ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(): Limit of memory bank reached" NL));
  69. return ETM_NOMEM;
  70. }
  71. status = etm_ffs2(pkt, data, size);
  72. return status;
  73. }
  74. /* Init of FFS in the ETM database */
  75. int etm_ffs_init(void)
  76. {
  77. int status;
  78. status = etm_register("FFS1", ETM_FFS1, 0, 0, etm_ffs1_pkt_receive);
  79. status = etm_register("FFS2", ETM_FFS2, 0, 0, etm_ffs2_pkt_receive);
  80. return status;
  81. }
  82. #endif // (TARGET == 1)
  83. /******************************************************************************
  84. * FFS1 Protocol
  85. ******************************************************************************/
  86. #ifndef TMFFS1
  87. int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize)
  88. {
  89. return -1; // FIXME handle error better
  90. }
  91. // Note these functions must be presented because ffs_query() use them but
  92. // they are only valid if FFS1_PROTOCOL is used.
  93. int tmffs_bufsize(void)
  94. {
  95. return EFFS_NOSYS;
  96. }
  97. unsigned char *tmffs_bufaddr(void)
  98. {
  99. return 0;
  100. }
  101. #else
  102. #define TMFFS1_BUFFER_SIZE 8192
  103. #define TMFFS1_STRING_SIZE 127
  104. /******************************************************************************
  105. * Macros
  106. ******************************************************************************/
  107. #define tmffs1_putdata(outp, src, size) \
  108. tmffs_put8(FPI_DATA); \
  109. tmffs_put16(size); \
  110. memcpy(outp, src, size); \
  111. outp += size;
  112. /******************************************************************************
  113. * Local globals
  114. ******************************************************************************/
  115. static unsigned char buffer[TMFFS1_BUFFER_SIZE];
  116. static bufindex;
  117. static char string[TMFFS1_STRING_SIZE];
  118. static effs_t tm_ffs_overflowck(void)
  119. {
  120. if (bufsize > TMFFS1_BUFFER_SIZE ||
  121. stringsize > TMFFS1_STRING_SIZE)
  122. return EFFS_TOOBIG;
  123. return EFFS_OK;
  124. }
  125. /******************************************************************************
  126. * tm_ffs
  127. ******************************************************************************/
  128. /**
  129. * NOTEME: This has been introduced when the ffs 1MB device limit was
  130. * broken. This made location_t go from uint16 to uint32, messing up
  131. * with PCTM.
  132. *
  133. * This makes the xstat_s look the same to PCTM PC side, though
  134. * location will be forced to 0.
  135. */
  136. void hack_xstat_2_look_like_old_xstat(struct xstat_s *xstat)
  137. {
  138. int i;
  139. char *location;
  140. xstat->location = 0;
  141. for (location = (char *) &(xstat->location) + 2; location <= (char *) &(xstat->sequence); location++)
  142. *location = location[2];
  143. }
  144. // Parse input message and execute function. Then fill output buffer with
  145. // return values from the called function and transmit the message. Return
  146. // number of bytes inserted into output buffer. If return value is negative,
  147. // it represents an error code.
  148. int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize)
  149. {
  150. int error;
  151. tmffs_cid_t fid;
  152. unsigned char *outp_start = outp;
  153. unsigned char *inp_start = inp;
  154. static uint8 i8[2]; static uint16 i8i;
  155. static uint16 i16[2]; static uint16 i16i;
  156. static uint32 i32[2]; static uint16 i32i;
  157. tw(tr(TR_BEGIN, TrTmffs, "TMFFS:\n"));
  158. while((fid = *inp++) != FPI_END)
  159. {
  160. switch(fid)
  161. {
  162. /**********************************************************
  163. * Generic Protocol Functions
  164. **********************************************************/
  165. case FPI_BEGIN:
  166. // for (i8i = 0; i8i < TMFFS1_STRING_SIZE; i8i++) // DEBUG
  167. // string[i8i] = '#';
  168. // for (i8i = 0; i8i < TMFFS1_BUFFER_SIZE; i8i++) // DEBUG
  169. // buffer[i8i] = '$';
  170. i8i = i16i = i32i = bufsize = stringsize = 0;
  171. bufindex = 0;
  172. i8[0] = i8[1] = 0;
  173. i16[0] = i16[1] = 0;
  174. i32[0] = i32[1] = 0;
  175. string[0] = buffer[0] = 0;
  176. tw(tr(TR_FUNC, TrTmffs, "FPI_BEGIN\n"));
  177. ttw(ttr(TTrTmffs, "tm1" NL));
  178. break;
  179. case FPI_TMFFS_VERSION:
  180. // NULL -> UINT16
  181. tmffs_put16(TMFFS1_VERSION);
  182. break;
  183. case FPI_INT8:
  184. i8[i8i++] = inp[0]; inp += 1;
  185. tw(tr(TR_FUNC, TrTmffs, "FPI_INT8(%d/0x%x)\n",
  186. i8[i8i-1], i8[i8i-1]));
  187. ttw(ttr(TTrTmffs, "tm_i8" NL));
  188. break;
  189. case FPI_INT16:
  190. i16[i16i++] = (inp[0]) | (inp[1] << 8); inp += 2;
  191. tw(tr(TR_FUNC, TrTmffs, "FPI_INT16(%d/0x%x)\n",
  192. i16[i16i-1], i16[i16i-1]));
  193. ttw(ttr(TTrTmffs, "tm_i16" NL));
  194. break;
  195. case FPI_INT32:
  196. i32[i32i++] = inp[0] | (inp[1] << 8)
  197. | (inp[2] << 16) | (inp[3] << 24);
  198. inp += 4;
  199. tw(tr(TR_FUNC, TrTmffs, "FPI_INT32(%d/0x%x)\n",
  200. i32[i32i-1], i32[i32i-1]));
  201. ttw(ttr(TTrTmffs, "tm_i32" NL));
  202. break;
  203. case FPI_BUFFER:
  204. bufsize = inp[0] | (inp[1] << 8); inp += 2;
  205. tw(tr(TR_FUNC, TrTmffs, "FPI_BUFFER(%d)\n", bufsize));
  206. ttw(ttr(TTrTmffs, "tm_buf" NL));
  207. break;
  208. case FPI_DATA:
  209. bufsize = inp[0] | (inp[1] << 8); inp += 2;
  210. memcpy(buffer, inp, bufsize); inp += bufsize;
  211. tw(tr(TR_FUNC, TrTmffs, "FPI_DATA(%d)\n", bufsize));
  212. ttw(ttr(TTrTmffs, "tm_data" NL));
  213. break;
  214. case FPI_STRBUF:
  215. // string buffer size MUST include null-terminator!
  216. stringsize = inp[0]; inp += 1;
  217. tw(tr(TR_FUNC, TrTmffs, "FPI_STRBUF(%d)\n", stringsize));
  218. ttw(ttr(TTrTmffs, "tm_sbuf" NL));
  219. break;
  220. case FPI_STRING:
  221. // stringsize MUST include null-terminator!
  222. // <INT8>, <BYTES> -> NULL (or ERROR)
  223. stringsize = inp[0]; inp += 1;
  224. if (stringsize <= TMFFS1_STRING_SIZE)
  225. memcpy(string, inp, stringsize);
  226. inp += stringsize;
  227. tw(tr(TR_FUNC, TrTmffs, "FPI_STRING(%d,'%s')\n",
  228. stringsize, string));
  229. ttw(ttr(TTrTmffs, "tm_s" NL));
  230. break;
  231. case FPI_BUFREAD:
  232. // <INT16> -> DATA
  233. tmpsize = inp[0] | (inp[1] << 8); inp += 2;
  234. tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_READ(%d)\n", tmpsize));
  235. tmffs1_putdata(outp, &buffer[bufindex], tmpsize);
  236. bufindex += tmpsize;
  237. ttw(ttr(TTrTmffs, "tm_bufrd" NL));
  238. break;
  239. case FPI_BUFWRITE:
  240. // <INT16>, <BYTES> -> NULL (or ERROR)
  241. tmpsize = inp[0] | (inp[1] << 8); inp += 2;
  242. tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_WRITE(%d)\n", tmpsize));
  243. if (bufsize + tmpsize <= TMFFS1_BUFFER_SIZE)
  244. memcpy(&buffer[bufsize], inp, tmpsize);
  245. inp += tmpsize;
  246. bufsize += tmpsize;
  247. ttw(ttr(TTrTmffs, "tm_bufwr" NL));
  248. break;
  249. case FPI_BUFSET:
  250. bufindex = inp[0] | (inp[1] << 8); inp += 2;
  251. tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_SET(%d)\n", bufindex));
  252. ttw(ttr(TTrTmffs, "tm_bufset" NL));
  253. break;
  254. /**********************************************************
  255. * FFS Functions
  256. **********************************************************/
  257. case FPI_PREFORMAT:
  258. // NULL -> ERROR
  259. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  260. error = ffs_preformat_nb(i16[0], 0);
  261. if (error > 0)
  262. error = 0; // ignore request id
  263. tmffs_put8(error);
  264. tw(tr(TR_FUNC, TrTmffs, "FPI_PREFORMAT(0x%x)\n", i16[0]));
  265. ttw(ttr(TTrTmffs, "tm_pfmt" NL));
  266. break;
  267. case FPI_FORMAT:
  268. // STRING -> ERROR
  269. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  270. error = ffs_format_nb(&string[0], i16[0], 0);
  271. if (error > 0)
  272. error = 0; // ignore request id
  273. tmffs_put8(error);
  274. tw(tr(TR_FUNC, TrTmffs, "FPI_FORMAT(0x%x)\n", i16[0]));
  275. ttw(ttr(TTrTmffs, "tm_fmt" NL));
  276. break;
  277. case FPI_FCREATE:
  278. // STRING, DATA -> ERROR
  279. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  280. error = ffs_file_write_nb(string, buffer, bufsize,
  281. FFS_O_CREATE | FFS_O_EXCL, 0);
  282. if (error > 0)
  283. error = 0; // ignore request id
  284. tmffs_put8(error);
  285. tw(tr(TR_FUNC, TrTmffs, "FPI_FCREATE('%s', 0x%x, %d/0x%x)\n",
  286. string, buffer, bufsize, bufsize));
  287. ttw(ttr(TTrTmffs, "tm_fcr" NL));
  288. break;
  289. case FPI_FUPDATE:
  290. // STRING, DATA -> ERROR
  291. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  292. error = ffs_file_write_nb(string, buffer, bufsize, FFS_O_TRUNC, 0);
  293. if (error > 0)
  294. error = 0; // ignore request id
  295. tmffs_put8(error);
  296. tw(tr(TR_FUNC, TrTmffs, "FPI_FUPDATE('%s', 0x%x, %d/0x%x)\n",
  297. string, buffer, bufsize, bufsize));
  298. ttw(ttr(TTrTmffs, "tm_fup" NL));
  299. break;
  300. case FPI_FWRITE:
  301. // STRING, DATA -> ERROR
  302. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  303. error = ffs_file_write_nb(string, buffer, bufsize,
  304. FFS_O_CREATE | FFS_O_TRUNC, 0);
  305. if (error > 0)
  306. error = 0; // ignore request id
  307. tmffs_put8(error);
  308. tw(tr(TR_FUNC, TrTmffs, "FPI_FWRITE('%s', 0x%x, %d/0x%x)\n",
  309. string, buffer, bufsize, bufsize));
  310. ttw(ttr(TTrTmffs, "tm_fwr" NL));
  311. break;
  312. case FPI_FREAD:
  313. // STRING, BUFFER -> ERROR
  314. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  315. error = ffs_file_read(string, buffer, TMFFS1_BUFFER_SIZE);
  316. // Because a 32-bit integer is returned, we have to saturate it
  317. // into an 8-bit value.
  318. if (error >= 0)
  319. error = 0;
  320. tmffs_put8(error);
  321. tw(tr(TR_FUNC, TrTmffs, "FPI_FREAD('%s', 0x%x, %d/0x%x)\n",
  322. string, buffer, bufsize, bufsize));
  323. ttw(ttr(TTrTmffs, "tm_frd" NL));
  324. break;
  325. case FPI_REMOVE:
  326. // STRING -> ERROR
  327. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  328. error = ffs_remove_nb(string, 0);
  329. if (error > 0)
  330. error = 0; // ignore request id
  331. tmffs_put8(error);
  332. tw(tr(TR_FUNC, TrTmffs, "FPI_REMOVE()\n"));
  333. ttw(ttr(TTrTmffs, "tm_rm" NL));
  334. break;
  335. case FPI_MKDIR:
  336. // STRING -> ERROR
  337. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  338. error = ffs_mkdir_nb(string, 0);
  339. if (error > 0)
  340. error = 0; // ignore request id
  341. tmffs_put8(error);
  342. tw(tr(TR_FUNC, TrTmffs, "FPI_MKDIR()\n"));
  343. ttw(ttr(TTrTmffs, "tm_mkd" NL));
  344. break;
  345. case FPI_OPENDIR:
  346. // STRING, BUFFER -> ERROR, DATA
  347. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  348. error = ffs_opendir(string, (struct dir_s *) buffer);
  349. // Because a 32-bit integer is returned, we have to saturate it
  350. // into an 8-bit value.
  351. if (error >= 0)
  352. error = 0;
  353. tmffs_put8(error);
  354. tmffs1_putdata(outp, buffer, sizeof(struct dir_s));
  355. tw(tr(TR_FUNC, TrTmffs, "FPI_OPENDIR()\n"));
  356. ttw(ttr(TTrTmffs, "tm_od" NL));
  357. break;
  358. case FPI_READDIR:
  359. // DATA, STRBUF -> ERROR, DATA, STRING
  360. string[0] = 0;
  361. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  362. error = ffs_readdir((struct dir_s *) buffer, string, stringsize);
  363. // Saturate error(i) in order to let it fit in type int8.
  364. if (error > 127)
  365. error = 127;
  366. tmffs_put8(error);
  367. tmffs1_putdata(outp, buffer, sizeof(struct dir_s));
  368. stringsize = strlen(string) + 1;
  369. tmffs_put8(FPI_STRING); // put directory entry's name...
  370. tmffs_put8(stringsize);
  371. memcpy(outp, string, stringsize);
  372. outp += stringsize;
  373. tw(tr(TR_FUNC, TrTmffs, "FPI_READDIR()\n"));
  374. ttw(ttr(TTrTmffs, "tm_rdd" NL));
  375. break;
  376. case FPI_STAT:
  377. // STRING, BUFFER -> ERROR, DATA
  378. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  379. error = ffs_stat(&string[0], (struct stat_s *) buffer);
  380. tmffs_put8(error);
  381. tmffs1_putdata(outp, buffer, sizeof(struct stat_s));
  382. tw(tr(TR_FUNC, TrTmffs, "FPI_STAT()\n"));
  383. ttw(ttr(TTrTmffs, "tm_st" NL));
  384. break;
  385. case FPI_LINKSTAT:
  386. // STRING, BUFFER -> ERROR, DATA
  387. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  388. error = ffs_xlstat(&string[0], (struct xstat_s *) buffer);
  389. tmffs_put8(error);
  390. hack_xstat_2_look_like_old_xstat((struct xstat_s *) buffer);
  391. tmffs1_putdata(outp, buffer, sizeof(struct xstat_s) - 2);
  392. tw(tr(TR_FUNC, TrTmffs, "FPI_()\n"));
  393. ttw(ttr(TTrTmffs, "tm_lst" NL));
  394. break;
  395. case FPI_SYMLINK:
  396. // STRING, DATA -> ERROR
  397. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  398. error = ffs_symlink_nb(string, (char *) buffer, 0);
  399. if (error > 0)
  400. error = 0; // ignore request id
  401. tmffs_put8(error);
  402. tw(tr(TR_FUNC, TrTmffs, "FPI_SYMLINK()\n"));
  403. ttw(ttr(TTrTmffs, "tm_sym" NL));
  404. break;
  405. case FPI_READLINK:
  406. // STRING, BUFFER -> ERROR, DATA
  407. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  408. error = ffs_readlink(string, (char *) buffer, TMFFS1_BUFFER_SIZE);
  409. // Because a 32-bit integer is returned, we have to saturate it
  410. // into an 8-bit value.
  411. if (error >= 0)
  412. error = 0;
  413. tmffs_put8(error);
  414. tmffs1_putdata(outp, buffer, bufsize); // put link contents
  415. tw(tr(TR_FUNC, TrTmffs, "FPI_READLINK()\n"));
  416. ttw(ttr(TTrTmffs, "tm_rdl" NL));
  417. break;
  418. case FPI_QUERY:
  419. // INT8 -> ERROR, DATA
  420. error = ffs_query(i8[0], buffer);
  421. tmffs_put8(error);
  422. tmffs1_putdata(outp, buffer, 16);
  423. tw(tr(TR_FUNC, TrTmffs, "FPI_QUERY()\n"));
  424. ttw(ttr(TTrTmffs, "tm_q" NL));
  425. break;
  426. case FPI_FCONTROL:
  427. // STRING INT8 INT32 -> ERROR
  428. if ((error = tm_ffs_overflowck()) == EFFS_OK)
  429. error = ffs_fcontrol_nb(string, i8[0], i32[0], 0);
  430. if (error > 0)
  431. error = 0; // ignore request id
  432. tmffs_put8(error);
  433. tw(tr(TR_FUNC, TrTmffs, "FPI_FCONTROL()\n"));
  434. ttw(ttr(TTrTmffs, "tm_fc" NL));
  435. break;
  436. case FPI_INIT:
  437. // NULL -> ERROR
  438. error =ffs_initialize();
  439. tmffs_put8(error);
  440. tw(tr(TR_FUNC, TrTmffs, "FPI_INIT()\n"));
  441. ttw(ttr(TTrTmffs, "tm_init" NL));
  442. break;
  443. case FPI_EXIT:
  444. // NULL -> ERROR
  445. error = ffs_exit();
  446. tmffs_put8(error);
  447. tw(tr(TR_FUNC, TrTmffs, "FPI_EXIT()\n"));
  448. ttw(ttr(TTrTmffs, "tm_exit" NL));
  449. break;
  450. case FPI_TFFS:
  451. {
  452. // STRING -> ERROR
  453. #if (WITH_TFFS == 1)
  454. extern char ffs_test_string[]; // defined in task.c
  455. memcpy(ffs_test_string, string, stringsize);
  456. tw(tr(TR_FUNC, TrTmffs, "FPI_TFFS()\n"));
  457. ttw(ttr(TTrTmffs, "tm_tffs" NL));
  458. #else
  459. tmffs_put8(EFFS_NOSYS);
  460. #endif
  461. break;
  462. }
  463. default:
  464. tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n"));
  465. ttw(ttr(TTrTmffs, "tm?" NL));
  466. break;
  467. }
  468. // check if we read beyond buffer end
  469. if (inp > inp_start + insize) {
  470. tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n"));
  471. ttw(ttr(TTrTmffs, "tm_fatal" NL));
  472. // NOTEME: We really should reset output buffer and put a return
  473. // code that tells us what went wrong!
  474. return 0;
  475. }
  476. }
  477. tw(tr(TR_END, TrTmffs, ""));
  478. return outp - outp_start;
  479. }
  480. int tmffs_bufsize(void)
  481. {
  482. return TMFFS1_BUFFER_SIZE;
  483. }
  484. unsigned char *tmffs_bufaddr(void)
  485. {
  486. return buffer;
  487. }
  488. #endif // TMFFS1
  489. /******************************************************************************
  490. * FFS2 protocol
  491. ******************************************************************************/
  492. #ifndef TMFFS2
  493. #if (TARGET == 1)
  494. int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize)
  495. {
  496. int error;
  497. tw(tr(TR_BEGIN, TrTmffs, "FFS2 protocol not represented in target\n"));
  498. error = -1; // FIXME other error?
  499. #if 0 // Note we can only use this if etm is in target
  500. // We return a packet instead of waiting for timeout.
  501. pkt->size = 0;
  502. pkt->status = -error;
  503. pkt->mid = ETM_FFS2;
  504. etm_pkt_send(pkt);
  505. #endif
  506. target_free(pkt);
  507. tw(tr(TR_END, TrTmffs, ""));
  508. return error;
  509. }
  510. #endif // (TARGET == 1)
  511. #else
  512. #define TMFFS_BUFFER_SIZE 256 // FIXME change to packet size
  513. #define TMFFS_STRING_SIZE 127
  514. /******************************************************************************
  515. * Macros
  516. ******************************************************************************/
  517. #define tmffs_get8() inp[0]; inp += 1;
  518. #define tmffs_get16() (inp[0]) | (inp[1] << 8); inp += 2;
  519. #define tmffs_get32() inp[0] | (inp[1] << 8) | (inp[2] << 16)\
  520. | (inp[3] << 24); inp += 4;
  521. #define tmffs_getdata() bufsize = inp[0]; inp += 1; \
  522. memcpy(buffer, inp, bufsize); inp += bufsize;
  523. /******************************************************************************
  524. * Helper function
  525. ******************************************************************************/
  526. // If size is less than zero it is because of a error and we dont have to put any
  527. // data if size is returned in status.
  528. int tmffs_putdata(unsigned char **buf, unsigned char *src, int size)
  529. {
  530. unsigned char *p = *buf;
  531. if (size > 0) {
  532. *p++ = size;
  533. memcpy(p, src, size);
  534. *buf += 1 + size;
  535. }
  536. return size;
  537. }
  538. int tmffs_putstring(unsigned char **buf, char *src, int size)
  539. {
  540. unsigned char *p = *buf;
  541. if (size > 0) {
  542. *p++ = size;
  543. memcpy(p, src, size);
  544. *buf += 1 + size;
  545. }
  546. return size;
  547. }
  548. int tmffs_getstring(unsigned char ** buf, char *string)
  549. {
  550. unsigned char *p = *buf;
  551. stringsize = *p++;
  552. if (stringsize > TMFFS_STRING_SIZE)
  553. return EFFS_TOOBIG;
  554. memcpy(string, p, stringsize);
  555. *buf += 1 + stringsize;
  556. return stringsize;
  557. }
  558. #if (RELIANCE_FS==1)
  559. /* Mantain only one open directory at a time */
  560. char is_dir_open = 0;
  561. T_FFS_DIR dir_backup;
  562. #endif
  563. /******************************************************************************
  564. * tm_ffs
  565. ******************************************************************************/
  566. // Parse input message and execute function. Then fill output buffer with
  567. // return values from the called function and transmit the message. Return
  568. // number of bytes inserted into output buffer. If return value is negative,
  569. // it represents an error code.
  570. int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize)
  571. {
  572. tmffs2_cid_t fid;
  573. unsigned char buffer[TMFFS_BUFFER_SIZE];
  574. char string[TMFFS_STRING_SIZE];
  575. unsigned char *outp_start;
  576. unsigned char *inp_start = inp;
  577. unsigned char *outp;
  578. int error = 0, i, fdi, size, param, flags;
  579. uint8 type;
  580. bufsize = stringsize = tmpsize = 0;
  581. tw(tr(TR_BEGIN, TrTmffs, "TmFFS2\n"));
  582. outp_start = outp = pkt->data;
  583. fid = (tmffs2_cid_t)*inp++;
  584. ttw(ttr(TTrTmffs, "etm_ffs2 0x%x" NL, fid));
  585. switch(fid)
  586. {
  587. /**********************************************************
  588. * Generic Protocol Functions
  589. **********************************************************/
  590. case TMFFS_VERSION:
  591. tmffs_put16(TMFFS2_VERSION);
  592. break;
  593. /**********************************************************
  594. * FFS Functions
  595. **********************************************************/
  596. case TMFFS_PREFORMAT:
  597. param = tmffs_get16();
  598. error = ffs_preformat(param);
  599. tw(tr(TR_FUNC, TrTmffs, "TMFFS_PREFORMAT(0x%x)\n", param));
  600. ttw(ttr(TTrTmffs, "tm_pfmt" NL));
  601. break;
  602. case TMFFS_FORMAT:
  603. error = tmffs_getstring(&inp, string);
  604. param = tmffs_get16();
  605. if (error >= 0)
  606. error = ffs_format(&string[0], param);
  607. tw(tr(TR_FUNC, TrTmffs, "TMFFS_FORMAT(0x%x)\n", param));
  608. ttw(ttr(TTrTmffs, "tm_fmt" NL));
  609. break;
  610. case TMFFS_FILE_WRITE:
  611. error = tmffs_getstring(&inp, string);
  612. tmffs_getdata();
  613. flags = tmffs_get8();
  614. if (error >= 0)
  615. error = ffs_file_write(string, buffer, bufsize, flags);
  616. ttw(ttr(TTrTmffs, "tm_fwr" NL));
  617. break;
  618. case TMFFS_FILE_READ:
  619. error = tmffs_getstring(&inp, string);
  620. bufsize = tmffs_get8();
  621. if (error >= 0)
  622. size = ffs_file_read(string, buffer, bufsize);
  623. error = tmffs_putdata(&outp, &buffer[0], size);
  624. tw(tr(TR_FUNC, TrTmffs, "TMFFS_FREAD('%s', 0x%x, %d/0x%x)\n",
  625. string, buffer, bufsize, bufsize));
  626. ttw(ttr(TTrTmffs, "tm_frd" NL));
  627. break;
  628. case TMFFS_REMOVE:
  629. error = tmffs_getstring(&inp, string);
  630. if (error >= 0)
  631. error = ffs_remove(string);
  632. tw(tr(TR_FUNC, TrTmffs, "TMFFS_REMOVE()\n"));
  633. ttw(ttr(TTrTmffs, "tm_rm" NL));
  634. break;
  635. case TMFFS_OPEN:
  636. error = tmffs_getstring(&inp, string);
  637. flags = tmffs_get8();
  638. if (error >= 0)
  639. error = ffs_open(string, flags);
  640. tmffs_put8(error); // fdi
  641. tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPEN('%s', %d)\n", string, flags));
  642. ttw(ttr(TTrTmffs, "tm_open" NL));
  643. break;
  644. case TMFFS_CLOSE:
  645. fdi = tmffs_get8();
  646. error = ffs_close(fdi);
  647. tw(tr(TR_FUNC, TrTmffs, "TMFFS_CLOSE(%d)\n", fdi));
  648. ttw(ttr(TTrTmffs, "tm_close" NL));
  649. break;
  650. case TMFFS_WRITE:
  651. fdi = tmffs_get8();
  652. tmffs_getdata();
  653. error = ffs_write(fdi, buffer, bufsize);
  654. tmffs_put8(error); // put size
  655. tw(tr(TR_FUNC, TrTmffs, "TMFFS_WRITE(%d, %d)\n", fdi, bufsize));
  656. ttw(ttr(TTrTmffs, "tm_write" NL));
  657. break;
  658. case TMFFS_READ:
  659. fdi = tmffs_get8();
  660. size = tmffs_get8();
  661. size = ffs_read(fdi, &buffer[0], size);
  662. error = tmffs_putdata(&outp, &buffer[0], size);
  663. tw(tr(TR_FUNC, TrTmffs, "TMFFS_READ(%d, %d)\n", fdi, size));
  664. ttw(ttr(TTrTmffs, "tm_read" NL));
  665. break;
  666. case TMFFS_MKDIR:
  667. error = tmffs_getstring(&inp, string);
  668. if (error >= 0)
  669. error = ffs_mkdir(string);
  670. tw(tr(TR_FUNC, TrTmffs, "TMFFS_MKDIR()\n"));
  671. ttw(ttr(TTrTmffs, "tm_mkd" NL));
  672. break;
  673. case TMFFS_OPENDIR:
  674. error = tmffs_getstring(&inp, string);
  675. if (error >= 0) {
  676. #if (RELIANCE_FS==1)
  677. if(is_dir_open)
  678. {
  679. /* close the previous directory */
  680. error=ffs_closedir(&dir_backup);
  681. is_dir_open=0;
  682. }
  683. #endif
  684. error = ffs_opendir(string, (struct dir_s *) buffer);
  685. #if (RELIANCE_FS==1)
  686. if(error >= 0)
  687. {
  688. is_dir_open=1; /* Indicate that directory is already opened */
  689. memcpy(&dir_backup,buffer,sizeof(T_FFS_DIR)); /* Keep the backup now */
  690. }
  691. #endif
  692. tmffs_put8(error); // Note: we must put error/number of objects.
  693. }
  694. if (error >= 0)
  695. tmffs_putdata(&outp, buffer, sizeof(struct dir_s));
  696. tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPENDIR()\n"));
  697. ttw(ttr(TTrTmffs, "tm_od" NL));
  698. break;
  699. case TMFFS_READDIR:
  700. tmffs_getdata();
  701. stringsize = tmffs_get8();
  702. error = ffs_readdir((struct dir_s *) buffer, string, stringsize);
  703. #if (RELIANCE_FS==1)
  704. // ignore . and .. folder entries if reliance is being used.
  705. if (strcmp(string, ".") == NULL) {
  706. error = ffs_readdir(((T_FFS_DIR *) buffer), string, stringsize);
  707. }
  708. if (strcmp(string, "..") == NULL) {
  709. error = ffs_readdir(((T_FFS_DIR *) buffer), string, stringsize);
  710. }
  711. #endif
  712. tmffs_put8(error); // Note: we have to return bytes read.
  713. if (error >= 0) {
  714. #if (RELIANCE_FS==1)
  715. if(error == 0 && is_dir_open) /* last entry read */
  716. { /* and backup has some directory opened */
  717. is_dir_open=0; /* Indicate that directory is already opened */
  718. }
  719. #endif
  720. tmffs_putdata(&outp, buffer, sizeof(struct dir_s));
  721. stringsize = strlen(string) + 1;
  722. tmffs_putstring(&outp, string, stringsize);
  723. }
  724. tw(tr(TR_FUNC, TrTmffs, "TMFFS_READDIR()\n"));
  725. ttw(ttr(TTrTmffs, "tm_rdd" NL));
  726. break;
  727. case TMFFS_STAT:
  728. error = tmffs_getstring(&inp, string);
  729. if (error >= 0)
  730. error = ffs_stat(string, (struct stat_s *) buffer);
  731. if (error >= 0)
  732. tmffs_putdata(&outp, buffer, sizeof(struct stat_s));
  733. tw(tr(TR_FUNC, TrTmffs, "TMFFS_STAT()\n"));
  734. ttw(ttr(TTrTmffs, "tm_st" NL));
  735. break;
  736. case TMFFS_XLSTAT:
  737. error = tmffs_getstring(&inp, string);
  738. if (error >= 0)
  739. error = ffs_xlstat(&string[0], (struct xstat_s *) buffer);
  740. if (error >= 0)
  741. tmffs_putdata(&outp, buffer, sizeof(struct xstat_s));
  742. tw(tr(TR_FUNC, TrTmffs, "TMFFS_()\n"));
  743. ttw(ttr(TTrTmffs, "tm_xlst" NL));
  744. break;
  745. case TMFFS_SYMLINK:
  746. error = tmffs_getstring(&inp, string);
  747. tmffs_getdata();
  748. if (error >= 0)
  749. error = ffs_symlink(string, (char *) buffer);
  750. tw(tr(TR_FUNC, TrTmffs, "TMFFS_SYMLINK()\n"));
  751. ttw(ttr(TTrTmffs, "tm_sym" NL));
  752. break;
  753. case TMFFS_READLINK:
  754. error = tmffs_getstring(&inp, string);
  755. tmffs_getdata();
  756. if (error >= 0) {
  757. size = ffs_readlink(string, (char *) buffer, TMFFS_BUFFER_SIZE);
  758. error = tmffs_putdata(&outp, buffer, size); // put link contents
  759. }
  760. tw(tr(TR_FUNC, TrTmffs, "TMFFS_READLINK()\n"));
  761. ttw(ttr(TTrTmffs, "tm_rdl" NL));
  762. break;
  763. case TMFFS_QUERY:
  764. param = tmffs_get8();
  765. error = ffs_query(param, buffer);
  766. if (error >= 0)
  767. tmffs_putdata(&outp, buffer, 16);
  768. tw(tr(TR_FUNC, TrTmffs, "TMFFS_QUERY(%d)\n", param));
  769. ttw(ttr(TTrTmffs, "tm_q" NL));
  770. break;
  771. case TMFFS_FCONTROL:
  772. error = tmffs_getstring(&inp, string);
  773. type = tmffs_get8();
  774. param = tmffs_get32();
  775. if (error >= 0)
  776. error = ffs_fcontrol(string, type, param);
  777. tw(tr(TR_FUNC, TrTmffs, "TMFFS_FCONTROL()\n"));
  778. ttw(ttr(TTrTmffs, "tm_fc" NL));
  779. break;
  780. case TMFFS_TFFS:
  781. {
  782. #if (WITH_TFFS == 1)
  783. extern char ffs_test_string[]; // defined in task.c
  784. error = tmffs_getstring(&inp, string);
  785. memcpy(ffs_test_string, string, stringsize);
  786. tw(tr(TR_FUNC, TrTmffs, "TMFFS_TFFS()\n"));
  787. ttw(ttr(TTrTmffs, "tm_tffs" NL));
  788. tmffs_put8(EFFS_OK);
  789. #else
  790. error=EFFS_NOSYS;
  791. tmffs_put8(error);
  792. #endif
  793. break;
  794. }
  795. default:
  796. error = EFFS_NOSYS;
  797. tmffs_put8(error);
  798. tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n"));
  799. ttw(ttr(TTrTmffs, "tm?" NL));
  800. break;
  801. }
  802. // check if we read beyond buffer end
  803. if (inp > inp_start + insize) {
  804. tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n"));
  805. ttw(ttr(TTrTmffs, "tm_fatal" NL));
  806. ttw(ttr(TTrTmffs, "insize: %d, diff: %d" NL, insize,
  807. inp - (inp_start + insize)));
  808. // NOTEME: We really should reset output buffer and put a return
  809. // code that tells us what went wrong!
  810. error = ETM_PACKET; // FIXME find another error
  811. }
  812. ttw(ttr(TTrTmffs, "error %d" NL, error));
  813. if (error > 0)
  814. error = 0;
  815. pkt->mid = ETM_FFS2;
  816. pkt->size = outp - outp_start;
  817. pkt->status = -error;
  818. etm_pkt_send(pkt);
  819. etm_free(pkt);
  820. tw(tr(TR_END, TrTmffs, ""));
  821. return ETM_OK;
  822. }
  823. #endif // TMFFS2