changeset 1451:077fd39935a2

Expand fconfig access via virtual vectors. Work around a TCP timing issue.
author gthomas
date Sun, 21 Dec 2003 13:17:51 +0000
parents 9a841f11f433
children c15fe26f81c7
files packages/redboot/current/ChangeLog packages/redboot/current/include/flash_config.h packages/redboot/current/src/fconfig.c packages/redboot/current/src/net/tcp.c
diffstat 4 files changed, 101 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,15 @@
+2003-12-21  Gary Thomas  <gary@mlbassoc.com>
+
+	* src/net/tcp.c (tcp_send): Add [restore] delay into TCP write
+	path.  Sadly, there seems to be some issue where some ACK packets
+	get lost unless this is present (at least on some hardware).  
+	n.b. a small delay here is definitely preferable to the horrendous
+	delays imposed by TCP retries if this condition occurs.
+
+	* src/fconfig.c: 
+	* include/flash_config.h: New functions for get/set/enumerate
+	config data which can be used via virtual vector interface.
+
 2003-12-12  Jani Monoses <jani@iv.ro>
 
 	* src/net/tcp.c: Cancel retransmission timer when SYN is acked
--- a/packages/redboot/current/include/flash_config.h
+++ b/packages/redboot/current/include/flash_config.h
@@ -87,9 +87,13 @@ CYG_HAL_TABLE_QUALIFIED_ENTRY(RedBoot_co
    {#_n_,_t_,_e_,_ie_,_type_,(unsigned long)_dflt_};
 
 // Cause the in-memory configuration data to be written to flash
-void flash_write_config(void);
+void flash_write_config(bool prompt);
 // Fetch a data item from flash storage, returns 'false' if not found
 bool flash_get_config(char *key, void *val, int type);
+// Update a data item from flash storage, returns 'false' if not found
+bool flash_set_config(char *key, void *val, int type);
+// Enumerate keys from configuration
+bool flash_next_key(char *key, int keylen, int *type, int *offset);
 // Add a new data item to configuration data base.  Returns 'false'
 // if no space is available.
 bool flash_add_config(struct config_option *opt, bool update);
--- a/packages/redboot/current/src/fconfig.c
+++ b/packages/redboot/current/src/fconfig.c
@@ -566,7 +566,7 @@ do_flash_config(int argc, char *argv[])
     }
     if (!need_update)
         return;
-    flash_write_config();
+    flash_write_config(true);
 }
 
 
@@ -681,7 +681,7 @@ flash_lookup_alias(char *alias, char *al
 // Write the in-memory copy of the configuration data to the flash device.
 //
 void
-flash_write_config(void)
+flash_write_config(bool prompt)
 {
 #if defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH)
     int stat;
@@ -692,7 +692,7 @@ flash_write_config(void)
     config->key1 = CONFIG_KEY1;  
     config->key2 = CONFIG_KEY2;
     config->cksum = cyg_crc32((unsigned char *)config, sizeof(struct _config)-sizeof(config->cksum));
-    if (verify_action("Update RedBoot non-volatile configuration")) {
+    if (!prompt || verify_action("Update RedBoot non-volatile configuration")) {
 #ifdef CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH
 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
         memcpy(fis_work_block, fis_addr, fisdir_size);
@@ -747,6 +747,27 @@ flash_lookup_config(char *key)
 }
 
 //
+// Enumerate the keys from the configuration
+//
+bool
+flash_next_key(char *key, int keylen, int *type, int *offset)
+{
+    unsigned char *dp;
+    int len;
+
+    if (!config_ok) return false;
+    if ((*offset < 0) || (*offset >= MAX_CONFIG_DATA)) return false;
+
+    dp = &config->config_data[*offset];
+    if ((*type = CONFIG_OBJECT_TYPE(dp)) == CONFIG_EMPTY) return false;
+    if ((len = CONFIG_OBJECT_KEYLEN(dp)) > keylen) return false;        
+    memcpy(key, CONFIG_OBJECT_KEY(dp), len);
+    *offset += 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) +
+        config_length(CONFIG_OBJECT_TYPE(dp));
+    return true;
+}
+
+//
 // Retrieve a data object from the data base (in memory copy)
 //
 bool
@@ -756,6 +777,7 @@ flash_get_config(char *key, void *val, i
     void *val_ptr;
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG_READONLY_FALLBACK
     struct _config *save_config = 0;
+    bool res;
 #endif
 
     if (!config_ok) return false;
@@ -812,7 +834,9 @@ flash_get_config(char *key, void *val, i
         }
         else{
             diag_printf("Getting config information in READONLY mode\n");
-            return flash_get_config(key, val, type);
+            res = flash_get_config(key, val, type);
+            config = save_config;
+            return res;
         }        
     }
 #endif
@@ -820,6 +844,54 @@ flash_get_config(char *key, void *val, i
 }
 
 //
+// Update a data object in the data base (in memory copy & backing store)
+//
+bool
+flash_set_config(char *key, void *val, int type)
+{
+    unsigned char *dp;
+    void *val_ptr;
+
+    if (!config_ok) return false;
+
+    if ((dp = flash_lookup_config(key)) != (unsigned char *)NULL) {
+        if (CONFIG_OBJECT_TYPE(dp) == type) {
+            val_ptr = (void *)CONFIG_OBJECT_VALUE(dp);
+            switch (type) {
+                // Note: the data may be unaligned in the configuration data
+            case CONFIG_BOOL:
+                memcpy(val_ptr, val, sizeof(bool));
+                break;
+            case CONFIG_INT:
+                memcpy(val_ptr, val, sizeof(unsigned long));
+                break;
+#ifdef CYGPKG_REDBOOT_NETWORKING
+            case CONFIG_IP:
+                memcpy(val_ptr, val, sizeof(in_addr_t));
+                break;
+            case CONFIG_ESA:
+                memcpy(val_ptr, val, sizeof(enet_addr_t));
+                break;
+#endif
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+	    case CONFIG_NETPORT:
+#endif
+            case CONFIG_STRING:
+            case CONFIG_SCRIPT:
+                memcpy(val_ptr, val, config_length(CONFIG_STRING));
+                break;
+            }
+        } else {
+            diag_printf("Can't set config value '%s' - wrong type\n", key);
+            return false;
+        }
+        flash_write_config(false);
+        return true;
+    }
+    return false;
+}
+
+//
 // Copy data into the config area
 //
 static void
@@ -878,7 +950,7 @@ flash_add_config(struct config_option *o
     if ((dp = flash_lookup_config(opt->key)) != (unsigned char *)NULL) {
         flash_config_insert_value(CONFIG_OBJECT_VALUE(dp), opt);
         if (update) {
-            flash_write_config();
+            flash_write_config(true);
         }
         return true;
     }
@@ -913,7 +985,7 @@ flash_add_config(struct config_option *o
             }
             flash_config_insert_value(dp, opt);
             if (update) {
-                flash_write_config();
+                flash_write_config(true);
             }
             return true;
         } else {
--- a/packages/redboot/current/src/net/tcp.c
+++ b/packages/redboot/current/src/net/tcp.c
@@ -9,6 +9,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
 //
 // 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
@@ -54,6 +55,7 @@
 
 #include <net/net.h>
 #include <cyg/infra/diag.h>
+#include <cyg/hal/hal_if.h>
 
 #define MAX_TCP_SEGMENT (ETH_MAX_PKTLEN - (sizeof(eth_header_t) + sizeof(ip_header_t)))
 #define MAX_TCP_DATA    (MAX_TCP_SEGMENT - sizeof(tcp_header_t))
@@ -161,6 +163,10 @@ tcp_send(tcp_socket_t *s, int flags, int
 
     __ip_send(pkt, IP_PROTO_TCP, &s->his_addr);
 
+    // HACK!  If this delay is not present, then if the target system sends
+    // back data (not just an ACK), then somehow we miss it :-(
+    CYGACC_CALL_IF_DELAY_US(2*1000);
+
     BSPLOG(bsp_log("tcp_send: state[%d] flags[%s] ack[%x] data[%d].\n",
 		   s->state, flags_to_str(tcp->flags), s->ack, s->data_bytes));