Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 May 2017 15:20:38 +0000 (UTC)
From:      "Kenneth D. Merry" <ken@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r318139 - in stable/11: share/man/man4 sys/cam/scsi
Message-ID:  <201705101520.v4AFKc5r001623@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ken
Date: Wed May 10 15:20:38 2017
New Revision: 318139
URL: https://svnweb.freebsd.org/changeset/base/318139

Log:
  MFC r317775:
  
    Fix error recovery behavior in the pass(4) driver.
  
    After FreeBSD SVN revision 236814, the pass(4) driver changed from
    only doing error recovery when the CAM_PASS_ERR_RECOVER flag was
    set on a CCB to sometimes doing error recovery if the passed in
    retry count was non-zero.
  
    Error recovery would happen if two conditions were met:
  
    1.  The error recovery action was simply a retry.  (Which is most
        cases.)
    2.  The retry_count is non-zero. (Which happened a lot because of
        cut-and-pasted code.)
  
    This explains a bug I noticed in with camcontrol:
  
    # camcontrol tur da34 -v
    Unit is ready
    # camcontrol reset da34
    Reset of 1:172:0 was successful
  
    At this point, there should be a Unit Attention:
  
    # camcontrol tur da34 -v
    Unit is ready
  
    No Unit Attention.
  
    Try it again:
  
    # camcontrol reset da34
    Reset of 1:172:0 was successful
  
    Now set the retry_count to 0 for the TUR:
  
    # camcontrol tur da34 -v -C 0
    Unit is not ready
    (pass42:mps1:0:172:0): TEST UNIT READY. CDB: 00 00 00 00 00 00
    (pass42:mps1:0:172:0): CAM status: SCSI Status Error
    (pass42:mps1:0:172:0): SCSI status: Check Condition
    (pass42:mps1:0:172:0): SCSI sense: UNIT ATTENTION asc:29,2 (SCSI bus reset
    occurred)
    (pass42:mps1:0:172:0): Field Replaceable Unit: 2
  
    There is the unit attention. camcontrol(8) has a default
    retry_count of 1, in case someone sets the -E flag without
    setting -C.
  
    The CAM_PASS_ERR_RECOVER behavior was only broken with the
    CAMIOCOMMAND ioctl, which is the synchronous pass(4) API.  It has
    worked as intended (error recovery is only done when the flag
    is set) in the asynchronous API (CAMIOQUEUE ioctl).
  
    sys/cam/scsi/scsi_pass.c:
    	In passsendccb(), when calling cam_periph_runccb(), only
    	specify the error routine when CAM_PASS_ERR_RECOVER is set.
  
    share/man/man4/pass.4:
    	Document that CAM_PASS_ERR_RECOVER is needed to enable
    	error recovery.
  
  Reported by:	Terry Kennedy <TERRY@glaver.org>
  PR:		kern/218572
  Sponsored by:	Spectra Logic

Modified:
  stable/11/share/man/man4/pass.4
  stable/11/sys/cam/scsi/scsi_pass.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/share/man/man4/pass.4
==============================================================================
--- stable/11/share/man/man4/pass.4	Wed May 10 14:54:32 2017	(r318138)
+++ stable/11/share/man/man4/pass.4	Wed May 10 15:20:38 2017	(r318139)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 17, 2015
+.Dd May 3, 2017
 .Dt PASS 4
 .Os
 .Sh NAME
@@ -85,6 +85,11 @@ Some examples of xpt-only CCBs are XPT_S
 XPT_DEV_MATCH, XPT_RESET_BUS, XPT_SCAN_LUN, XPT_ENG_INQ, and XPT_ENG_EXEC.
 These CCB types have various attributes that make it illogical or
 impossible to service them through the passthrough interface.
+.Pp
+If the user would like the kernel to do error recovery, the
+.Dv CAM_PASS_ERR_RECOVER
+flag must be set on the CCB, and the retry_count field set to the number
+of retries.
 .It CAMGETPASSTHRU union ccb *
 This ioctl takes an XPT_GDEVLIST CCB, and returns the passthrough device
 corresponding to the device in question.
@@ -160,6 +165,11 @@ available for userland use with the
 and
 .Dv CAMIOGET
 ioctls and will be preserved across calls.
+.Pp
+If the user would like the kernel to do error recovery, the
+.Dv CAM_PASS_ERR_RECOVER
+flag must be set on the CCB, and the retry_count field set to the number
+of retries.
 .It CAMIOGET union ccb *
 Retrieve completed CAM CCBs queued via the
 .Dv CAMIOQUEUE

Modified: stable/11/sys/cam/scsi/scsi_pass.c
==============================================================================
--- stable/11/sys/cam/scsi/scsi_pass.c	Wed May 10 14:54:32 2017	(r318138)
+++ stable/11/sys/cam/scsi/scsi_pass.c	Wed May 10 15:20:38 2017	(r318139)
@@ -2213,9 +2213,9 @@ passsendccb(struct cam_periph *periph, u
 	 * that request.  Otherwise, it's up to the user to perform any
 	 * error recovery.
 	 */
-	cam_periph_runccb(ccb, passerror, /* cam_flags */ CAM_RETRY_SELTO,
-	    /* sense_flags */ ((ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ?
-	     SF_RETRY_UA : SF_NO_RECOVERY) | SF_NO_PRINT,
+	cam_periph_runccb(ccb, (ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ? 
+	    passerror : NULL, /* cam_flags */ CAM_RETRY_SELTO,
+	    /* sense_flags */ SF_RETRY_UA | SF_NO_PRINT,
 	    softc->device_stats);
 
 	cam_periph_unmapmem(ccb, &mapinfo);



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