git: 15910dc0bcb5 - main - adaspindown: check disk power mode before sending IDLE command
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Dec 2021 09:03:15 UTC
The branch main has been updated by avg:
URL: https://cgit.FreeBSD.org/src/commit/?id=15910dc0bcb526d575f8cc49efe1f98a5091c88e
commit 15910dc0bcb526d575f8cc49efe1f98a5091c88e
Author: Andriy Gapon <avg@FreeBSD.org>
AuthorDate: 2021-12-24 09:02:22 +0000
Commit: Andriy Gapon <avg@FreeBSD.org>
CommitDate: 2021-12-24 09:02:22 +0000
adaspindown: check disk power mode before sending IDLE command
If a disk is already in STANDBY mode, then setting IDLE mode can
actually spin it up.
Reviewed by: mav
MFC after: 4 weeks
Differential Revision: https://reviews.freebsd.org/D33588
---
sys/cam/ata/ata_da.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index c05a9fa49d1c..adfcc0ee1845 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -3611,6 +3611,7 @@ adaspindown(uint8_t cmd, int flags)
struct ada_softc *softc;
struct ccb_ataio local_ccb;
int error;
+ int mode;
CAM_PERIPH_FOREACH(periph, &adadriver) {
/* If we paniced with lock held - not recurse here. */
@@ -3626,6 +3627,52 @@ adaspindown(uint8_t cmd, int flags)
continue;
}
+ /*
+ * Additionally check if we would spin up the drive instead of
+ * spinning it down.
+ */
+ if (cmd == ATA_IDLE_IMMEDIATE) {
+ memset(&local_ccb, 0, sizeof(local_ccb));
+ xpt_setup_ccb(&local_ccb.ccb_h, periph->path,
+ CAM_PRIORITY_NORMAL);
+ local_ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
+
+ cam_fill_ataio(&local_ccb, 0, NULL, CAM_DIR_NONE,
+ 0, NULL, 0, ada_default_timeout * 1000);
+ ata_28bit_cmd(&local_ccb, ATA_CHECK_POWER_MODE,
+ 0, 0, 0);
+ local_ccb.cmd.flags |= CAM_ATAIO_NEEDRESULT;
+
+ error = cam_periph_runccb((union ccb *)&local_ccb,
+ adaerror, /*cam_flags*/0,
+ /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
+ softc->disk->d_devstat);
+ if (error != 0) {
+ xpt_print(periph->path,
+ "Failed to read current power mode\n");
+ } else {
+ mode = local_ccb.res.sector_count;
+#ifdef DIAGNOSTIC
+ if (bootverbose) {
+ xpt_print(periph->path,
+ "disk power mode 0x%02x\n", mode);
+ }
+#endif
+ switch (mode) {
+ case 0x00:
+ case 0x01:
+ if (bootverbose) {
+ xpt_print(periph->path,
+ "already spun down\n");
+ }
+ cam_periph_unlock(periph);
+ continue;
+ default:
+ break;
+ }
+ }
+ }
+
if (bootverbose)
xpt_print(periph->path, "spin-down\n");