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

Commit 1a363108 authored by Keith Mange's avatar Keith Mange Committed by James Bottomley
Browse files

storvsc: Untangle the storage protocol negotiation from the vmbus protocol negotiation.



Currently we are making decisions based on vmbus protocol versions
that have been negotiated; use storage potocol versions instead.

[jejb: fold ARRAY_SIZE conversion suggested by Johannes Thumshirn
<jthumshirn@suse.de>
make vmstor_protocol static]
Tested-by: default avatarAlex Ng <alexng@microsoft.com>
Signed-off-by: default avatarKeith Mange <keith.mange@microsoft.com>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent 2492fd7a
Loading
Loading
Loading
Loading
+86 −22
Original line number Original line Diff line number Diff line
@@ -56,14 +56,18 @@
 * V1 RC > 2008/1/31:  2.0
 * V1 RC > 2008/1/31:  2.0
 * Win7: 4.2
 * Win7: 4.2
 * Win8: 5.1
 * Win8: 5.1
 * Win8.1: 6.0
 * Win10: 6.2
 */
 */


#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
						(((MINOR_) & 0xff)))
						(((MINOR_) & 0xff)))


#define VMSTOR_PROTO_VERSION_WIN6	VMSTOR_PROTO_VERSION(2, 0)
#define VMSTOR_PROTO_VERSION_WIN7	VMSTOR_PROTO_VERSION(4, 2)
#define VMSTOR_PROTO_VERSION_WIN7	VMSTOR_PROTO_VERSION(4, 2)
#define VMSTOR_PROTO_VERSION_WIN8	VMSTOR_PROTO_VERSION(5, 1)
#define VMSTOR_PROTO_VERSION_WIN8	VMSTOR_PROTO_VERSION(5, 1)

#define VMSTOR_PROTO_VERSION_WIN8_1	VMSTOR_PROTO_VERSION(6, 0)
#define VMSTOR_PROTO_VERSION_WIN10	VMSTOR_PROTO_VERSION(6, 2)


/*  Packet structure describing virtual storage requests. */
/*  Packet structure describing virtual storage requests. */
enum vstor_packet_operation {
enum vstor_packet_operation {
@@ -204,6 +208,45 @@ struct vmscsi_request {
} __attribute((packed));
} __attribute((packed));




/*
 * The list of storage protocols in order of preference.
 */
struct vmstor_protocol {
	int protocol_version;
	int sense_buffer_size;
	int vmscsi_size_delta;
};


static const struct vmstor_protocol vmstor_protocols[] = {
	{
		VMSTOR_PROTO_VERSION_WIN10,
		POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
		0
	},
	{
		VMSTOR_PROTO_VERSION_WIN8_1,
		POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
		0
	},
	{
		VMSTOR_PROTO_VERSION_WIN8,
		POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
		0
	},
	{
		VMSTOR_PROTO_VERSION_WIN7,
		PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
		sizeof(struct vmscsi_win8_extension),
	},
	{
		VMSTOR_PROTO_VERSION_WIN6,
		PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
		sizeof(struct vmscsi_win8_extension),
	}
};


/*
/*
 * This structure is sent during the intialization phase to get the different
 * This structure is sent during the intialization phase to get the different
 * properties of the channel.
 * properties of the channel.
@@ -864,7 +907,7 @@ static int storvsc_channel_init(struct hv_device *device)
	struct storvsc_device *stor_device;
	struct storvsc_device *stor_device;
	struct storvsc_cmd_request *request;
	struct storvsc_cmd_request *request;
	struct vstor_packet *vstor_packet;
	struct vstor_packet *vstor_packet;
	int ret, t;
	int ret, t, i;
	int max_chns;
	int max_chns;
	bool process_sub_channels = false;
	bool process_sub_channels = false;


@@ -904,12 +947,15 @@ static int storvsc_channel_init(struct hv_device *device)
		goto cleanup;
		goto cleanup;




	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_OPERATION_QUERY_PROTOCOL_VERSION;
		vstor_packet->operation =
			VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
		vstor_packet->flags = REQUEST_COMPLETION_FLAG;
		vstor_packet->flags = REQUEST_COMPLETION_FLAG;


	vstor_packet->version.major_minor = vmstor_proto_version;
		vstor_packet->version.major_minor =
			vmstor_protocols[i].protocol_version;


		/*
		/*
		 * The revision number is only used in Windows; set it to 0.
		 * The revision number is only used in Windows; set it to 0.
@@ -931,9 +977,29 @@ static int storvsc_channel_init(struct hv_device *device)
			goto cleanup;
			goto cleanup;
		}
		}


	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
		if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
	    vstor_packet->status != 0)
			ret = -EINVAL;
			goto cleanup;
		}

		if (vstor_packet->status == 0) {
			vmstor_proto_version =
				vmstor_protocols[i].protocol_version;

			sense_buffer_size =
				vmstor_protocols[i].sense_buffer_size;

			vmscsi_size_delta =
				vmstor_protocols[i].vmscsi_size_delta;

			break;
		}
	}

	if (vstor_packet->status != 0) {
		ret = -EINVAL;
		goto cleanup;
		goto cleanup;
	}




	memset(vstor_packet, 0, sizeof(struct vstor_packet));
	memset(vstor_packet, 0, sizeof(struct vstor_packet));
@@ -1746,14 +1812,12 @@ static int storvsc_probe(struct hv_device *device,
	if (vmbus_proto_version < VERSION_WIN8) {
	if (vmbus_proto_version < VERSION_WIN8) {
		sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
		sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
		vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
		vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
		vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN7;
		max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
		max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
		max_targets = STORVSC_IDE_MAX_TARGETS;
		max_targets = STORVSC_IDE_MAX_TARGETS;
		max_channels = STORVSC_IDE_MAX_CHANNELS;
		max_channels = STORVSC_IDE_MAX_CHANNELS;
	} else {
	} else {
		sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
		sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
		vmscsi_size_delta = 0;
		vmscsi_size_delta = 0;
		vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8;
		max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
		max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
		max_targets = STORVSC_MAX_TARGETS;
		max_targets = STORVSC_MAX_TARGETS;
		max_channels = STORVSC_MAX_CHANNELS;
		max_channels = STORVSC_MAX_CHANNELS;