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;
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);
}
/* 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;
}
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);
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)) {
"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;
}
#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 */