1*10465441SEvalZero /*
2*10465441SEvalZero This file is part of UFFS, the Ultra-low-cost Flash File System.
3*10465441SEvalZero
4*10465441SEvalZero Copyright (C) 2005-2009 Ricky Zheng <[email protected]>
5*10465441SEvalZero
6*10465441SEvalZero UFFS is free software; you can redistribute it and/or modify it under
7*10465441SEvalZero the GNU Library General Public License as published by the Free Software
8*10465441SEvalZero Foundation; either version 2 of the License, or (at your option) any
9*10465441SEvalZero later version.
10*10465441SEvalZero
11*10465441SEvalZero UFFS is distributed in the hope that it will be useful, but WITHOUT
12*10465441SEvalZero ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*10465441SEvalZero FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*10465441SEvalZero or GNU Library General Public License, as applicable, for more details.
15*10465441SEvalZero
16*10465441SEvalZero You should have received a copy of the GNU General Public License
17*10465441SEvalZero and GNU Library General Public License along with UFFS; if not, write
18*10465441SEvalZero to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19*10465441SEvalZero Boston, MA 02110-1301, USA.
20*10465441SEvalZero
21*10465441SEvalZero As a special exception, if other files instantiate templates or use
22*10465441SEvalZero macros or inline functions from this file, or you compile this file
23*10465441SEvalZero and link it with other works to produce a work based on this file,
24*10465441SEvalZero this file does not by itself cause the resulting work to be covered
25*10465441SEvalZero by the GNU General Public License. However the source code for this
26*10465441SEvalZero file must still be made available in accordance with section (3) of
27*10465441SEvalZero the GNU General Public License v2.
28*10465441SEvalZero
29*10465441SEvalZero This exception does not invalidate any other reasons why a work based
30*10465441SEvalZero on this file might be covered by the GNU General Public License.
31*10465441SEvalZero */
32*10465441SEvalZero
33*10465441SEvalZero /**
34*10465441SEvalZero * \file test_cmds.c
35*10465441SEvalZero * \brief commands for test uffs
36*10465441SEvalZero * \author Ricky Zheng
37*10465441SEvalZero */
38*10465441SEvalZero #include <stdio.h>
39*10465441SEvalZero #include <string.h>
40*10465441SEvalZero #include <stdlib.h>
41*10465441SEvalZero #include "uffs_config.h"
42*10465441SEvalZero #include "uffs/uffs_public.h"
43*10465441SEvalZero #include "uffs/uffs_fd.h"
44*10465441SEvalZero #include "uffs/uffs_utils.h"
45*10465441SEvalZero #include "uffs/uffs_core.h"
46*10465441SEvalZero #include "uffs/uffs_mtb.h"
47*10465441SEvalZero #include "uffs/uffs_find.h"
48*10465441SEvalZero #include "uffs/uffs_badblock.h"
49*10465441SEvalZero #include "cmdline.h"
50*10465441SEvalZero #include "api_test.h"
51*10465441SEvalZero
52*10465441SEvalZero #define PFX "test: "
53*10465441SEvalZero
54*10465441SEvalZero #define MAX_TEST_BUF_LEN 8192
55*10465441SEvalZero
56*10465441SEvalZero #define SEQ_INIT 10
57*10465441SEvalZero #define SEQ_MOD_LEN 120
58*10465441SEvalZero
59*10465441SEvalZero #define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
60*10465441SEvalZero #define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
61*10465441SEvalZero
62*10465441SEvalZero
memcp_seq(void * des,int size,int start_pos)63*10465441SEvalZero static void memcp_seq(void *des, int size, int start_pos)
64*10465441SEvalZero {
65*10465441SEvalZero int i;
66*10465441SEvalZero u8 *p = (u8 *)des;
67*10465441SEvalZero
68*10465441SEvalZero for (i = 0; i < size; i++, p++) {
69*10465441SEvalZero *p = (start_pos + SEQ_INIT + i) % SEQ_MOD_LEN;
70*10465441SEvalZero }
71*10465441SEvalZero }
72*10465441SEvalZero
check_entry_exist(const char * name)73*10465441SEvalZero static UBOOL check_entry_exist(const char *name)
74*10465441SEvalZero {
75*10465441SEvalZero struct uffs_stat sb;
76*10465441SEvalZero
77*10465441SEvalZero return uffs_stat(name, &sb) < 0 ? U_FALSE : U_TRUE;
78*10465441SEvalZero }
79*10465441SEvalZero
do_write_test_file(int fd,int size)80*10465441SEvalZero static URET do_write_test_file(int fd, int size)
81*10465441SEvalZero {
82*10465441SEvalZero long pos;
83*10465441SEvalZero unsigned char buf[100];
84*10465441SEvalZero int len;
85*10465441SEvalZero
86*10465441SEvalZero while (size > 0) {
87*10465441SEvalZero pos = uffs_seek(fd, 0, USEEK_CUR);
88*10465441SEvalZero len = (size > sizeof(buf) ? sizeof(buf) : size);
89*10465441SEvalZero memcp_seq(buf, len, pos);
90*10465441SEvalZero if (uffs_write(fd, buf, len) != len) {
91*10465441SEvalZero MSGLN("Write file failed, size %d at %d", len, pos);
92*10465441SEvalZero return U_FAIL;
93*10465441SEvalZero }
94*10465441SEvalZero size -= len;
95*10465441SEvalZero }
96*10465441SEvalZero
97*10465441SEvalZero return U_SUCC;
98*10465441SEvalZero }
99*10465441SEvalZero
test_write_file(const char * file_name,int pos,int size)100*10465441SEvalZero static URET test_write_file(const char *file_name, int pos, int size)
101*10465441SEvalZero {
102*10465441SEvalZero int ret = U_FAIL;
103*10465441SEvalZero int fd = -1;
104*10465441SEvalZero
105*10465441SEvalZero if ((fd = uffs_open(file_name, UO_RDWR|UO_CREATE)) < 0) {
106*10465441SEvalZero MSGLN("Can't open file %s for write.", file_name);
107*10465441SEvalZero goto test_exit;
108*10465441SEvalZero }
109*10465441SEvalZero
110*10465441SEvalZero if (uffs_seek(fd, pos, USEEK_SET) != pos) {
111*10465441SEvalZero MSGLN("Can't seek file %s at pos %d", file_name, pos);
112*10465441SEvalZero goto test_failed;
113*10465441SEvalZero }
114*10465441SEvalZero
115*10465441SEvalZero if (do_write_test_file(fd, size) == U_FAIL) {
116*10465441SEvalZero MSGLN("Write file %s failed.", file_name);
117*10465441SEvalZero goto test_failed;
118*10465441SEvalZero }
119*10465441SEvalZero ret = U_SUCC;
120*10465441SEvalZero
121*10465441SEvalZero test_failed:
122*10465441SEvalZero uffs_close(fd);
123*10465441SEvalZero
124*10465441SEvalZero test_exit:
125*10465441SEvalZero
126*10465441SEvalZero return ret;
127*10465441SEvalZero }
128*10465441SEvalZero
129*10465441SEvalZero
test_verify_file(const char * file_name,UBOOL noecc)130*10465441SEvalZero static URET test_verify_file(const char *file_name, UBOOL noecc)
131*10465441SEvalZero {
132*10465441SEvalZero int fd;
133*10465441SEvalZero int ret = U_FAIL;
134*10465441SEvalZero unsigned char buf[100];
135*10465441SEvalZero int i, pos, len;
136*10465441SEvalZero u8 x;
137*10465441SEvalZero
138*10465441SEvalZero if ((fd = uffs_open(file_name, (noecc ? UO_RDONLY|UO_NOECC : UO_RDONLY))) < 0) {
139*10465441SEvalZero MSGLN("Can't open file %s for read.", file_name);
140*10465441SEvalZero goto test_exit;
141*10465441SEvalZero }
142*10465441SEvalZero
143*10465441SEvalZero pos = 0;
144*10465441SEvalZero while (!uffs_eof(fd)) {
145*10465441SEvalZero len = uffs_read(fd, buf, sizeof(buf));
146*10465441SEvalZero if (len <= 0)
147*10465441SEvalZero goto test_failed;
148*10465441SEvalZero for (i = 0; i < len; i++) {
149*10465441SEvalZero x = (SEQ_INIT + pos + i) % SEQ_MOD_LEN;
150*10465441SEvalZero if (buf[i] != x) {
151*10465441SEvalZero MSGLN("Verify file %s failed at: %d, expect 0x%02x but got 0x%02x", file_name, pos + i, x, buf[i]);
152*10465441SEvalZero goto test_failed;
153*10465441SEvalZero }
154*10465441SEvalZero }
155*10465441SEvalZero pos += len;
156*10465441SEvalZero }
157*10465441SEvalZero
158*10465441SEvalZero if (pos != uffs_seek(fd, 0, USEEK_END)) {
159*10465441SEvalZero MSGLN("Verify file %s failed. invalid file length.", file_name);
160*10465441SEvalZero goto test_failed;
161*10465441SEvalZero }
162*10465441SEvalZero
163*10465441SEvalZero MSGLN("Verify file %s succ.", file_name);
164*10465441SEvalZero ret = U_SUCC;
165*10465441SEvalZero
166*10465441SEvalZero test_failed:
167*10465441SEvalZero uffs_close(fd);
168*10465441SEvalZero
169*10465441SEvalZero test_exit:
170*10465441SEvalZero
171*10465441SEvalZero return ret;
172*10465441SEvalZero }
173*10465441SEvalZero
test_append_file(const char * file_name,int size)174*10465441SEvalZero static URET test_append_file(const char *file_name, int size)
175*10465441SEvalZero {
176*10465441SEvalZero int ret = U_FAIL;
177*10465441SEvalZero int fd = -1;
178*10465441SEvalZero
179*10465441SEvalZero if ((fd = uffs_open(file_name, UO_RDWR|UO_APPEND|UO_CREATE)) < 0) {
180*10465441SEvalZero MSGLN("Can't open file %s for append.", file_name);
181*10465441SEvalZero goto test_exit;
182*10465441SEvalZero }
183*10465441SEvalZero
184*10465441SEvalZero uffs_seek(fd, 0, USEEK_END);
185*10465441SEvalZero
186*10465441SEvalZero if (do_write_test_file(fd, size) == U_FAIL) {
187*10465441SEvalZero MSGLN("Write file %s failed.", file_name);
188*10465441SEvalZero goto test_failed;
189*10465441SEvalZero }
190*10465441SEvalZero ret = U_SUCC;
191*10465441SEvalZero
192*10465441SEvalZero test_failed:
193*10465441SEvalZero uffs_close(fd);
194*10465441SEvalZero
195*10465441SEvalZero test_exit:
196*10465441SEvalZero
197*10465441SEvalZero return ret;
198*10465441SEvalZero }
199*10465441SEvalZero
200*10465441SEvalZero
201*10465441SEvalZero /* test create file, write file and read back */
cmd_t1(int argc,char * argv[])202*10465441SEvalZero static int cmd_t1(int argc, char *argv[])
203*10465441SEvalZero {
204*10465441SEvalZero int fd;
205*10465441SEvalZero URET ret;
206*10465441SEvalZero char buf[100];
207*10465441SEvalZero const char *name;
208*10465441SEvalZero
209*10465441SEvalZero if (argc < 2) {
210*10465441SEvalZero return CLI_INVALID_ARG;
211*10465441SEvalZero }
212*10465441SEvalZero
213*10465441SEvalZero name = argv[1];
214*10465441SEvalZero
215*10465441SEvalZero fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC);
216*10465441SEvalZero if (fd < 0) {
217*10465441SEvalZero MSGLN("Can't open %s", name);
218*10465441SEvalZero goto fail;
219*10465441SEvalZero }
220*10465441SEvalZero
221*10465441SEvalZero sprintf(buf, "123456789ABCDEF");
222*10465441SEvalZero ret = uffs_write(fd, buf, strlen(buf));
223*10465441SEvalZero MSGLN("write %d bytes to file, content: %s", ret, buf);
224*10465441SEvalZero
225*10465441SEvalZero ret = uffs_seek(fd, 3, USEEK_SET);
226*10465441SEvalZero MSGLN("new file position: %d", ret);
227*10465441SEvalZero
228*10465441SEvalZero memset(buf, 0, sizeof(buf));
229*10465441SEvalZero ret = uffs_read(fd, buf, 5);
230*10465441SEvalZero MSGLN("read %d bytes, content: %s", ret, buf);
231*10465441SEvalZero
232*10465441SEvalZero uffs_close(fd);
233*10465441SEvalZero
234*10465441SEvalZero return 0;
235*10465441SEvalZero fail:
236*10465441SEvalZero
237*10465441SEvalZero return -1;
238*10465441SEvalZero }
239*10465441SEvalZero
240*10465441SEvalZero
DoTest2(void)241*10465441SEvalZero static URET DoTest2(void)
242*10465441SEvalZero {
243*10465441SEvalZero int fd = -1;
244*10465441SEvalZero URET ret = U_FAIL;
245*10465441SEvalZero char buf[100], buf_1[100];
246*10465441SEvalZero
247*10465441SEvalZero fd = uffs_open("/abc/", UO_RDWR|UO_DIR);
248*10465441SEvalZero if (fd < 0) {
249*10465441SEvalZero MSGLN("Can't open dir abc, err: %d", uffs_get_error());
250*10465441SEvalZero MSGLN("Try to create a new one...");
251*10465441SEvalZero fd = uffs_open("/abc/", UO_RDWR|UO_CREATE|UO_DIR);
252*10465441SEvalZero if (fd < 0) {
253*10465441SEvalZero MSGLN("Can't create new dir /abc/");
254*10465441SEvalZero goto exit_test;
255*10465441SEvalZero }
256*10465441SEvalZero else {
257*10465441SEvalZero uffs_close(fd);
258*10465441SEvalZero }
259*10465441SEvalZero }
260*10465441SEvalZero else {
261*10465441SEvalZero uffs_close(fd);
262*10465441SEvalZero }
263*10465441SEvalZero
264*10465441SEvalZero fd = uffs_open("/abc/test.txt", UO_RDWR|UO_CREATE);
265*10465441SEvalZero if (fd < 0) {
266*10465441SEvalZero MSGLN("Can't open /abc/test.txt");
267*10465441SEvalZero goto exit_test;
268*10465441SEvalZero }
269*10465441SEvalZero
270*10465441SEvalZero sprintf(buf, "123456789ABCDEF");
271*10465441SEvalZero ret = uffs_write(fd, buf, strlen(buf));
272*10465441SEvalZero MSGLN("write %d bytes to file, content: %s", ret, buf);
273*10465441SEvalZero
274*10465441SEvalZero ret = uffs_seek(fd, 3, USEEK_SET);
275*10465441SEvalZero MSGLN("new file position: %d", ret);
276*10465441SEvalZero
277*10465441SEvalZero memset(buf_1, 0, sizeof(buf_1));
278*10465441SEvalZero ret = uffs_read(fd, buf_1, 5);
279*10465441SEvalZero MSGLN("read %d bytes, content: %s", ret, buf_1);
280*10465441SEvalZero
281*10465441SEvalZero if (memcmp(buf + 3, buf_1, 5) != 0) {
282*10465441SEvalZero ret = U_FAIL;
283*10465441SEvalZero }
284*10465441SEvalZero else {
285*10465441SEvalZero ret = U_SUCC;
286*10465441SEvalZero }
287*10465441SEvalZero
288*10465441SEvalZero uffs_close(fd);
289*10465441SEvalZero
290*10465441SEvalZero exit_test:
291*10465441SEvalZero
292*10465441SEvalZero return ret;
293*10465441SEvalZero }
294*10465441SEvalZero
295*10465441SEvalZero
cmd_t2(int argc,char * argv[])296*10465441SEvalZero static int cmd_t2(int argc, char *argv[])
297*10465441SEvalZero {
298*10465441SEvalZero URET ret;
299*10465441SEvalZero MSGLN("Test return: %s !", (ret = DoTest2()) == U_SUCC ? "succ" : "failed");
300*10465441SEvalZero
301*10465441SEvalZero return (ret == U_SUCC) ? 0 : -1;
302*10465441SEvalZero }
303*10465441SEvalZero
304*10465441SEvalZero
cmd_VerifyFile(int argc,char * argv[])305*10465441SEvalZero static int cmd_VerifyFile(int argc, char *argv[])
306*10465441SEvalZero {
307*10465441SEvalZero const char *name;
308*10465441SEvalZero UBOOL noecc = U_FALSE;
309*10465441SEvalZero
310*10465441SEvalZero if (argc < 2) {
311*10465441SEvalZero return CLI_INVALID_ARG;
312*10465441SEvalZero }
313*10465441SEvalZero
314*10465441SEvalZero name = argv[1];
315*10465441SEvalZero if (argc > 2 && strcmp(argv[2], "noecc") == 0) {
316*10465441SEvalZero noecc = U_TRUE;
317*10465441SEvalZero }
318*10465441SEvalZero
319*10465441SEvalZero MSGLN("Check file %s ... ", name);
320*10465441SEvalZero if (test_verify_file(name, noecc) != U_SUCC) {
321*10465441SEvalZero MSGLN("Verify file %s failed.", name);
322*10465441SEvalZero return -1;
323*10465441SEvalZero }
324*10465441SEvalZero
325*10465441SEvalZero return 0;
326*10465441SEvalZero }
327*10465441SEvalZero
328*10465441SEvalZero /* Test file append and 'random' write */
cmd_t3(int argc,char * argv[])329*10465441SEvalZero static int cmd_t3(int argc, char *argv[])
330*10465441SEvalZero {
331*10465441SEvalZero const char *name;
332*10465441SEvalZero int i;
333*10465441SEvalZero UBOOL noecc = U_FALSE;
334*10465441SEvalZero int write_test_seq[] = { 20, 10, 500, 40, 1140, 900, 329, 4560, 352, 1100 };
335*10465441SEvalZero
336*10465441SEvalZero if (argc < 2) {
337*10465441SEvalZero return CLI_INVALID_ARG;
338*10465441SEvalZero }
339*10465441SEvalZero
340*10465441SEvalZero name = argv[1];
341*10465441SEvalZero if (argv[2] && strcmp(argv[2], "noecc") == 0) {
342*10465441SEvalZero noecc = U_TRUE;
343*10465441SEvalZero }
344*10465441SEvalZero
345*10465441SEvalZero if (check_entry_exist(name)) {
346*10465441SEvalZero MSGLN("Check file %s ... ", name);
347*10465441SEvalZero if (test_verify_file(name, noecc) != U_SUCC) {
348*10465441SEvalZero MSGLN("Verify file %s failed.", name);
349*10465441SEvalZero return -1;
350*10465441SEvalZero }
351*10465441SEvalZero }
352*10465441SEvalZero
353*10465441SEvalZero MSGLN("Test append file %s ...", name);
354*10465441SEvalZero for (i = 1; i < 500; i += 29) {
355*10465441SEvalZero if (test_append_file(name, i) != U_SUCC) {
356*10465441SEvalZero MSGLN("Append file %s test failed at %d !", name, i);
357*10465441SEvalZero return -1;
358*10465441SEvalZero }
359*10465441SEvalZero }
360*10465441SEvalZero
361*10465441SEvalZero MSGLN("Check file %s ... ", name);
362*10465441SEvalZero if (test_verify_file(name, noecc) != U_SUCC) {
363*10465441SEvalZero MSGLN("Verify file %s failed.", name);
364*10465441SEvalZero return -1;
365*10465441SEvalZero }
366*10465441SEvalZero
367*10465441SEvalZero MSGLN("Test write file ...");
368*10465441SEvalZero for (i = 0; i < sizeof(write_test_seq) / sizeof(int) - 1; i++) {
369*10465441SEvalZero if (test_write_file(name, write_test_seq[i], write_test_seq[i+1]) != U_SUCC) {
370*10465441SEvalZero MSGLN("Test write file failed !");
371*10465441SEvalZero return -1;
372*10465441SEvalZero }
373*10465441SEvalZero }
374*10465441SEvalZero
375*10465441SEvalZero MSGLN("Check file %s ... ", name);
376*10465441SEvalZero if (test_verify_file(name, noecc) != U_SUCC) {
377*10465441SEvalZero MSGLN("Verify file %s failed.", name);
378*10465441SEvalZero return -1;
379*10465441SEvalZero }
380*10465441SEvalZero
381*10465441SEvalZero MSGLN("Test succ !");
382*10465441SEvalZero
383*10465441SEvalZero return 0;
384*10465441SEvalZero }
385*10465441SEvalZero
386*10465441SEvalZero /* open two files and test write */
cmd_t4(int argc,char * argv[])387*10465441SEvalZero static int cmd_t4(int argc, char *argv[])
388*10465441SEvalZero {
389*10465441SEvalZero int fd1 = -1, fd2 = -1;
390*10465441SEvalZero
391*10465441SEvalZero MSGLN("open /a ...");
392*10465441SEvalZero if ((fd1 = uffs_open("/a", UO_RDWR | UO_CREATE)) < 0) {
393*10465441SEvalZero MSGLN("Can't open /a");
394*10465441SEvalZero goto fail_exit;
395*10465441SEvalZero }
396*10465441SEvalZero
397*10465441SEvalZero MSGLN("open /b ...");
398*10465441SEvalZero if ((fd2 = uffs_open("/b", UO_RDWR | UO_CREATE)) < 0) {
399*10465441SEvalZero MSGLN("Can't open /b");
400*10465441SEvalZero uffs_close(fd1);
401*10465441SEvalZero goto fail_exit;
402*10465441SEvalZero }
403*10465441SEvalZero
404*10465441SEvalZero MSGLN("write (1) to /a ...");
405*10465441SEvalZero uffs_write(fd1, "Hello,", 6);
406*10465441SEvalZero MSGLN("write (1) to /b ...");
407*10465441SEvalZero uffs_write(fd2, "Hello,", 6);
408*10465441SEvalZero MSGLN("write (2) to /a ...");
409*10465441SEvalZero uffs_write(fd1, "World.", 6);
410*10465441SEvalZero MSGLN("write (2) to /b ...");
411*10465441SEvalZero uffs_write(fd2, "World.", 6);
412*10465441SEvalZero MSGLN("close /a ...");
413*10465441SEvalZero uffs_close(fd1);
414*10465441SEvalZero MSGLN("close /b ...");
415*10465441SEvalZero uffs_close(fd2);
416*10465441SEvalZero
417*10465441SEvalZero return 0;
418*10465441SEvalZero
419*10465441SEvalZero fail_exit:
420*10465441SEvalZero return -1;
421*10465441SEvalZero }
422*10465441SEvalZero
423*10465441SEvalZero /* test appending file */
cmd_t5(int argc,char * argv[])424*10465441SEvalZero static int cmd_t5(int argc, char *argv[])
425*10465441SEvalZero {
426*10465441SEvalZero int fd = -1;
427*10465441SEvalZero URET ret;
428*10465441SEvalZero char buf[100];
429*10465441SEvalZero const char *name;
430*10465441SEvalZero
431*10465441SEvalZero if (argc < 2) {
432*10465441SEvalZero return CLI_INVALID_ARG;
433*10465441SEvalZero }
434*10465441SEvalZero
435*10465441SEvalZero name = argv[1];
436*10465441SEvalZero
437*10465441SEvalZero fd = uffs_open(name, UO_RDWR|UO_APPEND);
438*10465441SEvalZero if (fd < 0) {
439*10465441SEvalZero MSGLN("Can't open %s", name);
440*10465441SEvalZero goto fail;
441*10465441SEvalZero }
442*10465441SEvalZero
443*10465441SEvalZero sprintf(buf, "append test...");
444*10465441SEvalZero ret = uffs_write(fd, buf, strlen(buf));
445*10465441SEvalZero if (ret != strlen(buf)) {
446*10465441SEvalZero MSGLN("write file failed, %d/%d", ret, strlen(buf));
447*10465441SEvalZero ret = -1;
448*10465441SEvalZero }
449*10465441SEvalZero else {
450*10465441SEvalZero MSGLN("write %d bytes to file, content: %s", ret, buf);
451*10465441SEvalZero ret = 0;
452*10465441SEvalZero }
453*10465441SEvalZero
454*10465441SEvalZero uffs_close(fd);
455*10465441SEvalZero
456*10465441SEvalZero return ret;
457*10465441SEvalZero fail:
458*10465441SEvalZero return -1;
459*10465441SEvalZero }
460*10465441SEvalZero
461*10465441SEvalZero
462*10465441SEvalZero /* usage: t_pgrw
463*10465441SEvalZero *
464*10465441SEvalZero * This test case test page read/write
465*10465441SEvalZero */
cmd_TestPageReadWrite(int argc,char * argv[])466*10465441SEvalZero static int cmd_TestPageReadWrite(int argc, char *argv[])
467*10465441SEvalZero {
468*10465441SEvalZero TreeNode *node = NULL;
469*10465441SEvalZero uffs_Device *dev;
470*10465441SEvalZero uffs_Tags local_tag;
471*10465441SEvalZero uffs_Tags *tag = &local_tag;
472*10465441SEvalZero int ret;
473*10465441SEvalZero u16 block;
474*10465441SEvalZero u16 page;
475*10465441SEvalZero uffs_Buf *buf = NULL;
476*10465441SEvalZero
477*10465441SEvalZero u32 i;
478*10465441SEvalZero int rc = -1;
479*10465441SEvalZero
480*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint("/");
481*10465441SEvalZero if (!dev)
482*10465441SEvalZero goto ext;
483*10465441SEvalZero
484*10465441SEvalZero buf = uffs_BufClone(dev, NULL);
485*10465441SEvalZero if (!buf)
486*10465441SEvalZero goto ext;
487*10465441SEvalZero
488*10465441SEvalZero node = uffs_TreeGetErasedNode(dev);
489*10465441SEvalZero if (!node) {
490*10465441SEvalZero MSGLN("no free block ?");
491*10465441SEvalZero goto ext;
492*10465441SEvalZero }
493*10465441SEvalZero
494*10465441SEvalZero for (i = 0; i < dev->com.pg_data_size; i++) {
495*10465441SEvalZero buf->data[i] = i & 0xFF;
496*10465441SEvalZero }
497*10465441SEvalZero
498*10465441SEvalZero block = node->u.list.block;
499*10465441SEvalZero page = 1;
500*10465441SEvalZero
501*10465441SEvalZero TAG_DIRTY_BIT(tag) = TAG_DIRTY;
502*10465441SEvalZero TAG_VALID_BIT(tag) = TAG_VALID;
503*10465441SEvalZero TAG_DATA_LEN(tag) = dev->com.pg_data_size;
504*10465441SEvalZero TAG_TYPE(tag) = UFFS_TYPE_DATA;
505*10465441SEvalZero TAG_PAGE_ID(tag) = 3;
506*10465441SEvalZero TAG_PARENT(tag) = 100;
507*10465441SEvalZero TAG_SERIAL(tag) = 10;
508*10465441SEvalZero TAG_BLOCK_TS(tag) = 1;
509*10465441SEvalZero SEAL_TAG(tag);
510*10465441SEvalZero
511*10465441SEvalZero ret = uffs_FlashWritePageCombine(dev, block, page, buf, tag);
512*10465441SEvalZero if (UFFS_FLASH_HAVE_ERR(ret)) {
513*10465441SEvalZero MSGLN("Write page error: %d", ret);
514*10465441SEvalZero goto ext;
515*10465441SEvalZero }
516*10465441SEvalZero
517*10465441SEvalZero ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE);
518*10465441SEvalZero if (UFFS_FLASH_HAVE_ERR(ret)) {
519*10465441SEvalZero MSGLN("Read page error: %d", ret);
520*10465441SEvalZero goto ext;
521*10465441SEvalZero }
522*10465441SEvalZero
523*10465441SEvalZero for (i = 0; i < dev->com.pg_data_size; i++) {
524*10465441SEvalZero if (buf->data[i] != (i & 0xFF)) {
525*10465441SEvalZero MSGLN("Data verify fail at: %d", i);
526*10465441SEvalZero goto ext;
527*10465441SEvalZero }
528*10465441SEvalZero }
529*10465441SEvalZero
530*10465441SEvalZero ret = uffs_FlashReadPageTag(dev, block, page, tag);
531*10465441SEvalZero if (UFFS_FLASH_HAVE_ERR(ret)) {
532*10465441SEvalZero MSGLN("Read tag (page spare) error: %d", ret);
533*10465441SEvalZero goto ext;
534*10465441SEvalZero }
535*10465441SEvalZero
536*10465441SEvalZero // verify tag:
537*10465441SEvalZero if (!TAG_IS_SEALED(tag)) {
538*10465441SEvalZero MSGLN("not sealed ? Tag verify fail!");
539*10465441SEvalZero goto ext;
540*10465441SEvalZero }
541*10465441SEvalZero
542*10465441SEvalZero if (!TAG_IS_DIRTY(tag)) {
543*10465441SEvalZero MSGLN("not dirty ? Tag verify fail!");
544*10465441SEvalZero goto ext;
545*10465441SEvalZero }
546*10465441SEvalZero
547*10465441SEvalZero if (!TAG_IS_VALID(tag)) {
548*10465441SEvalZero MSGLN("not valid ? Tag verify fail!");
549*10465441SEvalZero goto ext;
550*10465441SEvalZero }
551*10465441SEvalZero
552*10465441SEvalZero if (TAG_DATA_LEN(tag) != dev->com.pg_data_size ||
553*10465441SEvalZero TAG_TYPE(tag) != UFFS_TYPE_DATA ||
554*10465441SEvalZero TAG_PAGE_ID(tag) != 3 ||
555*10465441SEvalZero TAG_PARENT(tag) != 100 ||
556*10465441SEvalZero TAG_SERIAL(tag) != 10 ||
557*10465441SEvalZero TAG_BLOCK_TS(tag) != 1) {
558*10465441SEvalZero
559*10465441SEvalZero MSGLN("Tag verify fail!");
560*10465441SEvalZero goto ext;
561*10465441SEvalZero }
562*10465441SEvalZero
563*10465441SEvalZero MSGLN("Page read/write test succ.");
564*10465441SEvalZero rc = 0;
565*10465441SEvalZero
566*10465441SEvalZero ext:
567*10465441SEvalZero if (node) {
568*10465441SEvalZero uffs_FlashEraseBlock(dev, node->u.list.block);
569*10465441SEvalZero if (HAVE_BADBLOCK(dev))
570*10465441SEvalZero uffs_BadBlockProcess(dev, node);
571*10465441SEvalZero else
572*10465441SEvalZero uffs_TreeInsertToErasedListTail(dev, node);
573*10465441SEvalZero }
574*10465441SEvalZero
575*10465441SEvalZero if (dev)
576*10465441SEvalZero uffs_PutDevice(dev);
577*10465441SEvalZero
578*10465441SEvalZero if (buf)
579*10465441SEvalZero uffs_BufFreeClone(dev, buf);
580*10465441SEvalZero
581*10465441SEvalZero return rc;
582*10465441SEvalZero }
583*10465441SEvalZero
584*10465441SEvalZero /* t_format : test format partition */
cmd_TestFormat(int argc,char * argv[])585*10465441SEvalZero static int cmd_TestFormat(int argc, char *argv[])
586*10465441SEvalZero {
587*10465441SEvalZero URET ret;
588*10465441SEvalZero const char *mount = "/";
589*10465441SEvalZero uffs_Device *dev;
590*10465441SEvalZero UBOOL force = U_FALSE;
591*10465441SEvalZero const char *test_file = "/a.txt";
592*10465441SEvalZero int fd;
593*10465441SEvalZero int rc = -1;
594*10465441SEvalZero
595*10465441SEvalZero if (argc > 1) {
596*10465441SEvalZero mount = argv[1];
597*10465441SEvalZero if (argc > 2 && strcmp(argv[2], "-f") == 0)
598*10465441SEvalZero force = U_TRUE;
599*10465441SEvalZero }
600*10465441SEvalZero
601*10465441SEvalZero fd = uffs_open(test_file, UO_RDWR | UO_CREATE);
602*10465441SEvalZero if (fd < 0) {
603*10465441SEvalZero MSGLN("can't create test file %s", test_file);
604*10465441SEvalZero goto ext;
605*10465441SEvalZero }
606*10465441SEvalZero
607*10465441SEvalZero MSGLN("Formating %s ... ", mount);
608*10465441SEvalZero
609*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
610*10465441SEvalZero if (dev == NULL) {
611*10465441SEvalZero MSGLN("Can't get device from mount point.");
612*10465441SEvalZero goto ext;
613*10465441SEvalZero }
614*10465441SEvalZero else {
615*10465441SEvalZero ret = uffs_FormatDevice(dev, force);
616*10465441SEvalZero if (ret != U_SUCC) {
617*10465441SEvalZero MSGLN("Format fail.");
618*10465441SEvalZero }
619*10465441SEvalZero else {
620*10465441SEvalZero MSGLN("Format succ.");
621*10465441SEvalZero rc = 0;
622*10465441SEvalZero }
623*10465441SEvalZero uffs_PutDevice(dev);
624*10465441SEvalZero }
625*10465441SEvalZero
626*10465441SEvalZero uffs_close(fd); // this should fail on signature check !
627*10465441SEvalZero ext:
628*10465441SEvalZero return rc;
629*10465441SEvalZero }
630*10465441SEvalZero
631*10465441SEvalZero
632*10465441SEvalZero
633*10465441SEvalZero /**
634*10465441SEvalZero * usage: t_pfs <start> <n>
635*10465441SEvalZero *
636*10465441SEvalZero * for example: t_pfs /x/ 100
637*10465441SEvalZero *
638*10465441SEvalZero * This test case performs:
639*10465441SEvalZero * 1) create <n> files under <start>, write full file name as file content
640*10465441SEvalZero * 2) list files under <start>, check files are all listed once
641*10465441SEvalZero * 3) check file content aganist file name
642*10465441SEvalZero * 4) delete files on success
643*10465441SEvalZero */
cmd_TestPopulateFiles(int argc,char * argv[])644*10465441SEvalZero static int cmd_TestPopulateFiles(int argc, char *argv[])
645*10465441SEvalZero {
646*10465441SEvalZero const char *start = "/";
647*10465441SEvalZero int count = 80;
648*10465441SEvalZero int i, fd, num;
649*10465441SEvalZero char name[128];
650*10465441SEvalZero char buf[128];
651*10465441SEvalZero uffs_DIR *dirp;
652*10465441SEvalZero struct uffs_dirent *ent;
653*10465441SEvalZero unsigned long bitmap[50] = {0}; // one bit per file, maximu 32*50 = 1600 files
654*10465441SEvalZero UBOOL succ = U_TRUE;
655*10465441SEvalZero
656*10465441SEvalZero #define SBIT(n) bitmap[(n)/(sizeof(bitmap[0]) * 8)] |= (1 << ((n) % (sizeof(bitmap[0]) * 8)))
657*10465441SEvalZero #define GBIT(n) (bitmap[(n)/(sizeof(bitmap[0]) * 8)] & (1 << ((n) % (sizeof(bitmap[0]) * 8))))
658*10465441SEvalZero
659*10465441SEvalZero if (argc > 1) {
660*10465441SEvalZero start = argv[1];
661*10465441SEvalZero if (argc > 2) {
662*10465441SEvalZero count = strtol(argv[2], NULL, 10);
663*10465441SEvalZero }
664*10465441SEvalZero }
665*10465441SEvalZero
666*10465441SEvalZero if (count > sizeof(bitmap) * 8)
667*10465441SEvalZero count = sizeof(bitmap) * 8;
668*10465441SEvalZero
669*10465441SEvalZero for (i = 0, fd = -1; i < count; i++) {
670*10465441SEvalZero sprintf(name, "%sFile%03d", start, i);
671*10465441SEvalZero fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC);
672*10465441SEvalZero if (fd < 0) {
673*10465441SEvalZero MSGLN("Create file %s failed", name);
674*10465441SEvalZero break;
675*10465441SEvalZero }
676*10465441SEvalZero if (uffs_write(fd, name, strlen(name)) != strlen(name)) { // write full path name to file
677*10465441SEvalZero MSGLN("Write to file %s failed", name);
678*10465441SEvalZero uffs_close(fd);
679*10465441SEvalZero break;
680*10465441SEvalZero }
681*10465441SEvalZero uffs_close(fd);
682*10465441SEvalZero }
683*10465441SEvalZero
684*10465441SEvalZero if (i < count) {
685*10465441SEvalZero // not success, need to clean up
686*10465441SEvalZero for (; i >= 0; i--) {
687*10465441SEvalZero sprintf(name, "%sFile%03d", start, i);
688*10465441SEvalZero if (uffs_remove(name) < 0)
689*10465441SEvalZero MSGLN("Delete file %s failed", name);
690*10465441SEvalZero }
691*10465441SEvalZero succ = U_FALSE;
692*10465441SEvalZero goto ext;
693*10465441SEvalZero }
694*10465441SEvalZero
695*10465441SEvalZero MSGLN("%d files created.", count);
696*10465441SEvalZero
697*10465441SEvalZero // list files
698*10465441SEvalZero dirp = uffs_opendir(start);
699*10465441SEvalZero if (dirp == NULL) {
700*10465441SEvalZero MSGLN("Can't open dir %s !", start);
701*10465441SEvalZero succ = U_FALSE;
702*10465441SEvalZero goto ext;
703*10465441SEvalZero }
704*10465441SEvalZero ent = uffs_readdir(dirp);
705*10465441SEvalZero while (ent && succ) {
706*10465441SEvalZero
707*10465441SEvalZero if (!(ent->d_type & FILE_ATTR_DIR) && // not a dir
708*10465441SEvalZero ent->d_namelen == strlen("File000") && // check file name length
709*10465441SEvalZero memcmp(ent->d_name, "File", strlen("File")) == 0) { // file name start with "File"
710*10465441SEvalZero
711*10465441SEvalZero MSGLN("List entry %s", ent->d_name);
712*10465441SEvalZero
713*10465441SEvalZero num = strtol(ent->d_name + 4, NULL, 10);
714*10465441SEvalZero if (GBIT(num)) {
715*10465441SEvalZero // file already listed ?
716*10465441SEvalZero MSGLN("File %d listed twice !", ent->d_name);
717*10465441SEvalZero succ = U_FALSE;
718*10465441SEvalZero break;
719*10465441SEvalZero }
720*10465441SEvalZero SBIT(num);
721*10465441SEvalZero
722*10465441SEvalZero // check file content
723*10465441SEvalZero sprintf(name, "%s%s", start, ent->d_name);
724*10465441SEvalZero fd = uffs_open(name, UO_RDONLY);
725*10465441SEvalZero if (fd < 0) {
726*10465441SEvalZero MSGLN("Open file %d for read failed !", name);
727*10465441SEvalZero }
728*10465441SEvalZero else {
729*10465441SEvalZero memset(buf, 0, sizeof(buf));
730*10465441SEvalZero num = uffs_read(fd, buf, sizeof(buf));
731*10465441SEvalZero if (num != strlen(name)) {
732*10465441SEvalZero MSGLN("%s Read data length expect %d but got %d !", name, strlen(name), num);
733*10465441SEvalZero succ = U_FALSE;
734*10465441SEvalZero }
735*10465441SEvalZero else {
736*10465441SEvalZero if (memcmp(name, buf, num) != 0) {
737*10465441SEvalZero MSGLN("File %s have wrong content '%s' !", name, buf);
738*10465441SEvalZero succ = U_FALSE;
739*10465441SEvalZero }
740*10465441SEvalZero }
741*10465441SEvalZero uffs_close(fd);
742*10465441SEvalZero }
743*10465441SEvalZero }
744*10465441SEvalZero ent = uffs_readdir(dirp);
745*10465441SEvalZero }
746*10465441SEvalZero uffs_closedir(dirp);
747*10465441SEvalZero
748*10465441SEvalZero // check absent files
749*10465441SEvalZero for (i = 0; i < count; i++) {
750*10465441SEvalZero if (GBIT(i) == 0) {
751*10465441SEvalZero sprintf(name, "%sFile%03d", start, i);
752*10465441SEvalZero MSGLN("File %s not listed !", name);
753*10465441SEvalZero succ = U_FALSE;
754*10465441SEvalZero }
755*10465441SEvalZero }
756*10465441SEvalZero
757*10465441SEvalZero // delete files if pass the test
758*10465441SEvalZero for (i = 0; succ && i < count; i++) {
759*10465441SEvalZero sprintf(name, "%sFile%03d", start, i);
760*10465441SEvalZero if (uffs_remove(name) < 0) {
761*10465441SEvalZero MSGLN("Delete file %s failed", name);
762*10465441SEvalZero succ = U_FALSE;
763*10465441SEvalZero }
764*10465441SEvalZero }
765*10465441SEvalZero
766*10465441SEvalZero ext:
767*10465441SEvalZero MSGLN("Populate files test %s !", succ ? "SUCC" : "FAILED");
768*10465441SEvalZero return succ ? 0 : -1;
769*10465441SEvalZero
770*10465441SEvalZero }
771*10465441SEvalZero
772*10465441SEvalZero /**
773*10465441SEvalZero * Open <file> with <oflag>, save fd to $1
774*10465441SEvalZero *
775*10465441SEvalZero * t_open <oflag> <file>
776*10465441SEvalZero */
cmd_topen(int argc,char * argv[])777*10465441SEvalZero static int cmd_topen(int argc, char *argv[])
778*10465441SEvalZero {
779*10465441SEvalZero int fd;
780*10465441SEvalZero const char *name;
781*10465441SEvalZero char *p;
782*10465441SEvalZero int oflag = 0;
783*10465441SEvalZero
784*10465441SEvalZero CHK_ARGC(3, 3);
785*10465441SEvalZero
786*10465441SEvalZero name = argv[2];
787*10465441SEvalZero p = argv[1];
788*10465441SEvalZero while(*p) {
789*10465441SEvalZero switch(*p++) {
790*10465441SEvalZero case 'a':
791*10465441SEvalZero oflag |= UO_APPEND;
792*10465441SEvalZero break;
793*10465441SEvalZero case 'c':
794*10465441SEvalZero oflag |= UO_CREATE;
795*10465441SEvalZero break;
796*10465441SEvalZero case 't':
797*10465441SEvalZero oflag |= UO_TRUNC;
798*10465441SEvalZero break;
799*10465441SEvalZero case 'w':
800*10465441SEvalZero oflag |= UO_RDWR;
801*10465441SEvalZero break;
802*10465441SEvalZero case 'r':
803*10465441SEvalZero oflag |= UO_RDONLY;
804*10465441SEvalZero break;
805*10465441SEvalZero }
806*10465441SEvalZero }
807*10465441SEvalZero
808*10465441SEvalZero fd = uffs_open(name, oflag);
809*10465441SEvalZero
810*10465441SEvalZero if (fd >= 0) {
811*10465441SEvalZero cli_env_set('1', fd);
812*10465441SEvalZero return 0;
813*10465441SEvalZero }
814*10465441SEvalZero else {
815*10465441SEvalZero return -1;
816*10465441SEvalZero }
817*10465441SEvalZero }
818*10465441SEvalZero
819*10465441SEvalZero /**
820*10465441SEvalZero * seek file pointer
821*10465441SEvalZero * t_seek <fd> <offset> [<origin>]
822*10465441SEvalZero * if success, $1 = file position after seek
823*10465441SEvalZero */
cmd_tseek(int argc,char * argv[])824*10465441SEvalZero static int cmd_tseek(int argc, char *argv[])
825*10465441SEvalZero {
826*10465441SEvalZero int origin = USEEK_SET;
827*10465441SEvalZero int offset;
828*10465441SEvalZero int fd;
829*10465441SEvalZero int ret;
830*10465441SEvalZero
831*10465441SEvalZero CHK_ARGC(3, 4);
832*10465441SEvalZero
833*10465441SEvalZero if (sscanf(argv[1], "%d", &fd) != 1 ||
834*10465441SEvalZero sscanf(argv[2], "%d", &offset) != 1)
835*10465441SEvalZero {
836*10465441SEvalZero return CLI_INVALID_ARG;
837*10465441SEvalZero }
838*10465441SEvalZero
839*10465441SEvalZero if (argc > 3) {
840*10465441SEvalZero switch(argv[3][0]) {
841*10465441SEvalZero case 's':
842*10465441SEvalZero origin = USEEK_SET;
843*10465441SEvalZero break;
844*10465441SEvalZero case 'c':
845*10465441SEvalZero origin = USEEK_CUR;
846*10465441SEvalZero break;
847*10465441SEvalZero case 'e':
848*10465441SEvalZero origin = USEEK_END;
849*10465441SEvalZero break;
850*10465441SEvalZero default:
851*10465441SEvalZero return CLI_INVALID_ARG;
852*10465441SEvalZero }
853*10465441SEvalZero }
854*10465441SEvalZero
855*10465441SEvalZero ret = uffs_seek(fd, offset, origin);
856*10465441SEvalZero if (ret >= 0) {
857*10465441SEvalZero cli_env_set('1', ret);
858*10465441SEvalZero return 0;
859*10465441SEvalZero }
860*10465441SEvalZero else {
861*10465441SEvalZero return -1;
862*10465441SEvalZero }
863*10465441SEvalZero }
864*10465441SEvalZero
865*10465441SEvalZero /**
866*10465441SEvalZero * close file
867*10465441SEvalZero * t_close <fd>
868*10465441SEvalZero */
cmd_tclose(int argc,char * argv[])869*10465441SEvalZero static int cmd_tclose(int argc, char *argv[])
870*10465441SEvalZero {
871*10465441SEvalZero int fd;
872*10465441SEvalZero
873*10465441SEvalZero CHK_ARGC(2, 2);
874*10465441SEvalZero
875*10465441SEvalZero if (sscanf(argv[1], "%d", &fd) == 1) {
876*10465441SEvalZero return uffs_close(fd);
877*10465441SEvalZero }
878*10465441SEvalZero else
879*10465441SEvalZero return -1;
880*10465441SEvalZero }
881*10465441SEvalZero
882*10465441SEvalZero /**
883*10465441SEvalZero * write file
884*10465441SEvalZero * t_write <fd> <txt> [..]
885*10465441SEvalZero */
cmd_twrite(int argc,char * argv[])886*10465441SEvalZero static int cmd_twrite(int argc, char *argv[])
887*10465441SEvalZero {
888*10465441SEvalZero int fd;
889*10465441SEvalZero int i, len = 0;
890*10465441SEvalZero int ret = 0;
891*10465441SEvalZero
892*10465441SEvalZero CHK_ARGC(3, 0);
893*10465441SEvalZero if (sscanf(argv[1], "%d", &fd) != 1) {
894*10465441SEvalZero return -1;
895*10465441SEvalZero }
896*10465441SEvalZero else {
897*10465441SEvalZero for (i = 2; i < argc; i++) {
898*10465441SEvalZero len = strlen(argv[i]);
899*10465441SEvalZero if (uffs_write(fd, argv[i], len) != len) {
900*10465441SEvalZero ret = -1;
901*10465441SEvalZero break;
902*10465441SEvalZero }
903*10465441SEvalZero }
904*10465441SEvalZero }
905*10465441SEvalZero
906*10465441SEvalZero if (ret == 0)
907*10465441SEvalZero cli_env_set('1', len);
908*10465441SEvalZero
909*10465441SEvalZero return ret;
910*10465441SEvalZero }
911*10465441SEvalZero
912*10465441SEvalZero /**
913*10465441SEvalZero * read and check seq file
914*10465441SEvalZero * t_check_seq <fd> <size>
915*10465441SEvalZero */
cmd_tcheck_seq(int argc,char * argv[])916*10465441SEvalZero static int cmd_tcheck_seq(int argc, char *argv[])
917*10465441SEvalZero {
918*10465441SEvalZero int fd;
919*10465441SEvalZero int len, size;
920*10465441SEvalZero int ret = 0, r_ret = 0;
921*10465441SEvalZero long pos;
922*10465441SEvalZero u8 buf[MAX_TEST_BUF_LEN];
923*10465441SEvalZero int i;
924*10465441SEvalZero u8 x;
925*10465441SEvalZero
926*10465441SEvalZero CHK_ARGC(3, 3);
927*10465441SEvalZero
928*10465441SEvalZero if (sscanf(argv[1], "%d", &fd) != 1) {
929*10465441SEvalZero return -1;
930*10465441SEvalZero }
931*10465441SEvalZero
932*10465441SEvalZero if (sscanf(argv[2], "%d", &len) != 1) {
933*10465441SEvalZero return -1;
934*10465441SEvalZero }
935*10465441SEvalZero
936*10465441SEvalZero pos = uffs_tell(fd);
937*10465441SEvalZero while (len > 0) {
938*10465441SEvalZero size = (len > sizeof(buf) ? sizeof(buf) : len);
939*10465441SEvalZero if ((r_ret = uffs_read(fd, buf, size)) < 0) {
940*10465441SEvalZero MSGLN("Read fail! fd = %d, size = %d, pos = %ld", fd, size, pos);
941*10465441SEvalZero ret = -1;
942*10465441SEvalZero break;
943*10465441SEvalZero }
944*10465441SEvalZero
945*10465441SEvalZero // check seq
946*10465441SEvalZero for (i = 0; i < r_ret; i++) {
947*10465441SEvalZero x = (pos + SEQ_INIT + i) % SEQ_MOD_LEN;
948*10465441SEvalZero if (buf[i] != x) {
949*10465441SEvalZero MSGLN("Check fail! fd = %d, pos = %ld (expect 0x%02x but 0x%02x)\n", fd, pos + i, x, buf[i]);
950*10465441SEvalZero ret = -1;
951*10465441SEvalZero break;
952*10465441SEvalZero }
953*10465441SEvalZero }
954*10465441SEvalZero
955*10465441SEvalZero if (ret < 0)
956*10465441SEvalZero break;
957*10465441SEvalZero
958*10465441SEvalZero len -= r_ret;
959*10465441SEvalZero pos += r_ret;
960*10465441SEvalZero }
961*10465441SEvalZero
962*10465441SEvalZero return ret;
963*10465441SEvalZero }
964*10465441SEvalZero
965*10465441SEvalZero
966*10465441SEvalZero
967*10465441SEvalZero /**
968*10465441SEvalZero * write random seq to file
969*10465441SEvalZero * t_write_seq <fd> <size>
970*10465441SEvalZero */
cmd_twrite_seq(int argc,char * argv[])971*10465441SEvalZero static int cmd_twrite_seq(int argc, char *argv[])
972*10465441SEvalZero {
973*10465441SEvalZero int fd;
974*10465441SEvalZero int len = 0, size = 0;
975*10465441SEvalZero long pos = 0;
976*10465441SEvalZero int ret = 0, w_ret = 0;
977*10465441SEvalZero u8 buf[MAX_TEST_BUF_LEN];
978*10465441SEvalZero
979*10465441SEvalZero CHK_ARGC(3, 3);
980*10465441SEvalZero if (sscanf(argv[1], "%d", &fd) != 1) {
981*10465441SEvalZero return -1;
982*10465441SEvalZero }
983*10465441SEvalZero
984*10465441SEvalZero if (sscanf(argv[2], "%d", &len) != 1) {
985*10465441SEvalZero return -1;
986*10465441SEvalZero }
987*10465441SEvalZero
988*10465441SEvalZero pos = uffs_tell(fd);
989*10465441SEvalZero while (len > 0) {
990*10465441SEvalZero size = (len < sizeof(buf) ? len : sizeof(buf));
991*10465441SEvalZero memcp_seq(buf, size, pos);
992*10465441SEvalZero if ((w_ret = uffs_write(fd, buf, size)) < 0) {
993*10465441SEvalZero MSGLN("write fail! fd = %d, size = %d, pos = %ld", fd, size, pos);
994*10465441SEvalZero ret = -1;
995*10465441SEvalZero break;
996*10465441SEvalZero }
997*10465441SEvalZero pos += w_ret;
998*10465441SEvalZero len -= w_ret;
999*10465441SEvalZero }
1000*10465441SEvalZero
1001*10465441SEvalZero if (ret == 0)
1002*10465441SEvalZero cli_env_set('1', len);
1003*10465441SEvalZero
1004*10465441SEvalZero return ret;
1005*10465441SEvalZero }
1006*10465441SEvalZero
1007*10465441SEvalZero
1008*10465441SEvalZero /**
1009*10465441SEvalZero * read and check file
1010*10465441SEvalZero * t_read <fd> <txt>
1011*10465441SEvalZero */
cmd_tread(int argc,char * argv[])1012*10465441SEvalZero static int cmd_tread(int argc, char *argv[])
1013*10465441SEvalZero {
1014*10465441SEvalZero int fd;
1015*10465441SEvalZero int len, n;
1016*10465441SEvalZero int ret = 0;
1017*10465441SEvalZero char buf[64];
1018*10465441SEvalZero char *p;
1019*10465441SEvalZero
1020*10465441SEvalZero CHK_ARGC(3, 3);
1021*10465441SEvalZero
1022*10465441SEvalZero if (sscanf(argv[1], "%d", &fd) != 1) {
1023*10465441SEvalZero return -1;
1024*10465441SEvalZero }
1025*10465441SEvalZero else {
1026*10465441SEvalZero len = strlen(argv[2]);
1027*10465441SEvalZero n = 0;
1028*10465441SEvalZero p = argv[2];
1029*10465441SEvalZero while (n < len) {
1030*10465441SEvalZero n = (len > sizeof(buf) ? sizeof(buf) : len);
1031*10465441SEvalZero if (uffs_read(fd, buf, n) != n ||
1032*10465441SEvalZero memcmp(buf, p, n) != 0) {
1033*10465441SEvalZero ret = -1;
1034*10465441SEvalZero break;
1035*10465441SEvalZero }
1036*10465441SEvalZero len -= n;
1037*10465441SEvalZero p += n;
1038*10465441SEvalZero }
1039*10465441SEvalZero }
1040*10465441SEvalZero
1041*10465441SEvalZero return ret;
1042*10465441SEvalZero }
1043*10465441SEvalZero
1044*10465441SEvalZero
do_dump_page(uffs_Device * dev,uffs_Buf * buf)1045*10465441SEvalZero static void do_dump_page(uffs_Device *dev, uffs_Buf *buf)
1046*10465441SEvalZero {
1047*10465441SEvalZero int i, j;
1048*10465441SEvalZero const int line = 16;
1049*10465441SEvalZero struct uffs_MiniHeaderSt *header = (struct uffs_MiniHeaderSt *)buf->header;
1050*10465441SEvalZero MSG(" header.status = %d\n", header->status);
1051*10465441SEvalZero if (header->status != 0xFF) {
1052*10465441SEvalZero for (i = 0; i < 64; i += line) {
1053*10465441SEvalZero MSG(" ");
1054*10465441SEvalZero for (j = 0; j < line; j++)
1055*10465441SEvalZero MSG("%02X ", buf->header[i+j]);
1056*10465441SEvalZero MSG("\n");
1057*10465441SEvalZero }
1058*10465441SEvalZero MSG("\n");
1059*10465441SEvalZero }
1060*10465441SEvalZero }
1061*10465441SEvalZero
do_dump_tag(uffs_Device * dev,uffs_Tags * tag)1062*10465441SEvalZero static void do_dump_tag(uffs_Device *dev, uffs_Tags *tag)
1063*10465441SEvalZero {
1064*10465441SEvalZero MSG(" tag sealed: %s\n", TAG_IS_SEALED(tag) ? "yes" : "no");
1065*10465441SEvalZero if (TAG_IS_GOOD(tag)) {
1066*10465441SEvalZero if (TAG_IS_DIRTY(tag)) {
1067*10465441SEvalZero MSG(" block_ts = %d\n", tag->s.block_ts);
1068*10465441SEvalZero MSG(" type = %d\n", tag->s.type);
1069*10465441SEvalZero MSG(" dirty = %d\n", tag->s.dirty);
1070*10465441SEvalZero MSG(" page_id = %d\n", tag->s.page_id);
1071*10465441SEvalZero MSG(" serial = %d\n", tag->s.serial);
1072*10465441SEvalZero MSG(" parent = %d\n", tag->s.parent);
1073*10465441SEvalZero MSG(" data_len = %d\n", tag->s.data_len);
1074*10465441SEvalZero }
1075*10465441SEvalZero else {
1076*10465441SEvalZero MSG(" tag is GOOD but NOT DIRTY !!!???\n");
1077*10465441SEvalZero }
1078*10465441SEvalZero }
1079*10465441SEvalZero else if (TAG_IS_SEALED(tag)) {
1080*10465441SEvalZero MSG(" tag is INVALID\n");
1081*10465441SEvalZero }
1082*10465441SEvalZero }
1083*10465441SEvalZero
do_dump_device(uffs_Device * dev)1084*10465441SEvalZero static void do_dump_device(uffs_Device *dev)
1085*10465441SEvalZero {
1086*10465441SEvalZero URET ret;
1087*10465441SEvalZero int block, page;
1088*10465441SEvalZero uffs_Tags tag;
1089*10465441SEvalZero uffs_Buf *buf;
1090*10465441SEvalZero
1091*10465441SEvalZero buf = uffs_BufClone(dev, NULL);
1092*10465441SEvalZero if (buf == NULL) {
1093*10465441SEvalZero MSGLN("Can't clone buf");
1094*10465441SEvalZero return;
1095*10465441SEvalZero }
1096*10465441SEvalZero
1097*10465441SEvalZero for (block = dev->par.start; block <= dev->par.end; block++) {
1098*10465441SEvalZero MSG("---- block %d ----\n", block);
1099*10465441SEvalZero for (page = 0; page < dev->attr->pages_per_block; page++) {
1100*10465441SEvalZero MSG(" == page %d ==\n", page);
1101*10465441SEvalZero ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE);
1102*10465441SEvalZero if (UFFS_FLASH_HAVE_ERR(ret)) {
1103*10465441SEvalZero MSG(" !!! Read page failed, ret = %d !!!\n", ret);
1104*10465441SEvalZero }
1105*10465441SEvalZero else {
1106*10465441SEvalZero do_dump_page(dev, buf);
1107*10465441SEvalZero if (buf->header[0] != 0xFF) {
1108*10465441SEvalZero ret = uffs_FlashReadPageTag(dev, block, page, &tag);
1109*10465441SEvalZero if (UFFS_FLASH_HAVE_ERR(ret)) {
1110*10465441SEvalZero MSG(" !!! Read TAG failed, ret = %d !!!\n", ret);
1111*10465441SEvalZero }
1112*10465441SEvalZero else {
1113*10465441SEvalZero do_dump_tag(dev, &tag);
1114*10465441SEvalZero }
1115*10465441SEvalZero }
1116*10465441SEvalZero }
1117*10465441SEvalZero }
1118*10465441SEvalZero }
1119*10465441SEvalZero uffs_BufFreeClone(dev, buf);
1120*10465441SEvalZero }
1121*10465441SEvalZero
cmd_dump(int argc,char * argv[])1122*10465441SEvalZero static int cmd_dump(int argc, char *argv[])
1123*10465441SEvalZero {
1124*10465441SEvalZero const char *mount = "/";
1125*10465441SEvalZero uffs_Device *dev;
1126*10465441SEvalZero
1127*10465441SEvalZero if (argc > 1) {
1128*10465441SEvalZero mount = argv[1];
1129*10465441SEvalZero }
1130*10465441SEvalZero
1131*10465441SEvalZero MSGLN("Dumping %s ... ", mount);
1132*10465441SEvalZero
1133*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
1134*10465441SEvalZero if (dev == NULL) {
1135*10465441SEvalZero MSGLN("Can't get device from mount point.");
1136*10465441SEvalZero }
1137*10465441SEvalZero else {
1138*10465441SEvalZero do_dump_device(dev);
1139*10465441SEvalZero uffs_PutDevice(dev);
1140*10465441SEvalZero }
1141*10465441SEvalZero
1142*10465441SEvalZero return 0;
1143*10465441SEvalZero }
1144*10465441SEvalZero
cmd_apisrv(int argc,char * argv[])1145*10465441SEvalZero static int cmd_apisrv(int argc, char *argv[])
1146*10465441SEvalZero {
1147*10465441SEvalZero return api_server_start();
1148*10465441SEvalZero }
1149*10465441SEvalZero
1150*10465441SEvalZero static const struct cli_command test_cmds[] =
1151*10465441SEvalZero {
1152*10465441SEvalZero { cmd_t1, "t1", "<name>", "test 1" },
1153*10465441SEvalZero { cmd_t2, "t2", NULL, "test 2" },
1154*10465441SEvalZero { cmd_t3, "t3", "<name> [<noecc>]", "test 3" },
1155*10465441SEvalZero { cmd_t4, "t4", NULL, "test 4" },
1156*10465441SEvalZero { cmd_t5, "t5", "<name>", "test 5" },
1157*10465441SEvalZero { cmd_TestPageReadWrite, "t_pgrw", NULL, "test page read/write" },
1158*10465441SEvalZero { cmd_TestFormat, "t_format", NULL, "test format file system" },
1159*10465441SEvalZero { cmd_TestPopulateFiles, "t_pfs", "[<start> [<n>]]", "test populate <n> files under <start>" },
1160*10465441SEvalZero { cmd_VerifyFile, "t_vf", "<file> [<noecc>]", "verify file" },
1161*10465441SEvalZero
1162*10465441SEvalZero { cmd_topen, "t_open", "<oflg> <file>", "open file, fd save to $1", },
1163*10465441SEvalZero { cmd_tread, "t_read", "<fd> <txt>", "read <fd> and check against <txt>", },
1164*10465441SEvalZero { cmd_tcheck_seq, "t_check_seq", "<fd> <size>", "read seq file <fd> and check", },
1165*10465441SEvalZero { cmd_twrite, "t_write", "<fd> <txt> [...]", "write <fd>", },
1166*10465441SEvalZero { cmd_twrite_seq, "t_write_seq", "<fd> <size>", "write seq file <fd>", },
1167*10465441SEvalZero { cmd_tseek, "t_seek", "<fd> <offset> [<origin>]", "seek <fd> file pointer to <offset> from <origin>", },
1168*10465441SEvalZero { cmd_tclose, "t_close", "<fd>", "close <fd>", },
1169*10465441SEvalZero { cmd_dump, "dump", "<mount>", "dump <mount>", },
1170*10465441SEvalZero
1171*10465441SEvalZero { cmd_apisrv, "apisrv", NULL, "start API test server", },
1172*10465441SEvalZero
1173*10465441SEvalZero { NULL, NULL, NULL, NULL }
1174*10465441SEvalZero };
1175*10465441SEvalZero
1176*10465441SEvalZero static struct cli_commandset test_cmdset = {
1177*10465441SEvalZero test_cmds,
1178*10465441SEvalZero };
1179*10465441SEvalZero
get_test_cmds()1180*10465441SEvalZero struct cli_commandset * get_test_cmds()
1181*10465441SEvalZero {
1182*10465441SEvalZero return &test_cmdset;
1183*10465441SEvalZero };
1184*10465441SEvalZero
1185*10465441SEvalZero
1186*10465441SEvalZero
1187