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: K. Y. Srinivasan <kys@microsoft.com> Reviewed-by: Long Li <longli@microsoft.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Alex Ng <alexng@microsoft.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
dac582417b
commit
59635018f9
@ -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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
|
|
||||||
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)
|
|||||||
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 @@ done:
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user