Move legacy protocol and connection handling to the legacy driver.
Rename the former global functions using a common legacy_ prefix.
Note that all legacy protocols suffer from a connection initialisation
race in that the protocol-specific initialisation, which includes
allocation of protocol-specific state containers, can not happen until
*after* the connection has been enabled. This is a major flaw in the
original design that we can now finally address by converting the legacy
protocol drivers into proper bundle (class) drivers.
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
#include "greybus.h"
-static int gb_connection_bind_protocol(struct gb_connection *connection);
-static void gb_connection_unbind_protocol(struct gb_connection *connection);
-
-
static DEFINE_SPINLOCK(gb_connections_lock);
/* This is only used at initialization time; no locking is required. */
}
}
-/*
- * Request protocol version supported by the module.
- */
-static int gb_connection_protocol_get_version(struct gb_connection *connection)
-{
- int ret;
-
- ret = gb_protocol_get_version(connection);
- if (ret) {
- dev_err(&connection->hd->dev,
- "%s: failed to get protocol version: %d\n",
- connection->name, ret);
- return ret;
- }
-
- return 0;
-}
-
/*
* Cancel all active operations on a connection.
*
}
EXPORT_SYMBOL_GPL(gb_connection_disable);
-static int gb_legacy_request_handler(struct gb_operation *operation)
-{
- struct gb_protocol *protocol = operation->connection->protocol;
-
- return protocol->request_recv(operation->type, operation);
-}
-
-int gb_connection_legacy_init(struct gb_connection *connection)
-{
- gb_request_handler_t handler;
- int ret;
-
- ret = gb_connection_bind_protocol(connection);
- if (ret)
- return ret;
-
- if (connection->protocol->request_recv)
- handler = gb_legacy_request_handler;
- else
- handler = NULL;
-
- ret = gb_connection_enable(connection, handler);
- if (ret)
- goto err_unbind_protocol;
-
- ret = gb_connection_protocol_get_version(connection);
- if (ret)
- goto err_disable;
-
- ret = connection->protocol->connection_init(connection);
- if (ret)
- goto err_disable;
-
- return 0;
-
-err_disable:
- gb_connection_disable(connection);
-err_unbind_protocol:
- gb_connection_unbind_protocol(connection);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_connection_legacy_init);
-
-void gb_connection_legacy_exit(struct gb_connection *connection)
-{
- if (connection->state == GB_CONNECTION_STATE_DISABLED)
- return;
-
- gb_connection_disable(connection);
-
- connection->protocol->connection_exit(connection);
-
- gb_connection_unbind_protocol(connection);
-}
-EXPORT_SYMBOL_GPL(gb_connection_legacy_exit);
-
/*
* Tear down a previously set up connection.
*/
}
}
EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable);
-
-static int gb_connection_bind_protocol(struct gb_connection *connection)
-{
- struct gb_protocol *protocol;
-
- protocol = gb_protocol_get(connection->protocol_id,
- connection->major,
- connection->minor);
- if (!protocol) {
- dev_err(&connection->hd->dev,
- "protocol 0x%02x version %u.%u not found\n",
- connection->protocol_id,
- connection->major, connection->minor);
- return -EPROTONOSUPPORT;
- }
- connection->protocol = protocol;
-
- return 0;
-}
-
-static void gb_connection_unbind_protocol(struct gb_connection *connection)
-{
- struct gb_protocol *protocol = connection->protocol;
-
- gb_protocol_put(protocol);
-
- connection->protocol = NULL;
-}
void gb_connection_disable_rx(struct gb_connection *connection);
void gb_connection_disable(struct gb_connection *connection);
-int gb_connection_legacy_init(struct gb_connection *connection);
-void gb_connection_legacy_exit(struct gb_connection *connection);
-
void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
u8 *data, size_t length);
#include "greybus.h"
#include "legacy.h"
+#include "protocol.h"
+
+
+static int legacy_connection_get_version(struct gb_connection *connection)
+{
+ int ret;
+
+ ret = gb_protocol_get_version(connection);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: failed to get protocol version: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int legacy_connection_bind_protocol(struct gb_connection *connection)
+{
+ struct gb_protocol *protocol;
+
+ protocol = gb_protocol_get(connection->protocol_id,
+ connection->major,
+ connection->minor);
+ if (!protocol) {
+ dev_err(&connection->hd->dev,
+ "protocol 0x%02x version %u.%u not found\n",
+ connection->protocol_id,
+ connection->major, connection->minor);
+ return -EPROTONOSUPPORT;
+ }
+ connection->protocol = protocol;
+
+ return 0;
+}
+
+static void legacy_connection_unbind_protocol(struct gb_connection *connection)
+{
+ struct gb_protocol *protocol = connection->protocol;
+
+ gb_protocol_put(protocol);
+
+ connection->protocol = NULL;
+}
+
+static int legacy_request_handler(struct gb_operation *operation)
+{
+ struct gb_protocol *protocol = operation->connection->protocol;
+
+ return protocol->request_recv(operation->type, operation);
+}
+
+static int legacy_connection_init(struct gb_connection *connection)
+{
+ gb_request_handler_t handler;
+ int ret;
+
+ ret = legacy_connection_bind_protocol(connection);
+ if (ret)
+ return ret;
+
+ if (connection->protocol->request_recv)
+ handler = legacy_request_handler;
+ else
+ handler = NULL;
+
+ ret = gb_connection_enable(connection, handler);
+ if (ret)
+ goto err_unbind_protocol;
+
+ ret = legacy_connection_get_version(connection);
+ if (ret)
+ goto err_disable;
+
+ ret = connection->protocol->connection_init(connection);
+ if (ret)
+ goto err_disable;
+
+ return 0;
+
+err_disable:
+ gb_connection_disable(connection);
+err_unbind_protocol:
+ legacy_connection_unbind_protocol(connection);
+
+ return ret;
+}
+
+static void legacy_connection_exit(struct gb_connection *connection)
+{
+ if (connection->state == GB_CONNECTION_STATE_DISABLED)
+ return;
+
+ gb_connection_disable(connection);
+
+ connection->protocol->connection_exit(connection);
+
+ legacy_connection_unbind_protocol(connection);
+}
static int legacy_probe(struct gb_bundle *bundle,
const struct greybus_bundle_id *id)
dev_dbg(&bundle->dev, "enabling connection %s\n",
connection->name);
- ret = gb_connection_legacy_init(connection);
+ ret = legacy_connection_init(connection);
if (ret)
goto err_connections_disable;
}
err_connections_disable:
list_for_each_entry_reverse(connection, &bundle->connections,
bundle_links) {
- gb_connection_legacy_exit(connection);
+ legacy_connection_exit(connection);
}
return ret;
list_for_each_entry_reverse(connection, &bundle->connections,
bundle_links) {
- gb_connection_legacy_exit(connection);
+ legacy_connection_exit(connection);
}
}
return protocol;
}
+EXPORT_SYMBOL_GPL(gb_protocol_get);
int gb_protocol_get_version(struct gb_connection *connection)
{
out:
spin_unlock_irq(&gb_protocols_lock);
}
+EXPORT_SYMBOL_GPL(gb_protocol_put);