From owner-svn-src-all@FreeBSD.ORG Mon May 18 10:31:24 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9C083554; Mon, 18 May 2015 10:31:24 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8A5B71187; Mon, 18 May 2015 10:31:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4IAVOwd012356; Mon, 18 May 2015 10:31:24 GMT (envelope-from whu@FreeBSD.org) Received: (from whu@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4IAVOlA012354; Mon, 18 May 2015 10:31:24 GMT (envelope-from whu@FreeBSD.org) Message-Id: <201505181031.t4IAVOlA012354@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: whu set sender to whu@FreeBSD.org using -f From: Wei Hu Date: Mon, 18 May 2015 10:31:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r283053 - head/sys/dev/hyperv/storvsc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 May 2015 10:31:24 -0000 Author: whu Date: Mon May 18 10:31:23 2015 New Revision: 283053 URL: https://svnweb.freebsd.org/changeset/base/283053 Log: Add support for SCSI disk hot add and remove. Also add padding according to the requirement of different hypervisor releases. Submitted by: whu Reviewed by: royger Approved by: royger MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D2512 Modified: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c head/sys/dev/hyperv/storvsc/hv_vstorage.h Modified: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Mon May 18 08:12:08 2015 (r283052) +++ head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Mon May 18 10:31:23 2015 (r283053) @@ -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: head/sys/dev/hyperv/storvsc/hv_vstorage.h ============================================================================== --- head/sys/dev/hyperv/storvsc/hv_vstorage.h Mon May 18 08:12:08 2015 (r283052) +++ head/sys/dev/hyperv/storvsc/hv_vstorage.h Mon May 18 10:31:23 2015 (r283053) @@ -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; /**