Commit 800d6c8f authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

greybus: connection: add flush host-device callback

Add a new host-device callback to flush any host-device queues,
including any ongoing transfers, as part of connection tear down.

The host-device buffers are flushed after the disconnecting operation
have completed and the AP queues have been emptied.

This can be used to flush already queued messages which upon reception
would have been discarded by the remote end anyway.

Note that this does not remove the need to flush any host-device queues
as part of CPort disable which needs to make the CPort ready for reuse
after deallocating all associated state and resetting the port.
Suggested-by: default avatarMitchell Tasman <tasman@leaflabs.com>
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 3de5acfa
......@@ -302,6 +302,24 @@ static void gb_connection_hd_cport_disable(struct gb_connection *connection)
}
}
static int gb_connection_hd_cport_flush(struct gb_connection *connection)
{
struct gb_host_device *hd = connection->hd;
int ret;
if (!hd->driver->cport_flush)
return 0;
ret = hd->driver->cport_flush(hd, connection->hd_cport_id);
if (ret) {
dev_err(&hd->dev, "%s: failed to flush host cport: %d\n",
connection->name, ret);
return ret;
}
return 0;
}
static int
gb_connection_hd_cport_features_enable(struct gb_connection *connection)
{
......@@ -651,6 +669,9 @@ static int _gb_connection_enable(struct gb_connection *connection, bool rx)
gb_connection_cancel_operations(connection, -ESHUTDOWN);
spin_unlock_irq(&connection->lock);
/* Transmit queue should already be empty. */
gb_connection_hd_cport_flush(connection);
gb_connection_ping(connection);
gb_connection_hd_cport_features_disable(connection);
gb_connection_svc_connection_quiescing(connection);
......@@ -736,6 +757,8 @@ void gb_connection_disable(struct gb_connection *connection)
gb_connection_cancel_operations(connection, -ESHUTDOWN);
spin_unlock_irq(&connection->lock);
gb_connection_hd_cport_flush(connection);
gb_connection_ping(connection);
gb_connection_hd_cport_features_disable(connection);
gb_connection_svc_connection_quiescing(connection);
......@@ -766,6 +789,7 @@ void gb_connection_disable_forced(struct gb_connection *connection)
gb_connection_cancel_operations(connection, -ESHUTDOWN);
spin_unlock_irq(&connection->lock);
gb_connection_hd_cport_flush(connection);
gb_connection_hd_cport_features_disable(connection);
gb_connection_svc_connection_destroy(connection);
gb_connection_hd_cport_disable(connection);
......
......@@ -21,6 +21,7 @@ struct gb_hd_driver {
void (*cport_release)(struct gb_host_device *hd, u16 cport_id);
int (*cport_enable)(struct gb_host_device *hd, u16 cport_id);
int (*cport_disable)(struct gb_host_device *hd, u16 cport_id);
int (*cport_flush)(struct gb_host_device *hd, u16 cport_id);
int (*cport_ping)(struct gb_host_device *hd, u16 cport_id);
int (*message_send)(struct gb_host_device *hd, u16 dest_cport_id,
struct gb_message *message, gfp_t gfp_mask);
......
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