freemyipod r57 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r56‎ | r57 | r58 >
Date:22:53, 8 August 2010
Author:theseven
Status:new
Tags:
Comment:
Some more cleanup and fixes, get rid of all unaligned storage accesses from fat.c
Modified paths:
  • /embios/trunk/dir.h (modified) (history)
  • /embios/trunk/disk.h (modified) (history)
  • /embios/trunk/fat.c (modified) (history)
  • /embios/trunk/fat.h (modified) (history)
  • /embios/trunk/storage.c (modified) (history)
  • /embios/trunk/storage.h (modified) (history)
  • /embios/trunk/storage_nand.h (modified) (history)
  • /embios/trunk/target/ipodnano2g/storage_nand.c (modified) (history)
  • /embios/trunk/target/ipodnano2g/target.h (modified) (history)
  • /embios/trunk/usb/usb.c (modified) (history)

Diff [purge]

Index: embios/trunk/storage_nand.h
@@ -41,7 +41,6 @@
4242 int nand_flush(void);
4343 #endif
4444 void nand_spin(void);
45 -int nand_spinup_time(void); /* ticks */
4645
4746 #ifdef STORAGE_GET_INFO
4847 void nand_get_info(IF_MD2(int drive,) struct storage_info *info);
Index: embios/trunk/disk.h
@@ -21,6 +21,7 @@
2222 #ifndef _DISK_H_
2323 #define _DISK_H_
2424
 25+#include "global.h"
2526 #include "mv.h" /* for volume definitions */
2627
2728 struct partinfo {
@@ -43,9 +44,4 @@
4445 int disk_mount(int drive);
4546 int disk_unmount(int drive);
4647
47 -/* The number of 512-byte sectors in a "logical" sector. Needed for ipod 5.5G */
48 -#ifdef MAX_LOG_SECTOR_SIZE
49 -extern int disk_sector_multiplier;
5048 #endif
51 -
52 -#endif
Index: embios/trunk/storage.c
@@ -34,62 +34,9 @@
3535 #endif
3636
3737
38 -#ifdef HAVE_IO_PRIORITY
39 -
40 -/* Same for flash? */
41 -#define STORAGE_MINIMUM_IDLE_TIME (HZ/10)
42 -#define STORAGE_DELAY_UNIT (HZ/20)
43 -
44 -static unsigned int storage_last_thread[NUM_DRIVES];
45 -static unsigned int storage_last_activity[NUM_DRIVES];
46 -
47 -static bool storage_should_wait(int drive, int prio)
48 -{
49 - int other_prio = thread_get_io_priority(storage_last_thread[drive]);
50 - if(TIME_BEFORE(current_tick,storage_last_activity[drive]+STORAGE_MINIMUM_IDLE_TIME))
51 - {
52 - if(prio<=other_prio)
53 - {
54 - /* There is another active thread, but we have lower priority */
55 - return false;
56 - }
57 - else
58 - {
59 - /* There is another active thread, but it has lower priority */
60 - return true;
61 - }
62 - }
63 - else
64 - {
65 - /* There's nothing going on anyway */
66 - return false;
67 - }
68 -}
69 -
70 -static void storage_wait_turn(IF_MD_NONVOID(int drive))
71 -{
72 -#ifndef HAVE_MULTIDRIVE
73 - int drive=0;
74 -#endif
75 - int my_prio = thread_get_io_priority(THREAD_ID_CURRENT);
76 - int loops=my_prio;
77 - while(storage_should_wait(drive, my_prio) && (loops--)>=0)
78 - {
79 - sleep(STORAGE_DELAY_UNIT);
80 - }
81 -
82 - storage_last_thread[drive] = thread_get_current();
83 - storage_last_activity[drive] = current_tick;
84 -}
85 -#endif
86 -
8738 int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
8839 void* buf)
8940 {
90 -#ifdef HAVE_IO_PRIORITY
91 - storage_wait_turn(IF_MD(drive));
92 -#endif
93 -
9441 #ifdef CONFIG_STORAGE_MULTI
9542 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
9643 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
@@ -132,10 +79,6 @@
13380 int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
13481 const void* buf)
13582 {
136 -#ifdef HAVE_IO_PRIORITY
137 - storage_wait_turn(IF_MD(drive));
138 -#endif
139 -
14083 #ifdef CONFIG_STORAGE_MULTI
14184 int driver=(storage_drivers[drive] & DRIVER_MASK)>>DRIVER_OFFSET;
14285 int ldrive=(storage_drivers[drive] & DRIVE_MASK)>>DRIVE_OFFSET;
@@ -509,39 +452,6 @@
510453 return max;
511454 }
512455
513 -int storage_spinup_time(void)
514 -{
515 - int max=0;
516 - int t;
517 -
518 -#if (CONFIG_STORAGE & STORAGE_ATA)
519 - t=ata_spinup_time();
520 - if (t>max) max=t;
521 -#endif
522 -
523 -#if (CONFIG_STORAGE & STORAGE_MMC)
524 - t=mmc_spinup_time();
525 - if (t>max) max=t;
526 -#endif
527 -
528 -#if (CONFIG_STORAGE & STORAGE_SD)
529 - //t=sd_spinup_time();
530 - //if (t>max) max=t;
531 -#endif
532 -
533 -#if (CONFIG_STORAGE & STORAGE_NAND)
534 - t=nand_spinup_time();
535 - if (t>max) max=t;
536 -#endif
537 -
538 -#if (CONFIG_STORAGE & STORAGE_RAMDISK)
539 - t=ramdisk_spinup_time();
540 - if (t>max) max=t;
541 -#endif
542 -
543 - return max;
544 -}
545 -
546456 #ifdef STORAGE_GET_INFO
547457 void storage_get_info(int drive, struct storage_info *info)
548458 {
Index: embios/trunk/target/ipodnano2g/storage_nand.c
@@ -86,7 +86,7 @@
8787 int nand_flush(void)
8888 {
8989 int rc = ftl_sync();
90 - if (rc != 0) panicf("Failed to unmount flash: %X", rc);
 90+ if (rc != 0) panicf(PANIC_FATAL, "Failed to unmount flash: %X", rc);
9191 return rc;
9292 }
9393 #endif
Index: embios/trunk/target/ipodnano2g/target.h
@@ -37,6 +37,7 @@
3838
3939
4040 #define HAVE_FLASH_STORAGE
 41+#define HAVE_STORAGE_FLUSH
4142 #define CONFIG_STORAGE STORAGE_NAND
4243 #define SECTOR_SIZE 2048
4344
Index: embios/trunk/usb/usb.c
@@ -463,8 +463,9 @@
464464 dbgsendbuf[0] = 1;
465465 dbgsendbuf[1] = SCHEDULER_THREAD_INFO_VERSION;
466466 dbgsendbuf[2] = MAX_THREADS * sizeof(struct scheduler_thread);
467 - memcpy(&dbgsendbuf[4], (void*)((uint32_t)scheduler_threads + dbgrecvbuf[1]), dbgrecvbuf[2]);
468 - size = dbgrecvbuf[2] + 16;
 467+ memcpy(&dbgsendbuf[4], (void*)((uint32_t)scheduler_threads + dbgrecvbuf[1]),
 468+ dbgrecvbuf[2]);
 469+ size = dbgrecvbuf[2] + 16;
469470 break;
470471 case 16: // FREEZE SCHEDULER
471472 dbgsendbuf[1] = scheduler_freeze(dbgrecvbuf[1]);
@@ -490,7 +491,7 @@
491492 dbgsendbuf[0] = 1;
492493 size = 16;
493494 break;
494 - case 19: // CREATE THREAD
 495+ case 19: // KILL THREAD
495496 dbgsendbuf[0] = 1;
496497 dbgsendbuf[1] = thread_create((const char*)dbgsendbuf[1], (const void*)dbgsendbuf[2],
497498 (char*)dbgsendbuf[3], dbgsendbuf[4], dbgsendbuf[5],
Index: embios/trunk/storage.h
@@ -71,7 +71,6 @@
7272 #define storage_flush() (void)0
7373 #endif
7474 #define storage_last_disk_activity() ata_last_disk_activity()
75 - #define storage_spinup_time() ata_spinup_time()
7675 #define storage_get_identify() ata_get_identify()
7776
7877 #ifdef STORAGE_GET_INFO
@@ -96,7 +95,6 @@
9796 #define storage_flush() (void)0
9897 #endif
9998 #define storage_last_disk_activity() sd_last_disk_activity()
100 - #define storage_spinup_time() 0
10199 #define storage_get_identify() sd_get_identify()
102100
103101 #ifdef STORAGE_GET_INFO
@@ -121,7 +119,6 @@
122120 #define storage_flush() (void)0
123121 #endif
124122 #define storage_last_disk_activity() mmc_last_disk_activity()
125 - #define storage_spinup_time() 0
126123 #define storage_get_identify() mmc_get_identify()
127124
128125 #ifdef STORAGE_GET_INFO
@@ -146,7 +143,6 @@
147144 #define storage_flush() nand_flush()
148145 #endif
149146 #define storage_last_disk_activity() nand_last_disk_activity()
150 - #define storage_spinup_time() 0
151147 #define storage_get_identify() nand_get_identify()
152148
153149 #ifdef STORAGE_GET_INFO
@@ -171,7 +167,6 @@
172168 #define storage_flush() (void)0
173169 #endif
174170 #define storage_last_disk_activity() ramdisk_last_disk_activity()
175 - #define storage_spinup_time() 0
176171 #define storage_get_identify() ramdisk_get_identify()
177172
178173 #ifdef STORAGE_GET_INFO
@@ -184,7 +179,7 @@
185180 #else
186181 //#error No storage driver!
187182 #endif
188 -#else /* NOT CONFIG_STORAGE_MULTI and PLATFORM_NATIVE*/
 183+#else /* NOT CONFIG_STORAGE_MULTI */
189184
190185 /* Simulator and multi-driver use normal functions */
191186
@@ -198,7 +193,6 @@
199194 void storage_spin(void);
200195 void storage_spindown(int seconds);
201196 long storage_last_disk_activity(void);
202 -int storage_spinup_time(void);
203197 int storage_num_drives(void);
204198 #ifdef STORAGE_GET_INFO
205199 void storage_get_info(int drive, struct storage_info *info);
@@ -208,7 +202,7 @@
209203 bool storage_present(int drive);
210204 #endif
211205
212 -#endif /* NOT CONFIG_STORAGE_MULTI and NOT SIMULATOR*/
 206+#endif /* NOT CONFIG_STORAGE_MULTI */
213207
214208 int storage_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf);
215209 int storage_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf);
Index: embios/trunk/fat.c
@@ -186,6 +186,8 @@
187187 static int bpb_is_sane(IF_MV_NONVOID(struct bpb* fat_bpb));
188188 static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,)
189189 long secnum, bool dirty);
 190+static void unlock_fat_sector(IF_MV2(struct bpb* fat_bpb,)
 191+ long secnum);
190192 static void create_dos_name(const unsigned char *name, unsigned char *newname);
191193 static void randomize_dos_name(unsigned char *name);
192194 static unsigned long find_free_cluster(IF_MV2(struct bpb* fat_bpb,)
@@ -193,22 +195,26 @@
194196 static int transfer(IF_MV2(struct bpb* fat_bpb,) unsigned long start,
195197 long count, char* buf, bool write );
196198
197 -#define FAT_CACHE_SIZE 0x20
 199+#define FAT_CACHE_SIZE 4
198200 #define FAT_CACHE_MASK (FAT_CACHE_SIZE-1)
199201
200202 struct fat_cache_entry
201203 {
202204 long secnum;
203 - bool inuse;
 205+ bool valid;
 206+ int locked;
204207 bool dirty;
205208 #ifdef HAVE_MULTIVOLUME
206 - struct bpb* fat_vol ; /* shared cache for all volumes */
 209+ struct bpb* fat_vol; /* shared cache for all volumes */
207210 #endif
208211 };
209212
210 -static char fat_cache_sectors[FAT_CACHE_SIZE][SECTOR_SIZE];
 213+static char fat_cache_sectors[FAT_CACHE_SIZE][SECTOR_SIZE] CACHEALIGN_ATTR;
211214 static struct fat_cache_entry fat_cache[FAT_CACHE_SIZE];
212215 static struct mutex cache_mutex;
 216+static struct mutex tempbuf_mutex;
 217+static char fat_tempbuf[SECTOR_SIZE] CACHEALIGN_ATTR;
 218+static bool tempbuf_locked;
213219
214220 #if defined(HAVE_HOTSWAP) && !(CONFIG_STORAGE & STORAGE_MMC) /* A better condition ?? */
215221 void fat_lock(void)
@@ -264,19 +270,16 @@
265271 {
266272 initialized = true;
267273 mutex_init(&cache_mutex);
 274+ mutex_init(&tempbuf_mutex);
 275+ tempbuf_locked = false;
268276 }
269277
270 -#ifdef HAVE_PRIORITY_SCHEDULING
271 - /* Disable this because it is dangerous due to the assumption that
272 - * mutex_unlock won't yield */
273 - mutex_set_preempt(&cache_mutex, false);
274 -#endif
275 -
276278 /* mark the FAT cache as unused */
277279 for(i = 0;i < FAT_CACHE_SIZE;i++)
278280 {
279 - fat_cache[i].secnum = 8; /* We use a "safe" sector just in case */
280 - fat_cache[i].inuse = false;
 281+ fat_cache[i].secnum = -1;
 282+ fat_cache[i].valid = false;
 283+ fat_cache[i].locked = 0;
281284 fat_cache[i].dirty = false;
282285 #ifdef HAVE_MULTIVOLUME
283286 fat_cache[i].fat_vol = NULL;
@@ -297,7 +300,6 @@
298301 const int volume = 0;
299302 #endif
300303 struct bpb* fat_bpb = &fat_bpbs[volume];
301 - unsigned char buf[SECTOR_SIZE];
302304 int rc;
303305 int secmult;
304306 long datasec;
@@ -306,9 +308,11 @@
307309 #endif
308310
309311 /* Read the sector */
 312+ unsigned char* buf = fat_get_sector_buffer();
310313 rc = storage_read_sectors(IF_MD2(drive,) startsector,1,buf);
311314 if(rc)
312315 {
 316+ fat_release_sector_buffer();
313317 DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)", rc);
314318 return rc * 10 - 1;
315319 }
@@ -347,7 +351,10 @@
348352 #ifdef HAVE_FAT16SUPPORT
349353 fat_bpb->bpb_rootentcnt = BYTES2INT16(buf,BPB_ROOTENTCNT);
350354 if (!fat_bpb->bpb_bytspersec)
 355+ {
 356+ fat_release_sector_buffer();
351357 return -2;
 358+ }
352359 rootdirsectors = secmult * ((fat_bpb->bpb_rootentcnt * DIR_ENTRY_SIZE
353360 + fat_bpb->bpb_bytspersec - 1) / fat_bpb->bpb_bytspersec);
354361 #endif /* #ifdef HAVE_FAT16SUPPORT */
@@ -363,7 +370,10 @@
364371 if (fat_bpb->bpb_secperclus)
365372 fat_bpb->dataclusters = datasec / fat_bpb->bpb_secperclus;
366373 else
367 - return -2;
 374+ {
 375+ fat_release_sector_buffer();
 376+ return -2;
 377+ }
368378
369379 #ifdef TEST_FAT
370380 /*
@@ -379,10 +389,12 @@
380390 fat_bpb->is_fat16 = true;
381391 if (fat_bpb->dataclusters < 4085)
382392 { /* FAT12 */
 393+ fat_release_sector_buffer();
383394 DEBUGF("This is FAT12. Go away!");
384395 return -2;
385396 }
386397 #else /* #ifdef HAVE_FAT16SUPPORT */
 398+ fat_release_sector_buffer();
387399 DEBUGF("This is not FAT32. Go away!");
388400 return -2;
389401 #endif /* #ifndef HAVE_FAT16SUPPORT */
@@ -414,6 +426,7 @@
415427 rc = bpb_is_sane(IF_MV(fat_bpb));
416428 if (rc < 0)
417429 {
 430+ fat_release_sector_buffer();
418431 DEBUGF( "fat_mount() - BPB is not sane");
419432 return rc * 10 - 3;
420433 }
@@ -432,6 +445,7 @@
433446 startsector + fat_bpb->bpb_fsinfo, 1, buf);
434447 if (rc < 0)
435448 {
 449+ fat_release_sector_buffer();
436450 DEBUGF( "fat_mount() - Couldn't read FSInfo (error code %d)", rc);
437451 return rc * 10 - 4;
438452 }
@@ -438,6 +452,7 @@
439453 fat_bpb->fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT);
440454 fat_bpb->fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE);
441455 }
 456+ fat_release_sector_buffer();
442457
443458 /* calculate freecount if unset */
444459 if ( fat_bpb->fsinfo.freecount == 0xffffffff )
@@ -485,7 +500,8 @@
486501 #endif
487502 )
488503 {
489 - fce->inuse = false; /* discard all from that volume */
 504+ fce->valid = false; /* discard all from that volume */
 505+ fce->locked = 0;
490506 fce->dirty = false;
491507 }
492508 }
@@ -524,6 +540,7 @@
525541 fat_bpb->fsinfo.nextfree = c;
526542 }
527543 }
 544+ unlock_fat_sector(IF_MV2(fat_bpb,) i);
528545 }
529546 }
530547 else
@@ -543,6 +560,7 @@
544561 fat_bpb->fsinfo.nextfree = c;
545562 }
546563 }
 564+ unlock_fat_sector(IF_MV2(fat_bpb,) i);
547565 }
548566 }
549567 fat_bpb->fsinfo.freecount = free;
@@ -646,8 +664,6 @@
647665 fce->dirty = false;
648666 }
649667
650 -/* Note: The returned pointer is only safely valid until the next
651 - task switch! (Any subsequent ata read/write may yield.) */
652668 static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,)
653669 long fatsector, bool dirty)
654670 {
@@ -663,22 +679,23 @@
664680 mutex_lock(&cache_mutex, TIMEOUT_BLOCK); /* make changes atomic */
665681
666682 /* Delete the cache entry if it isn't the sector we want */
667 - if(fce->inuse && (fce->secnum != secnum
 683+ if(fce->valid && (fce->secnum != secnum
668684 #ifdef HAVE_MULTIVOLUME
669685 || fce->fat_vol != fat_bpb
670686 #endif
671687 ))
672688 {
 689+ while (fce->locked) sleep(1000);
673690 /* Write back if it is dirty */
674691 if(fce->dirty)
675692 {
676693 flush_fat_sector(fce, sectorbuf);
677694 }
678 - fce->inuse = false;
 695+ fce->valid = false;
679696 }
680697
681698 /* Load the sector if it is not cached */
682 - if(!fce->inuse)
 699+ if(!fce->valid)
683700 {
684701 rc = storage_read_sectors(IF_MD2(fat_bpb->drive,)
685702 secnum + fat_bpb->startsector,1,
@@ -690,12 +707,13 @@
691708 mutex_unlock(&cache_mutex);
692709 return NULL;
693710 }
694 - fce->inuse = true;
 711+ fce->valid = true;
695712 fce->secnum = secnum;
696713 #ifdef HAVE_MULTIVOLUME
697714 fce->fat_vol = fat_bpb;
698715 #endif
699716 }
 717+ fce->locked++;
700718 if (dirty)
701719 fce->dirty = true; /* dirt remains, sticky until flushed */
702720 mutex_unlock(&cache_mutex);
@@ -702,6 +720,31 @@
703721 return sectorbuf;
704722 }
705723
 724+static void unlock_fat_sector(IF_MV2(struct bpb* fat_bpb,) long fatsector)
 725+{
 726+#ifndef HAVE_MULTIVOLUME
 727+ struct bpb* fat_bpb = &fat_bpbs[0];
 728+#endif
 729+ long secnum = fatsector + fat_bpb->bpb_rsvdseccnt;
 730+ int cache_index = secnum & FAT_CACHE_MASK;
 731+ fat_cache[cache_index].locked--;
 732+}
 733+
 734+void* fat_get_sector_buffer()
 735+{
 736+ mutex_lock(&tempbuf_mutex, TIMEOUT_BLOCK);
 737+ if (tempbuf_locked)
 738+ panicf(PANIC_KILLUSERTHREADS, "FAT: Tried to lock temporary sector buffer twice!");
 739+ tempbuf_locked = true;
 740+ return fat_tempbuf;
 741+}
 742+
 743+void fat_release_sector_buffer()
 744+{
 745+ tempbuf_locked = false;
 746+ mutex_unlock(&tempbuf_mutex);
 747+}
 748+
706749 static unsigned long find_free_cluster(IF_MV2(struct bpb* fat_bpb,)
707750 unsigned long startcluster)
708751 {
@@ -732,11 +775,13 @@
733776 cluster numbers out of bounds */
734777 if ( c < 2 || c > fat_bpb->dataclusters+1 )
735778 continue;
 779+ unlock_fat_sector(IF_MV2(fat_bpb,) nr);
736780 DEBUGF("find_free_cluster(%x) == %x",startcluster,c);
737781 fat_bpb->fsinfo.nextfree = c;
738782 return c;
739783 }
740784 }
 785+ unlock_fat_sector(IF_MV2(fat_bpb,) nr);
741786 offset = 0;
742787 }
743788 }
@@ -760,11 +805,13 @@
761806 cluster numbers out of bounds */
762807 if ( c < 2 || c > fat_bpb->dataclusters+1 )
763808 continue;
 809+ unlock_fat_sector(IF_MV2(fat_bpb,) nr);
764810 DEBUGF("find_free_cluster(%lx) == %lx",startcluster,c);
765811 fat_bpb->fsinfo.nextfree = c;
766812 return c;
767813 }
768814 }
 815+ unlock_fat_sector(IF_MV2(fat_bpb,) nr);
769816 offset = 0;
770817 }
771818 }
@@ -816,6 +863,7 @@
817864 fat_bpb->fsinfo.freecount);
818865
819866 sec[offset] = htole16(val);
 867+ unlock_fat_sector(IF_MV2(fat_bpb,) sector);
820868 }
821869 else
822870 #endif /* #ifdef HAVE_FAT16SUPPORT */
@@ -855,6 +903,7 @@
856904 /* don't change top 4 bits */
857905 sec[offset] &= htole32(0xf0000000);
858906 sec[offset] |= htole32(val & 0x0fffffff);
 907+ unlock_fat_sector(IF_MV2(fat_bpb,) sector);
859908 }
860909
861910 return 0;
@@ -879,7 +928,10 @@
880929 return -1;
881930 }
882931
883 - return letoh16(sec[offset]);
 932+ long val = letoh16(sec[offset]);
 933+ unlock_fat_sector(IF_MV2(fat_bpb,) sector);
 934+
 935+ return val;
884936 }
885937 else
886938 #endif /* #ifdef HAVE_FAT16SUPPORT */
@@ -895,7 +947,10 @@
896948 return -1;
897949 }
898950
899 - return letoh32(sec[offset]) & 0x0fffffff;
 951+ long val = letoh32(sec[offset]) & 0x0fffffff;
 952+ unlock_fat_sector(IF_MV2(fat_bpb,) sector);
 953+
 954+ return val;
900955 }
901956 }
902957
@@ -929,7 +984,6 @@
930985 #ifndef HAVE_MULTIVOLUME
931986 struct bpb* fat_bpb = &fat_bpbs[0];
932987 #endif
933 - unsigned char fsinfo[SECTOR_SIZE];
934988 unsigned long* intptr;
935989 int rc;
936990
@@ -939,11 +993,13 @@
940994 #endif /* #ifdef HAVE_FAT16SUPPORT */
941995
942996 /* update fsinfo */
 997+ unsigned char* fsinfo = fat_get_sector_buffer();
943998 rc = storage_read_sectors(IF_MD2(fat_bpb->drive,)
944999 fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo);
9451000 if (rc < 0)
9461001 {
947 - DEBUGF( "flush_fat() - Couldn't read FSInfo (error code %d)", rc);
 1002+ fat_release_sector_buffer();
 1003+ DEBUGF( "update_fsinfo() - Couldn't read FSInfo (error code %d)", rc);
9481004 return rc * 10 - 1;
9491005 }
9501006 intptr = (long*)&(fsinfo[FSINFO_FREECOUNT]);
@@ -954,9 +1010,10 @@
9551011
9561012 rc = storage_write_sectors(IF_MD2(fat_bpb->drive,)
9571013 fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo);
 1014+ fat_release_sector_buffer();
9581015 if (rc < 0)
9591016 {
960 - DEBUGF( "flush_fat() - Couldn't write FSInfo (error code %d)", rc);
 1017+ DEBUGF( "update_fsinfo() - Couldn't write FSInfo (error code %d)", rc);
9611018 return rc * 10 - 2;
9621019 }
9631020
@@ -974,7 +1031,7 @@
9751032 for(i = 0;i < FAT_CACHE_SIZE;i++)
9761033 {
9771034 struct fat_cache_entry *fce = &fat_cache[i];
978 - if(fce->inuse
 1035+ if(fce->valid
9791036 #ifdef HAVE_MULTIVOLUME
9801037 && fce->fat_vol == fat_bpb
9811038 #endif
@@ -1028,7 +1085,6 @@
10291086 const unsigned char* shortname,
10301087 bool is_directory)
10311088 {
1032 - unsigned char buf[SECTOR_SIZE];
10331089 unsigned char* entry;
10341090 unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR;
10351091 unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR;
@@ -1045,9 +1101,13 @@
10461102 if (rc<0)
10471103 return rc * 10 - 1;
10481104
 1105+ unsigned char* buf = fat_get_sector_buffer();
10491106 rc = fat_readwrite(file, 1, buf, false);
10501107 if (rc<1)
 1108+ {
 1109+ fat_release_sector_buffer();
10511110 return rc * 10 - 2;
 1111+ }
10521112
10531113 /* calculate shortname checksum */
10541114 for (i=11; i>0; i--)
@@ -1070,15 +1130,22 @@
10711131 /* update current sector */
10721132 rc = fat_seek(file, sector);
10731133 if (rc<0)
 1134+ {
 1135+ fat_release_sector_buffer();
10741136 return rc * 10 - 3;
 1137+ }
10751138
10761139 rc = fat_readwrite(file, 1, buf, true);
10771140 if (rc<1)
 1141+ {
 1142+ fat_release_sector_buffer();
10781143 return rc * 10 - 4;
 1144+ }
10791145
10801146 /* read next sector */
10811147 rc = fat_readwrite(file, 1, buf, false);
10821148 if (rc<0) {
 1149+ fat_release_sector_buffer();
10831150 DEBUGF("Failed writing new sector: %d",rc);
10841151 return rc * 10 - 5;
10851152 }
@@ -1094,10 +1161,13 @@
10951162
10961163 /* verify this entry is free */
10971164 if (entry[0] && entry[0] != 0xe5 )
 1165+ {
 1166+ fat_release_sector_buffer();
10981167 panicf(PANIC_KILLUSERTHREADS, "Dir entry %d in sector %x is not free! "
10991168 "%02x %02x %02x %02x",
11001169 idx, sector,
11011170 entry[0], entry[1], entry[2], entry[3]);
 1171+ }
11021172
11031173 memset(entry, 0, DIR_ENTRY_SIZE);
11041174 if ( i+1 < numentries ) {
@@ -1157,9 +1227,13 @@
11581228 /* update last sector */
11591229 rc = fat_seek(file, sector);
11601230 if (rc<0)
 1231+ {
 1232+ fat_release_sector_buffer();
11611233 return rc * 10 - 6;
 1234+ }
11621235
11631236 rc = fat_readwrite(file, 1, buf, true);
 1237+ fat_release_sector_buffer();
11641238 if (rc<1)
11651239 return rc * 10 - 7;
11661240
@@ -1199,7 +1273,6 @@
12001274 #else
12011275 struct bpb* fat_bpb = &fat_bpbs[0];
12021276 #endif
1203 - unsigned char buf[SECTOR_SIZE];
12041277 unsigned char shortname[12];
12051278 int rc;
12061279 unsigned int sector;
@@ -1240,12 +1313,16 @@
12411314 / NAME_BYTES_PER_ENTRY + 1;
12421315 }
12431316
 1317+ unsigned char* buf = fat_get_sector_buffer();
12441318 restart:
12451319 firstentry = -1;
12461320
12471321 rc = fat_seek(&dir->file, 0);
12481322 if (rc < 0)
 1323+ {
 1324+ fat_release_sector_buffer();
12491325 return rc * 10 - 2;
 1326+ }
12501327
12511328 /* step 1: search for free entries and check for duplicate shortname */
12521329 for (sector = 0; !done; sector++)
@@ -1254,6 +1331,7 @@
12551332
12561333 rc = fat_readwrite(&dir->file, 1, buf, false);
12571334 if (rc < 0) {
 1335+ fat_release_sector_buffer();
12581336 DEBUGF( "add_dir_entry() - Couldn't read dir"
12591337 " (error code %d)", rc);
12601338 return rc * 10 - 3;
@@ -1310,7 +1388,10 @@
13111389 DEBUGF("Adding new sector(s) to dir");
13121390 rc = fat_seek(&dir->file, sector);
13131391 if (rc < 0)
 1392+ {
 1393+ fat_release_sector_buffer();
13141394 return rc * 10 - 4;
 1395+ }
13151396 memset(buf, 0, sizeof buf);
13161397
13171398 /* we must clear whole clusters */
@@ -1318,11 +1399,17 @@
13191400 (dir->file.sectornum < (int)fat_bpb->bpb_secperclus); sector++)
13201401 {
13211402 if (sector >= (65536/DIR_ENTRIES_PER_SECTOR))
 1403+ {
 1404+ fat_release_sector_buffer();
13221405 return -5; /* dir too large -- FAT specification */
 1406+ }
13231407
13241408 rc = fat_readwrite(&dir->file, 1, buf, true);
13251409 if (rc < 1) /* No more room or something went wrong */
 1410+ {
 1411+ fat_release_sector_buffer();
13261412 return rc * 10 - 6;
 1413+ }
13271414
13281415 entries_found += DIR_ENTRIES_PER_SECTOR;
13291416 }
@@ -1329,6 +1416,7 @@
13301417
13311418 firstentry = sector * DIR_ENTRIES_PER_SECTOR - entries_found;
13321419 }
 1420+ fat_release_sector_buffer();
13331421
13341422 /* step 3: add entry */
13351423 sector = firstentry / DIR_ENTRIES_PER_SECTOR;
@@ -1456,10 +1544,7 @@
14571545
14581546 static int update_short_entry( struct fat_file* file, long size, int attr )
14591547 {
1460 - unsigned char buf[SECTOR_SIZE];
14611548 int sector = file->direntry / DIR_ENTRIES_PER_SECTOR;
1462 - unsigned char* entry =
1463 - buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);
14641549 unsigned long* sizeptr;
14651550 unsigned short* clusptr;
14661551 struct fat_file dir;
@@ -1477,12 +1562,21 @@
14781563 if (rc<0)
14791564 return rc * 10 - 2;
14801565
 1566+ unsigned char* buf = fat_get_sector_buffer();
 1567+ unsigned char* entry =
 1568+ buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);
14811569 rc = fat_readwrite(&dir, 1, buf, false);
14821570 if (rc < 1)
 1571+ {
 1572+ fat_release_sector_buffer();
14831573 return rc * 10 - 3;
 1574+ }
14841575
14851576 if (!entry[0] || entry[0] == 0xe5)
 1577+ {
 1578+ fat_release_sector_buffer();
14861579 panicf(PANIC_KILLUSERTHREADS, "Updating size on empty dir entry %d", file->direntry);
 1580+ }
14871581
14881582 entry[FATDIR_ATTR] = attr & 0xFF;
14891583
@@ -1512,9 +1606,13 @@
15131607
15141608 rc = fat_seek( &dir, sector );
15151609 if (rc < 0)
 1610+ {
 1611+ fat_release_sector_buffer();
15161612 return rc * 10 - 4;
 1613+ }
15171614
15181615 rc = fat_readwrite(&dir, 1, buf, true);
 1616+ fat_release_sector_buffer();
15191617 if (rc < 1)
15201618 return rc * 10 - 5;
15211619
@@ -1624,7 +1722,7 @@
16251723 #else
16261724 struct bpb* fat_bpb = &fat_bpbs[0];
16271725 #endif
1628 - unsigned char buf[SECTOR_SIZE];
 1726+ unsigned char buf[4];
16291727 int i;
16301728 long sector;
16311729 int rc;
@@ -1762,7 +1860,6 @@
17631861
17641862 static int free_direntries(struct fat_file* file)
17651863 {
1766 - unsigned char buf[SECTOR_SIZE];
17671864 struct fat_file dir;
17681865 int numentries = file->direntries;
17691866 unsigned int entry = file->direntry - numentries + 1;
@@ -1779,9 +1876,13 @@
17801877 if (rc < 0)
17811878 return rc * 10 - 2;
17821879
 1880+ unsigned char* buf = fat_get_sector_buffer();
17831881 rc = fat_readwrite(&dir, 1, buf, false);
17841882 if (rc < 1)
 1883+ {
 1884+ fat_release_sector_buffer();
17851885 return rc * 10 - 3;
 1886+ }
17861887
17871888 for (i=0; i < numentries; i++) {
17881889 DEBUGF("Clearing dir entry %d (%d/%d)",
@@ -1793,17 +1894,26 @@
17941895 /* flush this sector */
17951896 rc = fat_seek(&dir, sector);
17961897 if (rc < 0)
 1898+ {
 1899+ fat_release_sector_buffer();
17971900 return rc * 10 - 4;
 1901+ }
17981902
17991903 rc = fat_readwrite(&dir, 1, buf, true);
18001904 if (rc < 1)
 1905+ {
 1906+ fat_release_sector_buffer();
18011907 return rc * 10 - 5;
 1908+ }
18021909
18031910 if ( i+1 < numentries ) {
18041911 /* read next sector */
18051912 rc = fat_readwrite(&dir, 1, buf, false);
18061913 if (rc < 1)
 1914+ {
 1915+ fat_release_sector_buffer();
18071916 return rc * 10 - 6;
 1917+ }
18081918 }
18091919 sector++;
18101920 }
@@ -1813,13 +1923,20 @@
18141924 /* flush this sector */
18151925 rc = fat_seek(&dir, sector);
18161926 if (rc < 0)
 1927+ {
 1928+ fat_release_sector_buffer();
18171929 return rc * 10 - 7;
 1930+ }
18181931
18191932 rc = fat_readwrite(&dir, 1, buf, true);
18201933 if (rc < 1)
 1934+ {
 1935+ fat_release_sector_buffer();
18211936 return rc * 10 - 8;
 1937+ }
18221938 }
18231939
 1940+ fat_release_sector_buffer();
18241941 return 0;
18251942 }
18261943
@@ -1864,7 +1981,6 @@
18651982 int rc;
18661983 struct fat_dir olddir;
18671984 struct fat_file newfile = *file;
1868 - unsigned char buf[SECTOR_SIZE];
18691985 unsigned char* entry = NULL;
18701986 unsigned short* clusptr = NULL;
18711987 unsigned int parentcluster;
@@ -1922,9 +2038,13 @@
19232039 if (rc < 0)
19242040 return rc * 10 - 7;
19252041
 2042+ unsigned char* buf = fat_get_sector_buffer();
19262043 rc = fat_readwrite(&olddir.file, 1, buf, false);
19272044 if (rc < 0)
 2045+ {
 2046+ fat_release_sector_buffer();
19282047 return rc * 10 - 8;
 2048+ }
19292049
19302050 /* parent cluster is 0 if parent dir is the root - FAT spec (p.29) */
19312051 if(dir->file.firstcluster == fat_bpb->bpb_rootclus)
@@ -1935,6 +2055,7 @@
19362056 entry = buf + DIR_ENTRY_SIZE;
19372057 if(strncmp(".. ", entry, 11))
19382058 {
 2059+ fat_release_sector_buffer();
19392060 /* .. entry must be second entry according to FAT spec (p.29) */
19402061 DEBUGF("Second dir entry is not double-dot!");
19412062 return rc * 10 - 9;
@@ -1948,9 +2069,13 @@
19492070 /* write back this sector */
19502071 rc = fat_seek(&olddir.file, 0);
19512072 if (rc < 0)
 2073+ {
 2074+ fat_release_sector_buffer();
19522075 return rc * 10 - 7;
 2076+ }
19532077
19542078 rc = fat_readwrite(&olddir.file, 1, buf, true);
 2079+ fat_release_sector_buffer();
19552080 if (rc < 1)
19562081 return rc * 10 - 8;
19572082 }
Index: embios/trunk/fat.h
@@ -22,16 +22,9 @@
2323 #ifndef FAT_H
2424 #define FAT_H
2525
26 -#include <stdbool.h>
 26+#include "global.h"
2727 #include "mv.h" /* for volume definitions */
28 -#include "config.h"
2928
30 -/* This value can be overwritten by a target in config-[target].h, but
31 - that behaviour is still experimental */
32 -#ifndef SECTOR_SIZE
33 -#define SECTOR_SIZE 512
34 -#endif
35 -
3629 /* Number of bytes reserved for a file name (including the trailing \0).
3730 Since names are stored in the entry as UTF-8, we won't be able to
3831 store all names allowed by FAT. In FAT, a name can have max 255
@@ -132,5 +125,7 @@
133126 extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry);
134127 extern unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); /* public for debug info screen */
135128 extern bool fat_ismounted(int volume);
 129+extern void* fat_get_sector_buffer(void);
 130+extern void fat_release_sector_buffer(void);
136131
137132 #endif
Index: embios/trunk/dir.h
@@ -21,7 +21,7 @@
2222 #ifndef __DIR_H__
2323 #define __DIR_H__
2424
25 -#include <stdbool.h>
 25+#include "global.h"
2626 #include "file.h"
2727
2828 #define ATTR_READ_ONLY 0x01