svn commit: r294890 - stable/10/sys/dev/hyperv/storvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Wed Jan 27 05:19:07 UTC 2016
Author: sephe
Date: Wed Jan 27 05:19:05 2016
New Revision: 294890
URL: https://svnweb.freebsd.org/changeset/base/294890
Log:
MFC r294557:
hyperv/stor: Verify returned inquiry data before further dispatching
Windows 10 and Window 2016 will return all zero inquiry data for
non-existing slots. If we dispatched them, then a lot of useless
(0 sized) disks would be created. So we verify the returned inquiry
data (valid type, non-empty vendor/product/revision etc.), before
further dispatching.
Minor white space cleanup and wording fix.
Submitted by: Hongjiang Zhang <honzhan microsoft com>
Reviewed by: adrian, sephe, Jun Su <junsu microsoft com>
Approved by: adrian (mentor)
Modified by: sephe
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D4928
Modified:
stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
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 Wed Jan 27 05:15:53 2016 (r294889)
+++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Jan 27 05:19:05 2016 (r294890)
@@ -1923,6 +1923,66 @@ create_storvsc_request(union ccb *ccb, s
return(0);
}
+/*
+ * Modified based on scsi_print_inquiry which is responsible to
+ * print the detail information for scsi_inquiry_data.
+ *
+ * Return 1 if it is valid, 0 otherwise.
+ */
+static inline int
+is_inquiry_valid(const struct scsi_inquiry_data *inq_data)
+{
+ uint8_t type;
+ char vendor[16], product[48], revision[16];
+
+ /*
+ * Check device type and qualifier
+ */
+ if (!(SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ||
+ SID_QUAL(inq_data) == SID_QUAL_LU_CONNECTED))
+ return (0);
+
+ type = SID_TYPE(inq_data);
+ switch (type) {
+ case T_DIRECT:
+ case T_SEQUENTIAL:
+ case T_PRINTER:
+ case T_PROCESSOR:
+ case T_WORM:
+ case T_CDROM:
+ case T_SCANNER:
+ case T_OPTICAL:
+ case T_CHANGER:
+ case T_COMM:
+ case T_STORARRAY:
+ case T_ENCLOSURE:
+ case T_RBC:
+ case T_OCRW:
+ case T_OSD:
+ case T_ADC:
+ break;
+ case T_NODEVICE:
+ default:
+ return (0);
+ }
+
+ /*
+ * Check vendor, product, and revision
+ */
+ cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor),
+ sizeof(vendor));
+ cam_strvis(product, inq_data->product, sizeof(inq_data->product),
+ sizeof(product));
+ cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision),
+ sizeof(revision));
+ if (strlen(vendor) == 0 ||
+ strlen(product) == 0 ||
+ strlen(revision) == 0)
+ return (0);
+
+ return (1);
+}
+
/**
* @brief completion function before returning to CAM
*
@@ -1993,11 +2053,33 @@ storvsc_io_done(struct hv_storvsc_reques
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
if (vm_srb->scsi_status == SCSI_STATUS_OK) {
- ccb->ccb_h.status |= CAM_REQ_CMP;
- } else {
+ const struct scsi_generic *cmd;
+
+ /*
+ * Check whether the data for INQUIRY cmd is valid or
+ * not. Windows 10 and Windows 2016 send all zero
+ * inquiry data to VM even for unpopulated slots.
+ */
+ cmd = (const struct scsi_generic *)
+ ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+ csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
+ if (cmd->opcode == INQUIRY &&
+ is_inquiry_valid(
+ (const struct scsi_inquiry_data *)csio->data_ptr) == 0) {
+ ccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+ if (bootverbose) {
+ mtx_lock(&sc->hs_lock);
+ xpt_print(ccb->ccb_h.path,
+ "storvsc uninstalled device\n");
+ mtx_unlock(&sc->hs_lock);
+ }
+ } else {
+ ccb->ccb_h.status |= CAM_REQ_CMP;
+ }
+ } else {
mtx_lock(&sc->hs_lock);
xpt_print(ccb->ccb_h.path,
- "srovsc scsi_status = %d\n",
+ "storvsc scsi_status = %d\n",
vm_srb->scsi_status);
mtx_unlock(&sc->hs_lock);
ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
More information about the svn-src-stable
mailing list