Commit 570dfa7c authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

greybus: connection: add unidirectional enabled state

Add a new connection state ENABLED_TX in which only outgoing operations
are allowed.

This allows drivers to query the device during probe before allocating
their state containers without having to worry about racing incoming
requests.
Reviewed-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 23268785
...@@ -396,6 +396,18 @@ int gb_connection_enable(struct gb_connection *connection, ...@@ -396,6 +396,18 @@ int gb_connection_enable(struct gb_connection *connection,
if (connection->state == GB_CONNECTION_STATE_ENABLED) if (connection->state == GB_CONNECTION_STATE_ENABLED)
goto out_unlock; goto out_unlock;
if (connection->state == GB_CONNECTION_STATE_ENABLED_TX) {
if (!handler)
goto out_unlock;
spin_lock_irq(&connection->lock);
connection->handler = handler;
connection->state = GB_CONNECTION_STATE_ENABLED;
spin_unlock_irq(&connection->lock);
goto out_unlock;
}
ret = gb_connection_hd_cport_enable(connection); ret = gb_connection_hd_cport_enable(connection);
if (ret) if (ret)
goto err_unlock; goto err_unlock;
...@@ -406,7 +418,10 @@ int gb_connection_enable(struct gb_connection *connection, ...@@ -406,7 +418,10 @@ int gb_connection_enable(struct gb_connection *connection,
spin_lock_irq(&connection->lock); spin_lock_irq(&connection->lock);
connection->handler = handler; connection->handler = handler;
if (handler)
connection->state = GB_CONNECTION_STATE_ENABLED; connection->state = GB_CONNECTION_STATE_ENABLED;
else
connection->state = GB_CONNECTION_STATE_ENABLED_TX;
spin_unlock_irq(&connection->lock); spin_unlock_irq(&connection->lock);
ret = gb_connection_control_connected(connection); ret = gb_connection_control_connected(connection);
...@@ -422,6 +437,7 @@ int gb_connection_enable(struct gb_connection *connection, ...@@ -422,6 +437,7 @@ int gb_connection_enable(struct gb_connection *connection,
spin_lock_irq(&connection->lock); spin_lock_irq(&connection->lock);
connection->state = GB_CONNECTION_STATE_DISABLED; connection->state = GB_CONNECTION_STATE_DISABLED;
gb_connection_cancel_operations(connection, -ESHUTDOWN); gb_connection_cancel_operations(connection, -ESHUTDOWN);
connection->handler = NULL;
spin_unlock_irq(&connection->lock); spin_unlock_irq(&connection->lock);
gb_connection_svc_connection_destroy(connection); gb_connection_svc_connection_destroy(connection);
...@@ -446,6 +462,7 @@ void gb_connection_disable(struct gb_connection *connection) ...@@ -446,6 +462,7 @@ void gb_connection_disable(struct gb_connection *connection)
spin_lock_irq(&connection->lock); spin_lock_irq(&connection->lock);
connection->state = GB_CONNECTION_STATE_DISABLED; connection->state = GB_CONNECTION_STATE_DISABLED;
gb_connection_cancel_operations(connection, -ESHUTDOWN); gb_connection_cancel_operations(connection, -ESHUTDOWN);
connection->handler = NULL;
spin_unlock_irq(&connection->lock); spin_unlock_irq(&connection->lock);
gb_connection_svc_connection_destroy(connection); gb_connection_svc_connection_destroy(connection);
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
enum gb_connection_state { enum gb_connection_state {
GB_CONNECTION_STATE_INVALID = 0, GB_CONNECTION_STATE_INVALID = 0,
GB_CONNECTION_STATE_DISABLED = 1, GB_CONNECTION_STATE_DISABLED = 1,
GB_CONNECTION_STATE_ENABLED = 2, GB_CONNECTION_STATE_ENABLED_TX = 2,
GB_CONNECTION_STATE_ENABLED = 3,
}; };
struct gb_operation; struct gb_operation;
...@@ -70,6 +71,10 @@ static inline bool gb_connection_is_static(struct gb_connection *connection) ...@@ -70,6 +71,10 @@ static inline bool gb_connection_is_static(struct gb_connection *connection)
int gb_connection_enable(struct gb_connection *connection, int gb_connection_enable(struct gb_connection *connection,
gb_request_handler_t handler); gb_request_handler_t handler);
static inline int gb_connection_enable_tx(struct gb_connection *connection)
{
return gb_connection_enable(connection, NULL);
}
void gb_connection_disable(struct gb_connection *connection); void gb_connection_disable(struct gb_connection *connection);
int gb_connection_legacy_init(struct gb_connection *connection); int gb_connection_legacy_init(struct gb_connection *connection);
......
...@@ -47,7 +47,9 @@ static int gb_operation_get_active(struct gb_operation *operation) ...@@ -47,7 +47,9 @@ static int gb_operation_get_active(struct gb_operation *operation)
spin_lock_irqsave(&connection->lock, flags); spin_lock_irqsave(&connection->lock, flags);
if (connection->state != GB_CONNECTION_STATE_ENABLED) { if (connection->state != GB_CONNECTION_STATE_ENABLED &&
connection->state != GB_CONNECTION_STATE_ENABLED_TX &&
!gb_operation_is_incoming(operation)) {
spin_unlock_irqrestore(&connection->lock, flags); spin_unlock_irqrestore(&connection->lock, flags);
return -ENOTCONN; return -ENOTCONN;
} }
...@@ -906,7 +908,8 @@ void gb_connection_recv(struct gb_connection *connection, ...@@ -906,7 +908,8 @@ void gb_connection_recv(struct gb_connection *connection,
size_t msg_size; size_t msg_size;
u16 operation_id; u16 operation_id;
if (connection->state != GB_CONNECTION_STATE_ENABLED) { if (connection->state != GB_CONNECTION_STATE_ENABLED &&
connection->state != GB_CONNECTION_STATE_ENABLED_TX) {
dev_warn(dev, "%s: dropping %zu received bytes\n", dev_warn(dev, "%s: dropping %zu received bytes\n",
connection->name, size); connection->name, size);
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment