]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/devs/disk/synth/v2_0/src/synthdisk.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / disk / synth / v2_0 / src / synthdisk.c
index 5e653daf1e2347a227d43fc3d84b0fd3da24cf87..ecb8c4fec91302f3bc9649477e7c001722daf1e4 100644 (file)
@@ -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(struct cyg_devtab_entry  **tab,
                                    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 *tab)
    
     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;
 }
 
 // ----------------------------------------------------------------------------