5fb46ea92668479148c0f85cc66f016e1426585b
[profile/mobile/platform/kernel/u-boot-tm1.git] / property / fs_common_rw.c
1 #include <common.h>
2 #include <linux/types.h>
3 #include <linux/string.h>
4 #include <nand.h>
5 #include <jffs2/jffs2.h>
6 #ifdef CONFIG_CMD_UBI
7 #include <ubi_uboot.h>
8 #endif
9 #ifdef  CONFIG_EMMC_BOOT
10 #include "../disk/part_uefi.h"
11 #include "../drivers/mmc/card_sdio.h"
12 #endif
13
14 int do_fs_file_read(char *mpart, char *filenm, void *buf, int len)
15 {
16         int ret=-1;
17 #ifdef CONFIG_FS_EXT4
18         int mmc_dev=1;
19         wchar_t *part=NULL;
20         wchar_t *tmp;
21         part = malloc(sizeof(wchar_t)*(strlen(mpart)+1));
22         if(!part)
23                 return -1;
24         tmp = part;
25         while ((*tmp++ = *mpart++) != '\0')
26                 /* do nothing */;
27         ret = ext4_read_content(mmc_dev,
28                         part,
29                         filenm,
30                         buf,
31                         0,/*not support non-zero offset*/
32                         len);
33         free(part);
34 #elif defined(CONFIG_FS_UBIFS)
35         static int is_ubifs_init = 0;
36         if(is_ubifs_init == 0){
37                 ubifs_init();
38                 is_ubifs_init = 1;
39         }
40
41         ret = ubifs_mount(mpart);
42         if(ret){
43                 printf("do_fs_file_read:mount %s failed!\n",mpart);
44                 return ret;
45         }
46         ret = ubifs_load(filenm, buf, len);
47         if(ret)
48                 printf("do_fs_file_read:file %s not found!\n", filenm);
49 #endif
50         return ret;
51 }
52
53 int do_fs_file_write(char *mpart, char *filenm, void *buf, int len)
54 {
55         /*do not write in uboot now*/
56         return -1;
57 }
58
59 int do_raw_data_read(char *part, u32 size, u32 off, char *buf)
60 {
61         int ret =-1;
62 #ifdef  CONFIG_EMMC_BOOT
63         u16 offp=0, len=0, left=0;
64         u32 nsct, cursct;
65         char *bufwp = buf;
66         char *sctbuf=NULL;
67         wchar_t *partition=NULL;
68         wchar_t *tmp;
69         disk_partition_t info;
70         block_dev_desc_t *dev = NULL;
71
72         if(NULL == buf)
73                 return -1;
74
75         dev = get_dev("mmc", 1);
76         if(NULL == dev){
77                 printf("get mmc dev failed!\n");
78                 return -1;
79         }
80
81         partition = malloc(sizeof(wchar_t)*(strlen(part)+1));
82         if(!partition)
83                 return -1;
84         tmp = partition;
85         while ((*tmp++ = *part++) != '\0');
86
87         offp = off%EMMC_SECTOR_SIZE;
88
89         if(offp)
90                 len = EMMC_SECTOR_SIZE - offp;
91         size = size - len;
92
93         nsct = size/EMMC_SECTOR_SIZE;
94         left = size%EMMC_SECTOR_SIZE;
95
96         if(offp || left){
97                 sctbuf = malloc(EMMC_SECTOR_SIZE);
98                 if(!sctbuf) {
99                         free(partition);
100                         return -1;
101                 }
102         }
103
104         if(get_partition_info_by_name(dev, partition, &info))
105                 goto end;
106
107         cursct = info.start + off/EMMC_SECTOR_SIZE;
108         //read first unaligned data
109         if(offp) {
110                 if(!Emmc_Read(PARTITION_USER, cursct, 1, sctbuf))
111                         goto end;
112                 cursct += 1;
113                 memcpy(bufwp,sctbuf+offp,len);
114                 bufwp += len;
115         }
116         //read sector aligned data
117         if(nsct) {
118                 if(!Emmc_Read(PARTITION_USER, cursct, nsct, bufwp))
119                         goto end;
120                 cursct += nsct;
121                 bufwp += size-left;
122         }
123         //read last unaligned data
124         if(left) {
125                 if(!Emmc_Read(PARTITION_USER, cursct, 1, sctbuf))
126                         goto end;
127                 memcpy(bufwp,sctbuf,left);
128                 bufwp += left;
129         }
130         ret = 0;
131         //debug tmp
132         printf("do_raw_data_read: wanted size :0x%x, real 0x%x\n",size+len,bufwp-buf);
133 end:
134         free(partition);
135         free(sctbuf);
136 #else
137         int ubi_dev;
138         struct ubi_volume_desc *vol;
139
140         ubi_dev = nand_ubi_dev_init();
141         if (ubi_dev<0) {
142                 printf("do_raw_data_read: ubi init failed.\n");
143                 return ret;
144         }
145         vol = ubi_open_volume_nm(ubi_dev, part, UBI_READONLY);
146         if (IS_ERR(vol)) {
147                 printf("cannot open \"%s\", error %d",
148                           part, (int)PTR_ERR(vol));
149                 return ret;
150         }
151
152         if(size != uboot_ubi_read(vol, buf, off, size)) 
153                 printf("%s: read vol %s failed!\n",__func__,part);
154         else
155                 ret = 0;
156
157         ubi_close_volume(vol);
158 #endif
159         if (ret)
160                 printf("do_raw_data_read error.\n");
161         return ret;
162 }
163
164 int do_raw_data_write(char *part, u32 updsz, u32 size, u32 off, char *buf)
165 {
166         int ret =-1;
167 #ifdef  CONFIG_EMMC_BOOT
168         //TODO
169 #else
170         int i =0;
171         int ubi_dev;
172         u8 pnum;
173         loff_t offset;
174         size_t length,wlen=0;
175         struct mtd_device *dev;
176         struct mtd_info *nand;
177         struct part_info *mtdpart;
178         struct ubi_volume_desc *vol;
179         nand_erase_options_t opts;
180
181 try_mtd:
182         ret = find_dev_and_part(part, &dev, &pnum, &mtdpart);
183         if (ret)
184                 goto try_ubi;
185         else if (dev->id->type != MTD_DEV_TYPE_NAND)
186                 goto end;
187
188         offset = mtdpart->offset+off;
189         length = size;
190         nand = &nand_info[dev->id->num];
191         memset(&opts, 0x0, sizeof(opts));
192         opts.offset = offset;
193         opts.length = length;
194         opts.quiet = 1;
195         opts.spread = 1;
196
197         ret = nand_erase_opts(nand, &opts);
198         if (ret) {
199                 printf("erase %s failed.\n",part);
200                 goto end;
201         }
202         //write spl part with header
203         if(strcmp(part, "spl")==0){
204                 ret = sprd_nand_write_spl(buf, nand);
205                 goto end;
206         }
207
208         while((size != wlen) && (i++<0xff)) {
209                 ret = nand_write_skip_bad(nand, offset, &length, buf);
210                 wlen += length;
211                 buf += length;
212                 offset += length;
213
214                 if(ret){
215                         //mark a block as badblock
216                         printf("nand write error %d, mark bad block 0x%llx\n",ret,offset&~(nand->erasesize-1));
217                         nand->block_markbad(nand,offset &~(nand->erasesize-1));
218                 }
219         }
220         goto end;
221
222 try_ubi:
223         ubi_dev = nand_ubi_dev_init();
224         if (ubi_dev<0) {
225                 printf("do_raw_data_write: ubi init failed.\n");
226                 return ret;
227         }
228         vol = ubi_open_volume_nm(ubi_dev, part, UBI_READWRITE);
229         if (IS_ERR(vol)) {
230                 printf("cannot open \"%s\", error %d",
231                           part, (int)PTR_ERR(vol));
232                 return ret;
233         }
234
235         //set total size to be updated in this volume
236         if (updsz) {
237                 ret = ubi_start_update(vol->vol->ubi, vol->vol, updsz);
238                 if (ret < 0) {
239                         printf("Cannot start volume %s update\n",part);
240                         return ret;
241                 }
242         }
243
244         ret = ubi_more_update_data(vol->vol->ubi, vol->vol, buf, size);
245         if (ret < 0) {
246                 printf("Couldnt write data in volume %s\n",part);
247                 return ret;
248         }
249         ret = 0;
250         ubi_close_volume(vol);
251 #endif
252
253 end:
254         if (ret)
255                 printf("do_raw_data_write error.\n");
256         return ret;
257 }
258