From 271a9eef9722e13dd467ad1614f6935e19d9d922 Mon Sep 17 00:00:00 2001
From: Florian Pose <fp@igh-essen.com>
Date: Mon, 22 May 2006 07:34:58 +0000
Subject: [PATCH] SysFS write access for slave state.

---
 master/globals.h |  5 ++++
 master/slave.c   | 61 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/master/globals.h b/master/globals.h
index bc389516..dc380120 100644
--- a/master/globals.h
+++ b/master/globals.h
@@ -111,6 +111,11 @@
         .name = EC_STR(NAME), .owner = THIS_MODULE, .mode = S_IRUGO \
     }
 
+#define EC_SYSFS_READ_WRITE_ATTR(NAME) \
+    static struct attribute attr_##NAME = { \
+        .name = EC_STR(NAME), .owner = THIS_MODULE, .mode = S_IRUGO | S_IWUSR \
+    }
+
 /*****************************************************************************/
 
 extern void ec_print_data(const uint8_t *, size_t);
diff --git a/master/slave.c b/master/slave.c
index 682a9b31..47d84e08 100644
--- a/master/slave.c
+++ b/master/slave.c
@@ -54,6 +54,8 @@ extern const ec_code_msg_t al_status_messages[];
 
 int ec_slave_fetch_categories(ec_slave_t *);
 ssize_t ec_show_slave_attribute(struct kobject *, struct attribute *, char *);
+ssize_t ec_store_slave_attribute(struct kobject *, struct attribute *,
+                                 const char *, size_t);
 
 /*****************************************************************************/
 
@@ -66,6 +68,7 @@ EC_SYSFS_READ_ATTR(product_name);
 EC_SYSFS_READ_ATTR(product_desc);
 EC_SYSFS_READ_ATTR(sii_desc);
 EC_SYSFS_READ_ATTR(type);
+EC_SYSFS_READ_WRITE_ATTR(state);
 
 static struct attribute *def_attrs[] = {
     &attr_ring_position,
@@ -75,12 +78,13 @@ static struct attribute *def_attrs[] = {
     &attr_product_desc,
     &attr_sii_desc,
     &attr_type,
+    &attr_state,
     NULL,
 };
 
 static struct sysfs_ops sysfs_ops = {
-    .show = &ec_show_slave_attribute,
-    .store = NULL
+    .show = ec_show_slave_attribute,
+    .store = ec_store_slave_attribute
 };
 
 static struct kobj_type ktype_ec_slave = {
@@ -1260,10 +1264,63 @@ ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
                 return sprintf(buffer, "normal\n");
         }
     }
+    else if (attr == &attr_state) {
+        switch (slave->current_state) {
+            case EC_SLAVE_STATE_INIT:
+                return sprintf(buffer, "INIT\n");
+            case EC_SLAVE_STATE_PREOP:
+                return sprintf(buffer, "PREOP\n");
+            case EC_SLAVE_STATE_SAVEOP:
+                return sprintf(buffer, "SAVEOP\n");
+            case EC_SLAVE_STATE_OP:
+                return sprintf(buffer, "OP\n");
+            default:
+                return sprintf(buffer, "UNKNOWN\n");
+        }
+    }
 
     return 0;
 }
 
+/*****************************************************************************/
+
+/**
+   Formats attribute data for SysFS write access.
+   \return number of bytes processed, or negative error code
+*/
+
+ssize_t ec_store_slave_attribute(struct kobject *kobj, /**< slave's kobject */
+                                 struct attribute *attr, /**< attribute */
+                                 const char *buffer, /**< memory with data */
+                                 size_t size /**< size of data to store */
+                                 )
+{
+    ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
+
+    if (attr == &attr_state) {
+        if (!strcmp(buffer, "INIT\n")) {
+            slave->requested_state = EC_SLAVE_STATE_INIT;
+            return size;
+        }
+        else if (!strcmp(buffer, "PREOP\n")) {
+            slave->requested_state = EC_SLAVE_STATE_PREOP;
+            return size;
+        }
+        else if (!strcmp(buffer, "SAVEOP\n")) {
+            slave->requested_state = EC_SLAVE_STATE_SAVEOP;
+            return size;
+        }
+        else if (!strcmp(buffer, "OP\n")) {
+            slave->requested_state = EC_SLAVE_STATE_OP;
+            return size;
+        }
+
+        EC_ERR("Failed to set slave state!\n");
+    }
+
+    return -EINVAL;
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
-- 
GitLab