]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: define connection state
authorAlex Elder <elder@linaro.org>
Wed, 22 Oct 2014 07:04:30 +0000 (02:04 -0500)
committerGreg Kroah-Hartman <greg@kroah.com>
Wed, 22 Oct 2014 09:20:28 +0000 (17:20 +0800)
Define the state of a connection.  A connection will not be
enabled until it has been successfully set up.  Once it starts
getting torn down its state will move to "being destroyed".

Don't send any operation request messages unless the connection is
enabled.  And drop any incoming messages if if the connection is
not enabled.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/connection.h
drivers/staging/greybus/operation.c

index 9bcda993685a84893e981097cae41d3d5ee3dcb1..b1e933fc7044bd47e9115ecb13506ad18be45b7d 100644 (file)
@@ -143,6 +143,7 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
        connection->interface = interface;      /* XXX refcount? */
        connection->interface_cport_id = cport_id;
        connection->protocol = protocol;
+       connection->state = GB_CONNECTION_STATE_DISABLED;
 
        spin_lock_irq(&gb_connections_lock);
        _gb_hd_connection_insert(hd, connection);
@@ -217,13 +218,20 @@ void gb_connection_err(struct gb_connection *connection, const char *fmt, ...)
  */
 int gb_connection_init(struct gb_connection *connection)
 {
+       int ret;
+
+       /* Need to enable the connection to initialize it */
+       connection->state = GB_CONNECTION_STATE_ENABLED;
        switch (connection->protocol) {
        case GREYBUS_PROTOCOL_I2C:
-               return gb_i2c_device_init(connection);
+               ret = gb_i2c_device_init(connection);
+               break;
        case GREYBUS_PROTOCOL_GPIO:
-               return gb_gpio_controller_init(connection);
+               ret = gb_gpio_controller_init(connection);
+               break;
        case GREYBUS_PROTOCOL_BATTERY:
-               return gb_battery_device_init(connection);
+               ret = gb_battery_device_init(connection);
+               break;
        case GREYBUS_PROTOCOL_CONTROL:
        case GREYBUS_PROTOCOL_AP:
        case GREYBUS_PROTOCOL_UART:
@@ -233,13 +241,20 @@ int gb_connection_init(struct gb_connection *connection)
        default:
                gb_connection_err(connection, "unimplemented protocol %u",
                        (u32)connection->protocol);
+               ret = -ENXIO;
                break;
        }
-       return -ENXIO;
+
+       if (ret)
+               connection->state = GB_CONNECTION_STATE_ERROR;
+
+       return ret;
 }
 
 void gb_connection_exit(struct gb_connection *connection)
 {
+       connection->state = GB_CONNECTION_STATE_DESTROYING;
+
        switch (connection->protocol) {
        case GREYBUS_PROTOCOL_I2C:
                gb_i2c_device_exit(connection);
index b5901a1b1a74265a19709312df51d9dd33703e07..a16e52a8ba18168c71ea001323d587f1c89e3bdd 100644 (file)
 
 #include "greybus.h"
 
+enum gb_connection_state {
+       GB_CONNECTION_STATE_INVALID     = 0,
+       GB_CONNECTION_STATE_DISABLED    = 1,
+       GB_CONNECTION_STATE_ENABLED     = 2,
+       GB_CONNECTION_STATE_ERROR       = 3,
+       GB_CONNECTION_STATE_DESTROYING  = 4,
+};
+
 struct gb_connection {
        struct greybus_host_device      *hd;
        struct gb_interface             *interface;
@@ -22,6 +30,7 @@ struct gb_connection {
        struct rb_node                  hd_node;
        struct list_head                interface_links;
        enum greybus_protocol           protocol;
+       enum gb_connection_state        state;
 
        struct list_head                operations;
        struct rb_root                  pending;        /* awaiting reponse */
index afb42d5e194106df725b87be30c2a0b7f8148dbf..5d23d1977297fe5fe1e0a16081853b72ada7d9ae 100644 (file)
@@ -417,6 +417,9 @@ int gb_operation_request_send(struct gb_operation *operation,
 {
        int ret;
 
+       if (operation->connection->state != GB_CONNECTION_STATE_ENABLED)
+               return -ENOTCONN;
+
        /*
         * XXX
         * I think the order of operations is going to be
@@ -461,6 +464,9 @@ void gb_connection_operation_recv(struct gb_connection *connection,
        struct gbuf *gbuf;
        u16 msg_size;
 
+       if (connection->state != GB_CONNECTION_STATE_ENABLED)
+               return;
+
        if (size > GB_OPERATION_MESSAGE_SIZE_MAX) {
                gb_connection_err(connection, "message too big");
                return;