summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/common/file.c72
-rw-r--r--firmware/drivers/fat.c36
-rw-r--r--firmware/test/fat/main.c56
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
198int 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
132void 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
132char current_directory[256] = "\\"; 185char current_directory[256] = "\\";
133int last_secnum = 0; 186int 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}