diff options
-rw-r--r-- | firmware/common/file.c | 72 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 36 | ||||
-rw-r--r-- | firmware/test/fat/main.c | 56 |
3 files changed, 145 insertions, 19 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index 41aaea570a..a5d9443aeb 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -100,7 +100,7 @@ int open(char* pathname, int flags) | |||
100 | return -1; | 100 | return -1; |
101 | } | 101 | } |
102 | 102 | ||
103 | openfiles[fd].cacheoffset = 0; | 103 | openfiles[fd].cacheoffset = -1; |
104 | openfiles[fd].fileoffset = 0; | 104 | openfiles[fd].fileoffset = 0; |
105 | openfiles[fd].busy = TRUE; | 105 | openfiles[fd].busy = TRUE; |
106 | return fd; | 106 | return fd; |
@@ -127,7 +127,7 @@ int read(int fd, void* buf, int count) | |||
127 | count = openfiles[fd].size - openfiles[fd].fileoffset; | 127 | count = openfiles[fd].size - openfiles[fd].fileoffset; |
128 | 128 | ||
129 | /* any head bytes? */ | 129 | /* any head bytes? */ |
130 | if ( openfiles[fd].cacheoffset ) { | 130 | if ( openfiles[fd].cacheoffset != -1 ) { |
131 | int headbytes; | 131 | int headbytes; |
132 | int offs = openfiles[fd].cacheoffset; | 132 | int offs = openfiles[fd].cacheoffset; |
133 | if ( count <= SECTOR_SIZE - openfiles[fd].cacheoffset ) { | 133 | if ( count <= SECTOR_SIZE - openfiles[fd].cacheoffset ) { |
@@ -138,7 +138,7 @@ int read(int fd, void* buf, int count) | |||
138 | } | 138 | } |
139 | else { | 139 | else { |
140 | headbytes = SECTOR_SIZE - openfiles[fd].cacheoffset; | 140 | headbytes = SECTOR_SIZE - openfiles[fd].cacheoffset; |
141 | openfiles[fd].cacheoffset = 0; | 141 | openfiles[fd].cacheoffset = -1; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* eof? */ | 144 | /* eof? */ |
@@ -169,7 +169,7 @@ int read(int fd, void* buf, int count) | |||
169 | count=0; | 169 | count=0; |
170 | } | 170 | } |
171 | 171 | ||
172 | openfiles[fd].cacheoffset = 0; | 172 | openfiles[fd].cacheoffset = -1; |
173 | } | 173 | } |
174 | } | 174 | } |
175 | 175 | ||
@@ -195,6 +195,70 @@ int read(int fd, void* buf, int count) | |||
195 | return nread; | 195 | return nread; |
196 | } | 196 | } |
197 | 197 | ||
198 | int lseek(int fd, int offset, int whence) | ||
199 | { | ||
200 | int pos; | ||
201 | int newsector; | ||
202 | int oldsector; | ||
203 | int sectoroffset; | ||
204 | int rc; | ||
205 | |||
206 | if ( !openfiles[fd].busy ) { | ||
207 | errno = EBADF; | ||
208 | return -1; | ||
209 | } | ||
210 | |||
211 | switch ( whence ) { | ||
212 | case SEEK_SET: | ||
213 | pos = offset; | ||
214 | break; | ||
215 | |||
216 | case SEEK_CUR: | ||
217 | pos = openfiles[fd].fileoffset + offset; | ||
218 | break; | ||
219 | |||
220 | case SEEK_END: | ||
221 | pos = openfiles[fd].size - offset; | ||
222 | break; | ||
223 | |||
224 | default: | ||
225 | errno = EINVAL; | ||
226 | return -1; | ||
227 | } | ||
228 | if ( (pos < 0) || | ||
229 | (pos > openfiles[fd].size) ) { | ||
230 | errno = EINVAL; | ||
231 | return -1; | ||
232 | } | ||
233 | |||
234 | /* new sector? */ | ||
235 | newsector = pos / SECTOR_SIZE; | ||
236 | oldsector = openfiles[fd].fileoffset / SECTOR_SIZE; | ||
237 | sectoroffset = pos % SECTOR_SIZE; | ||
238 | |||
239 | if ( (newsector != oldsector) || | ||
240 | ((openfiles[fd].cacheoffset==-1) && sectoroffset) ) { | ||
241 | if ( newsector != oldsector ) { | ||
242 | rc = fat_seek(&(openfiles[fd].fatfile), newsector); | ||
243 | if ( rc < 0 ) { | ||
244 | errno = EIO; | ||
245 | return -1; | ||
246 | } | ||
247 | } | ||
248 | rc = fat_read(&(openfiles[fd].fatfile), 1, | ||
249 | &(openfiles[fd].cache)); | ||
250 | if ( rc < 0 ) { | ||
251 | errno = EIO; | ||
252 | return -1; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | openfiles[fd].cacheoffset = sectoroffset; | ||
257 | openfiles[fd].fileoffset = pos; | ||
258 | |||
259 | return pos; | ||
260 | } | ||
261 | |||
198 | /* | 262 | /* |
199 | * local variables: | 263 | * local variables: |
200 | * eval: (load-file "../rockbox-mode.el") | 264 | * eval: (load-file "../rockbox-mode.el") |
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 3a3f63d9f1..a55a8a2864 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -838,22 +838,30 @@ int fat_seek(struct fat_file *file, int seeksector ) | |||
838 | int numsec = 0; | 838 | int numsec = 0; |
839 | int i; | 839 | int i; |
840 | 840 | ||
841 | for (i=0; i<seeksector; i++) { | 841 | if ( seeksector ) { |
842 | numsec++; | 842 | for (i=0; i<seeksector; i++) { |
843 | if ( numsec >= fat_bpb.bpb_secperclus ) { | 843 | numsec++; |
844 | cluster = get_next_cluster(cluster); | 844 | if ( numsec >= fat_bpb.bpb_secperclus ) { |
845 | if (!cluster) | 845 | cluster = get_next_cluster(cluster); |
846 | /* end of file */ | 846 | if (!cluster) |
847 | return -1; | 847 | /* end of file */ |
848 | 848 | return -1; | |
849 | sector = cluster2sec(cluster); | 849 | |
850 | if (sector<0) | 850 | sector = cluster2sec(cluster); |
851 | return -2; | 851 | if (sector<0) |
852 | numsec=0; | 852 | return -2; |
853 | numsec=0; | ||
854 | } | ||
855 | else | ||
856 | sector++; | ||
853 | } | 857 | } |
854 | else | ||
855 | sector++; | ||
856 | } | 858 | } |
859 | else { | ||
860 | sector = cluster2sec(cluster); | ||
861 | if (sector<0) | ||
862 | return -2; | ||
863 | } | ||
864 | |||
857 | file->nextcluster = cluster; | 865 | file->nextcluster = cluster; |
858 | file->nextsector = sector; | 866 | file->nextsector = sector; |
859 | file->sectornum = numsec; | 867 | file->sectornum = numsec; |
diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 5490fa9777..6d05dbe600 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c | |||
@@ -129,6 +129,59 @@ void dbg_type(char* name) | |||
129 | close(fd); | 129 | close(fd); |
130 | } | 130 | } |
131 | 131 | ||
132 | void dbg_tail(char* name) | ||
133 | { | ||
134 | unsigned char buf[SECTOR_SIZE*5]; | ||
135 | int fd,rc; | ||
136 | |||
137 | fd = open(name,O_RDONLY); | ||
138 | if (fd<0) | ||
139 | return; | ||
140 | DEBUGF("Got file descriptor %d\n",fd); | ||
141 | |||
142 | rc = lseek(fd,512,SEEK_SET); | ||
143 | if ( rc >= 0 ) { | ||
144 | rc = read(fd, buf, SECTOR_SIZE); | ||
145 | if( rc > 0 ) | ||
146 | { | ||
147 | buf[rc]=0; | ||
148 | printf("%d: %s\n", strlen(buf), buf); | ||
149 | } | ||
150 | else if ( rc == 0 ) { | ||
151 | DEBUGF("EOF\n"); | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | DEBUGF("Failed reading file: %d\n",rc); | ||
156 | } | ||
157 | } | ||
158 | else { | ||
159 | perror("lseek"); | ||
160 | } | ||
161 | |||
162 | rc = lseek(fd,-100,SEEK_CUR); | ||
163 | if ( rc >= 0 ) { | ||
164 | rc = read(fd, buf, SECTOR_SIZE); | ||
165 | if( rc > 0 ) | ||
166 | { | ||
167 | buf[rc]=0; | ||
168 | printf("%d: %s\n", strlen(buf), buf); | ||
169 | } | ||
170 | else if ( rc == 0 ) { | ||
171 | DEBUGF("EOF\n"); | ||
172 | } | ||
173 | else | ||
174 | { | ||
175 | DEBUGF("Failed reading file: %d\n",rc); | ||
176 | } | ||
177 | } | ||
178 | else { | ||
179 | perror("lseek"); | ||
180 | } | ||
181 | |||
182 | close(fd); | ||
183 | } | ||
184 | |||
132 | char current_directory[256] = "\\"; | 185 | char current_directory[256] = "\\"; |
133 | int last_secnum = 0; | 186 | int last_secnum = 0; |
134 | 187 | ||
@@ -221,7 +274,8 @@ int main(int argc, char *argv[]) | |||
221 | DEBUGF("*** Failed mounting fat\n"); | 274 | DEBUGF("*** Failed mounting fat\n"); |
222 | } | 275 | } |
223 | 276 | ||
224 | dbg_console(); | 277 | //dbg_console(); |
278 | dbg_tail("/fat.h"); | ||
225 | 279 | ||
226 | return 0; | 280 | return 0; |
227 | } | 281 | } |