Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 May 2015 09:20:35 +0000 (UTC)
From:      Wei Hu <whu@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: r283644 - stable/10/sys/dev/hyperv/storvsc
Message-ID:  <201505280920.t4S9KZWR099397@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: whu
Date: Thu May 28 09:20:35 2015
New Revision: 283644
URL: https://svnweb.freebsd.org/changeset/base/283644

Log:
  MFC r283053
  
  Submitted by:	whu
  Reviewed by:	royger
  Approved by:	royger
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D2661

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	Thu May 28 08:00:11 2015	(r283643)
+++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c	Thu May 28 09:20:35 2015	(r283644)
@@ -87,6 +87,8 @@ __FBSDID("$FreeBSD$");
 #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)
 
 struct storvsc_softc;
@@ -202,6 +204,21 @@ static struct storvsc_driver_props g_drv
 	 STORVSC_RINGBUFFER_SIZE}
 };
 
+/*
+ * Sense buffer size changed in win8; have a run-time
+ * variable to track the size we should use.
+ */
+static int sense_buffer_size;
+
+/*
+ * The size of the vmscsi_request has changed in win8. The
+ * additional size is for the newly added elements in the
+ * structure. These elements are valid only when we are talking
+ * to a win8 host.
+ * Track the correct size we need to apply.
+ */
+static int vmscsi_size_delta;
+
 static int storvsc_current_major;
 static int storvsc_current_minor;
 
@@ -214,6 +231,7 @@ static void storvsc_action(struct cam_si
 static int create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp);
 static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp);
 static enum hv_storage_type storvsc_get_storage_type(device_t dev);
+static void hv_storvsc_rescan_target(struct storvsc_softc *sc);
 static void hv_storvsc_on_channel_callback(void *context);
 static void hv_storvsc_on_iocompletion( struct storvsc_softc *sc,
 					struct vstor_packet *vstor_packet,
@@ -381,7 +399,7 @@ storvsc_send_multichannel_request(struct
 	ret = hv_vmbus_channel_send_packet(
 	    dev->channel,
 	    vstor_packet,
-	    sizeof(struct vstor_packet),
+	    VSTOR_PKT_SIZE,
 	    (uint64_t)(uintptr_t)request,
 	    HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 	    HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -448,7 +466,7 @@ hv_storvsc_channel_init(struct hv_device
 	ret = hv_vmbus_channel_send_packet(
 			dev->channel,
 			vstor_packet,
-			sizeof(struct vstor_packet),
+			VSTOR_PKT_SIZE,
 			(uint64_t)(uintptr_t)request,
 			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 			HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -481,7 +499,7 @@ hv_storvsc_channel_init(struct hv_device
 	ret = hv_vmbus_channel_send_packet(
 			dev->channel,
 			vstor_packet,
-			sizeof(struct vstor_packet),
+			VSTOR_PKT_SIZE,
 			(uint64_t)(uintptr_t)request,
 			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 			HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -510,7 +528,7 @@ hv_storvsc_channel_init(struct hv_device
 	ret = hv_vmbus_channel_send_packet(
 				dev->channel,
 				vstor_packet,
-				sizeof(struct vstor_packet),
+				VSTOR_PKT_SIZE,
 				(uint64_t)(uintptr_t)request,
 				HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 				HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -546,7 +564,7 @@ hv_storvsc_channel_init(struct hv_device
 	ret = hv_vmbus_channel_send_packet(
 			dev->channel,
 			vstor_packet,
-			sizeof(struct vstor_packet),
+			VSTOR_PKT_SIZE,
 			(uint64_t)(uintptr_t)request,
 			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 			HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -644,7 +662,7 @@ hv_storvsc_host_reset(struct hv_device *
 
 	ret = hv_vmbus_channel_send_packet(dev->channel,
 			vstor_packet,
-			sizeof(struct vstor_packet),
+			VSTOR_PKT_SIZE,
 			(uint64_t)(uintptr_t)&sc->hs_reset_req,
 			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 			HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -695,9 +713,9 @@ hv_storvsc_io_request(struct hv_device *
 
 	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
 
-	vstor_packet->u.vm_srb.length = sizeof(struct vmscsi_req);
+	vstor_packet->u.vm_srb.length = VSTOR_PKT_SIZE;
 	
-	vstor_packet->u.vm_srb.sense_info_len = SENSE_BUFFER_SIZE;
+	vstor_packet->u.vm_srb.sense_info_len = sense_buffer_size;
 
 	vstor_packet->u.vm_srb.transfer_len = request->data_buf.length;
 
@@ -711,14 +729,14 @@ hv_storvsc_io_request(struct hv_device *
 				outgoing_channel,
 				&request->data_buf,
 				vstor_packet,
-				sizeof(struct vstor_packet),
+				VSTOR_PKT_SIZE,
 				(uint64_t)(uintptr_t)request);
 
 	} else {
 		ret = hv_vmbus_channel_send_packet(
 			outgoing_channel,
 			vstor_packet,
-			sizeof(struct vstor_packet),
+			VSTOR_PKT_SIZE,
 			(uint64_t)(uintptr_t)request,
 			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
 			HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -772,6 +790,41 @@ hv_storvsc_on_iocompletion(struct storvs
 }
 
 static void
+hv_storvsc_rescan_target(struct storvsc_softc *sc)
+{
+	path_id_t pathid;
+	target_id_t targetid;
+	union ccb *ccb;
+
+	pathid = cam_sim_path(sc->hs_sim);
+	targetid = CAM_TARGET_WILDCARD;
+
+	/*
+	 * Allocate a CCB and schedule a rescan.
+	 */
+	ccb = xpt_alloc_ccb_nowait();
+	if (ccb == NULL) {
+		printf("unable to alloc CCB for rescan\n");
+		return;
+	}
+
+	if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, targetid,
+	    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+		printf("unable to create path for rescan, pathid: %d,"
+		    "targetid: %d\n", pathid, targetid);
+		xpt_free_ccb(ccb);
+		return;
+	}
+
+	if (targetid == CAM_TARGET_WILDCARD)
+		ccb->ccb_h.func_code = XPT_SCAN_BUS;
+	else
+		ccb->ccb_h.func_code = XPT_SCAN_TGT;
+
+	xpt_rescan(ccb);
+}
+
+static void
 hv_storvsc_on_channel_callback(void *context)
 {
 	int ret = 0;
@@ -801,7 +854,7 @@ hv_storvsc_on_channel_callback(void *con
 	ret = hv_vmbus_channel_recv_packet(
 			channel,
 			packet,
-			roundup2(sizeof(struct vstor_packet), 8),
+			roundup2(VSTOR_PKT_SIZE, 8),
 			&bytes_recvd,
 			&request_id);
 
@@ -826,11 +879,13 @@ hv_storvsc_on_channel_callback(void *con
 							vstor_packet, request);
 				break;
 			case VSTOR_OPERATION_REMOVEDEVICE:
-			case VSTOR_OPERATION_ENUMERATE_BUS:
 				printf("VMBUS: storvsc operation %d not "
 				    "implemented.\n", vstor_packet->operation);
 				/* TODO: implement */
 				break;
+			case VSTOR_OPERATION_ENUMERATE_BUS:
+				hv_storvsc_rescan_target(sc);
+				break;
 			default:
 				break;
 			}			
@@ -838,7 +893,7 @@ hv_storvsc_on_channel_callback(void *con
 		ret = hv_vmbus_channel_recv_packet(
 				channel,
 				packet,
-				roundup2(sizeof(struct vstor_packet), 8),
+				roundup2(VSTOR_PKT_SIZE, 8),
 				&bytes_recvd,
 				&request_id);
 	}
@@ -861,13 +916,17 @@ storvsc_probe(device_t dev)
 	int ata_disk_enable = 0;
 	int ret	= ENXIO;
 	
-	if ((HV_VMBUS_VERSION_WIN8 == hv_vmbus_protocal_version) ||
-	    (HV_VMBUS_VERSION_WIN8_1 == hv_vmbus_protocal_version)){
-		storvsc_current_major = STORVSC_WIN8_MAJOR;
-		storvsc_current_minor = STORVSC_WIN8_MINOR;
-	} else {
+	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)) {

Modified: stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h
==============================================================================
--- stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h	Thu May 28 08:00:11 2015	(r283643)
+++ stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h	Thu May 28 09:20:35 2015	(r283644)
@@ -51,6 +51,8 @@
  * V1 Beta                    0.1
  * V1 RC < 2008/1/31          1.0
  * V1 RC > 2008/1/31          2.0
+ * Win7: 4.2
+ * Win8: 5.1
  */
 
 #define VMSTOR_PROTOCOL_VERSION_CURRENT	VMSTOR_PROTOCOL_VERSION(5, 1)
@@ -83,9 +85,25 @@ enum vstor_packet_ops {
  */
 
 #define CDB16GENERIC_LENGTH			0x10
-#define SENSE_BUFFER_SIZE			0x12
+#define SENSE_BUFFER_SIZE			0x14
 #define MAX_DATA_BUFFER_LENGTH_WITH_PADDING	0x14
 
+#define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE	0x14
+#define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE	0x12
+
+
+struct vmscsi_win8_extension {
+	/*
+	 * The following were added in Windows 8
+	 */
+	uint16_t reserve;
+	uint8_t  queue_tag;
+	uint8_t  queue_action;
+	uint32_t srb_flags;
+	uint32_t time_out_value;
+	uint32_t queue_sort_ey;
+} __packed;
+
 struct vmscsi_req {
 	uint16_t length;
 	uint8_t  srb_status;
@@ -114,6 +132,11 @@ struct vmscsi_req {
 	    uint8_t reserved_array[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
 	} u;
 
+	/*
+	 * The following was added in win8.
+	 */
+	struct vmscsi_win8_extension win8_extension;
+
 } __packed;
 
 /**



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505280920.t4S9KZWR099397>