summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/fat.c334
-rw-r--r--firmware/drivers/fat.h38
2 files changed, 176 insertions, 196 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 329e149a7a..efb91cff33 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -113,9 +113,9 @@ struct fsinfo {
113#define FSINFO_FREECOUNT 488 113#define FSINFO_FREECOUNT 488
114#define FSINFO_NEXTFREE 492 114#define FSINFO_NEXTFREE 492
115 115
116static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster); 116static int first_sector_of_cluster(unsigned int cluster);
117static int bpb_is_sane(struct bpb *bpb); 117static int bpb_is_sane(void);
118static void *cache_fat_sector(struct bpb *bpb, int secnum); 118static void *cache_fat_sector(int secnum);
119#ifdef DISK_WRITE 119#ifdef DISK_WRITE
120static unsigned int getcurrdostime(unsigned short *dosdate, 120static unsigned int getcurrdostime(unsigned short *dosdate,
121 unsigned short *dostime, 121 unsigned short *dostime,
@@ -123,6 +123,9 @@ static unsigned int getcurrdostime(unsigned short *dosdate,
123static int create_dos_name(unsigned char *name, unsigned char *newname); 123static int create_dos_name(unsigned char *name, unsigned char *newname);
124#endif 124#endif
125 125
126/* global FAT info struct */
127struct bpb fat_bpb;
128
126/* fat cache */ 129/* fat cache */
127static unsigned char *fat_cache[256]; 130static unsigned char *fat_cache[256];
128#ifdef DISK_WRITE 131#ifdef DISK_WRITE
@@ -133,21 +136,21 @@ static int fat_cache_dirty[256];
133static unsigned char lastsector[SECTOR_SIZE]; 136static unsigned char lastsector[SECTOR_SIZE];
134static unsigned char lastsector2[SECTOR_SIZE]; 137static unsigned char lastsector2[SECTOR_SIZE];
135 138
136static int sec2cluster(struct bpb *bpb, unsigned int sec) 139static int sec2cluster(unsigned int sec)
137{ 140{
138 if ( sec < bpb->firstdatasector ) 141 if ( sec < fat_bpb.firstdatasector )
139 { 142 {
140 DEBUGF( "sec2cluster() - Bad sector number (%d)\n", sec); 143 DEBUGF( "sec2cluster() - Bad sector number (%d)\n", sec);
141 return -1; 144 return -1;
142 } 145 }
143 146
144 return ((sec - bpb->firstdatasector) / bpb->bpb_secperclus) + 2; 147 return ((sec - fat_bpb.firstdatasector) / fat_bpb.bpb_secperclus) + 2;
145} 148}
146 149
147static int cluster2sec(struct bpb *bpb, unsigned int cluster) 150static int cluster2sec(unsigned int cluster)
148{ 151{
149 int max_cluster = bpb->totalsectors - 152 int max_cluster = fat_bpb.totalsectors -
150 bpb->firstdatasector / bpb->bpb_secperclus + 1; 153 fat_bpb.firstdatasector / fat_bpb.bpb_secperclus + 1;
151 154
152 if(cluster > max_cluster) 155 if(cluster > max_cluster)
153 { 156 {
@@ -156,15 +159,15 @@ static int cluster2sec(struct bpb *bpb, unsigned int cluster)
156 return -1; 159 return -1;
157 } 160 }
158 161
159 return first_sector_of_cluster(bpb, cluster); 162 return first_sector_of_cluster(cluster);
160} 163}
161 164
162static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster) 165static int first_sector_of_cluster(unsigned int cluster)
163{ 166{
164 return (cluster - 2) * bpb->bpb_secperclus + bpb->firstdatasector; 167 return (cluster - 2) * fat_bpb.bpb_secperclus + fat_bpb.firstdatasector;
165} 168}
166 169
167int fat_mount(struct bpb *bpb, int startsector) 170int fat_mount(int startsector)
168{ 171{
169 unsigned char buf[SECTOR_SIZE]; 172 unsigned char buf[SECTOR_SIZE];
170 int err; 173 int err;
@@ -180,50 +183,50 @@ int fat_mount(struct bpb *bpb, int startsector)
180 return -1; 183 return -1;
181 } 184 }
182 185
183 memset(bpb, 0, sizeof(struct bpb)); 186 memset(&fat_bpb, 0, sizeof(struct bpb));
184 bpb->startsector = startsector; 187 fat_bpb.startsector = startsector;
185 188
186 strncpy(bpb->bs_oemname, &buf[BS_OEMNAME], 8); 189 strncpy(fat_bpb.bs_oemname, &buf[BS_OEMNAME], 8);
187 bpb->bs_oemname[8] = 0; 190 fat_bpb.bs_oemname[8] = 0;
188 191
189 bpb->bpb_bytspersec = BYTES2INT16(buf,BPB_BYTSPERSEC); 192 fat_bpb.bpb_bytspersec = BYTES2INT16(buf,BPB_BYTSPERSEC);
190 bpb->bpb_secperclus = buf[BPB_SECPERCLUS]; 193 fat_bpb.bpb_secperclus = buf[BPB_SECPERCLUS];
191 bpb->bpb_rsvdseccnt = BYTES2INT16(buf,BPB_RSVDSECCNT); 194 fat_bpb.bpb_rsvdseccnt = BYTES2INT16(buf,BPB_RSVDSECCNT);
192 bpb->bpb_numfats = buf[BPB_NUMFATS]; 195 fat_bpb.bpb_numfats = buf[BPB_NUMFATS];
193 bpb->bpb_rootentcnt = BYTES2INT16(buf,BPB_ROOTENTCNT); 196 fat_bpb.bpb_rootentcnt = BYTES2INT16(buf,BPB_ROOTENTCNT);
194 bpb->bpb_totsec16 = BYTES2INT16(buf,BPB_TOTSEC16); 197 fat_bpb.bpb_totsec16 = BYTES2INT16(buf,BPB_TOTSEC16);
195 bpb->bpb_media = buf[BPB_MEDIA]; 198 fat_bpb.bpb_media = buf[BPB_MEDIA];
196 bpb->bpb_fatsz16 = BYTES2INT16(buf,BPB_FATSZ16); 199 fat_bpb.bpb_fatsz16 = BYTES2INT16(buf,BPB_FATSZ16);
197 bpb->bpb_fatsz32 = BYTES2INT32(buf,BPB_FATSZ32); 200 fat_bpb.bpb_fatsz32 = BYTES2INT32(buf,BPB_FATSZ32);
198 bpb->bpb_secpertrk = BYTES2INT16(buf,BPB_SECPERTRK); 201 fat_bpb.bpb_secpertrk = BYTES2INT16(buf,BPB_SECPERTRK);
199 bpb->bpb_numheads = BYTES2INT16(buf,BPB_NUMHEADS); 202 fat_bpb.bpb_numheads = BYTES2INT16(buf,BPB_NUMHEADS);
200 bpb->bpb_hiddsec = BYTES2INT32(buf,BPB_HIDDSEC); 203 fat_bpb.bpb_hiddsec = BYTES2INT32(buf,BPB_HIDDSEC);
201 bpb->bpb_totsec32 = BYTES2INT32(buf,BPB_TOTSEC32); 204 fat_bpb.bpb_totsec32 = BYTES2INT32(buf,BPB_TOTSEC32);
202 bpb->last_word = BYTES2INT16(buf,BPB_LAST_WORD); 205 fat_bpb.last_word = BYTES2INT16(buf,BPB_LAST_WORD);
203 206
204 /* calculate a few commonly used values */ 207 /* calculate a few commonly used values */
205 if (bpb->bpb_fatsz16 != 0) 208 if (fat_bpb.bpb_fatsz16 != 0)
206 bpb->fatsize = bpb->bpb_fatsz16; 209 fat_bpb.fatsize = fat_bpb.bpb_fatsz16;
207 else 210 else
208 bpb->fatsize = bpb->bpb_fatsz32; 211 fat_bpb.fatsize = fat_bpb.bpb_fatsz32;
209 212
210 if (bpb->bpb_totsec16 != 0) 213 if (fat_bpb.bpb_totsec16 != 0)
211 bpb->totalsectors = bpb->bpb_totsec16; 214 fat_bpb.totalsectors = fat_bpb.bpb_totsec16;
212 else 215 else
213 bpb->totalsectors = bpb->bpb_totsec32; 216 fat_bpb.totalsectors = fat_bpb.bpb_totsec32;
214 bpb->firstdatasector = bpb->bpb_rsvdseccnt + 217 fat_bpb.firstdatasector = fat_bpb.bpb_rsvdseccnt +
215 bpb->bpb_numfats * bpb->fatsize; 218 fat_bpb.bpb_numfats * fat_bpb.fatsize;
216 219
217 /* Determine FAT type */ 220 /* Determine FAT type */
218 datasec = bpb->totalsectors - bpb->firstdatasector; 221 datasec = fat_bpb.totalsectors - fat_bpb.firstdatasector;
219 countofclusters = datasec / bpb->bpb_secperclus; 222 countofclusters = datasec / fat_bpb.bpb_secperclus;
220 223
221#ifdef TEST_FAT 224#ifdef TEST_FAT
222 /* 225 /*
223 we are sometimes testing with "illegally small" fat32 images, 226 we are sometimes testing with "illegally small" fat32 images,
224 so we don't use the proper fat32 test case for test code 227 so we don't use the proper fat32 test case for test code
225 */ 228 */
226 if ( bpb->bpb_fatsz16 ) 229 if ( fat_bpb.bpb_fatsz16 )
227#else 230#else
228 if ( countofclusters < 65525 ) 231 if ( countofclusters < 65525 )
229#endif 232#endif
@@ -232,78 +235,78 @@ int fat_mount(struct bpb *bpb, int startsector)
232 return -1; 235 return -1;
233 } 236 }
234 237
235 bpb->bpb_extflags = BYTES2INT16(buf,BPB_EXTFLAGS); 238 fat_bpb.bpb_extflags = BYTES2INT16(buf,BPB_EXTFLAGS);
236 bpb->bpb_fsver = BYTES2INT16(buf,BPB_FSVER); 239 fat_bpb.bpb_fsver = BYTES2INT16(buf,BPB_FSVER);
237 bpb->bpb_rootclus = BYTES2INT32(buf,BPB_ROOTCLUS); 240 fat_bpb.bpb_rootclus = BYTES2INT32(buf,BPB_ROOTCLUS);
238 bpb->bpb_fsinfo = BYTES2INT16(buf,BPB_FSINFO); 241 fat_bpb.bpb_fsinfo = BYTES2INT16(buf,BPB_FSINFO);
239 bpb->bpb_bkbootsec = BYTES2INT16(buf,BPB_BKBOOTSEC); 242 fat_bpb.bpb_bkbootsec = BYTES2INT16(buf,BPB_BKBOOTSEC);
240 bpb->bs_drvnum = buf[BS_32_DRVNUM]; 243 fat_bpb.bs_drvnum = buf[BS_32_DRVNUM];
241 bpb->bs_bootsig = buf[BS_32_BOOTSIG]; 244 fat_bpb.bs_bootsig = buf[BS_32_BOOTSIG];
242 245
243 if(bpb->bs_bootsig == 0x29) 246 if(fat_bpb.bs_bootsig == 0x29)
244 { 247 {
245 bpb->bs_volid = BYTES2INT32(buf,BS_32_VOLID); 248 fat_bpb.bs_volid = BYTES2INT32(buf,BS_32_VOLID);
246 strncpy(bpb->bs_vollab, &buf[BS_32_VOLLAB], 11); 249 strncpy(fat_bpb.bs_vollab, &buf[BS_32_VOLLAB], 11);
247 strncpy(bpb->bs_filsystype, &buf[BS_32_FILSYSTYPE], 8); 250 strncpy(fat_bpb.bs_filsystype, &buf[BS_32_FILSYSTYPE], 8);
248 } 251 }
249 252
250 if (bpb_is_sane(bpb) < 0) 253 if (bpb_is_sane() < 0)
251 { 254 {
252 DEBUGF( "fat_mount() - BPB is not sane\n"); 255 DEBUGF( "fat_mount() - BPB is not sane\n");
253 return -1; 256 return -1;
254 } 257 }
255 258
256 bpb->rootdirsector = cluster2sec(bpb,bpb->bpb_rootclus); 259 fat_bpb.rootdirsector = cluster2sec(fat_bpb.bpb_rootclus);
257 260
258 return 0; 261 return 0;
259} 262}
260 263
261static int bpb_is_sane(struct bpb *bpb) 264static int bpb_is_sane(void)
262{ 265{
263 if(bpb->bpb_bytspersec != 512) 266 if(fat_bpb.bpb_bytspersec != 512)
264 { 267 {
265 DEBUGF( "bpb_is_sane() - Error: sector size is not 512 (%i)\n", 268 DEBUGF( "bpb_is_sane() - Error: sector size is not 512 (%i)\n",
266 bpb->bpb_bytspersec); 269 fat_bpb.bpb_bytspersec);
267 return -1; 270 return -1;
268 } 271 }
269 if(bpb->bpb_secperclus * bpb->bpb_bytspersec > 32768) 272 if(fat_bpb.bpb_secperclus * fat_bpb.bpb_bytspersec > 32768)
270 { 273 {
271 DEBUGF( "bpb_is_sane() - Warning: cluster size is larger than 32K " 274 DEBUGF( "bpb_is_sane() - Warning: cluster size is larger than 32K "
272 "(%i * %i = %i)\n", 275 "(%i * %i = %i)\n",
273 bpb->bpb_bytspersec, bpb->bpb_secperclus, 276 fat_bpb.bpb_bytspersec, fat_bpb.bpb_secperclus,
274 bpb->bpb_bytspersec * bpb->bpb_secperclus); 277 fat_bpb.bpb_bytspersec * fat_bpb.bpb_secperclus);
275 } 278 }
276 if(bpb->bpb_rsvdseccnt != 1) 279 if(fat_bpb.bpb_rsvdseccnt != 1)
277 { 280 {
278 DEBUGF( "bpb_is_sane() - Warning: Reserved sectors is not 1 (%i)\n", 281 DEBUGF( "bpb_is_sane() - Warning: Reserved sectors is not 1 (%i)\n",
279 bpb->bpb_rsvdseccnt); 282 fat_bpb.bpb_rsvdseccnt);
280 } 283 }
281 if(bpb->bpb_numfats != 2) 284 if(fat_bpb.bpb_numfats != 2)
282 { 285 {
283 DEBUGF( "bpb_is_sane() - Warning: NumFATS is not 2 (%i)\n", 286 DEBUGF( "bpb_is_sane() - Warning: NumFATS is not 2 (%i)\n",
284 bpb->bpb_numfats); 287 fat_bpb.bpb_numfats);
285 } 288 }
286 if(bpb->bpb_rootentcnt != 512) 289 if(fat_bpb.bpb_rootentcnt != 512)
287 { 290 {
288 DEBUGF( "bpb_is_sane() - Warning: RootEntCnt is not 512 (%i)\n", 291 DEBUGF( "bpb_is_sane() - Warning: RootEntCnt is not 512 (%i)\n",
289 bpb->bpb_rootentcnt); 292 fat_bpb.bpb_rootentcnt);
290 } 293 }
291 if(bpb->bpb_media != 0xf0 && bpb->bpb_media < 0xf8) 294 if(fat_bpb.bpb_media != 0xf0 && fat_bpb.bpb_media < 0xf8)
292 { 295 {
293 DEBUGF( "bpb_is_sane() - Warning: Non-standard " 296 DEBUGF( "bpb_is_sane() - Warning: Non-standard "
294 "media type (0x%02x)\n", 297 "media type (0x%02x)\n",
295 bpb->bpb_media); 298 fat_bpb.bpb_media);
296 } 299 }
297 if(bpb->last_word != 0xaa55) 300 if(fat_bpb.last_word != 0xaa55)
298 { 301 {
299 DEBUGF( "bpb_is_sane() - Error: Last word is not " 302 DEBUGF( "bpb_is_sane() - Error: Last word is not "
300 "0xaa55 (0x%04x)\n", bpb->last_word); 303 "0xaa55 (0x%04x)\n", fat_bpb.last_word);
301 return -1; 304 return -1;
302 } 305 }
303 return 0; 306 return 0;
304} 307}
305 308
306static void *cache_fat_sector(struct bpb *bpb, int secnum) 309static void *cache_fat_sector(int secnum)
307{ 310{
308 unsigned char *sec; 311 unsigned char *sec;
309 312
@@ -311,13 +314,13 @@ static void *cache_fat_sector(struct bpb *bpb, int secnum)
311 /* Load the sector if it is not cached */ 314 /* Load the sector if it is not cached */
312 if(!sec) 315 if(!sec)
313 { 316 {
314 sec = malloc(bpb->bpb_bytspersec); 317 sec = malloc(fat_bpb.bpb_bytspersec);
315 if(!sec) 318 if(!sec)
316 { 319 {
317 DEBUGF( "cache_fat_sector() - Out of memory\n"); 320 DEBUGF( "cache_fat_sector() - Out of memory\n");
318 return NULL; 321 return NULL;
319 } 322 }
320 if(ata_read_sectors(secnum+bpb->startsector,1,sec)) 323 if(ata_read_sectors(secnum+fat_bpb.startsector,1,sec))
321 { 324 {
322 DEBUGF( "cache_fat_sector() - Could" 325 DEBUGF( "cache_fat_sector() - Could"
323 " not read sector %d\n", 326 " not read sector %d\n",
@@ -331,7 +334,7 @@ static void *cache_fat_sector(struct bpb *bpb, int secnum)
331} 334}
332 335
333#ifdef DISK_WRITE 336#ifdef DISK_WRITE
334static int update_entry(struct bpb *bpb, int entry, unsigned int val) 337static int update_entry(int entry, unsigned int val)
335{ 338{
336 unsigned long *sec; 339 unsigned long *sec;
337 int fatoffset; 340 int fatoffset;
@@ -339,11 +342,11 @@ static int update_entry(struct bpb *bpb, int entry, unsigned int val)
339 int thisfatentoffset; 342 int thisfatentoffset;
340 343
341 fatoffset = entry * 4; 344 fatoffset = entry * 4;
342 thisfatsecnum = fatoffset / bpb->bpb_bytspersec + bpb->bpb_rsvdseccnt; 345 thisfatsecnum = fatoffset / fat_bpb.bpb_bytspersec + fat_bpb.bpb_rsvdseccnt;
343 thisfatentoffset = fatoffset % bpb->bpb_bytspersec; 346 thisfatentoffset = fatoffset % fat_bpb.bpb_bytspersec;
344 347
345 /* Load the sector if it is not cached */ 348 /* Load the sector if it is not cached */
346 sec = cache_fat_sector(bpb, thisfatsecnum); 349 sec = cache_fat_sector(thisfatsecnum);
347 if(!sec) 350 if(!sec)
348 { 351 {
349 DEBUGF( "update_entry() - Could not cache sector %d\n", 352 DEBUGF( "update_entry() - Could not cache sector %d\n",
@@ -361,7 +364,7 @@ static int update_entry(struct bpb *bpb, int entry, unsigned int val)
361} 364}
362#endif 365#endif
363 366
364static int read_entry(struct bpb *bpb, int entry) 367static int read_entry(int entry)
365{ 368{
366 unsigned long *sec; 369 unsigned long *sec;
367 int fatoffset; 370 int fatoffset;
@@ -370,11 +373,11 @@ static int read_entry(struct bpb *bpb, int entry)
370 int val = -1; 373 int val = -1;
371 374
372 fatoffset = entry * 4; 375 fatoffset = entry * 4;
373 thisfatsecnum = fatoffset / bpb->bpb_bytspersec + bpb->bpb_rsvdseccnt; 376 thisfatsecnum = fatoffset / fat_bpb.bpb_bytspersec + fat_bpb.bpb_rsvdseccnt;
374 thisfatentoffset = fatoffset % bpb->bpb_bytspersec; 377 thisfatentoffset = fatoffset % fat_bpb.bpb_bytspersec;
375 378
376 /* Load the sector if it is not cached */ 379 /* Load the sector if it is not cached */
377 sec = cache_fat_sector(bpb, thisfatsecnum); 380 sec = cache_fat_sector(thisfatsecnum);
378 if(!sec) 381 if(!sec)
379 { 382 {
380 DEBUGF( "update_entry() - Could not cache sector %d\n", 383 DEBUGF( "update_entry() - Could not cache sector %d\n",
@@ -386,9 +389,9 @@ static int read_entry(struct bpb *bpb, int entry)
386 return val; 389 return val;
387} 390}
388 391
389static int get_next_cluster(struct bpb *bpb, unsigned int cluster) 392static int get_next_cluster(unsigned int cluster)
390{ 393{
391 int next_cluster = read_entry(bpb, cluster); 394 int next_cluster = read_entry(cluster);
392 395
393 /* is this last cluster in chain? */ 396 /* is this last cluster in chain? */
394 if ( next_cluster >= 0x0ffffff8 ) 397 if ( next_cluster >= 0x0ffffff8 )
@@ -407,7 +410,7 @@ static int flush_fat(struct bpb *bpb)
407 unsigned short d, t; 410 unsigned short d, t;
408 char m; 411 char m;
409 412
410 fatsz = bpb->fatsize; 413 fatsz = fat_bpb.fatsize;
411 414
412 for(i = 0;i < 256;i++) 415 for(i = 0;i < 256;i++)
413 { 416 {
@@ -415,21 +418,21 @@ static int flush_fat(struct bpb *bpb)
415 { 418 {
416 DEBUGF("Flushing FAT sector %d\n", i); 419 DEBUGF("Flushing FAT sector %d\n", i);
417 sec = fat_cache[i]; 420 sec = fat_cache[i];
418 err = ata_write_sectors(i + bpb->bpb_rsvdseccnt + bpb->startsector, 421 err = ata_write_sectors(i + fat_bpb.bpb_rsvdseccnt + fat_bpb.startsector,
419 1,sec); 422 1,sec);
420 if(err) 423 if(err)
421 { 424 {
422 DEBUGF( "flush_fat() - Couldn't write" 425 DEBUGF( "flush_fat() - Couldn't write"
423 " sector (%d)\n", i + bpb->bpb_rsvdseccnt); 426 " sector (%d)\n", i + fat_bpb.bpb_rsvdseccnt);
424 return -1; 427 return -1;
425 } 428 }
426 err = ata_write_sectors(i + bpb->bpb_rsvdseccnt + fatsz + 429 err = ata_write_sectors(i + fat_bpb.bpb_rsvdseccnt + fatsz +
427 bpb->startsector, 430 fat_bpb.startsector,
428 1,sec); 431 1,sec);
429 if(err) 432 if(err)
430 { 433 {
431 DEBUGF( "flush_fat() - Couldn't write" 434 DEBUGF( "flush_fat() - Couldn't write"
432 " sector (%d)\n", i + bpb->bpb_rsvdseccnt + fatsz); 435 " sector (%d)\n", i + fat_bpb.bpb_rsvdseccnt + fatsz);
433 return -1; 436 return -1;
434 } 437 }
435 fat_cache_dirty[i] = 0; 438 fat_cache_dirty[i] = 0;
@@ -440,9 +443,9 @@ static int flush_fat(struct bpb *bpb)
440 return 0; 443 return 0;
441} 444}
442 445
443unsigned int getcurrdostime(unsigned short *dosdate, 446static unsigned int getcurrdostime(unsigned short *dosdate,
444 unsigned short *dostime, 447 unsigned short *dostime,
445 unsigned char *dostenth) 448 unsigned char *dostenth)
446{ 449{
447 struct timeb tb; 450 struct timeb tb;
448 struct tm *tm; 451 struct tm *tm;
@@ -462,9 +465,7 @@ unsigned int getcurrdostime(unsigned short *dosdate,
462 return 0; 465 return 0;
463} 466}
464 467
465static int add_dir_entry(struct bpb *bpb, 468static int add_dir_entry(unsigned int currdir, struct fat_direntry *de)
466 unsigned int currdir,
467 struct fat_direntry *de)
468{ 469{
469 unsigned char buf[SECTOR_SIZE]; 470 unsigned char buf[SECTOR_SIZE];
470 unsigned char *eptr; 471 unsigned char *eptr;
@@ -479,11 +480,11 @@ static int add_dir_entry(struct bpb *bpb,
479 480
480 if(is_rootdir) 481 if(is_rootdir)
481 { 482 {
482 sec = bpb->rootdirsector; 483 sec = fat_bpb.rootdirsector;
483 } 484 }
484 else 485 else
485 { 486 {
486 sec = first_sector_of_cluster(bpb, currdir); 487 sec = first_sector_of_cluster(currdir);
487 } 488 }
488 489
489 sec_cnt = 0; 490 sec_cnt = 0;
@@ -493,7 +494,7 @@ static int add_dir_entry(struct bpb *bpb,
493 /* The root dir has a fixed size */ 494 /* The root dir has a fixed size */
494 if(is_rootdir) 495 if(is_rootdir)
495 { 496 {
496 if(sec_cnt >= bpb->bpb_rootentcnt * 32 / bpb->bpb_bytspersec) 497 if(sec_cnt >= fat_bpb.bpb_rootentcnt * 32 / fat_bpb.bpb_bytspersec)
497 { 498 {
498 /* We have reached the last sector of the root dir */ 499 /* We have reached the last sector of the root dir */
499 if(need_to_update_last_empty_marker) 500 if(need_to_update_last_empty_marker)
@@ -512,11 +513,11 @@ static int add_dir_entry(struct bpb *bpb,
512 } 513 }
513 else 514 else
514 { 515 {
515 if(sec_cnt >= bpb->bpb_secperclus) 516 if(sec_cnt >= fat_bpb.bpb_secperclus)
516 { 517 {
517 /* We have reached the end of this cluster */ 518 /* We have reached the end of this cluster */
518 DEBUGF("Moving to the next cluster..."); 519 DEBUGF("Moving to the next cluster...");
519 currdir = get_next_cluster(bpb, currdir); 520 currdir = get_next_cluster(currdir);
520 DEBUGF("new cluster is %d\n", currdir); 521 DEBUGF("new cluster is %d\n", currdir);
521 522
522 if(!currdir) 523 if(!currdir)
@@ -530,7 +531,7 @@ static int add_dir_entry(struct bpb *bpb,
530 531
531 DEBUGF("Reading sector %d...\n", sec); 532 DEBUGF("Reading sector %d...\n", sec);
532 /* Read the next sector in the current dir */ 533 /* Read the next sector in the current dir */
533 err = ata_read_sectors(sec + bpb->startsector,1,buf); 534 err = ata_read_sectors(sec + fat_bpb.startsector,1,buf);
534 if(err) 535 if(err)
535 { 536 {
536 DEBUGF( "add_dir_entry() - Couldn't read dir sector" 537 DEBUGF( "add_dir_entry() - Couldn't read dir sector"
@@ -595,7 +596,7 @@ static int add_dir_entry(struct bpb *bpb,
595 } 596 }
596 } 597 }
597 598
598 err = ata_write_sectors(sec + bpb->startsector,1,buf); 599 err = ata_write_sectors(sec + fat_bpb.startsector,1,buf);
599 if(err) 600 if(err)
600 { 601 {
601 DEBUGF( "add_dir_entry() - " 602 DEBUGF( "add_dir_entry() - "
@@ -708,7 +709,7 @@ static int create_dos_name(unsigned char *name, unsigned char *newname)
708 return 0; 709 return 0;
709} 710}
710 711
711int fat_create_dir(struct bpb *bpb, unsigned int currdir, char *name) 712int fat_create_dir(unsigned int currdir, char *name)
712{ 713{
713 struct fat_direntry de; 714 struct fat_direntry de;
714 int err; 715 int err;
@@ -727,11 +728,11 @@ int fat_create_dir(struct bpb *bpb, unsigned int currdir, char *name)
727 de.filesize = 0; 728 de.filesize = 0;
728 de.attr = FAT_ATTR_DIRECTORY; 729 de.attr = FAT_ATTR_DIRECTORY;
729 730
730 err = add_dir_entry(bpb, currdir, &de); 731 err = add_dir_entry(currdir, &de);
731 return 0; 732 return 0;
732} 733}
733 734
734int fat_create_file(struct bpb *bpb, unsigned int currdir, char *name) 735int fat_create_file(unsigned int currdir, char *name)
735{ 736{
736 struct fat_direntry de; 737 struct fat_direntry de;
737 int err; 738 int err;
@@ -748,7 +749,7 @@ int fat_create_file(struct bpb *bpb, unsigned int currdir, char *name)
748 de.wrttime = de.crttime; 749 de.wrttime = de.crttime;
749 de.filesize = 0; 750 de.filesize = 0;
750 751
751 err = add_dir_entry(bpb, currdir, &de); 752 err = add_dir_entry(currdir, &de);
752 return err; 753 return err;
753} 754}
754#endif 755#endif
@@ -770,29 +771,24 @@ static int parse_direntry(struct fat_direntry *de, unsigned char *buf)
770 return 1; 771 return 1;
771} 772}
772 773
773int fat_open(struct bpb *bpb, 774int fat_open( unsigned int startcluster, struct fat_file *file)
774 unsigned int startcluster,
775 struct fat_fileent *ent)
776{ 775{
777 ent->firstcluster = startcluster; 776 file->firstcluster = startcluster;
778 ent->nextcluster = startcluster; 777 file->nextcluster = startcluster;
779 ent->nextsector = cluster2sec(bpb,startcluster); 778 file->nextsector = cluster2sec(startcluster);
780 ent->sectornum = 0; 779 file->sectornum = 0;
781 return 0; 780 return 0;
782} 781}
783 782
784int fat_read(struct bpb *bpb, 783int fat_read( struct fat_file *file, int sectorcount, void* buf )
785 struct fat_fileent *ent,
786 int sectorcount,
787 void* buf )
788{ 784{
789 int cluster = ent->nextcluster; 785 int cluster = file->nextcluster;
790 int sector = ent->nextsector; 786 int sector = file->nextsector;
791 int numsec = ent->sectornum; 787 int numsec = file->sectornum;
792 int err, i; 788 int err, i;
793 789
794 for ( i=0; i<sectorcount; i++ ) { 790 for ( i=0; i<sectorcount; i++ ) {
795 err = ata_read_sectors(sector + bpb->startsector, 1, 791 err = ata_read_sectors(sector + fat_bpb.startsector, 1,
796 (char*)buf+(i*SECTOR_SIZE)); 792 (char*)buf+(i*SECTOR_SIZE));
797 if(err) { 793 if(err) {
798 DEBUGF( "fat_read() - Couldn't read sector %d" 794 DEBUGF( "fat_read() - Couldn't read sector %d"
@@ -801,12 +797,12 @@ int fat_read(struct bpb *bpb,
801 } 797 }
802 798
803 numsec++; 799 numsec++;
804 if ( numsec >= bpb->bpb_secperclus ) { 800 if ( numsec >= fat_bpb.bpb_secperclus ) {
805 cluster = get_next_cluster(bpb,cluster); 801 cluster = get_next_cluster(cluster);
806 if (!cluster) 802 if (!cluster)
807 break; /* end of file */ 803 break; /* end of file */
808 804
809 sector = cluster2sec(bpb,cluster); 805 sector = cluster2sec(cluster);
810 if (sector<0) 806 if (sector<0)
811 return -1; 807 return -1;
812 numsec=0; 808 numsec=0;
@@ -814,31 +810,29 @@ int fat_read(struct bpb *bpb,
814 else 810 else
815 sector++; 811 sector++;
816 } 812 }
817 ent->nextcluster = cluster; 813 file->nextcluster = cluster;
818 ent->nextsector = sector; 814 file->nextsector = sector;
819 ent->sectornum = numsec; 815 file->sectornum = numsec;
820 816
821 return sectorcount; 817 return sectorcount;
822} 818}
823 819
824int fat_seek(struct bpb *bpb, 820int fat_seek(struct fat_file *file, int seeksector )
825 struct fat_fileent *ent,
826 int seeksector )
827{ 821{
828 int cluster = ent->firstcluster; 822 int cluster = file->firstcluster;
829 int sector = seeksector; 823 int sector = seeksector;
830 int numsec = 0; 824 int numsec = 0;
831 int i; 825 int i;
832 826
833 for (i=0; i<seeksector; i++) { 827 for (i=0; i<seeksector; i++) {
834 numsec++; 828 numsec++;
835 if ( numsec >= bpb->bpb_secperclus ) { 829 if ( numsec >= fat_bpb.bpb_secperclus ) {
836 cluster = get_next_cluster(bpb,cluster); 830 cluster = get_next_cluster(cluster);
837 if (!cluster) 831 if (!cluster)
838 /* end of file */ 832 /* end of file */
839 return -1; 833 return -1;
840 834
841 sector = cluster2sec(bpb,cluster); 835 sector = cluster2sec(cluster);
842 if (sector<0) 836 if (sector<0)
843 return -2; 837 return -2;
844 numsec=0; 838 numsec=0;
@@ -846,15 +840,13 @@ int fat_seek(struct bpb *bpb,
846 else 840 else
847 sector++; 841 sector++;
848 } 842 }
849 ent->nextcluster = cluster; 843 file->nextcluster = cluster;
850 ent->nextsector = sector; 844 file->nextsector = sector;
851 ent->sectornum = numsec; 845 file->sectornum = numsec;
852 return 0; 846 return 0;
853} 847}
854 848
855int fat_opendir(struct bpb *bpb, 849int fat_opendir(struct fat_dir *dir, unsigned int currdir)
856 struct fat_dirent *ent,
857 unsigned int currdir)
858{ 850{
859 int is_rootdir = (currdir == 0); 851 int is_rootdir = (currdir == 0);
860 unsigned int sec; 852 unsigned int sec;
@@ -862,15 +854,15 @@ int fat_opendir(struct bpb *bpb,
862 854
863 if(is_rootdir) 855 if(is_rootdir)
864 { 856 {
865 sec = bpb->rootdirsector; 857 sec = fat_bpb.rootdirsector;
866 } 858 }
867 else 859 else
868 { 860 {
869 sec = first_sector_of_cluster(bpb, currdir); 861 sec = first_sector_of_cluster(currdir);
870 } 862 }
871 863
872 /* Read the first sector in the current dir */ 864 /* Read the first sector in the current dir */
873 err = ata_read_sectors(sec + bpb->startsector,1,ent->cached_buf); 865 err = ata_read_sectors(sec + fat_bpb.startsector,1,dir->cached_buf);
874 if(err) 866 if(err)
875 { 867 {
876 DEBUGF( "fat_getfirst() - Couldn't read dir sector" 868 DEBUGF( "fat_getfirst() - Couldn't read dir sector"
@@ -878,16 +870,14 @@ int fat_opendir(struct bpb *bpb,
878 return -1; 870 return -1;
879 } 871 }
880 872
881 ent->entry = 0; 873 dir->entry = 0;
882 ent->cached_sec = sec; 874 dir->cached_sec = sec;
883 ent->num_sec = 0; 875 dir->num_sec = 0;
884 876
885 return 0; 877 return 0;
886} 878}
887 879
888int fat_getnext(struct bpb *bpb, 880int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry)
889 struct fat_dirent *ent,
890 struct fat_direntry *entry)
891{ 881{
892 int done = 0; 882 int done = 0;
893 int i; 883 int i;
@@ -899,25 +889,27 @@ int fat_getnext(struct bpb *bpb,
899 889
900 while(!done) 890 while(!done)
901 { 891 {
902 for(i = ent->entry;i < SECTOR_SIZE/32;i++) 892 for(i = dir->entry;i < SECTOR_SIZE/32;i++)
903 { 893 {
904 firstbyte = ent->cached_buf[i*32]; 894 firstbyte = dir->cached_buf[i*32];
905 895
906 if(firstbyte == 0xe5) 896 if(firstbyte == 0xe5)
907 /* free entry */ 897 /* free entry */
908 continue; 898 continue;
909 899
910 if(firstbyte == 0) 900 if(firstbyte == 0) {
911 /* last entry */ 901 /* last entry */
912 return -1; 902 entry->name[0] = 0;
903 return 0;
904 }
913 905
914 /* longname entry? */ 906 /* longname entry? */
915 if ( ( ent->cached_buf[i*32 + FATDIR_ATTR] & 907 if ( ( dir->cached_buf[i*32 + FATDIR_ATTR] &
916 FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { 908 FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) {
917 longarray[longs++] = i*32 + sectoridx; 909 longarray[longs++] = i*32 + sectoridx;
918 } 910 }
919 else { 911 else {
920 if ( parse_direntry(entry, &ent->cached_buf[i*32]) ) { 912 if ( parse_direntry(entry, &dir->cached_buf[i*32]) ) {
921 913
922 /* replace shortname with longname? */ 914 /* replace shortname with longname? */
923 if ( longs ) { 915 if ( longs ) {
@@ -925,7 +917,7 @@ int fat_getnext(struct bpb *bpb,
925 917
926 /* iterate backwards through the dir entries */ 918 /* iterate backwards through the dir entries */
927 for (j=longs-1; j>=0; j--) { 919 for (j=longs-1; j>=0; j--) {
928 unsigned char* ptr = ent->cached_buf; 920 unsigned char* ptr = dir->cached_buf;
929 int index = longarray[j]; 921 int index = longarray[j];
930 922
931 /* current or cached sector? */ 923 /* current or cached sector? */
@@ -966,9 +958,9 @@ int fat_getnext(struct bpb *bpb,
966 958
967 /* save this sector, for longname use */ 959 /* save this sector, for longname use */
968 if ( sectoridx ) 960 if ( sectoridx )
969 memcpy( lastsector2, ent->cached_buf, SECTOR_SIZE ); 961 memcpy( lastsector2, dir->cached_buf, SECTOR_SIZE );
970 else 962 else
971 memcpy( lastsector, ent->cached_buf, SECTOR_SIZE ); 963 memcpy( lastsector, dir->cached_buf, SECTOR_SIZE );
972 sectoridx += SECTOR_SIZE; 964 sectoridx += SECTOR_SIZE;
973 965
974 /* Next sector? */ 966 /* Next sector? */
@@ -978,29 +970,29 @@ int fat_getnext(struct bpb *bpb,
978 } 970 }
979 else 971 else
980 { 972 {
981 ent->num_sec++; 973 dir->num_sec++;
982 974
983 /* Do we need to advance one cluster? */ 975 /* Do we need to advance one cluster? */
984 if(ent->num_sec < bpb->bpb_secperclus) 976 if(dir->num_sec < fat_bpb.bpb_secperclus)
985 { 977 {
986 ent->cached_sec++; 978 dir->cached_sec++;
987 } 979 }
988 else 980 else
989 { 981 {
990 int cluster = sec2cluster(bpb, ent->cached_sec); 982 int cluster = sec2cluster(dir->cached_sec);
991 if ( cluster < 0 ) { 983 if ( cluster < 0 ) {
992 DEBUGF("sec2cluster failed\n"); 984 DEBUGF("sec2cluster failed\n");
993 return -1; 985 return -1;
994 } 986 }
995 ent->num_sec = 0; 987 dir->num_sec = 0;
996 cluster = get_next_cluster( bpb, cluster ); 988 cluster = get_next_cluster( cluster );
997 if(!cluster) 989 if(!cluster)
998 { 990 {
999 DEBUGF("End of cluster chain.\n"); 991 DEBUGF("End of cluster chain.\n");
1000 return -1; 992 return -1;
1001 } 993 }
1002 ent->cached_sec = cluster2sec(bpb,cluster); 994 dir->cached_sec = cluster2sec(cluster);
1003 if ( ent->cached_sec < 0 ) 995 if ( dir->cached_sec < 0 )
1004 { 996 {
1005 DEBUGF("Invalid cluster: %d\n",cluster); 997 DEBUGF("Invalid cluster: %d\n",cluster);
1006 return -1; 998 return -1;
@@ -1009,8 +1001,8 @@ int fat_getnext(struct bpb *bpb,
1009 } 1001 }
1010 1002
1011 /* Read the next sector */ 1003 /* Read the next sector */
1012 err = ata_read_sectors(ent->cached_sec + bpb->startsector, 1, 1004 err = ata_read_sectors(dir->cached_sec + fat_bpb.startsector, 1,
1013 ent->cached_buf); 1005 dir->cached_buf);
1014 if(err) 1006 if(err)
1015 { 1007 {
1016 DEBUGF( "fat_getnext() - Couldn't read dir sector" 1008 DEBUGF( "fat_getnext() - Couldn't read dir sector"
@@ -1020,7 +1012,7 @@ int fat_getnext(struct bpb *bpb,
1020 1012
1021 i = 0; 1013 i = 0;
1022 } 1014 }
1023 ent->entry = i; 1015 dir->entry = i;
1024 } 1016 }
1025 return 0; 1017 return 0;
1026} 1018}
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h
index faec5384dd..3e8875f3e7 100644
--- a/firmware/drivers/fat.h
+++ b/firmware/drivers/fat.h
@@ -85,7 +85,7 @@ struct fat_direntry
85#define FAT_ATTR_DIRECTORY 0x10 85#define FAT_ATTR_DIRECTORY 0x10
86#define FAT_ATTR_ARCHIVE 0x20 86#define FAT_ATTR_ARCHIVE 0x20
87 87
88struct fat_dirent 88struct fat_dir
89{ 89{
90 int entry; 90 int entry;
91 unsigned int cached_sec; 91 unsigned int cached_sec;
@@ -93,7 +93,7 @@ struct fat_dirent
93 unsigned char cached_buf[SECTOR_SIZE]; 93 unsigned char cached_buf[SECTOR_SIZE];
94}; 94};
95 95
96struct fat_fileent 96struct fat_file
97{ 97{
98 int firstcluster; /* first cluster in file */ 98 int firstcluster; /* first cluster in file */
99 int nextcluster; /* cluster of last access */ 99 int nextcluster; /* cluster of last access */
@@ -101,32 +101,20 @@ struct fat_fileent
101 int sectornum; /* sector number in this cluster */ 101 int sectornum; /* sector number in this cluster */
102}; 102};
103 103
104extern int fat_mount(struct bpb *bpb, int startsector); 104/* global FAT info struct */
105extern struct bpb fat_bpb;
106
107extern int fat_mount(int startsector);
105 108
106#ifdef DISK_WRITE 109#ifdef DISK_WRITE
107extern int fat_create_file(struct bpb *bpb, 110extern int fat_create_file(unsigned int currdir, char *name);
108 unsigned int currdir, 111extern int fat_create_dir(unsigned int currdir, char *name);
109 char *name);
110extern int fat_create_dir(struct bpb *bpb,
111 unsigned int currdir,
112 char *name);
113#endif 112#endif
114extern int fat_open(struct bpb *bpb, 113extern int fat_open(unsigned int cluster, struct fat_file *ent);
115 unsigned int cluster, 114extern int fat_read(struct fat_file *ent, int sectorcount, void* buf );
116 struct fat_fileent *ent); 115extern int fat_seek(struct fat_file *ent, int sector );
117extern int fat_read(struct bpb *bpb,
118 struct fat_fileent *ent,
119 int sectorcount,
120 void* buf );
121extern int fat_seek(struct bpb *bpb,
122 struct fat_fileent *ent,
123 int sector );
124 116
125extern int fat_opendir(struct bpb *bpb, 117extern int fat_opendir(struct fat_dir *ent, unsigned int currdir);
126 struct fat_dirent *ent, 118extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry);
127 unsigned int currdir);
128extern int fat_getnext(struct bpb *bpb,
129 struct fat_dirent *ent,
130 struct fat_direntry *entry);
131 119
132#endif 120#endif