Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+46 −80
Original line number Diff line number Diff line
@@ -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;
	int ret, t, i;
	int max_chns;
	bool process_sub_channels = false;

	stor_device = get_out_stor_device(device);
	if (!stor_device)
		return -ENODEV;
	int ret, t;

	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));
	init_completion(&request->wait_event);
	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
	vstor_packet->flags = REQUEST_COMPLETION_FLAG;

	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)
		return -ETIMEDOUT;

	if (!status_check)
		return ret;

	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
	    vstor_packet->status != 0)
		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++) {
		/* reuse the packet for version range supported */
		memset(vstor_packet, 0, sizeof(struct vstor_packet));
		vstor_packet->operation =
			VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
		vstor_packet->flags = REQUEST_COMPLETION_FLAG;

		vstor_packet->version.major_minor =
			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.
		 */
		vstor_packet->version.revision = 0;

		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);
		ret = storvsc_execute_vstor_op(device, request, false);
		if (ret != 0)
			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)
			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));
	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
	vstor_packet->flags = REQUEST_COMPLETION_FLAG;

	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);

	ret = storvsc_execute_vstor_op(device, request, true);
	if (ret != 0)
		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.
	 * 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)
		goto done;

	/*
	 * For FC devices retrieve FC HBA data.
	 */
	memset(vstor_packet, 0, sizeof(struct vstor_packet));
	vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA;
	vstor_packet->flags = REQUEST_COMPLETION_FLAG;

	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);

	ret = storvsc_execute_vstor_op(device, request, true);
	if (ret != 0)
		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.
	 */
@@ -885,26 +867,10 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)

	memset(vstor_packet, 0, sizeof(struct vstor_packet));
	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
	vstor_packet->flags = REQUEST_COMPLETION_FLAG;

	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);

	ret = storvsc_execute_vstor_op(device, request, true);
	if (ret != 0)
		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)
		handle_multichannel_storage(device, max_chns);