comparison packages/devs/disk/synth/current/src/synthdisk.c @ 1476:f2453fae08d4

Added support for FAT filesystem. Several packages, see the individual ChangeLogs for details.
author nickg
date Mon, 19 Jan 2004 14:35:01 +0000
parents
children 3cd6f4cd3db2
comparison
equal deleted inserted replaced
1475:c9e09b1c18cb 1476:f2453fae08d4
1 //==========================================================================
2 //
3 // synthdisk.c
4 //
5 // Disk device driver for the synthetic target
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003 Savin Zlobec.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //==========================================================================
39 //#####DESCRIPTIONBEGIN####
40 //
41 // Author(s): savin
42 // Contributors:
43 // Date: 2003-06-18
44 //
45 //####DESCRIPTIONEND####
46 //
47 //==========================================================================
48
49 #include <pkgconf/devs_disk_ecosynth.h>
50
51 #include <cyg/infra/cyg_type.h>
52 #include <cyg/infra/cyg_ass.h>
53 #include <cyg/infra/diag.h>
54 #include <cyg/hal/hal_arch.h>
55 #include <cyg/hal/hal_io.h>
56 #include <cyg/hal/drv_api.h>
57 #include <cyg/io/io.h>
58 #include <cyg/io/devtab.h>
59 #include <cyg/io/disk.h>
60
61 #include <stdio.h> // sprintf
62
63 // ----------------------------------------------------------------------------
64
65 //#define DEBUG 1
66
67 // ----------------------------------------------------------------------------
68
69 typedef struct {
70 int num;
71 cyg_uint32 cylinders_num;
72 cyg_uint32 heads_num;
73 cyg_uint32 sectors_num;
74 cyg_uint32 size;
75 int filefd;
76 char *filename;
77 } synth_disk_info_t;
78
79 // ----------------------------------------------------------------------------
80
81 static cyg_bool synth_disk_init(struct cyg_devtab_entry *tab);
82
83 static Cyg_ErrNo synth_disk_read(disk_channel *chan,
84 void *buf,
85 cyg_uint32 len,
86 cyg_uint32 block_num);
87
88 static Cyg_ErrNo synth_disk_write(disk_channel *chan,
89 const void *buf,
90 cyg_uint32 len,
91 cyg_uint32 block_num);
92
93 static Cyg_ErrNo synth_disk_get_config(disk_channel *chan,
94 cyg_uint32 key,
95 const void *xbuf,
96 cyg_uint32 *len);
97
98 static Cyg_ErrNo synth_disk_set_config(disk_channel *chan,
99 cyg_uint32 key,
100 const void *xbuf,
101 cyg_uint32 *len);
102
103 static Cyg_ErrNo synth_disk_lookup(struct cyg_devtab_entry **tab,
104 struct cyg_devtab_entry *sub_tab,
105 const char *name);
106
107 static DISK_FUNS(synth_disk_funs,
108 synth_disk_read,
109 synth_disk_write,
110 synth_disk_get_config,
111 synth_disk_set_config
112 );
113
114 // ----------------------------------------------------------------------------
115
116 #define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_) \
117 static synth_disk_info_t synth_disk_info##_number_ = { \
118 num: _number_, \
119 cylinders_num: _cyl_, \
120 heads_num: _hpt_, \
121 sectors_num: _spt_, \
122 size: CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE, \
123 filefd: -1, \
124 filename: CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME \
125 }; \
126 static DISK_CHANNEL(synth_disk_channel##_number_, \
127 synth_disk_funs, \
128 synth_disk_info##_number_, \
129 _mbr_supp_ \
130 ); \
131 BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_, \
132 CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME, \
133 0, \
134 &cyg_io_disk_devio, \
135 synth_disk_init, \
136 synth_disk_lookup, \
137 &synth_disk_channel##_number_ \
138 );
139
140 // ----------------------------------------------------------------------------
141
142 #ifdef CYGVAR_DEVS_DISK_ECOSYNTH_DISK0
143 # ifndef CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
144 SYNTH_DISK_INSTANCE(0, false, 0, 0, 0);
145 # else
146 SYNTH_DISK_INSTANCE(0, true, CYGIMP_IO_DISK_ECOSYNTH_DISK0_CYLINDERS,
147 CYGIMP_IO_DISK_ECOSYNTH_DISK0_HEADS,
148 CYGIMP_IO_DISK_ECOSYNTH_DISK0_SECTORS);
149 # endif
150 #endif
151
152 // ----------------------------------------------------------------------------
153
154 static cyg_bool
155 synth_disk_init(struct cyg_devtab_entry *tab)
156 {
157 disk_channel *chan = (disk_channel *) tab->priv;
158 synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
159 bool result = true;
160
161 if (chan->init)
162 return true;
163
164 #ifdef DEBUG
165 diag_printf("synth disk %d init size=%d\n",
166 synth_info->num, synth_info->size);
167 #endif
168
169 synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
170 CYG_HAL_SYS_O_RDWR,
171 CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
172
173 if (-ENOENT == synth_info->filefd)
174 {
175 synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
176 CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
177
178 if (synth_info->filefd >= 0)
179 {
180 unsigned char b = 0x00;
181 int i;
182
183 for (i = 0; i < synth_info->size; i++)
184 cyg_hal_sys_write(synth_info->filefd, &b, 1);
185 }
186 }
187
188 if (synth_info->filefd < 0)
189 {
190 CYG_ASSERT(false, "Can't open/create disk image file");
191 return false;
192 }
193
194 if (result)
195 {
196 cyg_disk_identify_t ident;
197
198 ident.serial[0] = '\0';
199 ident.firmware_rev[0] = '\0';
200 ident.model_num[0] = '\0';
201 ident.lba_sectors_num = synth_info->size / 512;
202 ident.cylinders_num = synth_info->cylinders_num;
203 ident.heads_num = synth_info->heads_num;
204 ident.sectors_num = synth_info->sectors_num;
205
206 if (!(chan->callbacks->disk_init)(tab))
207 return false;
208 if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident))
209 return false;
210 }
211 return result;
212 }
213
214 static Cyg_ErrNo
215 synth_disk_lookup(struct cyg_devtab_entry **tab,
216 struct cyg_devtab_entry *sub_tab,
217 const char *name)
218 {
219 disk_channel *chan = (disk_channel *) (*tab)->priv;
220 return (chan->callbacks->disk_lookup(tab, sub_tab, name));
221 }
222
223 static Cyg_ErrNo
224 synth_disk_read(disk_channel *chan,
225 void *buf,
226 cyg_uint32 len,
227 cyg_uint32 block_num)
228 {
229 synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
230
231 #ifdef DEBUG
232 diag_printf("synth disk read block %d\n", block_num);
233 #endif
234
235 if (synth_info->filefd >= 0)
236 {
237 cyg_hal_sys_lseek(synth_info->filefd,
238 block_num * chan->info->block_size,
239 CYG_HAL_SYS_SEEK_SET);
240 cyg_hal_sys_read(synth_info->filefd, buf, len);
241 return ENOERR;
242 }
243 return -EIO;
244 }
245
246 static Cyg_ErrNo
247 synth_disk_write(disk_channel *chan,
248 const void *buf,
249 cyg_uint32 len,
250 cyg_uint32 block_num)
251 {
252 synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
253
254 #ifdef DEBUG
255 diag_printf("synth disk write block %d\n", block_num);
256 #endif
257
258 if (synth_info->filefd >= 0)
259 {
260 cyg_hal_sys_lseek(synth_info->filefd,
261 block_num * chan->info->block_size,
262 CYG_HAL_SYS_SEEK_SET);
263 cyg_hal_sys_write(synth_info->filefd, buf, len);
264 // cyg_hal_sys_fdatasync(synth_info->filefd);
265 return ENOERR;
266 }
267 return -EIO;
268 }
269
270 static Cyg_ErrNo
271 synth_disk_get_config(disk_channel *chan,
272 cyg_uint32 key,
273 const void *xbuf,
274 cyg_uint32 *len)
275 {
276
277 #ifdef DEBUG
278 diag_printf("synth disk get config\n");
279 #endif
280
281 return -EINVAL;
282 }
283
284 static Cyg_ErrNo
285 synth_disk_set_config(disk_channel *chan,
286 cyg_uint32 key,
287 const void *xbuf,
288 cyg_uint32 *len)
289 {
290
291 #ifdef DEBUG
292 diag_printf("synth disk set config\n");
293 #endif
294
295 return -EINVAL;
296 }
297
298 // ----------------------------------------------------------------------------
299 // EOF synthdisk.c