changeset 2298:474e1f0afb12

* src/synthdisk.c: Updated to match changes in io/disk package. * src/synthdisk.c: Mildly reorganized to support changeable media. Added synth_disk_change() function to allow us to fake a disk change for testing purposes. * cdl/synthdisk.cdl: Added testing config options, plus define_proc to export CYGDAT_DEVS_DISK_CFG include file name. * src/synthdisk.c: Updated to latest disk device specification.
author jlarmour
date Thu, 21 Sep 2006 16:36:04 +0000
parents fa76da61c460
children 04006a2b020d
files packages/devs/disk/synth/current/ChangeLog packages/devs/disk/synth/current/cdl/synthdisk.cdl packages/devs/disk/synth/current/src/synthdisk.c
diffstat 3 files changed, 229 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/disk/synth/current/ChangeLog
+++ b/packages/devs/disk/synth/current/ChangeLog
@@ -1,14 +1,33 @@
+2006-02-03  Nick Garnett  <nickg@ecoscentric.com>
+
+	* src/synthdisk.c: Updated to match changes in io/disk package.
+
 2004-07-01  Savin Zlobec  <savin@elatec.si> 
 
         * src/synthdisk.c:
         Updated to work with the new DISK_CHANNEL macro definition.
 
-2004-01-15  Nick Garnett  <nickg@calivar.com>
+2004-04-15  Nick Garnett  <nickg@ecoscentric.com>
+
+	* src/synthdisk.c: Mildly reorganized to support changeable
+	media. Added synth_disk_change() function to allow us to fake a
+	disk change for testing purposes.
+
+2004-02-05  Nick Garnett  <nickg@ecoscentric.com>
+
+	* cdl/synthdisk.cdl: Added testing config options, plus
+	define_proc to export CYGDAT_DEVS_DISK_CFG include file name.
+
+2004-01-30  Nick Garnett  <nickg@ecoscentric.com>
+
+	* src/synthdisk.c: Updated to latest disk device specification.
+
+2004-01-15  Nick Garnett  <nickg@ecoscentric.com>
 
 	* cdl/synthdisk.cdl:
 	* src/synthdisk.c: 	
 	Added _FILENAME option for disk instances to map device to an
-	arbitrary cinfigured file.
+	arbitrary configured file.
 	
 	* src/synthdisk.c: Removed block_pos arguments from read
 	and write calls: it is not necessary.
@@ -31,7 +50,8 @@ 2003-08-19 Savin Zlobec <savin@elatec.si
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 2003 Savin Zlobec 
+// Copyright (C) 2003 Savin Zlobec
+// Copyright (C) 2004, 2006 eCosCentric Limited
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
--- a/packages/devs/disk/synth/current/cdl/synthdisk.cdl
+++ b/packages/devs/disk/synth/current/cdl/synthdisk.cdl
@@ -8,7 +8,8 @@
 #####ECOSGPLCOPYRIGHTBEGIN####
 ## -------------------------------------------
 ## This file is part of eCos, the Embedded Configurable Operating System.
-## Copyright (C) 2003 Savin Zlobec 
+## Copyright (C) 2003 Savin Zlobec
+## Copyright (C) 2004 eCosCentric Limited
 ##
 ## eCos is free software; you can redistribute it and/or modify it under
 ## the terms of the GNU General Public License as published by the Free
@@ -52,6 +53,12 @@ cdl_package CYGPKG_DEVS_DISK_ECOSYNTH {
     active_if   CYGPKG_IO_DISK
     active_if   CYGPKG_HAL_SYNTH
 
+    define_proc {
+        puts $::cdl_system_header "/***** Synthdisk driver proc output start *****/"
+        puts $::cdl_system_header "#define CYGDAT_DEVS_DISK_CFG <pkgconf/devs_disk_ecosynth.h>"
+        puts $::cdl_system_header "/***** Synthdisk driver proc output end  *****/"        
+    }
+
     cdl_component CYGVAR_DEVS_DISK_ECOSYNTH_DISK0 {
     	display         "Provide disk 0 device"
         flavor          bool
@@ -61,7 +68,7 @@ cdl_package CYGPKG_DEVS_DISK_ECOSYNTH {
         cdl_option CYGDAT_IO_DISK_ECOSYNTH_DISK0_NAME {
             display       "Device name for ecosynth disk 0 device"
             flavor        data
-            default_value {"\"/dev/disk0/\""}
+            default_value {"\"/dev/hd0/\""}
             description   "This is the device name used to access this
                            device in eCos. Note that the trailing slash
                            character must be present."
@@ -163,4 +170,48 @@ cdl_package CYGPKG_DEVS_DISK_ECOSYNTH {
                 the set of global flags if present."
         }
     }
+
+    cdl_component CYGPKG_DEVS_DISK_ECOSYNTH_TESTING {
+        display          "Testing configuration"
+        default_value    1
+        
+        cdl_option CYGDAT_DEVS_DISK_TEST_DEVICE {
+            display      "Test device driver"
+            flavor       data
+            default_value {"\"/dev/hd0/1\"" }
+        }
+
+        cdl_option CYGDAT_DEVS_DISK_TEST_MOUNTPOINT {
+            display      "Test filesystem mountpoint"
+            flavor       data
+            default_value {"\"/dosfs\"" }
+        }
+
+        cdl_option CYGDAT_DEVS_DISK_TEST_DIRECTORY {
+            display      "Test directory on test device"
+            flavor       data
+            default_value {"\"/test\"" }
+        }
+
+        
+        cdl_option CYGDAT_DEVS_DISK_TEST_DEVICE2 {
+            display      "Second Test device driver"
+            flavor       data
+            default_value {"\"/dev/hd0/2\"" }
+        }
+
+        cdl_option CYGDAT_DEVS_DISK_TEST_MOUNTPOINT2 {
+            display      "Second Test filesystem mountpoint"
+            flavor       data
+            default_value {"\"/dosfs2\"" }
+        }
+
+        cdl_option CYGDAT_DEVS_DISK_TEST_DIRECTORY2 {
+            display      "Test directory on second test device"
+            flavor       data
+            default_value {"\"/test\"" }
+        }
+
+    }
+
 }
--- a/packages/devs/disk/synth/current/src/synthdisk.c
+++ b/packages/devs/disk/synth/current/src/synthdisk.c
@@ -8,7 +8,8 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 2003 Savin Zlobec.
+// Copyright (C) 2003 Savin Zlobec
+// Copyright (C) 2004, 2006 eCosCentric Limited
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -76,6 +77,8 @@ typedef struct {
     char       *filename;
 } synth_disk_info_t;
 
+typedef struct { int dummy; } synth_controller_t;
+
 // ----------------------------------------------------------------------------
 
 static cyg_bool synth_disk_init(struct cyg_devtab_entry *tab);
@@ -104,38 +107,42 @@ static Cyg_ErrNo synth_disk_lookup(struc
                                    struct cyg_devtab_entry   *sub_tab,
                                    const char                *name);
 
-static DISK_FUNS(synth_disk_funs, 
-                 synth_disk_read, 
-                 synth_disk_write, 
-                 synth_disk_get_config,
-                 synth_disk_set_config
+DISK_FUNS(synth_disk_funs, 
+          synth_disk_read, 
+          synth_disk_write, 
+          synth_disk_get_config,
+          synth_disk_set_config
 );
 
 // ----------------------------------------------------------------------------
 
-#define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_)        \
-static synth_disk_info_t synth_disk_info##_number_ = {                     \
-    num:           _number_,                                               \
-    cylinders_num: _cyl_,                                                  \
-    heads_num:     _hpt_,                                                  \
-    sectors_num:   _spt_,                                                  \
-    size:          CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE,          \
-    filefd:        -1,                                                     \
-    filename:      CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME       \
-};                                                                         \
-DISK_CHANNEL(synth_disk_channel##_number_,                                 \
-             synth_disk_funs,                                              \
-             synth_disk_info##_number_,                                    \
-             _mbr_supp_,                                                   \
-             4                                                             \
-);                                                                         \
-BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_,                                \
-             CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME,                \
-             0,                                                            \
-             &cyg_io_disk_devio,                                           \
-             synth_disk_init,                                              \
-             synth_disk_lookup,                                            \
-             &synth_disk_channel##_number_                                 \
+
+#define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_)                             \
+static synth_disk_info_t synth_disk_info##_number_ = {                                          \
+    num:           _number_,                                                                    \
+    cylinders_num: _cyl_,                                                                       \
+    heads_num:     _hpt_,                                                                       \
+    sectors_num:   _spt_,                                                                       \
+    size:          CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE,                               \
+    filefd:        -1,                                                                          \
+    filename:      CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME                            \
+};                                                                                              \
+static synth_controller_t synth_controller_##_number_;                                          \
+DISK_CONTROLLER( synth_disk_controller_##_number_, synth_controller_##_number_ );               \
+DISK_CHANNEL(synth_disk_channel##_number_,                                                      \
+                    synth_disk_funs,                                                            \
+                    synth_disk_info##_number_,                                                  \
+                    synth_disk_controller_##_number_,                                           \
+                    _mbr_supp_,                                                                 \
+                    4                                                                           \
+);                                                                                              \
+BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_,                                                     \
+             CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME,                                     \
+             0,                                                                                 \
+             &cyg_io_disk_devio,                                                                \
+             synth_disk_init,                                                                   \
+             synth_disk_lookup,                                                                 \
+             &synth_disk_channel##_number_                                                      \
 );
 
 // ----------------------------------------------------------------------------
@@ -194,33 +201,45 @@ synth_disk_init(struct cyg_devtab_entry 
    
     if (result)
     {
-        cyg_disk_identify_t ident;
-       
-        ident.serial[0]       = '\0';
-        ident.firmware_rev[0] = '\0';
-        ident.model_num[0]    = '\0';
-        ident.lba_sectors_num = synth_info->size / 512;
-        ident.cylinders_num   = synth_info->cylinders_num;
-        ident.heads_num       = synth_info->heads_num;
-        ident.sectors_num     = synth_info->sectors_num;
  
         if (!(chan->callbacks->disk_init)(tab))
             return false;
-        if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident))
-            return false;
     }
     return result;
 }
 
+// ----------------------------------------------------------------------------
+
 static Cyg_ErrNo 
-synth_disk_lookup(struct cyg_devtab_entry **tab, 
+synth_disk_lookup(struct cyg_devtab_entry  **tab, 
                   struct cyg_devtab_entry  *sub_tab,
                   const char               *name)
 {
+    Cyg_ErrNo res;
     disk_channel *chan = (disk_channel *) (*tab)->priv;
-    return (chan->callbacks->disk_lookup(tab, sub_tab, name));
+    synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
+    cyg_disk_identify_t ident;
+       
+    ident.serial[0]       = '\0';
+    ident.firmware_rev[0] = '\0';
+    ident.model_num[0]    = '\0';
+    ident.lba_sectors_num = synth_info->size / 512;
+    ident.cylinders_num   = synth_info->cylinders_num;
+    ident.heads_num       = synth_info->heads_num;
+    ident.sectors_num     = synth_info->sectors_num;
+    ident.phys_block_size = 1;
+    ident.max_transfer    = 2048;
+    
+    res = (chan->callbacks->disk_connected)(*tab, &ident);
+
+    if( res == ENOERR )    
+        res = (chan->callbacks->disk_lookup(tab, sub_tab, name));
+
+    return res;
 }
 
+// ----------------------------------------------------------------------------
+
 static Cyg_ErrNo 
 synth_disk_read(disk_channel *chan, 
                 void         *buf,
@@ -238,12 +257,14 @@ synth_disk_read(disk_channel *chan,
         cyg_hal_sys_lseek(synth_info->filefd, 
                           block_num * chan->info->block_size,
                           CYG_HAL_SYS_SEEK_SET);
-        cyg_hal_sys_read(synth_info->filefd, buf, len);
+        cyg_hal_sys_read(synth_info->filefd, buf, len*512);
         return ENOERR;
     }
     return -EIO; 
 }
 
+// ----------------------------------------------------------------------------
+
 static Cyg_ErrNo 
 synth_disk_write(disk_channel *chan,
                  const void   *buf,
@@ -261,13 +282,15 @@ synth_disk_write(disk_channel *chan,
         cyg_hal_sys_lseek(synth_info->filefd, 
                           block_num * chan->info->block_size,
                           CYG_HAL_SYS_SEEK_SET);
-        cyg_hal_sys_write(synth_info->filefd, buf, len);
+        cyg_hal_sys_write(synth_info->filefd, buf, len*512);
 //        cyg_hal_sys_fdatasync(synth_info->filefd);
         return ENOERR;
     }
     return -EIO; 
 }
 
+// ----------------------------------------------------------------------------
+
 static Cyg_ErrNo
 synth_disk_get_config(disk_channel *chan, 
                       cyg_uint32    key,
@@ -282,18 +305,101 @@ synth_disk_get_config(disk_channel *chan
     return -EINVAL;
 }
 
+// ----------------------------------------------------------------------------
+
 static Cyg_ErrNo
 synth_disk_set_config(disk_channel *chan, 
                       cyg_uint32    key,
                       const void   *xbuf, 
                       cyg_uint32   *len)
 {
-
+    Cyg_ErrNo res = ENOERR;
 #ifdef DEBUG
     diag_printf("synth disk set config\n");
 #endif
- 
-    return -EINVAL;
+
+    switch ( key )
+    {
+    case CYG_IO_SET_CONFIG_DISK_MOUNT:
+        // We have nothing to do here for this option.
+        break;
+            
+    case CYG_IO_SET_CONFIG_DISK_UMOUNT:
+        if( chan->info->mounts == 0 )
+        {
+            // If this is the last unmount of this disk, then disconnect it from
+            // the driver system so the user can swap it out if he wants.
+            res = (chan->callbacks->disk_disconnected)(chan);
+        }
+        break;
+            
+    default:
+        res = -EINVAL;
+        break;
+    }
+    
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+
+externC cyg_bool synth_disk_change( int unit, char *filename, int size,
+                                    int cyls, int heads, int sectors)
+{
+    struct cyg_devtab_entry  *tab        = &synth_disk_io0;
+    disk_channel             *chan       = (disk_channel *) tab->priv;
+    synth_disk_info_t        *synth_info = (synth_disk_info_t *) chan->dev_priv;
+    int err = 0;
+    
+    if (!chan->init) 
+        return false;
+
+    synth_info->filename = filename;
+    synth_info->size = size;
+    synth_info->cylinders_num = cyls;
+    synth_info->heads_num = heads;
+    synth_info->sectors_num = sectors;
+    
+#ifdef DEBUG
+    diag_printf("synth disk %d change size=%d\n", 
+                synth_info->num, synth_info->size);
+#endif
+
+    err = cyg_hal_sys_close( synth_info->filefd );
+
+#ifdef DEBUG
+    if( err != 0 )
+    {
+        diag_printf("synth disk change, failed to close old image: %d\n",err);
+    }
+#endif
+    
+    synth_info->filefd = cyg_hal_sys_open(synth_info->filename, 
+            CYG_HAL_SYS_O_RDWR,
+            CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+
+    if (-ENOENT == synth_info->filefd)
+    {
+        synth_info->filefd = cyg_hal_sys_open(synth_info->filename, 
+            CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
+        
+        if (synth_info->filefd >= 0)
+        {
+            unsigned char b = 0x00;
+            int i;
+        
+            for (i = 0; i < synth_info->size; i++)
+                cyg_hal_sys_write(synth_info->filefd, &b, 1);    
+        }
+    }
+
+    if (synth_info->filefd < 0)
+    {
+        CYG_ASSERT(false, "Can't open/create disk image file");
+        return false;
+    }
+
+    return true;
 }
 
 // ----------------------------------------------------------------------------