]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/disk/synth/v2_0/src/synthdisk.c
Initial revision
[karo-tx-redboot.git] / packages / devs / disk / synth / v2_0 / src / synthdisk.c
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 DISK_CHANNEL(synth_disk_channel##_number_,                                 \
127              synth_disk_funs,                                              \
128              synth_disk_info##_number_,                                    \
129              _mbr_supp_,                                                   \
130              4                                                             \
131 );                                                                         \
132 BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_,                                \
133              CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME,                \
134              0,                                                            \
135              &cyg_io_disk_devio,                                           \
136              synth_disk_init,                                              \
137              synth_disk_lookup,                                            \
138              &synth_disk_channel##_number_                                 \
139 );
140
141 // ----------------------------------------------------------------------------
142
143 #ifdef CYGVAR_DEVS_DISK_ECOSYNTH_DISK0
144 # ifndef CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
145 SYNTH_DISK_INSTANCE(0, false, 0, 0, 0);
146 # else
147 SYNTH_DISK_INSTANCE(0, true, CYGIMP_IO_DISK_ECOSYNTH_DISK0_CYLINDERS,
148                              CYGIMP_IO_DISK_ECOSYNTH_DISK0_HEADS,
149                              CYGIMP_IO_DISK_ECOSYNTH_DISK0_SECTORS);
150 # endif
151 #endif
152
153 // ----------------------------------------------------------------------------
154
155 static cyg_bool 
156 synth_disk_init(struct cyg_devtab_entry *tab)
157 {
158     disk_channel      *chan       = (disk_channel *) tab->priv;
159     synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
160     bool result = true;
161
162     if (chan->init) 
163         return true;
164
165 #ifdef DEBUG
166     diag_printf("synth disk %d init size=%d\n", 
167                 synth_info->num, synth_info->size);
168 #endif
169    
170     synth_info->filefd = cyg_hal_sys_open(synth_info->filename, 
171             CYG_HAL_SYS_O_RDWR,
172             CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
173
174     if (-ENOENT == synth_info->filefd)
175     {
176         synth_info->filefd = cyg_hal_sys_open(synth_info->filename, 
177             CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
178         
179         if (synth_info->filefd >= 0)
180         {
181             unsigned char b = 0x00;
182             int i;
183         
184             for (i = 0; i < synth_info->size; i++)
185                 cyg_hal_sys_write(synth_info->filefd, &b, 1);    
186         }
187     }
188
189     if (synth_info->filefd < 0)
190     {
191         CYG_ASSERT(false, "Can't open/create disk image file");
192         return false;
193     }
194    
195     if (result)
196     {
197         cyg_disk_identify_t ident;
198        
199         ident.serial[0]       = '\0';
200         ident.firmware_rev[0] = '\0';
201         ident.model_num[0]    = '\0';
202         ident.lba_sectors_num = synth_info->size / 512;
203         ident.cylinders_num   = synth_info->cylinders_num;
204         ident.heads_num       = synth_info->heads_num;
205         ident.sectors_num     = synth_info->sectors_num;
206  
207         if (!(chan->callbacks->disk_init)(tab))
208             return false;
209         if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident))
210             return false;
211     }
212     return result;
213 }
214
215 static Cyg_ErrNo 
216 synth_disk_lookup(struct cyg_devtab_entry **tab, 
217                   struct cyg_devtab_entry  *sub_tab,
218                   const char               *name)
219 {
220     disk_channel *chan = (disk_channel *) (*tab)->priv;
221     return (chan->callbacks->disk_lookup(tab, sub_tab, name));
222 }
223
224 static Cyg_ErrNo 
225 synth_disk_read(disk_channel *chan, 
226                 void         *buf,
227                 cyg_uint32    len,
228                 cyg_uint32    block_num)
229 {
230     synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
231
232 #ifdef DEBUG
233     diag_printf("synth disk read block %d\n", block_num);
234 #endif
235     
236     if (synth_info->filefd >= 0)
237     {
238         cyg_hal_sys_lseek(synth_info->filefd, 
239                           block_num * chan->info->block_size,
240                           CYG_HAL_SYS_SEEK_SET);
241         cyg_hal_sys_read(synth_info->filefd, buf, len);
242         return ENOERR;
243     }
244     return -EIO; 
245 }
246
247 static Cyg_ErrNo 
248 synth_disk_write(disk_channel *chan,
249                  const void   *buf,
250                  cyg_uint32    len,
251                  cyg_uint32    block_num)
252 {
253     synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
254
255 #ifdef DEBUG
256     diag_printf("synth disk write block %d\n", block_num);
257 #endif
258  
259     if (synth_info->filefd >= 0)
260     {
261         cyg_hal_sys_lseek(synth_info->filefd, 
262                           block_num * chan->info->block_size,
263                           CYG_HAL_SYS_SEEK_SET);
264         cyg_hal_sys_write(synth_info->filefd, buf, len);
265 //        cyg_hal_sys_fdatasync(synth_info->filefd);
266         return ENOERR;
267     }
268     return -EIO; 
269 }
270
271 static Cyg_ErrNo
272 synth_disk_get_config(disk_channel *chan, 
273                       cyg_uint32    key,
274                       const void   *xbuf, 
275                       cyg_uint32   *len)
276 {
277
278 #ifdef DEBUG
279     diag_printf("synth disk get config\n");
280 #endif
281     
282     return -EINVAL;
283 }
284
285 static Cyg_ErrNo
286 synth_disk_set_config(disk_channel *chan, 
287                       cyg_uint32    key,
288                       const void   *xbuf, 
289                       cyg_uint32   *len)
290 {
291
292 #ifdef DEBUG
293     diag_printf("synth disk set config\n");
294 #endif
295  
296     return -EINVAL;
297 }
298
299 // ----------------------------------------------------------------------------
300 // EOF synthdisk.c