From owner-svn-src-head@freebsd.org Fri Dec 9 03:16:37 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 86DE2C6C88C; Fri, 9 Dec 2016 03:16:37 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 618B21ADD; Fri, 9 Dec 2016 03:16:37 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uB93Gam3026133; Fri, 9 Dec 2016 03:16:36 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB93GaIw026132; Fri, 9 Dec 2016 03:16:36 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201612090316.uB93GaIw026132@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 9 Dec 2016 03:16:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309726 - 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-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Dec 2016 03:16:37 -0000 Author: sephe Date: Fri Dec 9 03:16:36 2016 New Revision: 309726 URL: https://svnweb.freebsd.org/changeset/base/309726 Log: hyperv/storvsc: Fix the SCSI disk attachment issue. On pre-WS2016 Hyper-V, if the only LUNs > 7 are used, then all disks fails to attach. Mainly because those versions of Hyper-V do not set SRB_STATUS properly and deliver junky INQUERY responses. Submitted by: Hongjiang Zhang Reported by: Hongxiong Xian MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8724 Modified: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Modified: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c ============================================================================== --- head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Fri Dec 9 02:21:27 2016 (r309725) +++ head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Fri Dec 9 03:16:36 2016 (r309726) @@ -2053,6 +2053,17 @@ create_storvsc_request(union ccb *ccb, s return(0); } +static uint32_t +is_scsi_valid(const struct scsi_inquiry_data *inq_data) +{ + u_int8_t type; + type = SID_TYPE(inq_data); + if (type == T_NODEVICE) + return (0); + if (SID_QUAL(inq_data) == SID_QUAL_BAD_LU) + return (0); + return (1); +} /** * @brief completion function before returning to CAM * @@ -2164,32 +2175,46 @@ storvsc_io_done(struct hv_storvsc_reques ccb->ccb_h.status |= CAM_REQ_CMP; } - if (cmd->opcode == INQUIRY) { + if (cmd->opcode == INQUIRY && + vm_srb->srb_status == SRB_STATUS_SUCCESS) { + int resp_xfer_len, resp_buf_len, data_len; struct scsi_inquiry_data *inq_data = (struct scsi_inquiry_data *)csio->data_ptr; - uint8_t *resp_buf = (uint8_t *)csio->data_ptr; - int resp_xfer_len, resp_buf_len, data_len; - /* Get the buffer length reported by host */ resp_xfer_len = vm_srb->transfer_len; + uint8_t *resp_buf = (uint8_t *)csio->data_ptr; + /* Get the available buffer length */ resp_buf_len = resp_xfer_len >= 5 ? resp_buf[4] + 5 : 0; data_len = (resp_buf_len < resp_xfer_len) ? resp_buf_len : resp_xfer_len; - if (bootverbose && data_len >= 5) { xpt_print(ccb->ccb_h.path, "storvsc inquiry " "(%d) [%x %x %x %x %x ... ]\n", data_len, resp_buf[0], resp_buf[1], resp_buf[2], resp_buf[3], resp_buf[4]); } - if (vm_srb->srb_status == SRB_STATUS_SUCCESS && - data_len >= SHORT_INQUIRY_LENGTH) { + /* + * XXX: Manually fix the wrong response returned from WS2012 + */ + if (!is_scsi_valid(inq_data) && + (vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN8_1 || + vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN8 || + vmstor_proto_version == VMSTOR_PROTOCOL_VERSION_WIN7)) { + if (data_len >= 4 && + (resp_buf[2] == 0 || resp_buf[3] == 0)) { + resp_buf[2] = 5; // verion=5 means SPC-3 + resp_buf[3] = 2; // resp fmt must be 2 + if (bootverbose) + xpt_print(ccb->ccb_h.path, + "fix version and resp fmt for 0x%x\n", + vmstor_proto_version); + } + } else if (data_len >= SHORT_INQUIRY_LENGTH) { char vendor[16]; cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), sizeof(vendor)); - /* * XXX: Upgrade SPC2 to SPC3 if host is WIN8 or * WIN2012 R2 in order to support UNMAP feature.