From: Alex Elder Date: Wed, 5 Nov 2014 22:12:50 +0000 (-0600) Subject: greybus: identify protocol by id *and* version X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=6ae7fa4520c9a3e316996320ad6d6439f08bb63c;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git greybus: identify protocol by id *and* version Right now we only look up a protocol based on its protocol id. Add support for maintaining a major and minor version as well, and use them when looking up a protocol. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 1a8f53ef34cf..703c286f5631 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -157,13 +157,16 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface, struct gb_connection *connection; struct greybus_host_device *hd; int retval; + u8 major = 0; + u8 minor = 1; connection = kzalloc(sizeof(*connection), GFP_KERNEL); if (!connection) return NULL; INIT_LIST_HEAD(&connection->protocol_links); - if (!gb_protocol_get(connection, protocol_id)) { + /* XXX Will have to establish connections to get version */ + if (!gb_protocol_get(connection, protocol_id, major, minor)) { pr_err("protocol 0x%02hhx not found\n", protocol_id); kfree(connection); return NULL; diff --git a/drivers/staging/greybus/protocol.c b/drivers/staging/greybus/protocol.c index e0bcd4bc28a5..704b180f0ffb 100644 --- a/drivers/staging/greybus/protocol.c +++ b/drivers/staging/greybus/protocol.c @@ -13,30 +13,31 @@ static DEFINE_SPINLOCK(gb_protocols_lock); static LIST_HEAD(gb_protocols); /* Caller must hold gb_protocols_lock */ -static struct gb_protocol *_gb_protocol_find(u8 id) +static struct gb_protocol *_gb_protocol_find(u8 id, u8 major, u8 minor) { struct gb_protocol *protocol; list_for_each_entry(protocol, &gb_protocols, links) - if (protocol->id == id) + if (protocol->id == id && protocol->major == major + && protocol->minor == minor) return protocol; return NULL; } /* This is basically for debug */ -static struct gb_protocol *gb_protocol_find(u8 id) +static struct gb_protocol *gb_protocol_find(u8 id, u8 major, u8 minor) { struct gb_protocol *protocol; spin_lock_irq(&gb_protocols_lock); - protocol = _gb_protocol_find(id); + protocol = _gb_protocol_find(id, major, minor); spin_unlock_irq(&gb_protocols_lock); return protocol; } /* Returns true if protocol was succesfully registered, false otherwise */ -bool gb_protocol_register(u8 id) +bool gb_protocol_register(u8 id, u8 major, u8 minor) { struct gb_protocol *protocol; struct gb_protocol *existing; @@ -46,10 +47,12 @@ bool gb_protocol_register(u8 id) if (!protocol) return false; protocol->id = id; + protocol->major = major; + protocol->minor = minor; INIT_LIST_HEAD(&protocol->connections); spin_lock_irq(&gb_protocols_lock); - existing = _gb_protocol_find(id); + existing = _gb_protocol_find(id, major, minor); if (!existing) list_add(&protocol->links, &gb_protocols); spin_unlock_irq(&gb_protocols_lock); @@ -77,7 +80,8 @@ bool gb_protocol_deregister(struct gb_protocol *protocol) } /* Returns true if successful, false otherwise */ -bool gb_protocol_get(struct gb_connection *connection, u8 id) +bool +gb_protocol_get(struct gb_connection *connection, u8 id, u8 major, u8 minor) { struct gb_protocol *protocol; @@ -90,7 +94,7 @@ bool gb_protocol_get(struct gb_connection *connection, u8 id) } spin_lock_irq(&gb_protocols_lock); - protocol = _gb_protocol_find(id); + protocol = _gb_protocol_find(id, major, minor); if (protocol) list_add(&connection->protocol_links, &protocol->connections); spin_unlock_irq(&gb_protocols_lock); @@ -102,6 +106,8 @@ bool gb_protocol_get(struct gb_connection *connection, u8 id) void gb_protocol_put(struct gb_connection *connection) { struct gb_protocol *protocol = connection->protocol; + u8 major = protocol->major; + u8 minor = protocol->minor; /* Sanity checks */ if (list_empty(&connection->protocol_links)) { @@ -109,9 +115,12 @@ void gb_protocol_put(struct gb_connection *connection) "connection protocol not recorded"); return; } - if (!protocol || gb_protocol_find(protocol->id) != protocol) { - gb_connection_err(connection, - "connection has undefined protocol"); + if (!protocol) { + gb_connection_err(connection, "connection has no protocol"); + return; + } + if (gb_protocol_find(protocol->id, major, minor) != protocol) { + gb_connection_err(connection, "connection protocol not found"); return; } diff --git a/drivers/staging/greybus/protocol.h b/drivers/staging/greybus/protocol.h index d244e9d3eca1..d53f67def779 100644 --- a/drivers/staging/greybus/protocol.h +++ b/drivers/staging/greybus/protocol.h @@ -11,16 +11,25 @@ #include "greybus.h" +/* + * Protocols having the same id but different major and/or minor + * version numbers are treated as distinct protocols. If it makes + * sense someday we could group protocols having the same id. + */ struct gb_protocol { - u8 id; - struct list_head connections; /* protocol users */ - struct list_head links; /* global list */ + u8 id; + u8 major; + u8 minor; + + struct list_head connections; /* protocol users */ + struct list_head links; /* global list */ }; -bool gb_protocol_register(u8 id); +bool gb_protocol_register(u8 id, u8 major, u8 minor); bool gb_protocol_deregister(struct gb_protocol *protocol); -bool gb_protocol_get(struct gb_connection *connection, u8 id); +bool gb_protocol_get(struct gb_connection *connection, u8 id, + u8 major, u8 minor); void gb_protocol_put(struct gb_connection *connection); #endif /* __PROTOCOL_H */