comparison src/cs/drivers/drv_app/ffs/board/tmffs.c @ 0:4e78acac3d88

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