Index: sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c =================================================================== --- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c +++ sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c @@ -2053,6 +2053,17 @@ 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 * @@ -2165,31 +2176,42 @@ } if (cmd->opcode == INQUIRY) { + 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)) { + if (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\n"); + } + } else if (vm_srb->srb_status == SRB_STATUS_SUCCESS && + 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.