svn commit: r215173 - in stable/8: share/man/man4 sys/cam sys/cam/ata

Bruce Cran brucec at FreeBSD.org
Fri Nov 12 11:22:59 UTC 2010


Author: brucec
Date: Fri Nov 12 11:22:59 2010
New Revision: 215173
URL: http://svn.freebsd.org/changeset/base/215173

Log:
  MFC r214279:
  
  Mostly revert r203420, and add similar functionality into ada(4) since the
  existing code caused problems with some SCSI controllers.
  
  A new sysctl kern.cam.ada.spindown_shutdown has been added that controls
  whether or not to spin-down disks when shutting down.
  Spinning down the disks unloads/parks the heads - this is much better than
  removing power when the disk is still spinning because otherwise an
  Emergency Unload occurs which may cause damage to the actuator.
  
  The FLUSH_CACHE + STANDBY_IMMEDIATE commands are issued following the
  procedure documented in Fujitsu's MHW series product documentation under
  section 1.10.1, "Recommended power-off sequence".
  
  PR:	kern/140752
  Submitted by: olli

Modified:
  stable/8/share/man/man4/ada.4
  stable/8/sys/cam/ata/ata_da.c
  stable/8/sys/cam/cam_xpt.c
Directory Properties:
  stable/8/share/man/man4/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/share/man/man4/ada.4
==============================================================================
--- stable/8/share/man/man4/ada.4	Fri Nov 12 09:52:56 2010	(r215172)
+++ stable/8/share/man/man4/ada.4	Fri Nov 12 11:22:59 2010	(r215173)
@@ -118,6 +118,9 @@ This variable determines how long the
 driver will wait before timing out an outstanding command.
 The units for this value are seconds, and the default is currently 30
 seconds.
+.It kern.cam.ada.spindown_shutdown
+.Pp
+This variable determines whether to spin-down disks when shutting down.
 .El
 .Sh FILES
 .Bl -tag -width ".Pa /dev/ada*" -compact

Modified: stable/8/sys/cam/ata/ata_da.c
==============================================================================
--- stable/8/sys/cam/ata/ata_da.c	Fri Nov 12 09:52:56 2010	(r215172)
+++ stable/8/sys/cam/ata/ata_da.c	Fri Nov 12 11:22:59 2010	(r215173)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/eventhandler.h>
 #include <sys/malloc.h>
 #include <sys/cons.h>
+#include <sys/reboot.h>
 #include <geom/geom_disk.h>
 #endif /* _KERNEL */
 
@@ -79,7 +80,8 @@ typedef enum {
 	ADA_FLAG_CAN_TRIM	= 0x080,
 	ADA_FLAG_OPEN		= 0x100,
 	ADA_FLAG_SCTX_INIT	= 0x200,
-	ADA_FLAG_CAN_CFA        = 0x400
+	ADA_FLAG_CAN_CFA        = 0x400,
+	ADA_FLAG_CAN_POWERMGT   = 0x800
 } ada_flags;
 
 typedef enum {
@@ -180,6 +182,10 @@ static void		adashutdown(void *arg, int 
 #define	ADA_DEFAULT_SEND_ORDERED	1
 #endif
 
+#ifndef	ADA_DEFAULT_SPINDOWN_SHUTDOWN
+#define	ADA_DEFAULT_SPINDOWN_SHUTDOWN	1
+#endif
+
 /*
  * Most platforms map firmware geometry to actual, but some don't.  If
  * not overridden, default to nothing.
@@ -191,6 +197,7 @@ static void		adashutdown(void *arg, int 
 static int ada_retry_count = ADA_DEFAULT_RETRY;
 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT;
 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED;
+static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOWN_SHUTDOWN;
 
 SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0,
             "CAM Direct Access Disk driver");
@@ -203,6 +210,9 @@ TUNABLE_INT("kern.cam.ada.default_timeou
 SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW,
            &ada_send_ordered, 0, "Send Ordered Tags");
 TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered);
+SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RW,
+           &ada_spindown_shutdown, 0, "Spin down upon shutdown");
+TUNABLE_INT("kern.cam.ada.spindown_shutdown", &ada_spindown_shutdown);
 
 /*
  * ADA_ORDEREDTAG_INTERVAL determines how often, relative
@@ -665,6 +675,8 @@ adaregister(struct cam_periph *periph, v
 		softc->flags |= ADA_FLAG_CAN_48BIT;
 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
 		softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
+	if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
+		softc->flags |= ADA_FLAG_CAN_POWERMGT;
 	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
 	    cgd->inq_flags & SID_CmdQue)
 		softc->flags |= ADA_FLAG_CAN_NCQ;
@@ -1223,6 +1235,56 @@ adashutdown(void * arg, int howto)
 					 /*getcount_only*/0);
 		cam_periph_unlock(periph);
 	}
+
+	if (ada_spindown_shutdown == 0 ||
+	    (howto & (RB_HALT | RB_POWEROFF)) == 0)
+		return;
+
+	TAILQ_FOREACH(periph, &adadriver.units, unit_links) {
+		union ccb ccb;
+
+		/* If we paniced with lock held - not recurse here. */
+		if (cam_periph_owned(periph))
+			continue;
+		cam_periph_lock(periph);
+		softc = (struct ada_softc *)periph->softc;
+		/*
+		 * We only spin-down the drive if it is capable of it..
+		 */
+		if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
+			cam_periph_unlock(periph);
+			continue;
+		}
+
+		if (bootverbose)
+			xpt_print(periph->path, "spin-down\n");
+
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+
+		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
+		cam_fill_ataio(&ccb.ataio,
+				    1,
+				    adadone,
+				    CAM_DIR_NONE,
+				    0,
+				    NULL,
+				    0,
+				    ada_default_timeout*1000);
+
+		ata_28bit_cmd(&ccb.ataio, ATA_STANDBY_IMMEDIATE, 0, 0, 0);
+		xpt_polled_action(&ccb);
+
+		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+			xpt_print(periph->path, "Spin-down disk failed\n");
+
+		if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
+			cam_release_devq(ccb.ccb_h.path,
+					 /*relsim_flags*/0,
+					 /*reduction*/0,
+					 /*timeout*/0,
+					 /*getcount_only*/0);
+		cam_periph_unlock(periph);
+	}
 }
 
 #endif /* _KERNEL */

Modified: stable/8/sys/cam/cam_xpt.c
==============================================================================
--- stable/8/sys/cam/cam_xpt.c	Fri Nov 12 09:52:56 2010	(r215172)
+++ stable/8/sys/cam/cam_xpt.c	Fri Nov 12 11:22:59 2010	(r215173)
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/time.h>
 #include <sys/conf.h>
 #include <sys/fcntl.h>
-#include <sys/md5.h>
+#include <sys/reboot.h>
 #include <sys/interrupt.h>
 #include <sys/sbuf.h>
 #include <sys/taskqueue.h>


More information about the svn-src-stable-8 mailing list