Commit 5ef32384 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

greybus: hd: fix svc-connection handling

Create the svc connection when registering the host-device and
remove the current svc connection hacks that "upgraded" the svc
connection once the endo id and ap interface id was known.

Note that the old implementation was partly based on a misunderstanding
as it was the remote interface id, rather than the local AP interface id,
that used to define a connection (but we also needed the endo_id).

The remote interface is no longer needed as static connections, such as
the svc connection, are now simply defined by the host-device and host
cport id.
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 87757e32
...@@ -77,24 +77,6 @@ static void gb_connection_kref_release(struct kref *kref) ...@@ -77,24 +77,6 @@ static void gb_connection_kref_release(struct kref *kref)
mutex_unlock(&connection_mutex); mutex_unlock(&connection_mutex);
} }
int svc_update_connection(struct gb_interface *intf,
struct gb_connection *connection)
{
struct gb_bundle *bundle;
bundle = gb_bundle_create(intf, GB_SVC_BUNDLE_ID, GREYBUS_CLASS_SVC);
if (!bundle)
return -EINVAL;
connection->bundle = bundle;
spin_lock_irq(&gb_connections_lock);
list_add(&connection->bundle_links, &bundle->connections);
spin_unlock_irq(&gb_connections_lock);
return 0;
}
static void gb_connection_init_name(struct gb_connection *connection) static void gb_connection_init_name(struct gb_connection *connection)
{ {
u16 hd_cport_id = connection->hd_cport_id; u16 hd_cport_id = connection->hd_cport_id;
......
...@@ -51,9 +51,6 @@ struct gb_connection { ...@@ -51,9 +51,6 @@ struct gb_connection {
void *private; void *private;
}; };
int svc_update_connection(struct gb_interface *intf,
struct gb_connection *connection);
struct gb_connection *gb_connection_create_static(struct gb_host_device *hd, struct gb_connection *gb_connection_create_static(struct gb_host_device *hd,
u16 hd_cport_id, u8 protocol_id); u16 hd_cport_id, u8 protocol_id);
struct gb_connection *gb_connection_create_dynamic(struct gb_interface *intf, struct gb_connection *gb_connection_create_dynamic(struct gb_interface *intf,
......
...@@ -98,6 +98,18 @@ struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver, ...@@ -98,6 +98,18 @@ struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
} }
EXPORT_SYMBOL_GPL(gb_hd_create); EXPORT_SYMBOL_GPL(gb_hd_create);
static int gb_hd_create_svc_connection(struct gb_host_device *hd)
{
hd->svc_connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID,
GREYBUS_PROTOCOL_SVC);
if (!hd->svc_connection) {
dev_err(&hd->dev, "failed to create svc connection\n");
return -ENOMEM;
}
return 0;
}
int gb_hd_add(struct gb_host_device *hd) int gb_hd_add(struct gb_host_device *hd)
{ {
int ret; int ret;
...@@ -106,19 +118,10 @@ int gb_hd_add(struct gb_host_device *hd) ...@@ -106,19 +118,10 @@ int gb_hd_add(struct gb_host_device *hd)
if (ret) if (ret)
return ret; return ret;
/* ret = gb_hd_create_svc_connection(hd);
* Initialize AP's SVC protocol connection: if (ret) {
*
* This is required as part of early initialization of the host device
* as we need this connection in order to start any kind of message
* exchange between the AP and the SVC. SVC will start with a
* 'get-version' request followed by a 'svc-hello' message and at that
* time we will create a fully initialized svc-connection, as we need
* endo-id and AP's interface id for that.
*/
if (!gb_ap_svc_connection_create(hd)) {
device_del(&hd->dev); device_del(&hd->dev);
return -ENOMEM; return ret;
} }
return 0; return 0;
...@@ -135,9 +138,7 @@ void gb_hd_del(struct gb_host_device *hd) ...@@ -135,9 +138,7 @@ void gb_hd_del(struct gb_host_device *hd)
gb_interfaces_remove(hd); gb_interfaces_remove(hd);
gb_endo_remove(hd->endo); gb_endo_remove(hd->endo);
/* Is the SVC still using the partially uninitialized connection ? */ gb_connection_destroy(hd->svc_connection);
if (hd->initial_svc_connection)
gb_connection_destroy(hd->initial_svc_connection);
device_del(&hd->dev); device_del(&hd->dev);
} }
......
...@@ -41,8 +41,8 @@ struct gb_host_device { ...@@ -41,8 +41,8 @@ struct gb_host_device {
size_t buffer_size_max; size_t buffer_size_max;
struct gb_endo *endo; struct gb_endo *endo;
struct gb_connection *initial_svc_connection;
struct gb_svc *svc; struct gb_svc *svc;
struct gb_connection *svc_connection;
/* Private data for the host driver */ /* Private data for the host driver */
unsigned long hd_priv[0] __aligned(sizeof(s64)); unsigned long hd_priv[0] __aligned(sizeof(s64));
......
...@@ -49,51 +49,6 @@ static struct attribute *svc_attrs[] = { ...@@ -49,51 +49,6 @@ static struct attribute *svc_attrs[] = {
}; };
ATTRIBUTE_GROUPS(svc); ATTRIBUTE_GROUPS(svc);
/*
* AP's SVC cport is required early to get messages from the SVC. This happens
* even before the Endo is created and hence any modules or interfaces.
*
* This is a temporary connection, used only at initial bootup.
*/
struct gb_connection *
gb_ap_svc_connection_create(struct gb_host_device *hd)
{
struct gb_connection *connection;
connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID,
GREYBUS_PROTOCOL_SVC);
return connection;
}
/*
* We know endo-type and AP's interface id now, lets create a proper svc
* connection (and its interface/bundle) now and get rid of the initial
* 'partially' initialized one svc connection.
*/
static struct gb_interface *
gb_ap_interface_create(struct gb_host_device *hd,
struct gb_connection *connection, u8 interface_id)
{
struct gb_interface *intf;
struct device *dev = &hd->endo->dev;
intf = gb_interface_create(hd, interface_id);
if (!intf) {
dev_err(dev, "%s: Failed to create interface with id %hhu\n",
__func__, interface_id);
return NULL;
}
intf->device_id = GB_DEVICE_ID_AP;
svc_update_connection(intf, connection);
/* Its no longer a partially initialized connection */
hd->initial_svc_connection = NULL;
return intf;
}
static int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id) static int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id)
{ {
struct gb_svc_intf_device_id_request request; struct gb_svc_intf_device_id_request request;
...@@ -360,7 +315,6 @@ static int gb_svc_hello(struct gb_operation *op) ...@@ -360,7 +315,6 @@ static int gb_svc_hello(struct gb_operation *op)
struct gb_svc *svc = connection->private; struct gb_svc *svc = connection->private;
struct gb_host_device *hd = connection->hd; struct gb_host_device *hd = connection->hd;
struct gb_svc_hello_request *hello_request; struct gb_svc_hello_request *hello_request;
struct gb_interface *intf;
int ret; int ret;
/* /*
...@@ -389,16 +343,6 @@ static int gb_svc_hello(struct gb_operation *op) ...@@ -389,16 +343,6 @@ static int gb_svc_hello(struct gb_operation *op)
if (ret) if (ret)
return ret; return ret;
/*
* Endo and its modules are ready now, fix AP's partially initialized
* svc protocol and its connection.
*/
intf = gb_ap_interface_create(hd, connection, svc->ap_intf_id);
if (!intf) {
gb_endo_remove(hd->endo);
return ret;
}
return 0; return 0;
} }
...@@ -720,9 +664,6 @@ static int gb_svc_connection_init(struct gb_connection *connection) ...@@ -720,9 +664,6 @@ static int gb_svc_connection_init(struct gb_connection *connection)
hd->svc = svc; hd->svc = svc;
WARN_ON(connection->hd->initial_svc_connection);
connection->hd->initial_svc_connection = connection;
return 0; return 0;
} }
......
...@@ -41,6 +41,4 @@ int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, ...@@ -41,6 +41,4 @@ int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
int gb_svc_protocol_init(void); int gb_svc_protocol_init(void);
void gb_svc_protocol_exit(void); void gb_svc_protocol_exit(void);
struct gb_connection *gb_ap_svc_connection_create(struct gb_host_device *hd);
#endif /* __SVC_H */ #endif /* __SVC_H */
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