udisks2/0001-udisksata-Move-the-low-level-PM-state-call.patch

130 lines
4.4 KiB
Diff

From a7d9b97c9460f65a726b727e9eaee31ea5016538 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Wed, 5 Jan 2022 20:17:55 +0100
Subject: [PATCH] udisksata: Move the low-level PM state call
(cherry picked from commit 4588dbeecd23c17d1cb7f7fa60afd56702acd455)
---
doc/udisks2-sections.txt.daemon.sections.in | 2 +
src/udisksata.c | 62 +++++++++++++++++++++
src/udisksata.h | 13 +++++
3 files changed, 77 insertions(+)
diff --git a/doc/udisks2-sections.txt.daemon.sections.in b/doc/udisks2-sections.txt.daemon.sections.in
index 12935c4d..9a2bfa03 100644
--- a/doc/udisks2-sections.txt.daemon.sections.in
+++ b/doc/udisks2-sections.txt.daemon.sections.in
@@ -270,6 +270,8 @@ UDisksAtaCommandProtocol
UDisksAtaCommandInput
UDisksAtaCommandOutput
udisks_ata_send_command_sync
+udisks_ata_get_pm_state
+UDISKS_ATA_PM_STATE_AWAKE
</SECTION>
<SECTION>
diff --git a/src/udisksata.c b/src/udisksata.c
index 9491af5e..e6da8c35 100644
--- a/src/udisksata.c
+++ b/src/udisksata.c
@@ -308,3 +308,65 @@ udisks_ata_send_command_sync (gint fd,
out:
return ret;
}
+
+/**
+ * udisks_ata_get_pm_state:
+ * @device: ATA drive block device path.
+ * @error: Return location for error.
+ * @pm_state: Return location for the current power state value.
+ *
+ * Get the current power mode state.
+ *
+ * The format of @pm_state is the result obtained from sending the
+ * ATA command `CHECK POWER MODE` to the drive.
+ *
+ * Known values include:
+ * - `0x00`: Device is in PM2: Standby state.
+ * - `0x40`: Device is in the PM0: Active state, the NV Cache power mode is enabled, and the spindle is spun down or spinning down.
+ * - `0x41`: Device is in the PM0: Active state, the NV Cache power mode is enabled, and the spindle is spun up or spinning up.
+ * - `0x80`: Device is in PM1: Idle state.
+ * - `0xff`: Device is in the PM0: Active state or PM1: Idle State.
+ *
+ * Typically user interfaces will report "Drive is spun down" if @pm_state is
+ * 0x00 and "Drive is spun up" otherwise.
+ *
+ * Returns: %TRUE if the operation succeeded, %FALSE if @error is set.
+ */
+gboolean
+udisks_ata_get_pm_state (const gchar *device, GError **error, guchar *count)
+{
+ int fd;
+ gboolean rc = FALSE;
+ /* ATA8: 7.8 CHECK POWER MODE - E5h, Non-Data */
+ UDisksAtaCommandInput input = {.command = 0xe5};
+ UDisksAtaCommandOutput output = {0};
+
+ g_warn_if_fail (device != NULL);
+
+ fd = open (device, O_RDONLY|O_NONBLOCK);
+ if (fd == -1)
+ {
+ g_set_error (error, UDISKS_ERROR, UDISKS_ERROR_FAILED,
+ "Error opening device file %s while getting PM state: %m",
+ device);
+ goto out;
+ }
+
+ if (!udisks_ata_send_command_sync (fd,
+ -1,
+ UDISKS_ATA_COMMAND_PROTOCOL_NONE,
+ &input,
+ &output,
+ error))
+ {
+ g_prefix_error (error, "Error sending ATA command CHECK POWER MODE: ");
+ goto out;
+ }
+ /* count field is used for the state, see ATA8: table 102 */
+ *count = output.count;
+ rc = TRUE;
+ out:
+ if (fd != -1)
+ close (fd);
+ return rc;
+}
diff --git a/src/udisksata.h b/src/udisksata.h
index 1d4918f1..d652f3ab 100644
--- a/src/udisksata.h
+++ b/src/udisksata.h
@@ -73,6 +73,16 @@ struct _UDisksAtaCommandOutput
guchar *buffer;
};
+/**
+ * UDISKS_ATA_PM_STATE_AWAKE:
+ * @pm_state: The power state value.
+ *
+ * Decodes the power state value as returned by #udisks_ata_get_pm_state.
+ *
+ * Returns: %TRUE when the drive is awake, %FALSE when sleeping.
+*/
+#define UDISKS_ATA_PM_STATE_AWAKE(pm_state) (pm_state >= 0x41)
+
gboolean udisks_ata_send_command_sync (gint fd,
gint timeout_msec,
UDisksAtaCommandProtocol protocol,
@@ -80,6 +90,9 @@ gboolean udisks_ata_send_command_sync (gint fd,
UDisksAtaCommandOutput *output,
GError **error);
+gboolean udisks_ata_get_pm_state (const gchar *device,
+ GError **error,
+ guchar *count);
G_END_DECLS
--
2.38.1