1 //==========================================================================
5 // Disk device driver for the synthetic target
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003 Savin Zlobec
12 // Copyright (C) 2004, 2006 eCosCentric Limited
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // -------------------------------------------
38 //####ECOSGPLCOPYRIGHTEND####
39 //==========================================================================
40 //#####DESCRIPTIONBEGIN####
46 //####DESCRIPTIONEND####
48 //==========================================================================
50 #include <pkgconf/devs_disk_ecosynth.h>
52 #include <cyg/infra/cyg_type.h>
53 #include <cyg/infra/cyg_ass.h>
54 #include <cyg/infra/diag.h>
55 #include <cyg/hal/hal_arch.h>
56 #include <cyg/hal/hal_io.h>
57 #include <cyg/hal/drv_api.h>
58 #include <cyg/io/io.h>
59 #include <cyg/io/devtab.h>
60 #include <cyg/io/disk.h>
62 #include <stdio.h> // sprintf
64 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
72 cyg_uint32 cylinders_num;
74 cyg_uint32 sectors_num;
80 typedef struct { int dummy; } synth_controller_t;
82 // ----------------------------------------------------------------------------
84 static cyg_bool synth_disk_init(struct cyg_devtab_entry *tab);
86 static Cyg_ErrNo synth_disk_read(disk_channel *chan,
89 cyg_uint32 block_num);
91 static Cyg_ErrNo synth_disk_write(disk_channel *chan,
94 cyg_uint32 block_num);
96 static Cyg_ErrNo synth_disk_get_config(disk_channel *chan,
101 static Cyg_ErrNo synth_disk_set_config(disk_channel *chan,
106 static Cyg_ErrNo synth_disk_lookup(struct cyg_devtab_entry **tab,
107 struct cyg_devtab_entry *sub_tab,
110 DISK_FUNS(synth_disk_funs,
113 synth_disk_get_config,
114 synth_disk_set_config
117 // ----------------------------------------------------------------------------
120 #define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_) \
121 static synth_disk_info_t synth_disk_info##_number_ = { \
123 cylinders_num: _cyl_, \
125 sectors_num: _spt_, \
126 size: CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE, \
128 filename: CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME \
130 static synth_controller_t synth_controller_##_number_; \
131 DISK_CONTROLLER( synth_disk_controller_##_number_, synth_controller_##_number_ ); \
132 DISK_CHANNEL(synth_disk_channel##_number_, \
134 synth_disk_info##_number_, \
135 synth_disk_controller_##_number_, \
139 BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_, \
140 CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME, \
142 &cyg_io_disk_devio, \
145 &synth_disk_channel##_number_ \
148 // ----------------------------------------------------------------------------
150 #ifdef CYGVAR_DEVS_DISK_ECOSYNTH_DISK0
151 # ifndef CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
152 SYNTH_DISK_INSTANCE(0, false, 0, 0, 0);
154 SYNTH_DISK_INSTANCE(0, true, CYGIMP_IO_DISK_ECOSYNTH_DISK0_CYLINDERS,
155 CYGIMP_IO_DISK_ECOSYNTH_DISK0_HEADS,
156 CYGIMP_IO_DISK_ECOSYNTH_DISK0_SECTORS);
160 // ----------------------------------------------------------------------------
163 synth_disk_init(struct cyg_devtab_entry *tab)
165 disk_channel *chan = (disk_channel *) tab->priv;
166 synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
173 diag_printf("synth disk %d init size=%d\n",
174 synth_info->num, synth_info->size);
177 synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
179 CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
181 if (-ENOENT == synth_info->filefd)
183 synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
184 CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
186 if (synth_info->filefd >= 0)
188 unsigned char b = 0x00;
191 for (i = 0; i < synth_info->size; i++)
192 cyg_hal_sys_write(synth_info->filefd, &b, 1);
196 if (synth_info->filefd < 0)
198 CYG_ASSERT(false, "Can't open/create disk image file");
205 if (!(chan->callbacks->disk_init)(tab))
211 // ----------------------------------------------------------------------------
214 synth_disk_lookup(struct cyg_devtab_entry **tab,
215 struct cyg_devtab_entry *sub_tab,
219 disk_channel *chan = (disk_channel *) (*tab)->priv;
220 synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
221 cyg_disk_identify_t ident;
223 ident.serial[0] = '\0';
224 ident.firmware_rev[0] = '\0';
225 ident.model_num[0] = '\0';
226 ident.lba_sectors_num = synth_info->size / 512;
227 ident.cylinders_num = synth_info->cylinders_num;
228 ident.heads_num = synth_info->heads_num;
229 ident.sectors_num = synth_info->sectors_num;
230 ident.phys_block_size = 1;
231 ident.max_transfer = 2048;
233 res = (chan->callbacks->disk_connected)(*tab, &ident);
236 res = (chan->callbacks->disk_lookup(tab, sub_tab, name));
241 // ----------------------------------------------------------------------------
244 synth_disk_read(disk_channel *chan,
247 cyg_uint32 block_num)
249 synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
252 diag_printf("synth disk read block %d\n", block_num);
255 if (synth_info->filefd >= 0)
257 cyg_hal_sys_lseek(synth_info->filefd,
258 block_num * chan->info->block_size,
259 CYG_HAL_SYS_SEEK_SET);
260 cyg_hal_sys_read(synth_info->filefd, buf, len*512);
266 // ----------------------------------------------------------------------------
269 synth_disk_write(disk_channel *chan,
272 cyg_uint32 block_num)
274 synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
277 diag_printf("synth disk write block %d\n", block_num);
280 if (synth_info->filefd >= 0)
282 cyg_hal_sys_lseek(synth_info->filefd,
283 block_num * chan->info->block_size,
284 CYG_HAL_SYS_SEEK_SET);
285 cyg_hal_sys_write(synth_info->filefd, buf, len*512);
286 // cyg_hal_sys_fdatasync(synth_info->filefd);
292 // ----------------------------------------------------------------------------
295 synth_disk_get_config(disk_channel *chan,
302 diag_printf("synth disk get config\n");
308 // ----------------------------------------------------------------------------
311 synth_disk_set_config(disk_channel *chan,
316 Cyg_ErrNo res = ENOERR;
318 diag_printf("synth disk set config\n");
323 case CYG_IO_SET_CONFIG_DISK_MOUNT:
324 // We have nothing to do here for this option.
327 case CYG_IO_SET_CONFIG_DISK_UMOUNT:
328 if( chan->info->mounts == 0 )
330 // If this is the last unmount of this disk, then disconnect it from
331 // the driver system so the user can swap it out if he wants.
332 res = (chan->callbacks->disk_disconnected)(chan);
344 // ----------------------------------------------------------------------------
346 externC cyg_bool synth_disk_change( int unit, char *filename, int size,
347 int cyls, int heads, int sectors)
349 struct cyg_devtab_entry *tab = &synth_disk_io0;
350 disk_channel *chan = (disk_channel *) tab->priv;
351 synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
357 synth_info->filename = filename;
358 synth_info->size = size;
359 synth_info->cylinders_num = cyls;
360 synth_info->heads_num = heads;
361 synth_info->sectors_num = sectors;
364 diag_printf("synth disk %d change size=%d\n",
365 synth_info->num, synth_info->size);
368 err = cyg_hal_sys_close( synth_info->filefd );
373 diag_printf("synth disk change, failed to close old image: %d\n",err);
377 synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
379 CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
381 if (-ENOENT == synth_info->filefd)
383 synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
384 CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
386 if (synth_info->filefd >= 0)
388 unsigned char b = 0x00;
391 for (i = 0; i < synth_info->size; i++)
392 cyg_hal_sys_write(synth_info->filefd, &b, 1);
396 if (synth_info->filefd < 0)
398 CYG_ASSERT(false, "Can't open/create disk image file");
405 // ----------------------------------------------------------------------------