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