if (connection->state == GB_CONNECTION_STATE_ENABLED)
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);
if (ret)
goto err_unlock;
spin_lock_irq(&connection->lock);
connection->handler = handler;
- connection->state = GB_CONNECTION_STATE_ENABLED;
+ if (handler)
+ connection->state = GB_CONNECTION_STATE_ENABLED;
+ else
+ connection->state = GB_CONNECTION_STATE_ENABLED_TX;
spin_unlock_irq(&connection->lock);
ret = gb_connection_control_connected(connection);
spin_lock_irq(&connection->lock);
connection->state = GB_CONNECTION_STATE_DISABLED;
gb_connection_cancel_operations(connection, -ESHUTDOWN);
+ connection->handler = NULL;
spin_unlock_irq(&connection->lock);
gb_connection_svc_connection_destroy(connection);
spin_lock_irq(&connection->lock);
connection->state = GB_CONNECTION_STATE_DISABLED;
gb_connection_cancel_operations(connection, -ESHUTDOWN);
+ connection->handler = NULL;
spin_unlock_irq(&connection->lock);
gb_connection_svc_connection_destroy(connection);
enum gb_connection_state {
GB_CONNECTION_STATE_INVALID = 0,
GB_CONNECTION_STATE_DISABLED = 1,
- GB_CONNECTION_STATE_ENABLED = 2,
+ GB_CONNECTION_STATE_ENABLED_TX = 2,
+ GB_CONNECTION_STATE_ENABLED = 3,
};
struct gb_operation;
int gb_connection_enable(struct gb_connection *connection,
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);
int gb_connection_legacy_init(struct gb_connection *connection);
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);
return -ENOTCONN;
}
size_t msg_size;
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",
connection->name, size);
return;