tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / fs / yaffs2 / yaffs_format_data_translate.c
1 //#include "yaffs_packedtags2.h"\r
2 #include "fdl_yaffs2.h"\r
3 #include "yaffs_format_data_translate.h"\r
4 \r
5 #define YAFFS_LOWEST_SEQUENCE_NUMBER    0x00001000\r
6 #define YAFFS_HIGHEST_SEQUENCE_NUMBER   0xEFFFFF00\r
7 #define NULL ((void*)0)\r
8 //global variables\r
9 static unsigned long totalchunk = 0;\r
10 static unsigned long chunknumber = 0;\r
11 /*******************************************************************************\r
12 * this function used to translate yaffs format binary data stream.\r
13 * p_dst_page->p_pagedata        hold the actually one dst 'page' data that needed.\r
14 * the return values:\r
15 * -1    there is an error occured\r
16 * >0    how many src 'pages' has been translated in the src binary data stream.\r
17 ********************************************************************************/\r
18 int yaffs_page_translate(yaffs_page *p_src_page,yaffs_page *p_dst_page){\r
19 \r
20         int ret = -1;\r
21         yaffs_ObjectHeader * pheader = NULL;\r
22         //src chunk\r
23         char *p_src_data = p_src_page->p_pagedata;\r
24         yaffs_PackedTags2 *p_src_spare = (yaffs_PackedTags2*)&p_src_page->p_pagedata[p_src_page->pagesize];\r
25         //dst chunk\r
26         char *p_dst_data = p_dst_page->p_pagedata;\r
27         yaffs_PackedTags2 *p_dst_spare = (yaffs_PackedTags2*)&p_dst_page->p_pagedata[p_dst_page->pagesize];\r
28         //how many src_page become one dst page\r
29         int  count = p_dst_page->pagesize/p_src_page->pagesize;\r
30         //object id,this used to identify which fileobject this chunk belongs to\r
31         unsigned int  object_id = p_src_spare->t.objectId;\r
32 \r
33         if(p_dst_page->pagesize%p_src_page->pagesize != 0){\r
34                 //the translation may become too complex,here we do not cover it.\r
35                 return ret;\r
36         }\r
37 \r
38         //first of all,reset the buffer.\r
39         memset(p_dst_page->p_pagedata,0xff,p_dst_page->pagesize+p_dst_page->oobsize);\r
40         if(p_src_spare->t.chunkId == 0){\r
41                 //header chunk\r
42                 //data\r
43                 memcpy(p_dst_data,p_src_data,p_src_page->pagesize);\r
44                 //spare\r
45                 p_dst_spare->t.chunkId = 0;//p_src_spare->t.chunkId;\r
46                 p_dst_spare->t.sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;\r
47                 p_dst_spare->t.byteCount = p_src_spare->t.byteCount;\r
48                 p_dst_spare->t.objectId = object_id;\r
49                 yaffs_ECCCalculateOther((unsigned char *)&p_dst_spare->t, sizeof(yaffs_PackedTags2TagsPart), &p_dst_spare->ecc);\r
50                 //store the number of trunks hold by this file\r
51                 pheader = (yaffs_ObjectHeader *)p_src_data;\r
52                 if (pheader->type == YAFFS_OBJECT_TYPE_FILE) {\r
53                         totalchunk = (pheader->fileSize + p_src_page->pagesize - 1) / p_src_page->pagesize;\r
54                         chunknumber = 0;\r
55                 }\r
56                 ret = 1;\r
57         }else if(p_src_spare->t.chunkId > 0){\r
58                 //common data chunk\r
59                 unsigned int offset = 0;\r
60                 unsigned int i = count;\r
61                 //data\r
62                 ret = 0;\r
63                 while(i){\r
64                         //every time canculate one 'src' page\r
65                         chunknumber++;\r
66                         if(chunknumber > totalchunk){\r
67                                 //now we run out of the end of the file.\r
68                                 i--;\r
69                                 continue;\r
70                         }\r
71                         if(object_id != p_src_spare->t.objectId){\r
72                                 //the two trunk do not belongs to the same fileobject.error!!\r
73                                 return -1;\r
74                         }\r
75 \r
76                         memcpy(&p_dst_data[offset],p_src_data,p_src_spare->t.byteCount);\r
77                         offset += p_src_spare->t.byteCount;\r
78 \r
79                         //update iterators\r
80                         ret++;\r
81                         i--;\r
82                         p_src_data += p_src_page->pagesize + p_src_page->oobsize;\r
83                         p_src_spare = (yaffs_PackedTags2*)&p_src_data[p_src_page->pagesize];\r
84                 }\r
85                 //spare\r
86                 p_dst_spare->t.chunkId = chunknumber/count;\r
87                 p_dst_spare->t.sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;\r
88                 p_dst_spare->t.byteCount = offset;\r
89                 p_dst_spare->t.objectId = object_id;\r
90                 yaffs_ECCCalculateOther((unsigned char *)&p_dst_spare->t, sizeof(yaffs_PackedTags2TagsPart), &p_dst_spare->ecc);\r
91         }else{\r
92                 //unused chunk,current it means encounter an fatal error.\r
93                 return ret;\r
94         }\r
95 \r
96         //reset global contex\r
97         if(chunknumber >= totalchunk){\r
98                 chunknumber = 0;\r
99                 totalchunk = 0;\r
100         }\r
101 \r
102         return ret;\r
103 }\r