Skip to content

Commit

Permalink
protocol: Add 'get_latest' supported protocol
Browse files Browse the repository at this point in the history
Change the implementation of finding the protocol driver - which looks
for a hardcoded 0,1 major/minor initiated in connection_create - to
finding the highest supported major,minor version overall, or one that
matches the requested major version.

This is the initial re-design of the version negotiation that allows us
to correctly send the currently implemented protocol driver version.

Change-Id: I8f5aa67a92622d69b6f469920fe1d9cd15e56c6e
Signed-off-by: Jason Hrycay <jason.hrycay@motorola.com>
Reviewed-on: http://gerrit.mot.com/841249
SLTApproved: Slta Waiver <sltawvr@motorola.com>
SME-Granted: SME Approvals Granted
Reviewed-by: Gregory Meiste <w30289@motorola.com>
  • Loading branch information
jhrycay committed Jun 14, 2016
1 parent e117ddf commit c5db445
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
9 changes: 3 additions & 6 deletions connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,14 +550,11 @@ static int gb_connection_bind_protocol(struct gb_connection *connection)
{
struct gb_protocol *protocol;

protocol = gb_protocol_get(connection->protocol_id,
connection->major,
connection->minor);
protocol = gb_protocol_get_latest(connection->protocol_id, 0, false);
if (!protocol) {
dev_err(&connection->hd->dev,
"protocol 0x%02x version %u.%u not found\n",
connection->protocol_id,
connection->major, connection->minor);
"protocol 0x%02x not found\n",
connection->protocol_id);
return -EPROTONOSUPPORT;
}
connection->protocol = protocol;
Expand Down
49 changes: 49 additions & 0 deletions protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@ static struct gb_protocol *gb_protocol_find(u8 id, u8 major, u8 minor)
return NULL;
}

/* Caller must hold gb_protocols_lock */
static struct gb_protocol *gb_protocol_find_latest(u8 id, u8 major, bool match)
{
struct gb_protocol *protocol;

list_for_each_entry(protocol, &gb_protocols, links) {
if (protocol->id < id)
continue;
if (protocol->id > id)
break;

if (!match)
return protocol;

if (protocol->major > major)
continue;
if (protocol->major < major)
break;

return protocol;
}
return NULL;
}

int __gb_protocol_register(struct gb_protocol *protocol, struct module *module)
{
struct gb_protocol *existing;
Expand Down Expand Up @@ -142,6 +166,31 @@ struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor)
return protocol;
}

/* Returns the latest protocol version supported, or null pointer */
struct gb_protocol *gb_protocol_get_latest(u8 id, u8 major, bool match)
{
struct gb_protocol *protocol;
u8 protocol_count;

spin_lock_irq(&gb_protocols_lock);
protocol = gb_protocol_find_latest(id, major, match);
if (protocol) {
if (!try_module_get(protocol->owner)) {
protocol = NULL;
} else {
protocol_count = protocol->count;
if (protocol_count != U8_MAX)
protocol->count++;
}
}
spin_unlock_irq(&gb_protocols_lock);

if (protocol)
WARN_ON(protocol_count == U8_MAX);

return protocol;
}

int gb_protocol_get_version(struct gb_connection *connection)
{
struct gb_protocol_version_request request;
Expand Down
1 change: 1 addition & 0 deletions protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void gb_protocol_deregister(struct gb_protocol *protocol);
__gb_protocol_register(protocol, THIS_MODULE)

struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
struct gb_protocol *gb_protocol_get_latest(u8 id, u8 major, bool match);
int gb_protocol_get_version(struct gb_connection *connection);

void gb_protocol_put(struct gb_protocol *protocol);
Expand Down

0 comments on commit c5db445

Please sign in to comment.