/peek-build/m23/csw-system/drv_app/ffs/board/tmffs.c
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
- /******************************************************************************
- * Flash File System (ffs)
- * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
- *
- * ffs testmode interface
- *
- * $Id: tmffs.c 1.51 Thu, 18 Dec 2003 10:50:52 +0100 tsj $
- *
- ******************************************************************************/
- #ifndef TARGET
- #include "ffs.cfg"
- #endif
- #if (TARGET == 1)
- #include "etm/etm.h"
- #include "etm/etm_api.h"
- #include "ffs/board/task.h"
- #endif
- #include "ffs/board/ffstrace.h"
- #include "ffs/board/tmffs.h"
- #include "ffs/ffs_api.h"
- #include "ffs/pcm.h"
- #include "swconfig.cfg"
- #include <string.h>
- /******************************************************************************
- * Local globals for all protocols
- ******************************************************************************/
- static int32 bufsize, tmpsize;
- static uint8 stringsize;
- effs_t ffs_initialize(void);
- effs_t ffs_exit(void);
- #define tmffs_put8(x) *outp++ = x;
- #define tmffs_put16(x) *outp++ = (x & 0xff); *outp++ = (x>>8);
- #if (TARGET == 1)
- int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize);
- // Not in use
- //#define tmffs_put32(x) tmffs_put16(x); tmffs_put16(x >> 16);
- /******************************************************************************
- * TM FFS registration to ETM database
- *****************************************************************************/
- /* Callback function registered in ETM database */
- int etm_ffs1_pkt_receive(uint8 *data, int size)
- {
- int mid;
- T_ETM_PKT *pkt;
- ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(*, %d)" NL, size));
-
- /* Create TestMode return Packet */
- if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) {
- ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(): Limit of memory bank reached" NL));
- return ETM_NOMEM;
- }
-
- // Max packet size for TM3 is 128 bytes
- size = tm_ffs(pkt->data, TM3_PACKET_SIZE, data, size);
- pkt->size = size;
- pkt->status = ETM_OK;
- pkt->mid = ETM_FFS1;
-
- etm_pkt_send(pkt);
- target_free(pkt);
- return ETM_OK;
- }
- /* Callback function registered in ETM database */
- int etm_ffs2_pkt_receive(uint8 *data, int size)
- {
- int status;
- T_ETM_PKT *pkt = NULL;
- ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(*, %d)" NL, size));
- /* Create TestMode return Packet */
- if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) {
- ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(): Limit of memory bank reached" NL));
- return ETM_NOMEM;
- }
-
- status = etm_ffs2(pkt, data, size);
- return status;
- }
- /* Init of FFS in the ETM database */
- int etm_ffs_init(void)
- {
- int status;
-
- status = etm_register("FFS1", ETM_FFS1, 0, 0, etm_ffs1_pkt_receive);
- status = etm_register("FFS2", ETM_FFS2, 0, 0, etm_ffs2_pkt_receive);
- return status;
- }
- #endif // (TARGET == 1)
- /******************************************************************************
- * FFS1 Protocol
- ******************************************************************************/
- #ifndef TMFFS1
- int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize)
- {
- return -1; // FIXME handle error better
- }
- // Note these functions must be presented because ffs_query() use them but
- // they are only valid if FFS1_PROTOCOL is used.
- int tmffs_bufsize(void)
- {
- return EFFS_NOSYS;
- }
- unsigned char *tmffs_bufaddr(void)
- {
- return 0;
- }
- #else
- #define TMFFS1_BUFFER_SIZE 8192
- #define TMFFS1_STRING_SIZE 127
- /******************************************************************************
- * Macros
- ******************************************************************************/
- #define tmffs1_putdata(outp, src, size) \
- tmffs_put8(FPI_DATA); \
- tmffs_put16(size); \
- memcpy(outp, src, size); \
- outp += size;
- /******************************************************************************
- * Local globals
- ******************************************************************************/
- static unsigned char buffer[TMFFS1_BUFFER_SIZE];
- static bufindex;
- static char string[TMFFS1_STRING_SIZE];
- static effs_t tm_ffs_overflowck(void)
- {
- if (bufsize > TMFFS1_BUFFER_SIZE ||
- stringsize > TMFFS1_STRING_SIZE)
- return EFFS_TOOBIG;
- return EFFS_OK;
- }
- /******************************************************************************
- * tm_ffs
- ******************************************************************************/
- /**
- * NOTEME: This has been introduced when the ffs 1MB device limit was
- * broken. This made location_t go from uint16 to uint32, messing up
- * with PCTM.
- *
- * This makes the xstat_s look the same to PCTM PC side, though
- * location will be forced to 0.
- */
- void hack_xstat_2_look_like_old_xstat(struct xstat_s *xstat)
- {
- int i;
- char *location;
- xstat->location = 0;
-
- for (location = (char *) &(xstat->location) + 2; location <= (char *) &(xstat->sequence); location++)
- *location = location[2];
- }
- // Parse input message and execute function. Then fill output buffer with
- // return values from the called function and transmit the message. Return
- // number of bytes inserted into output buffer. If return value is negative,
- // it represents an error code.
- int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize)
- {
- int error;
- tmffs_cid_t fid;
- unsigned char *outp_start = outp;
- unsigned char *inp_start = inp;
- static uint8 i8[2]; static uint16 i8i;
- static uint16 i16[2]; static uint16 i16i;
- static uint32 i32[2]; static uint16 i32i;
- tw(tr(TR_BEGIN, TrTmffs, "TMFFS:\n"));
- while((fid = *inp++) != FPI_END)
- {
- switch(fid)
- {
- /**********************************************************
- * Generic Protocol Functions
- **********************************************************/
- case FPI_BEGIN:
- // for (i8i = 0; i8i < TMFFS1_STRING_SIZE; i8i++) // DEBUG
- // string[i8i] = '#';
- // for (i8i = 0; i8i < TMFFS1_BUFFER_SIZE; i8i++) // DEBUG
- // buffer[i8i] = '$';
- i8i = i16i = i32i = bufsize = stringsize = 0;
- bufindex = 0;
- i8[0] = i8[1] = 0;
- i16[0] = i16[1] = 0;
- i32[0] = i32[1] = 0;
- string[0] = buffer[0] = 0;
- tw(tr(TR_FUNC, TrTmffs, "FPI_BEGIN\n"));
- ttw(ttr(TTrTmffs, "tm1" NL));
- break;
- case FPI_TMFFS_VERSION:
- // NULL -> UINT16
- tmffs_put16(TMFFS1_VERSION);
- break;
- case FPI_INT8:
- i8[i8i++] = inp[0]; inp += 1;
- tw(tr(TR_FUNC, TrTmffs, "FPI_INT8(%d/0x%x)\n",
- i8[i8i-1], i8[i8i-1]));
- ttw(ttr(TTrTmffs, "tm_i8" NL));
- break;
- case FPI_INT16:
- i16[i16i++] = (inp[0]) | (inp[1] << 8); inp += 2;
- tw(tr(TR_FUNC, TrTmffs, "FPI_INT16(%d/0x%x)\n",
- i16[i16i-1], i16[i16i-1]));
- ttw(ttr(TTrTmffs, "tm_i16" NL));
- break;
- case FPI_INT32:
- i32[i32i++] = inp[0] | (inp[1] << 8)
- | (inp[2] << 16) | (inp[3] << 24);
- inp += 4;
- tw(tr(TR_FUNC, TrTmffs, "FPI_INT32(%d/0x%x)\n",
- i32[i32i-1], i32[i32i-1]));
- ttw(ttr(TTrTmffs, "tm_i32" NL));
- break;
- case FPI_BUFFER:
- bufsize = inp[0] | (inp[1] << 8); inp += 2;
- tw(tr(TR_FUNC, TrTmffs, "FPI_BUFFER(%d)\n", bufsize));
- ttw(ttr(TTrTmffs, "tm_buf" NL));
- break;
- case FPI_DATA:
- bufsize = inp[0] | (inp[1] << 8); inp += 2;
- memcpy(buffer, inp, bufsize); inp += bufsize;
- tw(tr(TR_FUNC, TrTmffs, "FPI_DATA(%d)\n", bufsize));
- ttw(ttr(TTrTmffs, "tm_data" NL));
- break;
- case FPI_STRBUF:
- // string buffer size MUST include null-terminator!
- stringsize = inp[0]; inp += 1;
- tw(tr(TR_FUNC, TrTmffs, "FPI_STRBUF(%d)\n", stringsize));
- ttw(ttr(TTrTmffs, "tm_sbuf" NL));
- break;
- case FPI_STRING:
- // stringsize MUST include null-terminator!
- // <INT8>, <BYTES> -> NULL (or ERROR)
- stringsize = inp[0]; inp += 1;
- if (stringsize <= TMFFS1_STRING_SIZE)
- memcpy(string, inp, stringsize);
- inp += stringsize;
- tw(tr(TR_FUNC, TrTmffs, "FPI_STRING(%d,'%s')\n",
- stringsize, string));
- ttw(ttr(TTrTmffs, "tm_s" NL));
- break;
- case FPI_BUFREAD:
- // <INT16> -> DATA
- tmpsize = inp[0] | (inp[1] << 8); inp += 2;
- tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_READ(%d)\n", tmpsize));
- tmffs1_putdata(outp, &buffer[bufindex], tmpsize);
- bufindex += tmpsize;
- ttw(ttr(TTrTmffs, "tm_bufrd" NL));
- break;
- case FPI_BUFWRITE:
- // <INT16>, <BYTES> -> NULL (or ERROR)
- tmpsize = inp[0] | (inp[1] << 8); inp += 2;
- tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_WRITE(%d)\n", tmpsize));
- if (bufsize + tmpsize <= TMFFS1_BUFFER_SIZE)
- memcpy(&buffer[bufsize], inp, tmpsize);
- inp += tmpsize;
- bufsize += tmpsize;
- ttw(ttr(TTrTmffs, "tm_bufwr" NL));
- break;
- case FPI_BUFSET:
- bufindex = inp[0] | (inp[1] << 8); inp += 2;
- tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_SET(%d)\n", bufindex));
- ttw(ttr(TTrTmffs, "tm_bufset" NL));
- break;
- /**********************************************************
- * FFS Functions
- **********************************************************/
- case FPI_PREFORMAT:
- // NULL -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_preformat_nb(i16[0], 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_PREFORMAT(0x%x)\n", i16[0]));
- ttw(ttr(TTrTmffs, "tm_pfmt" NL));
- break;
- case FPI_FORMAT:
- // STRING -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_format_nb(&string[0], i16[0], 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_FORMAT(0x%x)\n", i16[0]));
- ttw(ttr(TTrTmffs, "tm_fmt" NL));
- break;
- case FPI_FCREATE:
- // STRING, DATA -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_file_write_nb(string, buffer, bufsize,
- FFS_O_CREATE | FFS_O_EXCL, 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_FCREATE('%s', 0x%x, %d/0x%x)\n",
- string, buffer, bufsize, bufsize));
- ttw(ttr(TTrTmffs, "tm_fcr" NL));
- break;
- case FPI_FUPDATE:
- // STRING, DATA -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_file_write_nb(string, buffer, bufsize, FFS_O_TRUNC, 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_FUPDATE('%s', 0x%x, %d/0x%x)\n",
- string, buffer, bufsize, bufsize));
- ttw(ttr(TTrTmffs, "tm_fup" NL));
- break;
- case FPI_FWRITE:
- // STRING, DATA -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_file_write_nb(string, buffer, bufsize,
- FFS_O_CREATE | FFS_O_TRUNC, 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_FWRITE('%s', 0x%x, %d/0x%x)\n",
- string, buffer, bufsize, bufsize));
- ttw(ttr(TTrTmffs, "tm_fwr" NL));
- break;
- case FPI_FREAD:
- // STRING, BUFFER -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_file_read(string, buffer, TMFFS1_BUFFER_SIZE);
- // Because a 32-bit integer is returned, we have to saturate it
- // into an 8-bit value.
- if (error >= 0)
- error = 0;
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_FREAD('%s', 0x%x, %d/0x%x)\n",
- string, buffer, bufsize, bufsize));
- ttw(ttr(TTrTmffs, "tm_frd" NL));
- break;
- case FPI_REMOVE:
- // STRING -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_remove_nb(string, 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_REMOVE()\n"));
- ttw(ttr(TTrTmffs, "tm_rm" NL));
- break;
- case FPI_MKDIR:
- // STRING -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_mkdir_nb(string, 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_MKDIR()\n"));
- ttw(ttr(TTrTmffs, "tm_mkd" NL));
- break;
- case FPI_OPENDIR:
- // STRING, BUFFER -> ERROR, DATA
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_opendir(string, (struct dir_s *) buffer);
- // Because a 32-bit integer is returned, we have to saturate it
- // into an 8-bit value.
- if (error >= 0)
- error = 0;
- tmffs_put8(error);
- tmffs1_putdata(outp, buffer, sizeof(struct dir_s));
- tw(tr(TR_FUNC, TrTmffs, "FPI_OPENDIR()\n"));
- ttw(ttr(TTrTmffs, "tm_od" NL));
- break;
- case FPI_READDIR:
- // DATA, STRBUF -> ERROR, DATA, STRING
- string[0] = 0;
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_readdir((struct dir_s *) buffer, string, stringsize);
- // Saturate error(i) in order to let it fit in type int8.
- if (error > 127)
- error = 127;
- tmffs_put8(error);
- tmffs1_putdata(outp, buffer, sizeof(struct dir_s));
- stringsize = strlen(string) + 1;
- tmffs_put8(FPI_STRING); // put directory entry's name...
- tmffs_put8(stringsize);
- memcpy(outp, string, stringsize);
- outp += stringsize;
- tw(tr(TR_FUNC, TrTmffs, "FPI_READDIR()\n"));
- ttw(ttr(TTrTmffs, "tm_rdd" NL));
- break;
- case FPI_STAT:
- // STRING, BUFFER -> ERROR, DATA
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_stat(&string[0], (struct stat_s *) buffer);
- tmffs_put8(error);
- tmffs1_putdata(outp, buffer, sizeof(struct stat_s));
- tw(tr(TR_FUNC, TrTmffs, "FPI_STAT()\n"));
- ttw(ttr(TTrTmffs, "tm_st" NL));
- break;
- case FPI_LINKSTAT:
- // STRING, BUFFER -> ERROR, DATA
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_xlstat(&string[0], (struct xstat_s *) buffer);
- tmffs_put8(error);
- hack_xstat_2_look_like_old_xstat((struct xstat_s *) buffer);
- tmffs1_putdata(outp, buffer, sizeof(struct xstat_s) - 2);
- tw(tr(TR_FUNC, TrTmffs, "FPI_()\n"));
- ttw(ttr(TTrTmffs, "tm_lst" NL));
- break;
- case FPI_SYMLINK:
- // STRING, DATA -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_symlink_nb(string, (char *) buffer, 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_SYMLINK()\n"));
- ttw(ttr(TTrTmffs, "tm_sym" NL));
- break;
- case FPI_READLINK:
- // STRING, BUFFER -> ERROR, DATA
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_readlink(string, (char *) buffer, TMFFS1_BUFFER_SIZE);
- // Because a 32-bit integer is returned, we have to saturate it
- // into an 8-bit value.
- if (error >= 0)
- error = 0;
- tmffs_put8(error);
- tmffs1_putdata(outp, buffer, bufsize); // put link contents
- tw(tr(TR_FUNC, TrTmffs, "FPI_READLINK()\n"));
- ttw(ttr(TTrTmffs, "tm_rdl" NL));
- break;
- case FPI_QUERY:
- // INT8 -> ERROR, DATA
- error = ffs_query(i8[0], buffer);
- tmffs_put8(error);
- tmffs1_putdata(outp, buffer, 16);
- tw(tr(TR_FUNC, TrTmffs, "FPI_QUERY()\n"));
- ttw(ttr(TTrTmffs, "tm_q" NL));
- break;
- case FPI_FCONTROL:
- // STRING INT8 INT32 -> ERROR
- if ((error = tm_ffs_overflowck()) == EFFS_OK)
- error = ffs_fcontrol_nb(string, i8[0], i32[0], 0);
- if (error > 0)
- error = 0; // ignore request id
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_FCONTROL()\n"));
- ttw(ttr(TTrTmffs, "tm_fc" NL));
- break;
- case FPI_INIT:
- // NULL -> ERROR
- error =ffs_initialize();
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_INIT()\n"));
- ttw(ttr(TTrTmffs, "tm_init" NL));
- break;
- case FPI_EXIT:
- // NULL -> ERROR
- error = ffs_exit();
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "FPI_EXIT()\n"));
- ttw(ttr(TTrTmffs, "tm_exit" NL));
- break;
- case FPI_TFFS:
- {
- // STRING -> ERROR
- #if (WITH_TFFS == 1)
- extern char ffs_test_string[]; // defined in task.c
- memcpy(ffs_test_string, string, stringsize);
- tw(tr(TR_FUNC, TrTmffs, "FPI_TFFS()\n"));
- ttw(ttr(TTrTmffs, "tm_tffs" NL));
- #else
- tmffs_put8(EFFS_NOSYS);
- #endif
- break;
- }
- default:
- tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n"));
- ttw(ttr(TTrTmffs, "tm?" NL));
- break;
- }
- // check if we read beyond buffer end
- if (inp > inp_start + insize) {
- tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n"));
- ttw(ttr(TTrTmffs, "tm_fatal" NL));
- // NOTEME: We really should reset output buffer and put a return
- // code that tells us what went wrong!
- return 0;
- }
- }
- tw(tr(TR_END, TrTmffs, ""));
- return outp - outp_start;
- }
- int tmffs_bufsize(void)
- {
- return TMFFS1_BUFFER_SIZE;
- }
- unsigned char *tmffs_bufaddr(void)
- {
- return buffer;
- }
- #endif // TMFFS1
- /******************************************************************************
- * FFS2 protocol
- ******************************************************************************/
- #ifndef TMFFS2
- #if (TARGET == 1)
- int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize)
- {
- int error;
- tw(tr(TR_BEGIN, TrTmffs, "FFS2 protocol not represented in target\n"));
- error = -1; // FIXME other error?
- #if 0 // Note we can only use this if etm is in target
- // We return a packet instead of waiting for timeout.
- pkt->size = 0;
- pkt->status = -error;
- pkt->mid = ETM_FFS2;
- etm_pkt_send(pkt);
- #endif
- target_free(pkt);
- tw(tr(TR_END, TrTmffs, ""));
- return error;
- }
- #endif // (TARGET == 1)
- #else
- #define TMFFS_BUFFER_SIZE 256 // FIXME change to packet size
- #define TMFFS_STRING_SIZE 127
- /******************************************************************************
- * Macros
- ******************************************************************************/
- #define tmffs_get8() inp[0]; inp += 1;
- #define tmffs_get16() (inp[0]) | (inp[1] << 8); inp += 2;
- #define tmffs_get32() inp[0] | (inp[1] << 8) | (inp[2] << 16)\
- | (inp[3] << 24); inp += 4;
- #define tmffs_getdata() bufsize = inp[0]; inp += 1; \
- memcpy(buffer, inp, bufsize); inp += bufsize;
- /******************************************************************************
- * Helper function
- ******************************************************************************/
- // If size is less than zero it is because of a error and we dont have to put any
- // data if size is returned in status.
- int tmffs_putdata(unsigned char **buf, unsigned char *src, int size)
- {
- unsigned char *p = *buf;
- if (size > 0) {
- *p++ = size;
- memcpy(p, src, size);
- *buf += 1 + size;
- }
- return size;
- }
- int tmffs_putstring(unsigned char **buf, char *src, int size)
- {
- unsigned char *p = *buf;
- if (size > 0) {
- *p++ = size;
- memcpy(p, src, size);
- *buf += 1 + size;
- }
- return size;
- }
- int tmffs_getstring(unsigned char ** buf, char *string)
- {
- unsigned char *p = *buf;
-
- stringsize = *p++;
- if (stringsize > TMFFS_STRING_SIZE)
- return EFFS_TOOBIG;
- memcpy(string, p, stringsize);
- *buf += 1 + stringsize;
- return stringsize;
- }
- #if (RELIANCE_FS==1)
- /* Mantain only one open directory at a time */
- char is_dir_open = 0;
- T_FFS_DIR dir_backup;
- #endif
- /******************************************************************************
- * tm_ffs
- ******************************************************************************/
- // Parse input message and execute function. Then fill output buffer with
- // return values from the called function and transmit the message. Return
- // number of bytes inserted into output buffer. If return value is negative,
- // it represents an error code.
- int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize)
- {
- tmffs2_cid_t fid;
- unsigned char buffer[TMFFS_BUFFER_SIZE];
- char string[TMFFS_STRING_SIZE];
- unsigned char *outp_start;
- unsigned char *inp_start = inp;
- unsigned char *outp;
- int error = 0, i, fdi, size, param, flags;
- uint8 type;
- bufsize = stringsize = tmpsize = 0;
- tw(tr(TR_BEGIN, TrTmffs, "TmFFS2\n"));
-
- outp_start = outp = pkt->data;
-
- fid = (tmffs2_cid_t)*inp++;
- ttw(ttr(TTrTmffs, "etm_ffs2 0x%x" NL, fid));
- switch(fid)
- {
- /**********************************************************
- * Generic Protocol Functions
- **********************************************************/
- case TMFFS_VERSION:
- tmffs_put16(TMFFS2_VERSION);
- break;
- /**********************************************************
- * FFS Functions
- **********************************************************/
- case TMFFS_PREFORMAT:
- param = tmffs_get16();
- error = ffs_preformat(param);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_PREFORMAT(0x%x)\n", param));
- ttw(ttr(TTrTmffs, "tm_pfmt" NL));
- break;
- case TMFFS_FORMAT:
- error = tmffs_getstring(&inp, string);
- param = tmffs_get16();
- if (error >= 0)
- error = ffs_format(&string[0], param);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_FORMAT(0x%x)\n", param));
- ttw(ttr(TTrTmffs, "tm_fmt" NL));
- break;
-
- case TMFFS_FILE_WRITE:
- error = tmffs_getstring(&inp, string);
- tmffs_getdata();
- flags = tmffs_get8();
- if (error >= 0)
- error = ffs_file_write(string, buffer, bufsize, flags);
- ttw(ttr(TTrTmffs, "tm_fwr" NL));
- break;
- case TMFFS_FILE_READ:
- error = tmffs_getstring(&inp, string);
- bufsize = tmffs_get8();
- if (error >= 0)
- size = ffs_file_read(string, buffer, bufsize);
- error = tmffs_putdata(&outp, &buffer[0], size);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_FREAD('%s', 0x%x, %d/0x%x)\n",
- string, buffer, bufsize, bufsize));
- ttw(ttr(TTrTmffs, "tm_frd" NL));
- break;
- case TMFFS_REMOVE:
- error = tmffs_getstring(&inp, string);
- if (error >= 0)
- error = ffs_remove(string);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_REMOVE()\n"));
- ttw(ttr(TTrTmffs, "tm_rm" NL));
- break;
- case TMFFS_OPEN:
- error = tmffs_getstring(&inp, string);
- flags = tmffs_get8();
- if (error >= 0)
- error = ffs_open(string, flags);
- tmffs_put8(error); // fdi
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPEN('%s', %d)\n", string, flags));
- ttw(ttr(TTrTmffs, "tm_open" NL));
- break;
- case TMFFS_CLOSE:
- fdi = tmffs_get8();
- error = ffs_close(fdi);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_CLOSE(%d)\n", fdi));
- ttw(ttr(TTrTmffs, "tm_close" NL));
- break;
- case TMFFS_WRITE:
- fdi = tmffs_get8();
- tmffs_getdata();
- error = ffs_write(fdi, buffer, bufsize);
- tmffs_put8(error); // put size
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_WRITE(%d, %d)\n", fdi, bufsize));
- ttw(ttr(TTrTmffs, "tm_write" NL));
- break;
- case TMFFS_READ:
- fdi = tmffs_get8();
- size = tmffs_get8();
- size = ffs_read(fdi, &buffer[0], size);
- error = tmffs_putdata(&outp, &buffer[0], size);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_READ(%d, %d)\n", fdi, size));
- ttw(ttr(TTrTmffs, "tm_read" NL));
- break;
- case TMFFS_MKDIR:
- error = tmffs_getstring(&inp, string);
- if (error >= 0)
- error = ffs_mkdir(string);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_MKDIR()\n"));
- ttw(ttr(TTrTmffs, "tm_mkd" NL));
- break;
- case TMFFS_OPENDIR:
- error = tmffs_getstring(&inp, string);
- if (error >= 0) {
- #if (RELIANCE_FS==1)
- if(is_dir_open)
- {
- /* close the previous directory */
- error=ffs_closedir(&dir_backup);
- is_dir_open=0;
- }
- #endif
- error = ffs_opendir(string, (struct dir_s *) buffer);
- #if (RELIANCE_FS==1)
- if(error >= 0)
- {
- is_dir_open=1; /* Indicate that directory is already opened */
- memcpy(&dir_backup,buffer,sizeof(T_FFS_DIR)); /* Keep the backup now */
- }
- #endif
- tmffs_put8(error); // Note: we must put error/number of objects.
- }
- if (error >= 0)
- tmffs_putdata(&outp, buffer, sizeof(struct dir_s));
-
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPENDIR()\n"));
- ttw(ttr(TTrTmffs, "tm_od" NL));
- break;
- case TMFFS_READDIR:
- tmffs_getdata();
- stringsize = tmffs_get8();
- error = ffs_readdir((struct dir_s *) buffer, string, stringsize);
- #if (RELIANCE_FS==1)
- // ignore . and .. folder entries if reliance is being used.
- if (strcmp(string, ".") == NULL) {
- error = ffs_readdir(((T_FFS_DIR *) buffer), string, stringsize);
- }
- if (strcmp(string, "..") == NULL) {
- error = ffs_readdir(((T_FFS_DIR *) buffer), string, stringsize);
- }
- #endif
- tmffs_put8(error); // Note: we have to return bytes read.
- if (error >= 0) {
- #if (RELIANCE_FS==1)
- if(error == 0 && is_dir_open) /* last entry read */
- { /* and backup has some directory opened */
- is_dir_open=0; /* Indicate that directory is already opened */
- }
- #endif
- tmffs_putdata(&outp, buffer, sizeof(struct dir_s));
- stringsize = strlen(string) + 1;
- tmffs_putstring(&outp, string, stringsize);
- }
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_READDIR()\n"));
- ttw(ttr(TTrTmffs, "tm_rdd" NL));
- break;
- case TMFFS_STAT:
- error = tmffs_getstring(&inp, string);
- if (error >= 0)
- error = ffs_stat(string, (struct stat_s *) buffer);
- if (error >= 0)
- tmffs_putdata(&outp, buffer, sizeof(struct stat_s));
-
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_STAT()\n"));
- ttw(ttr(TTrTmffs, "tm_st" NL));
- break;
- case TMFFS_XLSTAT:
- error = tmffs_getstring(&inp, string);
- if (error >= 0)
- error = ffs_xlstat(&string[0], (struct xstat_s *) buffer);
- if (error >= 0)
- tmffs_putdata(&outp, buffer, sizeof(struct xstat_s));
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_()\n"));
- ttw(ttr(TTrTmffs, "tm_xlst" NL));
- break;
- case TMFFS_SYMLINK:
- error = tmffs_getstring(&inp, string);
- tmffs_getdata();
- if (error >= 0)
- error = ffs_symlink(string, (char *) buffer);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_SYMLINK()\n"));
- ttw(ttr(TTrTmffs, "tm_sym" NL));
- break;
- case TMFFS_READLINK:
- error = tmffs_getstring(&inp, string);
- tmffs_getdata();
- if (error >= 0) {
- size = ffs_readlink(string, (char *) buffer, TMFFS_BUFFER_SIZE);
- error = tmffs_putdata(&outp, buffer, size); // put link contents
- }
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_READLINK()\n"));
- ttw(ttr(TTrTmffs, "tm_rdl" NL));
- break;
- case TMFFS_QUERY:
- param = tmffs_get8();
- error = ffs_query(param, buffer);
- if (error >= 0)
- tmffs_putdata(&outp, buffer, 16);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_QUERY(%d)\n", param));
- ttw(ttr(TTrTmffs, "tm_q" NL));
- break;
- case TMFFS_FCONTROL:
- error = tmffs_getstring(&inp, string);
- type = tmffs_get8();
- param = tmffs_get32();
- if (error >= 0)
- error = ffs_fcontrol(string, type, param);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_FCONTROL()\n"));
- ttw(ttr(TTrTmffs, "tm_fc" NL));
- break;
- case TMFFS_TFFS:
- {
- #if (WITH_TFFS == 1)
- extern char ffs_test_string[]; // defined in task.c
- error = tmffs_getstring(&inp, string);
- memcpy(ffs_test_string, string, stringsize);
- tw(tr(TR_FUNC, TrTmffs, "TMFFS_TFFS()\n"));
- ttw(ttr(TTrTmffs, "tm_tffs" NL));
- tmffs_put8(EFFS_OK);
- #else
- error=EFFS_NOSYS;
- tmffs_put8(error);
- #endif
- break;
- }
- default:
- error = EFFS_NOSYS;
- tmffs_put8(error);
- tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n"));
- ttw(ttr(TTrTmffs, "tm?" NL));
- break;
- }
-
- // check if we read beyond buffer end
- if (inp > inp_start + insize) {
- tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n"));
- ttw(ttr(TTrTmffs, "tm_fatal" NL));
- ttw(ttr(TTrTmffs, "insize: %d, diff: %d" NL, insize,
- inp - (inp_start + insize)));
- // NOTEME: We really should reset output buffer and put a return
- // code that tells us what went wrong!
- error = ETM_PACKET; // FIXME find another error
- }
- ttw(ttr(TTrTmffs, "error %d" NL, error));
- if (error > 0)
- error = 0;
- pkt->mid = ETM_FFS2;
- pkt->size = outp - outp_start;
- pkt->status = -error;
- etm_pkt_send(pkt);
- etm_free(pkt);
- tw(tr(TR_END, TrTmffs, ""));
- return ETM_OK;
- }
- #endif // TMFFS2