diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-05-07 16:01:53 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-05-07 16:01:53 +0000 |
commit | 4bd870360af595a3f90b9ccc5a09d1414fd654e9 (patch) | |
tree | fccdc0da07d36d858560129f9a3b4c66d4669943 /firmware | |
parent | 44b1a21f17975c896fd41dfff2e128a81ca77fc3 (diff) | |
download | rockbox-4bd870360af595a3f90b9ccc5a09d1414fd654e9.tar.gz rockbox-4bd870360af595a3f90b9ccc5a09d1414fd654e9.zip |
Added open/close/read. read() only works on whole sectors right now.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@498 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/common/dir.c | 1 | ||||
-rw-r--r-- | firmware/common/dir.h | 1 | ||||
-rw-r--r-- | firmware/common/file.c | 170 | ||||
-rw-r--r-- | firmware/common/file.h | 7 | ||||
-rw-r--r-- | firmware/test/fat/Makefile | 5 | ||||
-rw-r--r-- | firmware/test/fat/main.c | 97 |
6 files changed, 230 insertions, 51 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c index b0927c09c6..acc412c570 100644 --- a/firmware/common/dir.c +++ b/firmware/common/dir.c | |||
@@ -94,6 +94,7 @@ struct dirent* readdir(DIR* dir) | |||
94 | strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) ); | 94 | strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) ); |
95 | theent.attribute = entry.attr; | 95 | theent.attribute = entry.attr; |
96 | theent.size = entry.filesize; | 96 | theent.size = entry.filesize; |
97 | theent.startcluster = entry.firstcluster; | ||
97 | 98 | ||
98 | return &theent; | 99 | return &theent; |
99 | } | 100 | } |
diff --git a/firmware/common/dir.h b/firmware/common/dir.h index e03d50901c..274c0b1ea4 100644 --- a/firmware/common/dir.h +++ b/firmware/common/dir.h | |||
@@ -32,6 +32,7 @@ struct dirent { | |||
32 | unsigned char d_name[256]; | 32 | unsigned char d_name[256]; |
33 | int attribute; | 33 | int attribute; |
34 | int size; | 34 | int size; |
35 | int startcluster; | ||
35 | }; | 36 | }; |
36 | #endif | 37 | #endif |
37 | 38 | ||
diff --git a/firmware/common/file.c b/firmware/common/file.c new file mode 100644 index 0000000000..86e1099918 --- /dev/null +++ b/firmware/common/file.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Björn Stenberg | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <string.h> | ||
20 | #include "file.h" | ||
21 | #include "fat.h" | ||
22 | #include "types.h" | ||
23 | #include "dir.h" | ||
24 | #include "debug.h" | ||
25 | |||
26 | #define MAX_OPEN_FILES 4 | ||
27 | |||
28 | struct filedesc { | ||
29 | unsigned char sector[SECTOR_SIZE]; | ||
30 | int offset; | ||
31 | struct fat_file fatfile; | ||
32 | bool busy; | ||
33 | }; | ||
34 | |||
35 | static struct filedesc openfiles[MAX_OPEN_FILES]; | ||
36 | |||
37 | int open(char* pathname, int flags) | ||
38 | { | ||
39 | DIR* dir; | ||
40 | struct dirent* entry; | ||
41 | int fd; | ||
42 | char* name; | ||
43 | int namelen; | ||
44 | |||
45 | if ( pathname[0] != '/' ) { | ||
46 | DEBUGF("'%s' is not an absolute path.\n",pathname); | ||
47 | DEBUGF("Only absolute pathnames supported at the moment\n"); | ||
48 | return -1; | ||
49 | } | ||
50 | |||
51 | /* find a free file descriptor */ | ||
52 | for ( fd=0; fd<MAX_OPEN_FILES; fd++ ) | ||
53 | if ( !openfiles[fd].busy ) | ||
54 | break; | ||
55 | |||
56 | if ( fd == MAX_OPEN_FILES ) { | ||
57 | DEBUGF("Too many files open\n"); | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | /* locate filename */ | ||
62 | name=strrchr(pathname+1,'/'); | ||
63 | if ( name ) { | ||
64 | *name = 0; | ||
65 | dir = opendir(pathname); | ||
66 | *name = '/'; | ||
67 | name++; | ||
68 | } | ||
69 | else { | ||
70 | dir = opendir("/"); | ||
71 | name = pathname+1; | ||
72 | } | ||
73 | if (!dir) { | ||
74 | DEBUGF("Failed opening dir\n"); | ||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | /* scan dir for name */ | ||
79 | namelen = strlen(name); | ||
80 | while ((entry = readdir(dir))) { | ||
81 | if ( !strncmp(name, entry->d_name, namelen) ) { | ||
82 | fat_open(entry->startcluster, &(openfiles[fd].fatfile)); | ||
83 | break; | ||
84 | } | ||
85 | else { | ||
86 | DEBUGF("entry: %s\n",entry->d_name); | ||
87 | } | ||
88 | } | ||
89 | closedir(dir); | ||
90 | if ( !entry ) { | ||
91 | DEBUGF("Couldn't find %s in %s\n",name,pathname); | ||
92 | /* fixme: we need to use proper error codes */ | ||
93 | return -1; | ||
94 | } | ||
95 | |||
96 | openfiles[fd].offset = 0; | ||
97 | openfiles[fd].busy = TRUE; | ||
98 | return fd; | ||
99 | } | ||
100 | |||
101 | int close(int fd) | ||
102 | { | ||
103 | openfiles[fd].busy = FALSE; | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | int read(int fd, void* buf, int count) | ||
108 | { | ||
109 | int sectors; | ||
110 | int nread=0; | ||
111 | |||
112 | /* are we in the middle of a cached sector? */ | ||
113 | if ( openfiles[fd].offset ) { | ||
114 | if ( count > (SECTOR_SIZE - openfiles[fd].offset) ) { | ||
115 | memcpy( buf, openfiles[fd].sector, | ||
116 | SECTOR_SIZE - openfiles[fd].offset ); | ||
117 | openfiles[fd].offset = 0; | ||
118 | nread = SECTOR_SIZE - openfiles[fd].offset; | ||
119 | count -= nread; | ||
120 | } | ||
121 | else { | ||
122 | memcpy( buf, openfiles[fd].sector, count ); | ||
123 | openfiles[fd].offset += count; | ||
124 | nread = count; | ||
125 | count = 0; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | /* read whole sectors right into the supplied buffer */ | ||
130 | sectors = count / SECTOR_SIZE; | ||
131 | if ( sectors ) { | ||
132 | if ( fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ) < 0 ) { | ||
133 | DEBUGF("Failed reading %d sectors\n",sectors); | ||
134 | return -1; | ||
135 | } | ||
136 | nread += sectors * SECTOR_SIZE; | ||
137 | count -= sectors * SECTOR_SIZE; | ||
138 | openfiles[fd].offset = 0; | ||
139 | } | ||
140 | |||
141 | /* trailing odd bytes? */ | ||
142 | if ( count ) { | ||
143 | /* do we already have the sector cached? */ | ||
144 | if ( count < (SECTOR_SIZE - openfiles[fd].offset) ) { | ||
145 | memcpy( buf + nread, openfiles[fd].sector, count ); | ||
146 | openfiles[fd].offset += count; | ||
147 | nread += count; | ||
148 | count = 0; | ||
149 | } | ||
150 | else { | ||
151 | /* cache one sector and copy the trailing bytes */ | ||
152 | if ( fat_read(&(openfiles[fd].fatfile), 1, | ||
153 | &(openfiles[fd].sector)) < 0 ) { | ||
154 | DEBUGF("Failed reading odd sector\n"); | ||
155 | return -1; | ||
156 | } | ||
157 | memcpy( buf + nread, openfiles[fd].sector, count ); | ||
158 | openfiles[fd].offset = nread; | ||
159 | nread += count; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return nread; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * local variables: | ||
168 | * eval: (load-file "../rockbox-mode.el") | ||
169 | * end: | ||
170 | */ | ||
diff --git a/firmware/common/file.h b/firmware/common/file.h index 58fb22d881..9d0d6f0501 100644 --- a/firmware/common/file.h +++ b/firmware/common/file.h | |||
@@ -33,14 +33,15 @@ | |||
33 | #ifndef SIMULATOR | 33 | #ifndef SIMULATOR |
34 | extern int open(char* pathname, int flags); | 34 | extern int open(char* pathname, int flags); |
35 | extern int close(int fd); | 35 | extern int close(int fd); |
36 | |||
37 | extern int read(int fd, void* buf, int count); | 36 | extern int read(int fd, void* buf, int count); |
38 | extern int write(int fd, void* buf, int count); | ||
39 | |||
40 | extern int lseek(int fd, int offset, int whence); | 37 | extern int lseek(int fd, int offset, int whence); |
41 | 38 | ||
39 | #ifdef DISK_WRITE | ||
40 | extern int write(int fd, void* buf, int count); | ||
42 | extern int remove(char* pathname); | 41 | extern int remove(char* pathname); |
43 | extern int rename(char* oldname, char* newname); | 42 | extern int rename(char* oldname, char* newname); |
43 | #endif | ||
44 | |||
44 | #else | 45 | #else |
45 | #ifdef WIN32 | 46 | #ifdef WIN32 |
46 | #include <io.h> | 47 | #include <io.h> |
diff --git a/firmware/test/fat/Makefile b/firmware/test/fat/Makefile index 48bddb9630..bd6869e8e9 100644 --- a/firmware/test/fat/Makefile +++ b/firmware/test/fat/Makefile | |||
@@ -5,7 +5,7 @@ CFLAGS = -g -Wall -DTEST_FAT -I$(DRIVERS) -I$(FIRMWARE)/common -I$(FIRMWARE) -I. | |||
5 | 5 | ||
6 | TARGET = fat | 6 | TARGET = fat |
7 | 7 | ||
8 | $(TARGET): fat.o ata-sim.o main.o disk.o debug.o dir.o | 8 | $(TARGET): fat.o ata-sim.o main.o disk.o debug.o dir.o file.o |
9 | gcc -g -o fat $+ -lfl | 9 | gcc -g -o fat $+ -lfl |
10 | 10 | ||
11 | fat.o: $(DRIVERS)/fat.c $(DRIVERS)/fat.h $(DRIVERS)/ata.h | 11 | fat.o: $(DRIVERS)/fat.c $(DRIVERS)/fat.h $(DRIVERS)/ata.h |
@@ -17,6 +17,9 @@ disk.o: $(FIRMWARE)/common/disk.c | |||
17 | dir.o: $(FIRMWARE)/common/dir.c | 17 | dir.o: $(FIRMWARE)/common/dir.c |
18 | $(CC) $(CFLAGS) -c $< -o $@ | 18 | $(CC) $(CFLAGS) -c $< -o $@ |
19 | 19 | ||
20 | file.o: $(FIRMWARE)/common/file.c | ||
21 | $(CC) $(CFLAGS) -c $< -o $@ | ||
22 | |||
20 | debug.o: $(FIRMWARE)/debug.c | 23 | debug.o: $(FIRMWARE)/debug.c |
21 | $(CC) $(CFLAGS) -c $< -o $@ | 24 | $(CC) $(CFLAGS) -c $< -o $@ |
22 | 25 | ||
diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 13c30b2ed5..0cf06bdac3 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include "debug.h" | 6 | #include "debug.h" |
7 | #include "disk.h" | 7 | #include "disk.h" |
8 | #include "dir.h" | 8 | #include "dir.h" |
9 | #include "file.h" | ||
9 | 10 | ||
10 | void dbg_dump_sector(int sec); | 11 | void dbg_dump_sector(int sec); |
11 | void dbg_dump_buffer(unsigned char *buf); | 12 | void dbg_dump_buffer(unsigned char *buf); |
@@ -17,7 +18,7 @@ void dbg_dump_sector(int sec) | |||
17 | unsigned char buf[512]; | 18 | unsigned char buf[512]; |
18 | 19 | ||
19 | ata_read_sectors(sec,1,buf); | 20 | ata_read_sectors(sec,1,buf); |
20 | printf("---< Sector %d >-----------------------------------------\n", sec); | 21 | DEBUGF("---< Sector %d >-----------------------------------------\n", sec); |
21 | dbg_dump_buffer(buf); | 22 | dbg_dump_buffer(buf); |
22 | } | 23 | } |
23 | 24 | ||
@@ -33,7 +34,7 @@ void dbg_dump_buffer(unsigned char *buf) | |||
33 | { | 34 | { |
34 | c = buf[i*16+j]; | 35 | c = buf[i*16+j]; |
35 | 36 | ||
36 | printf("%02x ", c); | 37 | DEBUGF("%02x ", c); |
37 | if(c < 32 || c > 127) | 38 | if(c < 32 || c > 127) |
38 | { | 39 | { |
39 | ascii[j] = '.'; | 40 | ascii[j] = '.'; |
@@ -45,39 +46,39 @@ void dbg_dump_buffer(unsigned char *buf) | |||
45 | } | 46 | } |
46 | 47 | ||
47 | ascii[j] = 0; | 48 | ascii[j] = 0; |
48 | printf("%s\n", ascii); | 49 | DEBUGF("%s\n", ascii); |
49 | } | 50 | } |
50 | } | 51 | } |
51 | 52 | ||
52 | void dbg_print_bpb(struct bpb *bpb) | 53 | void dbg_print_bpb(struct bpb *bpb) |
53 | { | 54 | { |
54 | printf("bpb_oemname = \"%s\"\n", bpb->bs_oemname); | 55 | DEBUGF("bpb_oemname = \"%s\"\n", bpb->bs_oemname); |
55 | printf("bpb_bytspersec = %d\n", bpb->bpb_bytspersec); | 56 | DEBUGF("bpb_bytspersec = %d\n", bpb->bpb_bytspersec); |
56 | printf("bpb_secperclus = %d\n", bpb->bpb_secperclus); | 57 | DEBUGF("bpb_secperclus = %d\n", bpb->bpb_secperclus); |
57 | printf("bpb_rsvdseccnt = %d\n", bpb->bpb_rsvdseccnt); | 58 | DEBUGF("bpb_rsvdseccnt = %d\n", bpb->bpb_rsvdseccnt); |
58 | printf("bpb_numfats = %d\n", bpb->bpb_numfats); | 59 | DEBUGF("bpb_numfats = %d\n", bpb->bpb_numfats); |
59 | printf("bpb_rootentcnt = %d\n", bpb->bpb_rootentcnt); | 60 | DEBUGF("bpb_rootentcnt = %d\n", bpb->bpb_rootentcnt); |
60 | printf("bpb_totsec16 = %d\n", bpb->bpb_totsec16); | 61 | DEBUGF("bpb_totsec16 = %d\n", bpb->bpb_totsec16); |
61 | printf("bpb_media = %02x\n", bpb->bpb_media); | 62 | DEBUGF("bpb_media = %02x\n", bpb->bpb_media); |
62 | printf("bpb_fatsz16 = %d\n", bpb->bpb_fatsz16); | 63 | DEBUGF("bpb_fatsz16 = %d\n", bpb->bpb_fatsz16); |
63 | printf("bpb_secpertrk = %d\n", bpb->bpb_secpertrk); | 64 | DEBUGF("bpb_secpertrk = %d\n", bpb->bpb_secpertrk); |
64 | printf("bpb_numheads = %d\n", bpb->bpb_numheads); | 65 | DEBUGF("bpb_numheads = %d\n", bpb->bpb_numheads); |
65 | printf("bpb_hiddsec = %u\n", bpb->bpb_hiddsec); | 66 | DEBUGF("bpb_hiddsec = %u\n", bpb->bpb_hiddsec); |
66 | printf("bpb_totsec32 = %u\n", bpb->bpb_totsec32); | 67 | DEBUGF("bpb_totsec32 = %u\n", bpb->bpb_totsec32); |
67 | 68 | ||
68 | printf("bs_drvnum = %d\n", bpb->bs_drvnum); | 69 | DEBUGF("bs_drvnum = %d\n", bpb->bs_drvnum); |
69 | printf("bs_bootsig = %02x\n", bpb->bs_bootsig); | 70 | DEBUGF("bs_bootsig = %02x\n", bpb->bs_bootsig); |
70 | if(bpb->bs_bootsig == 0x29) | 71 | if(bpb->bs_bootsig == 0x29) |
71 | { | 72 | { |
72 | printf("bs_volid = %xl\n", bpb->bs_volid); | 73 | DEBUGF("bs_volid = %xl\n", bpb->bs_volid); |
73 | printf("bs_vollab = \"%s\"\n", bpb->bs_vollab); | 74 | DEBUGF("bs_vollab = \"%s\"\n", bpb->bs_vollab); |
74 | printf("bs_filsystype = \"%s\"\n", bpb->bs_filsystype); | 75 | DEBUGF("bs_filsystype = \"%s\"\n", bpb->bs_filsystype); |
75 | } | 76 | } |
76 | 77 | ||
77 | printf("bpb_fatsz32 = %u\n", bpb->bpb_fatsz32); | 78 | DEBUGF("bpb_fatsz32 = %u\n", bpb->bpb_fatsz32); |
78 | printf("last_word = %04x\n", bpb->last_word); | 79 | DEBUGF("last_word = %04x\n", bpb->last_word); |
79 | 80 | ||
80 | printf("fat_type = FAT32\n"); | 81 | DEBUGF("fat_type = FAT32\n"); |
81 | } | 82 | } |
82 | 83 | ||
83 | void dbg_dir(char* currdir) | 84 | void dbg_dir(char* currdir) |
@@ -88,38 +89,40 @@ void dbg_dir(char* currdir) | |||
88 | dir = opendir(currdir); | 89 | dir = opendir(currdir); |
89 | if (dir) | 90 | if (dir) |
90 | { | 91 | { |
91 | for ( entry = readdir(dir); | 92 | while ( (entry = readdir(dir)) ) { |
92 | entry; | 93 | DEBUGF("%15s (%d bytes)\n", entry->d_name, entry->size); |
93 | entry = readdir(dir) ) | ||
94 | { | ||
95 | printf("%s (%08x)\n", entry->d_name, entry->size); | ||
96 | } | 94 | } |
97 | } | 95 | } |
98 | else | 96 | else |
99 | { | 97 | { |
100 | fprintf(stderr, "Could not open dir %s\n", currdir); | 98 | DEBUGF( "Could not open dir %s\n", currdir); |
101 | } | 99 | } |
102 | closedir(dir); | 100 | closedir(dir); |
103 | } | 101 | } |
104 | 102 | ||
105 | void dbg_type(int cluster) | 103 | void dbg_type(char* name) |
106 | { | 104 | { |
107 | unsigned char buf[SECTOR_SIZE*5]; | 105 | unsigned char buf[SECTOR_SIZE*5]; |
108 | struct fat_file ent; | 106 | int i,fd,rc; |
109 | int i; | ||
110 | 107 | ||
111 | fat_open(cluster,&ent); | 108 | fd = open(name,O_RDONLY); |
109 | if (fd<0) | ||
110 | return; | ||
111 | DEBUGF("Got file descriptor %d\n",fd); | ||
112 | 112 | ||
113 | for (i=0;i<5;i++) | 113 | for (i=0;i<5;i++) { |
114 | if(fat_read(&ent, 1, buf) >= 0) | 114 | rc = read(fd, buf, SECTOR_SIZE/3); |
115 | if( rc >= 0 ) | ||
115 | { | 116 | { |
116 | buf[SECTOR_SIZE]=0; | 117 | buf[SECTOR_SIZE]=0; |
117 | printf("%s\n", buf); | 118 | DEBUGF("%d: %d\n", i, rc); |
118 | } | 119 | } |
119 | else | 120 | else |
120 | { | 121 | { |
121 | fprintf(stderr, "Could not read file on cluster %d\n", cluster); | 122 | DEBUGF("Failed reading file\n"); |
122 | } | 123 | } |
124 | } | ||
125 | close(fd); | ||
123 | } | 126 | } |
124 | 127 | ||
125 | char current_directory[256] = "\\"; | 128 | char current_directory[256] = "\\"; |
@@ -127,7 +130,7 @@ int last_secnum = 0; | |||
127 | 130 | ||
128 | void dbg_prompt(void) | 131 | void dbg_prompt(void) |
129 | { | 132 | { |
130 | printf("C:%s> ", current_directory); | 133 | DEBUGF("C:%s> ", current_directory); |
131 | } | 134 | } |
132 | 135 | ||
133 | void dbg_console(void) | 136 | void dbg_console(void) |
@@ -173,19 +176,17 @@ void dbg_console(void) | |||
173 | { | 176 | { |
174 | last_secnum++; | 177 | last_secnum++; |
175 | } | 178 | } |
176 | printf("secnum: %d\n", last_secnum); | 179 | DEBUGF("secnum: %d\n", last_secnum); |
177 | dbg_dump_sector(last_secnum); | 180 | dbg_dump_sector(last_secnum); |
178 | continue; | 181 | continue; |
179 | } | 182 | } |
180 | 183 | ||
181 | if(!strcasecmp(s, "type")) | 184 | if(!strcasecmp(s, "type")) |
182 | { | 185 | { |
183 | int cluster = 0; | 186 | s = strtok(NULL, " \n"); |
184 | if((s = strtok(NULL, " \n"))) | 187 | if (!s) |
185 | { | 188 | continue; |
186 | cluster = atoi(s); | 189 | dbg_type(s); |
187 | } | ||
188 | dbg_type(cluster); | ||
189 | continue; | 190 | continue; |
190 | } | 191 | } |
191 | 192 | ||
@@ -196,6 +197,8 @@ void dbg_console(void) | |||
196 | } | 197 | } |
197 | } | 198 | } |
198 | } | 199 | } |
200 | else | ||
201 | quit = 1; | ||
199 | } | 202 | } |
200 | } | 203 | } |
201 | 204 | ||