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;
 
 /**
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to