Commit 59635018 authored by K. Y. Srinivasan's avatar K. Y. Srinivasan Committed by Martin K. Petersen

storvsc: Refactor the code in storvsc_channel_init()

The function storvsc_channel_init() repeatedly interacts with the host
to extract various channel properties. Refactor this code to eliminate
code repetition.
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: default avatarLong Li <longli@microsoft.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Tested-by: default avatarAlex Ng <alexng@microsoft.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dac58241
...@@ -723,29 +723,17 @@ static void cache_wwn(struct storvsc_device *stor_device, ...@@ -723,29 +723,17 @@ static void cache_wwn(struct storvsc_device *stor_device,
} }
} }
static int storvsc_channel_init(struct hv_device *device, bool is_fc)
static int storvsc_execute_vstor_op(struct hv_device *device,
struct storvsc_cmd_request *request,
bool status_check)
{ {
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet; struct vstor_packet *vstor_packet;
int ret, t, i; int ret, t;
int max_chns;
bool process_sub_channels = false;
stor_device = get_out_stor_device(device);
if (!stor_device)
return -ENODEV;
request = &stor_device->init_request;
vstor_packet = &request->vstor_packet; vstor_packet = &request->vstor_packet;
/*
* Now, initiate the vsc/vsp initialization protocol on the open
* channel
*/
memset(request, 0, sizeof(struct storvsc_cmd_request));
init_completion(&request->wait_event); init_completion(&request->wait_event);
vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->flags = REQUEST_COMPLETION_FLAG;
ret = vmbus_sendpacket(device->channel, vstor_packet, ret = vmbus_sendpacket(device->channel, vstor_packet,
...@@ -761,17 +749,50 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) ...@@ -761,17 +749,50 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
if (t == 0) if (t == 0)
return -ETIMEDOUT; return -ETIMEDOUT;
if (!status_check)
return ret;
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0) vstor_packet->status != 0)
return -EINVAL; return -EINVAL;
return ret;
}
static int storvsc_channel_init(struct hv_device *device, bool is_fc)
{
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
int ret, i;
int max_chns;
bool process_sub_channels = false;
stor_device = get_out_stor_device(device);
if (!stor_device)
return -ENODEV;
request = &stor_device->init_request;
vstor_packet = &request->vstor_packet;
/*
* Now, initiate the vsc/vsp initialization protocol on the open
* channel
*/
memset(request, 0, sizeof(struct storvsc_cmd_request));
vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
ret = storvsc_execute_vstor_op(device, request, true);
if (ret)
return ret;
/*
* Query host supported protocol version.
*/
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) { for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
/* reuse the packet for version range supported */ /* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet)); memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = vstor_packet->operation =
VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
vstor_packet->version.major_minor = vstor_packet->version.major_minor =
vmstor_protocols[i].protocol_version; vmstor_protocols[i].protocol_version;
...@@ -780,20 +801,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) ...@@ -780,20 +801,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
* The revision number is only used in Windows; set it to 0. * The revision number is only used in Windows; set it to 0.
*/ */
vstor_packet->version.revision = 0; vstor_packet->version.revision = 0;
ret = storvsc_execute_vstor_op(device, request, false);
ret = vmbus_sendpacket(device->channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0) if (ret != 0)
return ret; return ret;
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
if (t == 0)
return -ETIMEDOUT;
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
return -EINVAL; return -EINVAL;
...@@ -817,26 +828,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) ...@@ -817,26 +828,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
memset(vstor_packet, 0, sizeof(struct vstor_packet)); memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = storvsc_execute_vstor_op(device, request, true);
ret = vmbus_sendpacket(device->channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0) if (ret != 0)
return ret; return ret;
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
if (t == 0)
return -ETIMEDOUT;
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return -EINVAL;
/* /*
* Check to see if multi-channel support is there. * Check to see if multi-channel support is there.
* Hosts that implement protocol version of 5.1 and above * Hosts that implement protocol version of 5.1 and above
...@@ -854,28 +849,15 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) ...@@ -854,28 +849,15 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
if (!is_fc) if (!is_fc)
goto done; goto done;
/*
* For FC devices retrieve FC HBA data.
*/
memset(vstor_packet, 0, sizeof(struct vstor_packet)); memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA; vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA;
vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = storvsc_execute_vstor_op(device, request, true);
ret = vmbus_sendpacket(device->channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0) if (ret != 0)
return ret; return ret;
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
if (t == 0)
return -ETIMEDOUT;
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return -EINVAL;
/* /*
* Cache the currently active port and node ww names. * Cache the currently active port and node ww names.
*/ */
...@@ -885,26 +867,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) ...@@ -885,26 +867,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
memset(vstor_packet, 0, sizeof(struct vstor_packet)); memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = storvsc_execute_vstor_op(device, request, true);
ret = vmbus_sendpacket(device->channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0) if (ret != 0)
return ret; return ret;
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
if (t == 0)
return -ETIMEDOUT;
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return -EINVAL;
if (process_sub_channels) if (process_sub_channels)
handle_multichannel_storage(device, max_chns); handle_multichannel_storage(device, max_chns);
......
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