svn commit: r294557 - head/sys/dev/hyperv/storvsc

Sepherosa Ziehau sephe at FreeBSD.org
Fri Jan 22 09:06:41 UTC 2016


Author: sephe
Date: Fri Jan 22 09:06:40 2016
New Revision: 294557
URL: https://svnweb.freebsd.org/changeset/base/294557

Log:
  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:
  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 Jan 22 08:29:23 2016	(r294556)
+++ head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c	Fri Jan 22 09:06:40 2016	(r294557)
@@ -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-all mailing list