FreeCalypso > hg > freecalypso-sw
view gsm-fw/services/ffs/tmffs.c @ 992:a7b0b426f9ca
target-utils: boot ROM UART autodetection revamped
The new implementation should work with both the familiar Calypso C035
boot ROM version found in our regular targets as well as the older
Calypso F741979B version found on the vintage D-Sample board.
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 30 Dec 2015 21:28:41 +0000 |
parents | 842c9fd828fd |
children |
line wrap: on
line source
/****************************************************************************** * 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 $ * ******************************************************************************/ #include "../../include/config.h" #include "../../riviera/rv/rv_defined_swe.h" #ifdef RVM_ETM_SWE #include "../etm/etm.h" #include "../etm/etm_api.h" #endif #include "ffs.h" #include "task.h" #include "ffstrace.h" #include "tmffs.h" #include <string.h> /****************************************************************************** * Local globals for all protocols ******************************************************************************/ #if TMFFS1 || TMFFS2 static int32 bufsize, tmpsize; static uint8 stringsize; #endif 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); // Not in use //#define tmffs_put32(x) tmffs_put16(x); tmffs_put16(x >> 16); #ifdef RVM_ETM_SWE int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize); /****************************************************************************** * 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; } #endif /* Init of FFS in the ETM database */ int etm_ffs_init(void) { int status; #ifdef RVM_ETM_SWE status = etm_register("FFS1", ETM_FFS1, 0, 0, etm_ffs1_pkt_receive); status = etm_register("FFS2", ETM_FFS2, 0, 0, etm_ffs2_pkt_receive); #else status = 0; #endif return status; } /****************************************************************************** * 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 #if (GSMLITE == 1) #define TMFFS1_BUFFER_SIZE 4000 //previously 8192 #else #define TMFFS1_BUFFER_SIZE 8192 #endif #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_fcreate_nb(string, buffer, bufsize, 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_fupdate_nb(string, buffer, bufsize, 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_fwrite_nb(string, buffer, bufsize, 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 #ifdef RVM_ETM_SWE 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? // We return a packet instead of waiting for timeout. pkt->size = 0; pkt->status = -error; pkt->mid = ETM_FFS2; etm_pkt_send(pkt); target_free(pkt); tw(tr(TR_END, TrTmffs, "")); return error; } #endif #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; } /****************************************************************************** * 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 = *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) { error = ffs_opendir(string, (struct dir_s *) buffer); 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); tmffs_put8(error); // Note: we have to return bytes read. if (error >= 0) { 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 tmffs_put8(EFFS_NOSYS); #endif break; } default: error = EFFS_NOSYS; tmffs_put8(EFFS_NOSYS); 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