Drivers: hv: vmbus: Introduce table of VMBus protocol versions
The technique used to get the next VMBus version seems increasisly clumsy as the number of VMBus versions increases. Performance is not a concern since this is only done once during system boot; it's just that we'll end up with more lines of code than is really needed. As an alternative, introduce a table with the version numbers listed in order (from the most recent to the oldest). vmbus_connect() loops through the versions listed in the table until it gets an accepted connection or gets to the end of the table (invalid version). Suggested-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Andrea Parri <parri.andrea@gmail.com> Reviewed-by: Wei Liu <wei.liu@kernel.org> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
a99d8080aa
Коммит
bedc61a922
|
@ -40,29 +40,17 @@ EXPORT_SYMBOL_GPL(vmbus_connection);
|
|||
__u32 vmbus_proto_version;
|
||||
EXPORT_SYMBOL_GPL(vmbus_proto_version);
|
||||
|
||||
static __u32 vmbus_get_next_version(__u32 current_version)
|
||||
{
|
||||
switch (current_version) {
|
||||
case (VERSION_WIN7):
|
||||
return VERSION_WS2008;
|
||||
|
||||
case (VERSION_WIN8):
|
||||
return VERSION_WIN7;
|
||||
|
||||
case (VERSION_WIN8_1):
|
||||
return VERSION_WIN8;
|
||||
|
||||
case (VERSION_WIN10):
|
||||
return VERSION_WIN8_1;
|
||||
|
||||
case (VERSION_WIN10_V5):
|
||||
return VERSION_WIN10;
|
||||
|
||||
case (VERSION_WS2008):
|
||||
default:
|
||||
return VERSION_INVAL;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Table of VMBus versions listed from newest to oldest.
|
||||
*/
|
||||
static __u32 vmbus_versions[] = {
|
||||
VERSION_WIN10_V5,
|
||||
VERSION_WIN10,
|
||||
VERSION_WIN8_1,
|
||||
VERSION_WIN8,
|
||||
VERSION_WIN7,
|
||||
VERSION_WS2008
|
||||
};
|
||||
|
||||
int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
|
||||
{
|
||||
|
@ -169,8 +157,8 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
|
|||
*/
|
||||
int vmbus_connect(void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct vmbus_channel_msginfo *msginfo = NULL;
|
||||
int i, ret = 0;
|
||||
__u32 version;
|
||||
|
||||
/* Initialize the vmbus connection */
|
||||
|
@ -244,21 +232,19 @@ int vmbus_connect(void)
|
|||
* version.
|
||||
*/
|
||||
|
||||
version = VERSION_CURRENT;
|
||||
for (i = 0; ; i++) {
|
||||
if (i == ARRAY_SIZE(vmbus_versions))
|
||||
goto cleanup;
|
||||
|
||||
version = vmbus_versions[i];
|
||||
|
||||
do {
|
||||
ret = vmbus_negotiate_version(msginfo, version);
|
||||
if (ret == -ETIMEDOUT)
|
||||
goto cleanup;
|
||||
|
||||
if (vmbus_connection.conn_state == CONNECTED)
|
||||
break;
|
||||
|
||||
version = vmbus_get_next_version(version);
|
||||
} while (version != VERSION_INVAL);
|
||||
|
||||
if (version == VERSION_INVAL)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
vmbus_proto_version = version;
|
||||
pr_info("Vmbus version:%d.%d\n",
|
||||
|
|
|
@ -2220,8 +2220,7 @@ static int vmbus_bus_resume(struct device *dev)
|
|||
* We only use the 'vmbus_proto_version', which was in use before
|
||||
* hibernation, to re-negotiate with the host.
|
||||
*/
|
||||
if (vmbus_proto_version == VERSION_INVAL ||
|
||||
vmbus_proto_version == 0) {
|
||||
if (!vmbus_proto_version) {
|
||||
pr_err("Invalid proto version = 0x%x\n", vmbus_proto_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -192,10 +192,6 @@ static inline u32 hv_get_avail_to_write_percent(
|
|||
#define VERSION_WIN10 ((4 << 16) | (0))
|
||||
#define VERSION_WIN10_V5 ((5 << 16) | (0))
|
||||
|
||||
#define VERSION_INVAL -1
|
||||
|
||||
#define VERSION_CURRENT VERSION_WIN10_V5
|
||||
|
||||
/* Make maximum size of pipe payload of 16K */
|
||||
#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче