Date: Wed, 25 May 2016 06:15:26 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r300656 - stable/10/sys/dev/hyperv/storvsc Message-ID: <201605250615.u4P6FQDR003173@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Wed May 25 06:15:26 2016 New Revision: 300656 URL: https://svnweb.freebsd.org/changeset/base/300656 Log: MFC r299505 hyperv/stor: Enable INQUIRY result check only on WIN10 like host systems On WIN8 like host systems, when rescan happens, the already installed disks seem to return random invalid results for INQUIRY. More investigation is under way to figure out why random invalid INQUIRY results are delivered to VM on WIN8 like host systems. Submitted by: Hongjiang Zhang <honzhan microsoft com> Reviewed by: sephe MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6316 Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed May 25 06:01:47 2016 (r300655) +++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed May 25 06:15:26 2016 (r300656) @@ -81,12 +81,6 @@ __FBSDID("$FreeBSD$"); #define BLKVSC_MAX_IO_REQUESTS STORVSC_MAX_IO_REQUESTS #define STORVSC_MAX_TARGETS (2) -#define STORVSC_WIN7_MAJOR 4 -#define STORVSC_WIN7_MINOR 2 - -#define STORVSC_WIN8_MAJOR 5 -#define STORVSC_WIN8_MINOR 1 - #define VSTOR_PKT_SIZE (sizeof(struct vstor_packet) - vmscsi_size_delta) #define HV_ALIGN(x, a) roundup2(x, a) @@ -208,7 +202,7 @@ static struct storvsc_driver_props g_drv * Sense buffer size changed in win8; have a run-time * variable to track the size we should use. */ -static int sense_buffer_size; +static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; /* * The size of the vmscsi_request has changed in win8. The @@ -218,9 +212,46 @@ static int sense_buffer_size; * Track the correct size we need to apply. */ static int vmscsi_size_delta; +/* + * The storage protocol version is determined during the + * initial exchange with the host. It will indicate which + * storage functionality is available in the host. +*/ +static int vmstor_proto_version; + +struct vmstor_proto { + int proto_version; + int sense_buffer_size; + int vmscsi_size_delta; +}; -static int storvsc_current_major; -static int storvsc_current_minor; +static const struct vmstor_proto vmstor_proto_list[] = { + { + VMSTOR_PROTOCOL_VERSION_WIN10, + POST_WIN7_STORVSC_SENSE_BUFFER_SIZE, + 0 + }, + { + VMSTOR_PROTOCOL_VERSION_WIN8_1, + POST_WIN7_STORVSC_SENSE_BUFFER_SIZE, + 0 + }, + { + VMSTOR_PROTOCOL_VERSION_WIN8, + POST_WIN7_STORVSC_SENSE_BUFFER_SIZE, + 0 + }, + { + VMSTOR_PROTOCOL_VERSION_WIN7, + PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE, + sizeof(struct vmscsi_win8_extension), + }, + { + VMSTOR_PROTOCOL_VERSION_WIN6, + PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE, + sizeof(struct vmscsi_win8_extension), + } +}; /* static functions */ static int storvsc_probe(device_t dev); @@ -435,7 +466,7 @@ storvsc_send_multichannel_request(struct static int hv_storvsc_channel_init(struct hv_device *dev) { - int ret = 0; + int ret = 0, i; struct hv_storvsc_request *request; struct vstor_packet *vstor_packet; struct storvsc_softc *sc; @@ -484,19 +515,20 @@ hv_storvsc_channel_init(struct hv_device goto cleanup; } - /* reuse the packet for version range supported */ + for (i = 0; i < nitems(vmstor_proto_list); i++) { + /* reuse the packet for version range supported */ - memset(vstor_packet, 0, sizeof(struct vstor_packet)); - vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; - vstor_packet->u.version.major_minor = - VMSTOR_PROTOCOL_VERSION(storvsc_current_major, storvsc_current_minor); + vstor_packet->u.version.major_minor = + vmstor_proto_list[i].proto_version; - /* revision is only significant for Windows guests */ - vstor_packet->u.version.revision = 0; + /* revision is only significant for Windows guests */ + vstor_packet->u.version.revision = 0; - ret = hv_vmbus_channel_send_packet( + ret = hv_vmbus_channel_send_packet( dev->channel, vstor_packet, VSTOR_PKT_SIZE, @@ -504,20 +536,34 @@ hv_storvsc_channel_init(struct hv_device HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) - goto cleanup; + if (ret != 0) + goto cleanup; - /* wait 5 seconds */ - ret = sema_timedwait(&request->synch_sema, 5 * hz); + /* wait 5 seconds */ + ret = sema_timedwait(&request->synch_sema, 5 * hz); - if (ret) - goto cleanup; + if (ret) + goto cleanup; - /* TODO: Check returned version */ - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO || - vstor_packet->status != 0) - goto cleanup; + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO) { + ret = EINVAL; + goto cleanup; + } + if (vstor_packet->status == 0) { + vmstor_proto_version = + vmstor_proto_list[i].proto_version; + sense_buffer_size = + vmstor_proto_list[i].sense_buffer_size; + vmscsi_size_delta = + vmstor_proto_list[i].vmscsi_size_delta; + break; + } + } + if (vstor_packet->status != 0) { + ret = EINVAL; + goto cleanup; + } /** * Query channel properties */ @@ -916,19 +962,6 @@ storvsc_probe(device_t dev) int ata_disk_enable = 0; int ret = ENXIO; - if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || - hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) { - sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE; - vmscsi_size_delta = sizeof(struct vmscsi_win8_extension); - storvsc_current_major = STORVSC_WIN7_MAJOR; - storvsc_current_minor = STORVSC_WIN7_MINOR; - } else { - sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE; - vmscsi_size_delta = 0; - storvsc_current_major = STORVSC_WIN8_MAJOR; - storvsc_current_minor = STORVSC_WIN8_MINOR; - } - switch (storvsc_get_storage_type(dev)) { case DRIVER_BLKVSC: if(bootverbose) @@ -2070,6 +2103,13 @@ storvsc_io_done(struct hv_storvsc_reques ((ccb->ccb_h.flags & CAM_CDB_POINTER) ? csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes); if (cmd->opcode == INQUIRY && + /* + * XXX: Temporary work around disk hot plugin on win2k12r2, + * only filtering the invalid disk on win10 or 2016 server. + * So, the hot plugin on win10 and 2016 server needs + * to be fixed. + */ + vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN10 && is_inquiry_valid( (const struct scsi_inquiry_data *)csio->data_ptr) == 0) { ccb->ccb_h.status |= CAM_DEV_NOT_THERE; Modified: stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h ============================================================================== --- stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h Wed May 25 06:01:47 2016 (r300655) +++ stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h Wed May 25 06:15:26 2016 (r300656) @@ -41,6 +41,11 @@ #define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \ (((MINOR_) & 0xff) )) +#define VMSTOR_PROTOCOL_VERSION_WIN6 VMSTOR_PROTOCOL_VERSION(2, 0) +#define VMSTOR_PROTOCOL_VERSION_WIN7 VMSTOR_PROTOCOL_VERSION(4, 2) +#define VMSTOR_PROTOCOL_VERSION_WIN8 VMSTOR_PROTOCOL_VERSION(5, 1) +#define VMSTOR_PROTOCOL_VERSION_WIN8_1 VMSTOR_PROTOCOL_VERSION(6, 0) +#define VMSTOR_PROTOCOL_VERSION_WIN10 VMSTOR_PROTOCOL_VERSION(6, 2) /* * Invalid version. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605250615.u4P6FQDR003173>