OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [disk/] [synth/] [current/] [src/] [synthdisk.c] - Blame information for rev 851

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
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, 2004, 2006 Free Software Foundation, Inc.            
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      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    savin
43
// Contributors: 
44
// Date:         2003-06-18
45
//
46
//####DESCRIPTIONEND####
47
//
48
//==========================================================================
49
 
50
#include <pkgconf/devs_disk_ecosynth.h>
51
 
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>
61
 
62
#include <stdio.h> // sprintf
63
 
64
// ----------------------------------------------------------------------------
65
 
66
//#define DEBUG 1
67
 
68
// ----------------------------------------------------------------------------
69
 
70
typedef struct {
71
    int        num;
72
    cyg_uint32 cylinders_num;
73
    cyg_uint32 heads_num;
74
    cyg_uint32 sectors_num;
75
    cyg_uint32 size;
76
    int        filefd;
77
    char       *filename;
78
} synth_disk_info_t;
79
 
80
typedef struct { int dummy; } synth_controller_t;
81
 
82
// ----------------------------------------------------------------------------
83
 
84
static cyg_bool synth_disk_init(struct cyg_devtab_entry *tab);
85
 
86
static Cyg_ErrNo synth_disk_read(disk_channel *chan,
87
                                 void         *buf,
88
                                 cyg_uint32    len,
89
                                 cyg_uint32    block_num);
90
 
91
static Cyg_ErrNo synth_disk_write(disk_channel *chan,
92
                                  const void   *buf,
93
                                  cyg_uint32    len,
94
                                  cyg_uint32    block_num);
95
 
96
static Cyg_ErrNo synth_disk_get_config(disk_channel *chan,
97
                                       cyg_uint32    key,
98
                                       const void   *xbuf,
99
                                       cyg_uint32   *len);
100
 
101
static Cyg_ErrNo synth_disk_set_config(disk_channel *chan,
102
                                       cyg_uint32    key,
103
                                       const void   *xbuf,
104
                                       cyg_uint32   *len);
105
 
106
static Cyg_ErrNo synth_disk_lookup(struct cyg_devtab_entry  **tab,
107
                                   struct cyg_devtab_entry   *sub_tab,
108
                                   const char                *name);
109
 
110
DISK_FUNS(synth_disk_funs,
111
          synth_disk_read,
112
          synth_disk_write,
113
          synth_disk_get_config,
114
          synth_disk_set_config
115
);
116
 
117
// ----------------------------------------------------------------------------
118
 
119
 
120
#define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_)                             \
121
static synth_disk_info_t synth_disk_info##_number_ = {                                          \
122
    num:           _number_,                                                                    \
123
    cylinders_num: _cyl_,                                                                       \
124
    heads_num:     _hpt_,                                                                       \
125
    sectors_num:   _spt_,                                                                       \
126
    size:          CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE,                               \
127
    filefd:        -1,                                                                          \
128
    filename:      CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME                            \
129
};                                                                                              \
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_,                                                      \
133
                    synth_disk_funs,                                                            \
134
                    synth_disk_info##_number_,                                                  \
135
                    synth_disk_controller_##_number_,                                           \
136
                    _mbr_supp_,                                                                 \
137
                    4                                                                           \
138
);                                                                                              \
139
BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_,                                                     \
140
             CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME,                                     \
141
             0,                                                                                 \
142
             &cyg_io_disk_devio,                                                                \
143
             synth_disk_init,                                                                   \
144
             synth_disk_lookup,                                                                 \
145
             &synth_disk_channel##_number_                                                      \
146
);
147
 
148
// ----------------------------------------------------------------------------
149
 
150
#ifdef CYGVAR_DEVS_DISK_ECOSYNTH_DISK0
151
# ifndef CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
152
SYNTH_DISK_INSTANCE(0, false, 0, 0, 0);
153
# else
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);
157
# endif
158
#endif
159
 
160
// ----------------------------------------------------------------------------
161
 
162
static cyg_bool
163
synth_disk_init(struct cyg_devtab_entry *tab)
164
{
165
    disk_channel      *chan       = (disk_channel *) tab->priv;
166
    synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
167
    bool result = true;
168
 
169
    if (chan->init)
170
        return true;
171
 
172
#ifdef DEBUG
173
    diag_printf("synth disk %d init size=%d\n",
174
                synth_info->num, synth_info->size);
175
#endif
176
 
177
    synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
178
            CYG_HAL_SYS_O_RDWR,
179
            CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
180
 
181
    if (-ENOENT == synth_info->filefd)
182
    {
183
        synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
184
            CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
185
 
186
        if (synth_info->filefd >= 0)
187
        {
188
            unsigned char b = 0x00;
189
            int i;
190
 
191
            for (i = 0; i < synth_info->size; i++)
192
                cyg_hal_sys_write(synth_info->filefd, &b, 1);
193
        }
194
    }
195
 
196
    if (synth_info->filefd < 0)
197
    {
198
        CYG_ASSERT(false, "Can't open/create disk image file");
199
        return false;
200
    }
201
 
202
    if (result)
203
    {
204
 
205
        if (!(chan->callbacks->disk_init)(tab))
206
            return false;
207
    }
208
    return result;
209
}
210
 
211
// ----------------------------------------------------------------------------
212
 
213
static Cyg_ErrNo
214
synth_disk_lookup(struct cyg_devtab_entry  **tab,
215
                  struct cyg_devtab_entry  *sub_tab,
216
                  const char               *name)
217
{
218
    Cyg_ErrNo res;
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;
222
 
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;
232
 
233
    res = (chan->callbacks->disk_connected)(*tab, &ident);
234
 
235
    if( res == ENOERR )
236
        res = (chan->callbacks->disk_lookup(tab, sub_tab, name));
237
 
238
    return res;
239
}
240
 
241
// ----------------------------------------------------------------------------
242
 
243
static Cyg_ErrNo
244
synth_disk_read(disk_channel *chan,
245
                void         *buf,
246
                cyg_uint32    len,
247
                cyg_uint32    block_num)
248
{
249
    synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
250
 
251
#ifdef DEBUG
252
    diag_printf("synth disk read block %d\n", block_num);
253
#endif
254
 
255
    if (synth_info->filefd >= 0)
256
    {
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);
261
        return ENOERR;
262
    }
263
    return -EIO;
264
}
265
 
266
// ----------------------------------------------------------------------------
267
 
268
static Cyg_ErrNo
269
synth_disk_write(disk_channel *chan,
270
                 const void   *buf,
271
                 cyg_uint32    len,
272
                 cyg_uint32    block_num)
273
{
274
    synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
275
 
276
#ifdef DEBUG
277
    diag_printf("synth disk write block %d\n", block_num);
278
#endif
279
 
280
    if (synth_info->filefd >= 0)
281
    {
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);
287
        return ENOERR;
288
    }
289
    return -EIO;
290
}
291
 
292
// ----------------------------------------------------------------------------
293
 
294
static Cyg_ErrNo
295
synth_disk_get_config(disk_channel *chan,
296
                      cyg_uint32    key,
297
                      const void   *xbuf,
298
                      cyg_uint32   *len)
299
{
300
 
301
#ifdef DEBUG
302
    diag_printf("synth disk get config\n");
303
#endif
304
 
305
    return -EINVAL;
306
}
307
 
308
// ----------------------------------------------------------------------------
309
 
310
static Cyg_ErrNo
311
synth_disk_set_config(disk_channel *chan,
312
                      cyg_uint32    key,
313
                      const void   *xbuf,
314
                      cyg_uint32   *len)
315
{
316
    Cyg_ErrNo res = ENOERR;
317
#ifdef DEBUG
318
    diag_printf("synth disk set config\n");
319
#endif
320
 
321
    switch ( key )
322
    {
323
    case CYG_IO_SET_CONFIG_DISK_MOUNT:
324
        // We have nothing to do here for this option.
325
        break;
326
 
327
    case CYG_IO_SET_CONFIG_DISK_UMOUNT:
328
        if( chan->info->mounts == 0 )
329
        {
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);
333
        }
334
        break;
335
 
336
    default:
337
        res = -EINVAL;
338
        break;
339
    }
340
 
341
    return res;
342
}
343
 
344
// ----------------------------------------------------------------------------
345
 
346
externC cyg_bool synth_disk_change( int unit, char *filename, int size,
347
                                    int cyls, int heads, int sectors)
348
{
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;
352
    int err = 0;
353
 
354
    if (!chan->init)
355
        return false;
356
 
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;
362
 
363
#ifdef DEBUG
364
    diag_printf("synth disk %d change size=%d\n",
365
                synth_info->num, synth_info->size);
366
#endif
367
 
368
    err = cyg_hal_sys_close( synth_info->filefd );
369
 
370
#ifdef DEBUG
371
    if( err != 0 )
372
    {
373
        diag_printf("synth disk change, failed to close old image: %d\n",err);
374
    }
375
#endif
376
 
377
    synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
378
            CYG_HAL_SYS_O_RDWR,
379
            CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
380
 
381
    if (-ENOENT == synth_info->filefd)
382
    {
383
        synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
384
            CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
385
 
386
        if (synth_info->filefd >= 0)
387
        {
388
            unsigned char b = 0x00;
389
            int i;
390
 
391
            for (i = 0; i < synth_info->size; i++)
392
                cyg_hal_sys_write(synth_info->filefd, &b, 1);
393
        }
394
    }
395
 
396
    if (synth_info->filefd < 0)
397
    {
398
        CYG_ASSERT(false, "Can't open/create disk image file");
399
        return false;
400
    }
401
 
402
    return true;
403
}
404
 
405
// ----------------------------------------------------------------------------
406
// EOF synthdisk.c

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.