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: Alex Ng <alexng@microsoft.com> Signed-off-by: Keith Mange <keith.mange@microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
This commit is contained in:
parent
2492fd7a60
commit
1a3631081d
|
@ -56,14 +56,18 @@
|
|||
* V1 RC > 2008/1/31: 2.0
|
||||
* Win7: 4.2
|
||||
* Win8: 5.1
|
||||
* Win8.1: 6.0
|
||||
* Win10: 6.2
|
||||
*/
|
||||
|
||||
#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
|
||||
(((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_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. */
|
||||
enum vstor_packet_operation {
|
||||
|
@ -204,6 +208,45 @@ struct vmscsi_request {
|
|||
} __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
|
||||
* properties of the channel.
|
||||
|
@ -864,7 +907,7 @@ static int storvsc_channel_init(struct hv_device *device)
|
|||
struct storvsc_device *stor_device;
|
||||
struct storvsc_cmd_request *request;
|
||||
struct vstor_packet *vstor_packet;
|
||||
int ret, t;
|
||||
int ret, t, i;
|
||||
int max_chns;
|
||||
bool process_sub_channels = false;
|
||||
|
||||
|
@ -904,36 +947,59 @@ static int storvsc_channel_init(struct hv_device *device)
|
|||
goto cleanup;
|
||||
|
||||
|
||||
/* 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;
|
||||
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_proto_version;
|
||||
vstor_packet->version.major_minor =
|
||||
vmstor_protocols[i].protocol_version;
|
||||
|
||||
/*
|
||||
* The revision number is only used in Windows; set it to 0.
|
||||
*/
|
||||
vstor_packet->version.revision = 0;
|
||||
/*
|
||||
* The revision number is only used in Windows; set it to 0.
|
||||
*/
|
||||
vstor_packet->version.revision = 0;
|
||||
|
||||
ret = vmbus_sendpacket(device->channel, vstor_packet,
|
||||
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)
|
||||
goto cleanup;
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||
if (t == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto cleanup;
|
||||
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||
if (t == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
|
||||
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->operation != VSTOR_OPERATION_COMPLETE_IO ||
|
||||
vstor_packet->status != 0)
|
||||
if (vstor_packet->status != 0) {
|
||||
ret = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
|
||||
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_targets = STORVSC_IDE_MAX_TARGETS;
|
||||
max_channels = STORVSC_IDE_MAX_CHANNELS;
|
||||
} else {
|
||||
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
|
||||
vmscsi_size_delta = 0;
|
||||
vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8;
|
||||
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
|
||||
max_targets = STORVSC_MAX_TARGETS;
|
||||
max_channels = STORVSC_MAX_CHANNELS;
|
||||
|
|
Loading…
Reference in New Issue