Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Feb 2015 09:14:23 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r278441 - in stable/9/sys/cam: . scsi
Message-ID:  <201502090914.t199ENJV023644@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Feb  9 09:14:22 2015
New Revision: 278441
URL: https://svnweb.freebsd.org/changeset/base/278441

Log:
  MFC r278111: Retry indefinitely on SCSI BUSY status from VMware disks and CDs.
  
  VMware returns BUSY status when storage has transient connectivity issues.
  It is often better to wait and let VM admin fix the problem then crash.

Modified:
  stable/9/sys/cam/cam.h
  stable/9/sys/cam/cam_periph.c
  stable/9/sys/cam/scsi/scsi_cd.c
  stable/9/sys/cam/scsi/scsi_da.c
Directory Properties:
  stable/9/   (props changed)
  stable/9/sys/   (props changed)

Modified: stable/9/sys/cam/cam.h
==============================================================================
--- stable/9/sys/cam/cam.h	Mon Feb  9 09:10:46 2015	(r278440)
+++ stable/9/sys/cam/cam.h	Mon Feb  9 09:14:22 2015	(r278441)
@@ -115,7 +115,8 @@ enum {
 	SF_QUIET_IR		= 0x04,	/* Be quiet about Illegal Request reponses */
 	SF_PRINT_ALWAYS		= 0x08,	/* Always print error status. */
 	SF_NO_RECOVERY		= 0x10,	/* Don't do active error recovery. */
-	SF_NO_RETRY		= 0x20	/* Don't do any retries. */
+	SF_NO_RETRY		= 0x20,	/* Don't do any retries. */
+	SF_RETRY_BUSY		= 0x40	/* Retry BUSY status. */
 };
 
 /* CAM  Status field values */

Modified: stable/9/sys/cam/cam_periph.c
==============================================================================
--- stable/9/sys/cam/cam_periph.c	Mon Feb  9 09:10:46 2015	(r278440)
+++ stable/9/sys/cam/cam_periph.c	Mon Feb  9 09:14:22 2015	(r278441)
@@ -1366,8 +1366,8 @@ camperiphscsistatuserror(union ccb *ccb,
 		 * Restart the queue after either another
 		 * command completes or a 1 second timeout.
 		 */
-	 	if (ccb->ccb_h.retry_count > 0) {
-	 		ccb->ccb_h.retry_count--;
+		if ((sense_flags & SF_RETRY_BUSY) != 0 ||
+		    (ccb->ccb_h.retry_count--) > 0) {
 			error = ERESTART;
 			*relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT
 				      | RELSIM_RELEASE_AFTER_CMDCMPLT;

Modified: stable/9/sys/cam/scsi/scsi_cd.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_cd.c	Mon Feb  9 09:10:46 2015	(r278440)
+++ stable/9/sys/cam/scsi/scsi_cd.c	Mon Feb  9 09:14:22 2015	(r278441)
@@ -89,7 +89,8 @@ typedef enum {
 	CD_Q_BCD_TRACKS		= 0x02,
 	CD_Q_NO_CHANGER		= 0x04,
 	CD_Q_CHANGER		= 0x08,
-	CD_Q_10_BYTE_ONLY	= 0x10
+	CD_Q_10_BYTE_ONLY	= 0x10,
+	CD_Q_RETRY_BUSY		= 0x40
 } cd_quirks;
 
 #define CD_Q_BIT_STRING		\
@@ -98,7 +99,8 @@ typedef enum {
 	"\002BCD_TRACKS"	\
 	"\003NO_CHANGER"	\
 	"\004CHANGER"		\
-	"\00510_BYTE_ONLY"
+	"\00510_BYTE_ONLY"	\
+	"\007RETRY_BUSY"
 
 typedef enum {
 	CD_FLAG_INVALID		= 0x0001,
@@ -224,6 +226,14 @@ static struct cd_quirk_entry cd_quirk_ta
 	{
 		{ T_CDROM, SIP_MEDIA_REMOVABLE, "CHINON", "CD-ROM CDS-535","*"},
 		/* quirks */ CD_Q_BCD_TRACKS
+	},
+	{
+		/*
+		 * VMware returns BUSY status when storage has transient
+		 * connectivity problems, so better wait.
+		 */
+		{T_CDROM, SIP_MEDIA_REMOVABLE, "NECVMWar", "VMware IDE CDR10", "*"},
+		/*quirks*/ CD_Q_RETRY_BUSY
 	}
 };
 
@@ -3275,6 +3285,9 @@ cderror(union ccb *ccb, u_int32_t cam_fl
 	 * don't treat UAs as errors.
 	 */
 	sense_flags |= SF_RETRY_UA;
+
+	if (softc->quirks & CD_Q_RETRY_BUSY)
+		sense_flags |= SF_RETRY_BUSY;
 	return (cam_periph_error(ccb, cam_flags, sense_flags, 
 				 &softc->saved_ccb));
 }

Modified: stable/9/sys/cam/scsi/scsi_da.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_da.c	Mon Feb  9 09:10:46 2015	(r278440)
+++ stable/9/sys/cam/scsi/scsi_da.c	Mon Feb  9 09:14:22 2015	(r278441)
@@ -101,7 +101,8 @@ typedef enum {
 	DA_Q_NO_PREVENT		= 0x04,
 	DA_Q_4K			= 0x08,
 	DA_Q_NO_RC16		= 0x10,
-	DA_Q_NO_UNMAP		= 0x20
+	DA_Q_NO_UNMAP		= 0x20,
+	DA_Q_RETRY_BUSY		= 0x40
 } da_quirks;
 
 #define DA_Q_BIT_STRING		\
@@ -110,7 +111,9 @@ typedef enum {
 	"\002NO_6_BYTE"		\
 	"\003NO_PREVENT"	\
 	"\0044K"		\
-	"\005NO_RC16"
+	"\005NO_RC16"		\
+	"\006NO_UNMAP"		\
+	"\007RETRY_BUSY"
 
 typedef enum {
 	DA_CCB_PROBE_RC		= 0x01,
@@ -360,6 +363,14 @@ static struct da_quirk_entry da_quirk_ta
 		{T_DIRECT, SIP_MEDIA_FIXED, "STEC", "*", "*"},
 		/*quirks*/ DA_Q_NO_UNMAP
 	},
+	{
+		/*
+		 * VMware returns BUSY status when storage has transient
+		 * connectivity problems, so better wait.
+		 */
+		{T_DIRECT, SIP_MEDIA_FIXED, "VMware", "Virtual disk", "*"},
+		/*quirks*/ DA_Q_RETRY_BUSY
+	},
 	/* USB mass storage devices supported by umass(4) */
 	{
 		/*
@@ -3603,6 +3614,9 @@ daerror(union ccb *ccb, u_int32_t cam_fl
 	 * don't treat UAs as errors.
 	 */
 	sense_flags |= SF_RETRY_UA;
+
+	if (softc->quirks & DA_Q_RETRY_BUSY)
+		sense_flags |= SF_RETRY_BUSY;
 	return(cam_periph_error(ccb, cam_flags, sense_flags,
 				&softc->saved_ccb));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502090914.t199ENJV023644>