diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/common/file.c | 11 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 159 | ||||
-rw-r--r-- | firmware/drivers/fat.h | 5 | ||||
-rw-r--r-- | firmware/test/fat/ata-sim.c | 8 | ||||
-rw-r--r-- | firmware/test/fat/main.c | 42 |
5 files changed, 120 insertions, 105 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index 3e402bde2b..0cde938a70 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -178,7 +178,7 @@ int close(int fd) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | /* tie up all loose ends */ | 180 | /* tie up all loose ends */ |
181 | fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size); | 181 | fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].fileoffset); |
182 | } | 182 | } |
183 | openfiles[fd].busy = false; | 183 | openfiles[fd].busy = false; |
184 | return rc; | 184 | return rc; |
@@ -239,8 +239,6 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
239 | 239 | ||
240 | nread = headbytes; | 240 | nread = headbytes; |
241 | count -= headbytes; | 241 | count -= headbytes; |
242 | |||
243 | LDEBUGF("readwrite incache: offs=%d\n",openfiles[fd].cacheoffset); | ||
244 | } | 242 | } |
245 | 243 | ||
246 | /* read whole sectors right into the supplied buffer */ | 244 | /* read whole sectors right into the supplied buffer */ |
@@ -316,6 +314,13 @@ int lseek(int fd, int offset, int whence) | |||
316 | return -1; | 314 | return -1; |
317 | } | 315 | } |
318 | 316 | ||
317 | if ( openfiles[fd].write ) { | ||
318 | DEBUGF("lseek() is not supported when writing\n"); | ||
319 | errno = EROFS; | ||
320 | return -2; | ||
321 | } | ||
322 | |||
323 | |||
319 | switch ( whence ) { | 324 | switch ( whence ) { |
320 | case SEEK_SET: | 325 | case SEEK_SET: |
321 | pos = offset; | 326 | pos = offset; |
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 322ae76a2d..a60a017d3e 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -241,8 +241,7 @@ int fat_mount(int startsector) | |||
241 | err = ata_read_sectors(startsector,1,buf); | 241 | err = ata_read_sectors(startsector,1,buf); |
242 | if(err) | 242 | if(err) |
243 | { | 243 | { |
244 | DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", | 244 | DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", err); |
245 | err); | ||
246 | return -1; | 245 | return -1; |
247 | } | 246 | } |
248 | 247 | ||
@@ -325,7 +324,7 @@ int fat_mount(int startsector) | |||
325 | if (err) | 324 | if (err) |
326 | { | 325 | { |
327 | DEBUGF( "fat_mount() - Couldn't read FSInfo (error code %d)\n", err); | 326 | DEBUGF( "fat_mount() - Couldn't read FSInfo (error code %d)\n", err); |
328 | return -1; | 327 | return -4; |
329 | } | 328 | } |
330 | fat_bpb.fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT); | 329 | fat_bpb.fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT); |
331 | fat_bpb.fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); | 330 | fat_bpb.fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); |
@@ -430,8 +429,6 @@ static int find_free_cluster(int startcluster) | |||
430 | int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; | 429 | int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; |
431 | int i; | 430 | int i; |
432 | 431 | ||
433 | LDEBUGF("find_free_cluster(%x)\n",startcluster); | ||
434 | |||
435 | for (i = sector; i<fat_bpb.fatsize; i++) { | 432 | for (i = sector; i<fat_bpb.fatsize; i++) { |
436 | int j; | 433 | int j; |
437 | unsigned int* fat = cache_fat_sector(i); | 434 | unsigned int* fat = cache_fat_sector(i); |
@@ -440,15 +437,16 @@ static int find_free_cluster(int startcluster) | |||
440 | for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++) | 437 | for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++) |
441 | if (!(SWAB32(fat[j]) & 0x0fffffff)) { | 438 | if (!(SWAB32(fat[j]) & 0x0fffffff)) { |
442 | int c = i * CLUSTERS_PER_FAT_SECTOR + j; | 439 | int c = i * CLUSTERS_PER_FAT_SECTOR + j; |
443 | LDEBUGF("Found free cluster %x\n",c); | 440 | LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c); |
444 | fat_bpb.fsinfo.nextfree = c; | 441 | fat_bpb.fsinfo.nextfree = c; |
445 | return c; | 442 | return c; |
446 | } | 443 | } |
447 | } | 444 | } |
445 | LDEBUGF("find_free_cluster(%x) == 0\n",startcluster); | ||
448 | return 0; /* 0 is an illegal cluster number */ | 446 | return 0; /* 0 is an illegal cluster number */ |
449 | } | 447 | } |
450 | 448 | ||
451 | static int update_fat_entry(int entry, unsigned int val) | 449 | static int update_fat_entry(unsigned int entry, unsigned int val) |
452 | { | 450 | { |
453 | int sector = entry / CLUSTERS_PER_FAT_SECTOR; | 451 | int sector = entry / CLUSTERS_PER_FAT_SECTOR; |
454 | int offset = entry % CLUSTERS_PER_FAT_SECTOR; | 452 | int offset = entry % CLUSTERS_PER_FAT_SECTOR; |
@@ -456,6 +454,12 @@ static int update_fat_entry(int entry, unsigned int val) | |||
456 | 454 | ||
457 | LDEBUGF("update_fat_entry(%x,%x)\n",entry,val); | 455 | LDEBUGF("update_fat_entry(%x,%x)\n",entry,val); |
458 | 456 | ||
457 | if (entry==val) | ||
458 | panicf("Creating FAT loop: %x,%x\n",entry,val); | ||
459 | |||
460 | if ( entry < 2 ) | ||
461 | panicf("Updating reserved FAT entry %d.\n",entry); | ||
462 | |||
459 | sec = cache_fat_sector(sector); | 463 | sec = cache_fat_sector(sector); |
460 | if (!sec) | 464 | if (!sec) |
461 | { | 465 | { |
@@ -465,14 +469,14 @@ static int update_fat_entry(int entry, unsigned int val) | |||
465 | fat_cache[sector & FAT_CACHE_MASK].dirty = true; | 469 | fat_cache[sector & FAT_CACHE_MASK].dirty = true; |
466 | 470 | ||
467 | if ( val ) { | 471 | if ( val ) { |
468 | if (!(sec[offset] & 0x0fffffff)) | 472 | if (!(SWAB32(sec[offset]) & 0x0fffffff)) |
469 | fat_bpb.fsinfo.freecount--; | 473 | fat_bpb.fsinfo.freecount--; |
470 | } | 474 | } |
471 | else | 475 | else |
472 | fat_bpb.fsinfo.freecount++; | 476 | fat_bpb.fsinfo.freecount++; |
473 | 477 | ||
474 | /* don't change top 4 bits */ | 478 | /* don't change top 4 bits */ |
475 | sec[offset] &= SWAB32(0xf000000); | 479 | sec[offset] &= SWAB32(0xf0000000); |
476 | sec[offset] |= SWAB32(val & 0x0fffffff); | 480 | sec[offset] |= SWAB32(val & 0x0fffffff); |
477 | 481 | ||
478 | return 0; | 482 | return 0; |
@@ -491,7 +495,7 @@ static int read_fat_entry(int entry) | |||
491 | return -1; | 495 | return -1; |
492 | } | 496 | } |
493 | 497 | ||
494 | return SWAB32(sec[offset]); | 498 | return SWAB32(sec[offset]) & 0x0fffffff; |
495 | } | 499 | } |
496 | 500 | ||
497 | static int get_next_cluster(unsigned int cluster) | 501 | static int get_next_cluster(unsigned int cluster) |
@@ -499,6 +503,7 @@ static int get_next_cluster(unsigned int cluster) | |||
499 | int next_cluster; | 503 | int next_cluster; |
500 | 504 | ||
501 | next_cluster = read_fat_entry(cluster); | 505 | next_cluster = read_fat_entry(cluster); |
506 | LDEBUGF("get_next_cluster(%x) == %x\n",cluster,next_cluster); | ||
502 | 507 | ||
503 | /* is this last cluster in chain? */ | 508 | /* is this last cluster in chain? */ |
504 | if ( next_cluster >= FAT_EOF_MARK ) | 509 | if ( next_cluster >= FAT_EOF_MARK ) |
@@ -608,34 +613,37 @@ static int add_dir_entry(struct fat_dir* dir, | |||
608 | int i; | 613 | int i; |
609 | int err; | 614 | int err; |
610 | int sec; | 615 | int sec; |
611 | int sec_cnt; | 616 | int sec_cnt = 0; |
612 | bool need_to_update_last_empty_marker = false; | 617 | bool need_to_update_last_empty_marker = false; |
613 | bool done = false; | 618 | bool done = false; |
614 | unsigned char firstbyte; | 619 | unsigned char firstbyte; |
615 | int currdir = dir->startcluster; | 620 | int currdir = dir->startcluster; |
616 | bool is_rootdir = (currdir == 0); | 621 | bool is_rootdir = (currdir == 0); |
617 | 622 | ||
618 | LDEBUGF( "add_dir_entry()\n"); | 623 | LDEBUGF( "add_dir_entry(%x,%s,%x)\n", |
624 | dir->startcluster, de->name, file->firstcluster); | ||
619 | 625 | ||
620 | if (is_rootdir) | 626 | if (is_rootdir) |
621 | sec = fat_bpb.rootdirsector; | 627 | sec = fat_bpb.rootdirsector; |
622 | else | 628 | else |
623 | sec = first_sector_of_cluster(currdir); | 629 | sec = first_sector_of_cluster(currdir); |
624 | 630 | ||
625 | sec_cnt = 0; | ||
626 | |||
627 | while(!done) | 631 | while(!done) |
628 | { | 632 | { |
629 | if (sec_cnt >= fat_bpb.bpb_secperclus) | 633 | if (sec_cnt >= fat_bpb.bpb_secperclus) |
630 | { | 634 | { |
631 | int oldcluster = currdir; | 635 | int oldcluster; |
636 | if (!currdir) | ||
637 | currdir = sec2cluster(fat_bpb.rootdirsector); | ||
638 | oldcluster = currdir; | ||
639 | |||
632 | /* We have reached the end of this cluster */ | 640 | /* We have reached the end of this cluster */ |
633 | LDEBUGF("Moving to the next cluster..."); | 641 | LDEBUGF("Moving to the next cluster...\n"); |
634 | currdir = get_next_cluster(currdir); | 642 | currdir = get_next_cluster(currdir); |
635 | LDEBUGF("new cluster is %d\n", currdir); | ||
636 | |||
637 | if (!currdir) | 643 | if (!currdir) |
638 | { | 644 | { |
645 | /* end of dir, add new cluster */ | ||
646 | LDEBUGF("Adding cluster to dir\n"); | ||
639 | currdir = find_free_cluster(fat_bpb.fsinfo.nextfree); | 647 | currdir = find_free_cluster(fat_bpb.fsinfo.nextfree); |
640 | if (!currdir) { | 648 | if (!currdir) { |
641 | currdir = find_free_cluster(0); | 649 | currdir = find_free_cluster(0); |
@@ -646,9 +654,11 @@ static int add_dir_entry(struct fat_dir* dir, | |||
646 | } | 654 | } |
647 | update_fat_entry(oldcluster, currdir); | 655 | update_fat_entry(oldcluster, currdir); |
648 | } | 656 | } |
657 | LDEBUGF("new cluster is %x\n", currdir); | ||
658 | sec = cluster2sec(currdir); | ||
649 | } | 659 | } |
650 | 660 | ||
651 | LDEBUGF("Reading sector %d...\n", sec); | 661 | LDEBUGF("Reading sector %x...\n", sec); |
652 | /* Read the next sector in the current dir */ | 662 | /* Read the next sector in the current dir */ |
653 | err = ata_read_sectors(sec + fat_bpb.startsector,1,buf); | 663 | err = ata_read_sectors(sec + fat_bpb.startsector,1,buf); |
654 | if (err) | 664 | if (err) |
@@ -673,7 +683,7 @@ static int add_dir_entry(struct fat_dir* dir, | |||
673 | firstbyte = buf[i]; | 683 | firstbyte = buf[i]; |
674 | if (firstbyte == 0xe5 || firstbyte == 0) | 684 | if (firstbyte == 0xe5 || firstbyte == 0) |
675 | { | 685 | { |
676 | LDEBUGF("Found free slot at entry %d in sector %x\n", | 686 | LDEBUGF("Found free entry %d in sector %x\n", |
677 | i/DIR_ENTRY_SIZE, sec); | 687 | i/DIR_ENTRY_SIZE, sec); |
678 | eptr = &buf[i]; | 688 | eptr = &buf[i]; |
679 | memset(eptr, 0, DIR_ENTRY_SIZE); | 689 | memset(eptr, 0, DIR_ENTRY_SIZE); |
@@ -681,22 +691,6 @@ static int add_dir_entry(struct fat_dir* dir, | |||
681 | eptr[FATDIR_ATTR] = de->attr; | 691 | eptr[FATDIR_ATTR] = de->attr; |
682 | eptr[FATDIR_NTRES] = 0; | 692 | eptr[FATDIR_NTRES] = 0; |
683 | 693 | ||
684 | eptr[FATDIR_CRTTIMETENTH] = de->crttimetenth; | ||
685 | eptr[FATDIR_CRTDATE] = de->crtdate & 0xff; | ||
686 | eptr[FATDIR_CRTDATE+1] = de->crtdate >> 8; | ||
687 | eptr[FATDIR_CRTTIME] = de->crttime & 0xff; | ||
688 | eptr[FATDIR_CRTTIME+1] = de->crttime >> 8; | ||
689 | |||
690 | eptr[FATDIR_WRTDATE] = de->wrtdate & 0xff; | ||
691 | eptr[FATDIR_WRTDATE+1] = de->wrtdate >> 8; | ||
692 | eptr[FATDIR_WRTTIME] = de->wrttime & 0xff; | ||
693 | eptr[FATDIR_WRTTIME+1] = de->wrttime >> 8; | ||
694 | |||
695 | eptr[FATDIR_FILESIZE] = de->filesize & 0xff; | ||
696 | eptr[FATDIR_FILESIZE+1] = (de->filesize >> 8) & 0xff; | ||
697 | eptr[FATDIR_FILESIZE+2] = (de->filesize >> 16) & 0xff; | ||
698 | eptr[FATDIR_FILESIZE+3] = (de->filesize >> 24) & 0xff; | ||
699 | |||
700 | /* remember where the dir entry is located */ | 694 | /* remember where the dir entry is located */ |
701 | file->dirsector = sec; | 695 | file->dirsector = sec; |
702 | file->direntry = i/DIR_ENTRY_SIZE; | 696 | file->direntry = i/DIR_ENTRY_SIZE; |
@@ -853,15 +847,21 @@ static void update_dir_entry( struct fat_file* file, int size ) | |||
853 | " (error code %d)\n", sector, err); | 847 | " (error code %d)\n", sector, err); |
854 | return; | 848 | return; |
855 | } | 849 | } |
856 | |||
857 | clusptr = (short*)(entry + FATDIR_FSTCLUSHI); | ||
858 | *clusptr = SWAB16(file->firstcluster >> 16); | ||
859 | 850 | ||
860 | clusptr = (short*)(entry + FATDIR_FSTCLUSLO); | 851 | if ( size == -1 ) { |
861 | *clusptr = SWAB16(file->firstcluster & 0xffff); | 852 | /* mark entry deleted */ |
853 | entry[0] = 0xe5; | ||
854 | } | ||
855 | else { | ||
856 | clusptr = (short*)(entry + FATDIR_FSTCLUSHI); | ||
857 | *clusptr = SWAB16(file->firstcluster >> 16); | ||
858 | |||
859 | clusptr = (short*)(entry + FATDIR_FSTCLUSLO); | ||
860 | *clusptr = SWAB16(file->firstcluster & 0xffff); | ||
862 | 861 | ||
863 | sizeptr = (int*)(entry + FATDIR_FILESIZE); | 862 | sizeptr = (int*)(entry + FATDIR_FILESIZE); |
864 | *sizeptr = SWAB32(size); | 863 | *sizeptr = SWAB32(size); |
864 | } | ||
865 | 865 | ||
866 | err = ata_write_sectors(sector, 1, buf); | 866 | err = ata_write_sectors(sector, 1, buf); |
867 | if (err) | 867 | if (err) |
@@ -902,8 +902,8 @@ int fat_open(unsigned int startcluster, | |||
902 | struct fat_dir* dir) | 902 | struct fat_dir* dir) |
903 | { | 903 | { |
904 | file->firstcluster = startcluster; | 904 | file->firstcluster = startcluster; |
905 | file->nextcluster = startcluster; | 905 | file->lastcluster = startcluster; |
906 | file->nextsector = cluster2sec(startcluster); | 906 | file->lastsector = cluster2sec(startcluster); |
907 | file->sectornum = 0; | 907 | file->sectornum = 0; |
908 | 908 | ||
909 | /* remember where the file's dir entry is located */ | 909 | /* remember where the file's dir entry is located */ |
@@ -935,8 +935,8 @@ int fat_create_file(char* name, | |||
935 | err = add_dir_entry(dir, &de, file); | 935 | err = add_dir_entry(dir, &de, file); |
936 | if (!err) { | 936 | if (!err) { |
937 | file->firstcluster = 0; | 937 | file->firstcluster = 0; |
938 | file->nextcluster = 0; | 938 | file->lastcluster = 0; |
939 | file->nextsector = 0; | 939 | file->lastsector = 0; |
940 | file->sectornum = 0; | 940 | file->sectornum = 0; |
941 | } | 941 | } |
942 | 942 | ||
@@ -945,21 +945,38 @@ int fat_create_file(char* name, | |||
945 | 945 | ||
946 | int fat_closewrite(struct fat_file *file, int size) | 946 | int fat_closewrite(struct fat_file *file, int size) |
947 | { | 947 | { |
948 | int endcluster = file->nextcluster; | 948 | int next, last = file->lastcluster; |
949 | int next, last = endcluster; | 949 | int endcluster = last; |
950 | 950 | ||
951 | /* free unused clusters, if any */ | 951 | LDEBUGF("fat_closewrite()\n"); |
952 | for ( next = get_next_cluster(last); next; last = next ) { | 952 | |
953 | LDEBUGF("Clearing cluster %x\n",last); | 953 | last = get_next_cluster(last); |
954 | while ( last && last != FAT_EOF_MARK ) { | ||
955 | next = get_next_cluster(last); | ||
954 | update_fat_entry(last,0); | 956 | update_fat_entry(last,0); |
957 | last = next; | ||
955 | } | 958 | } |
956 | 959 | ||
957 | /* mark last used cluster as last in chain */ | ||
958 | update_fat_entry(endcluster, FAT_EOF_MARK); | 960 | update_fat_entry(endcluster, FAT_EOF_MARK); |
959 | 961 | update_dir_entry(file, size); | |
960 | flush_fat(); | 962 | flush_fat(); |
961 | 963 | ||
962 | update_dir_entry(file, size); | 964 | return 0; |
965 | } | ||
966 | |||
967 | int fat_remove(struct fat_file* file) | ||
968 | { | ||
969 | int next, last = file->firstcluster; | ||
970 | |||
971 | LDEBUGF("fat_remove(%x)\n",last); | ||
972 | |||
973 | while ( last != FAT_EOF_MARK ) { | ||
974 | LDEBUGF("Freeing cluster %x\n",last); | ||
975 | next = get_next_cluster(last); | ||
976 | update_fat_entry(last,0); | ||
977 | last = next; | ||
978 | } | ||
979 | update_dir_entry(file, -1); | ||
963 | 980 | ||
964 | return 0; | 981 | return 0; |
965 | } | 982 | } |
@@ -967,15 +984,15 @@ int fat_closewrite(struct fat_file *file, int size) | |||
967 | int fat_readwrite( struct fat_file *file, int sectorcount, | 984 | int fat_readwrite( struct fat_file *file, int sectorcount, |
968 | void* buf, bool write ) | 985 | void* buf, bool write ) |
969 | { | 986 | { |
970 | int cluster = file->nextcluster; | 987 | int cluster = file->lastcluster; |
971 | int sector = file->nextsector; | 988 | int sector = file->lastsector; |
972 | int numsec = file->sectornum; | 989 | int numsec = file->sectornum; |
973 | int first, last; | 990 | int first=0, last=0; |
974 | int err, i; | 991 | int err, i; |
975 | 992 | ||
976 | LDEBUGF( "fat_readwrite(file:%x,count:%d,buf:%x,%s)\n", | 993 | LDEBUGF( "fat_readwrite(file:%x,count:%d,buf:%x,%s)\n", |
977 | cluster,sectorcount,buf,write?"write":"read"); | 994 | cluster,sectorcount,buf,write?"write":"read"); |
978 | 995 | LDEBUGF( "fat_readwrite: c=%x s=%x n=%d\n", cluster,sector,numsec); | |
979 | if ( sector == -1 ) | 996 | if ( sector == -1 ) |
980 | return 0; | 997 | return 0; |
981 | 998 | ||
@@ -995,12 +1012,8 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
995 | return -1; | 1012 | return -1; |
996 | } | 1013 | } |
997 | 1014 | ||
998 | first = sector; | ||
999 | last = sector; | ||
1000 | |||
1001 | /* find sequential sectors and read/write them all at once */ | 1015 | /* find sequential sectors and read/write them all at once */ |
1002 | for (i=0; i<sectorcount && sector>=0; i++ ) { | 1016 | for (i=0; i<sectorcount && sector>=0; i++ ) { |
1003 | numsec++; | ||
1004 | if ( numsec >= fat_bpb.bpb_secperclus ) { | 1017 | if ( numsec >= fat_bpb.bpb_secperclus ) { |
1005 | int oldcluster = cluster; | 1018 | int oldcluster = cluster; |
1006 | cluster = get_next_cluster(cluster); | 1019 | cluster = get_next_cluster(cluster); |
@@ -1008,9 +1021,9 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
1008 | if ( write ) { | 1021 | if ( write ) { |
1009 | /* writing past end-of-file, | 1022 | /* writing past end-of-file, |
1010 | find a new free cluster to use. */ | 1023 | find a new free cluster to use. */ |
1011 | cluster = find_free_cluster(cluster); | 1024 | cluster = find_free_cluster(oldcluster+1); |
1012 | if (!cluster) { | 1025 | if (!cluster) { |
1013 | /* no cluster found after last, | 1026 | /* no free cluster found after last, |
1014 | search from beginning */ | 1027 | search from beginning */ |
1015 | cluster = find_free_cluster(0); | 1028 | cluster = find_free_cluster(0); |
1016 | if (!cluster) { | 1029 | if (!cluster) { |
@@ -1030,6 +1043,7 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
1030 | 1043 | ||
1031 | if (cluster) { | 1044 | if (cluster) { |
1032 | sector = cluster2sec(cluster); | 1045 | sector = cluster2sec(cluster); |
1046 | LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector); | ||
1033 | if (sector<0) | 1047 | if (sector<0) |
1034 | return -1; | 1048 | return -1; |
1035 | numsec=0; | 1049 | numsec=0; |
@@ -1037,7 +1051,13 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
1037 | } | 1051 | } |
1038 | else | 1052 | else |
1039 | sector++; | 1053 | sector++; |
1054 | numsec++; | ||
1040 | 1055 | ||
1056 | if (!first) | ||
1057 | first = sector; | ||
1058 | if (!last) | ||
1059 | last = sector; | ||
1060 | |||
1041 | if ( (sector != last+1) || /* not sequential any more? */ | 1061 | if ( (sector != last+1) || /* not sequential any more? */ |
1042 | (i == sectorcount-1) || /* last sector requested? */ | 1062 | (i == sectorcount-1) || /* last sector requested? */ |
1043 | (last-first+1 == 256) ) { /* max 256 sectors per ata request */ | 1063 | (last-first+1 == 256) ) { /* max 256 sectors per ata request */ |
@@ -1056,8 +1076,9 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
1056 | } | 1076 | } |
1057 | last = sector; | 1077 | last = sector; |
1058 | } | 1078 | } |
1059 | file->nextcluster = cluster; | 1079 | |
1060 | file->nextsector = sector; | 1080 | file->lastcluster = cluster; |
1081 | file->lastsector = sector; | ||
1061 | file->sectornum = numsec; | 1082 | file->sectornum = numsec; |
1062 | 1083 | ||
1063 | return sectorcount; | 1084 | return sectorcount; |
@@ -1099,8 +1120,8 @@ int fat_seek(struct fat_file *file, int seeksector ) | |||
1099 | } | 1120 | } |
1100 | } | 1121 | } |
1101 | 1122 | ||
1102 | file->nextcluster = cluster; | 1123 | file->lastcluster = cluster; |
1103 | file->nextsector = sector; | 1124 | file->lastsector = sector; |
1104 | file->sectornum = numsec; | 1125 | file->sectornum = numsec; |
1105 | return 0; | 1126 | return 0; |
1106 | } | 1127 | } |
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h index 3052488c5a..1316202a6c 100644 --- a/firmware/drivers/fat.h +++ b/firmware/drivers/fat.h | |||
@@ -58,8 +58,8 @@ struct fat_dir | |||
58 | struct fat_file | 58 | struct fat_file |
59 | { | 59 | { |
60 | int firstcluster; /* first cluster in file */ | 60 | int firstcluster; /* first cluster in file */ |
61 | int nextcluster; /* cluster of last access */ | 61 | int lastcluster; /* cluster of last access */ |
62 | int nextsector; /* sector of last access */ | 62 | int lastsector; /* sector of last access */ |
63 | int sectornum; /* sector number in this cluster */ | 63 | int sectornum; /* sector number in this cluster */ |
64 | int dirsector; /* sector where the dir entry is located */ | 64 | int dirsector; /* sector where the dir entry is located */ |
65 | int direntry; /* dir entry index in sector */ | 65 | int direntry; /* dir entry index in sector */ |
@@ -79,6 +79,7 @@ extern int fat_readwrite(struct fat_file *ent, int sectorcount, | |||
79 | void* buf, bool write ); | 79 | void* buf, bool write ); |
80 | extern int fat_closewrite(struct fat_file *ent, int size); | 80 | extern int fat_closewrite(struct fat_file *ent, int size); |
81 | extern int fat_seek(struct fat_file *ent, int sector ); | 81 | extern int fat_seek(struct fat_file *ent, int sector ); |
82 | extern int fat_remove(struct fat_file *ent); | ||
82 | 83 | ||
83 | extern int fat_opendir(struct fat_dir *ent, unsigned int currdir); | 84 | extern int fat_opendir(struct fat_dir *ent, unsigned int currdir); |
84 | extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); | 85 | extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); |
diff --git a/firmware/test/fat/ata-sim.c b/firmware/test/fat/ata-sim.c index a37fabcfc0..a64e0a4d4d 100644 --- a/firmware/test/fat/ata-sim.c +++ b/firmware/test/fat/ata-sim.c | |||
@@ -9,7 +9,7 @@ static FILE* file; | |||
9 | 9 | ||
10 | int ata_read_sectors(unsigned long start, unsigned char count, void* buf) | 10 | int ata_read_sectors(unsigned long start, unsigned char count, void* buf) |
11 | { | 11 | { |
12 | DEBUGF("Reading block 0x%lx\n",start); | 12 | DEBUGF("[Reading block 0x%lx]\n",start); |
13 | if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) { | 13 | if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) { |
14 | perror("fseek"); | 14 | perror("fseek"); |
15 | return -1; | 15 | return -1; |
@@ -17,14 +17,14 @@ int ata_read_sectors(unsigned long start, unsigned char count, void* buf) | |||
17 | if(!fread(buf,BLOCK_SIZE,count,file)) { | 17 | if(!fread(buf,BLOCK_SIZE,count,file)) { |
18 | printf("Failed reading %d blocks starting at block 0x%lx\n",count,start); | 18 | printf("Failed reading %d blocks starting at block 0x%lx\n",count,start); |
19 | perror("fread"); | 19 | perror("fread"); |
20 | return -1; | 20 | return -2; |
21 | } | 21 | } |
22 | return 0; | 22 | return 0; |
23 | } | 23 | } |
24 | 24 | ||
25 | int ata_write_sectors(unsigned long start, unsigned char count, void* buf) | 25 | int ata_write_sectors(unsigned long start, unsigned char count, void* buf) |
26 | { | 26 | { |
27 | DEBUGF("Writing block 0x%lx\n",start); | 27 | DEBUGF("[Writing block 0x%lx]\n",start); |
28 | 28 | ||
29 | if (start == 0) { | 29 | if (start == 0) { |
30 | DEBUGF("Holy crap! You're writing on sector 0!\n"); | 30 | DEBUGF("Holy crap! You're writing on sector 0!\n"); |
@@ -37,7 +37,7 @@ int ata_write_sectors(unsigned long start, unsigned char count, void* buf) | |||
37 | } | 37 | } |
38 | if(!fwrite(buf,BLOCK_SIZE,count,file)) { | 38 | if(!fwrite(buf,BLOCK_SIZE,count,file)) { |
39 | perror("fwrite"); | 39 | perror("fwrite"); |
40 | return -1; | 40 | return -2; |
41 | } | 41 | } |
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 1b9fd22183..91e7444999 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c | |||
@@ -19,6 +19,7 @@ void panicf( char *fmt, ...) | |||
19 | { | 19 | { |
20 | va_list ap; | 20 | va_list ap; |
21 | va_start( ap, fmt ); | 21 | va_start( ap, fmt ); |
22 | printf("***PANIC*** "); | ||
22 | vprintf( fmt, ap ); | 23 | vprintf( fmt, ap ); |
23 | va_end( ap ); | 24 | va_end( ap ); |
24 | exit(0); | 25 | exit(0); |
@@ -82,17 +83,20 @@ void dbg_dir(char* currdir) | |||
82 | } | 83 | } |
83 | } | 84 | } |
84 | 85 | ||
85 | void dbg_mkfile(char* name) | 86 | void dbg_mkfile(char* name, int num) |
86 | { | 87 | { |
87 | char* text = "Detta är en dummy-text\n"; | 88 | char text[800]; |
88 | int i; | 89 | int i; |
89 | int fd = open(name,O_WRONLY); | 90 | int fd = open(name,O_WRONLY); |
90 | if (fd<0) { | 91 | if (fd<0) { |
91 | DEBUGF("Failed creating file\n"); | 92 | DEBUGF("Failed creating file\n"); |
92 | return; | 93 | return; |
93 | } | 94 | } |
94 | for (i=0;i<200;i++) | 95 | for (i=0; i<sizeof(text)/4; i++ ) |
95 | if (write(fd, text, strlen(text)) < 0) | 96 | sprintf(text+i*4,"%03x,",i); |
97 | |||
98 | for (i=0;i<num;i++) | ||
99 | if (write(fd, text, sizeof(text)) < 0) | ||
96 | DEBUGF("Failed writing data\n"); | 100 | DEBUGF("Failed writing data\n"); |
97 | 101 | ||
98 | close(fd); | 102 | close(fd); |
@@ -137,27 +141,7 @@ void dbg_tail(char* name) | |||
137 | return; | 141 | return; |
138 | DEBUGF("Got file descriptor %d\n",fd); | 142 | DEBUGF("Got file descriptor %d\n",fd); |
139 | 143 | ||
140 | rc = lseek(fd,512,SEEK_SET); | 144 | rc = lseek(fd,-512,SEEK_END); |
141 | if ( rc >= 0 ) { | ||
142 | rc = read(fd, buf, SECTOR_SIZE); | ||
143 | if( rc > 0 ) | ||
144 | { | ||
145 | buf[rc]=0; | ||
146 | printf("%d: %s\n", strlen(buf), buf); | ||
147 | } | ||
148 | else if ( rc == 0 ) { | ||
149 | DEBUGF("EOF\n"); | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | DEBUGF("Failed reading file: %d\n",rc); | ||
154 | } | ||
155 | } | ||
156 | else { | ||
157 | perror("lseek"); | ||
158 | } | ||
159 | |||
160 | rc = lseek(fd,-100,SEEK_CUR); | ||
161 | if ( rc >= 0 ) { | 145 | if ( rc >= 0 ) { |
162 | rc = read(fd, buf, SECTOR_SIZE); | 146 | rc = read(fd, buf, SECTOR_SIZE); |
163 | if( rc > 0 ) | 147 | if( rc > 0 ) |
@@ -284,6 +268,8 @@ void dbg_console(void) | |||
284 | } | 268 | } |
285 | } | 269 | } |
286 | 270 | ||
271 | extern void ata_exit(void); | ||
272 | |||
287 | int main(int argc, char *argv[]) | 273 | int main(int argc, char *argv[]) |
288 | { | 274 | { |
289 | int rc,i; | 275 | int rc,i; |
@@ -325,12 +311,14 @@ int main(int argc, char *argv[]) | |||
325 | //dbg_console(); | 311 | //dbg_console(); |
326 | //dbg_dir("/"); | 312 | //dbg_dir("/"); |
327 | #if 1 | 313 | #if 1 |
328 | dbg_head("/bepa.txt"); | 314 | dbg_tail("/depa.txt"); |
329 | #else | 315 | #else |
330 | dbg_mkfile("/bepa.txt"); | 316 | dbg_mkfile("/depa.txt", 10); |
331 | #endif | 317 | #endif |
332 | dbg_dir("/"); | 318 | dbg_dir("/"); |
333 | 319 | ||
320 | ata_exit(); | ||
321 | |||
334 | return 0; | 322 | return 0; |
335 | } | 323 | } |
336 | 324 | ||