summaryrefslogtreecommitdiffstats
path: root/freed-ora/current/f17/libata-replace-sata_settings-with-devslp_timing.patch
diff options
context:
space:
mode:
Diffstat (limited to 'freed-ora/current/f17/libata-replace-sata_settings-with-devslp_timing.patch')
-rw-r--r--freed-ora/current/f17/libata-replace-sata_settings-with-devslp_timing.patch131
1 files changed, 131 insertions, 0 deletions
diff --git a/freed-ora/current/f17/libata-replace-sata_settings-with-devslp_timing.patch b/freed-ora/current/f17/libata-replace-sata_settings-with-devslp_timing.patch
new file mode 100644
index 000000000..f620a20bd
--- /dev/null
+++ b/freed-ora/current/f17/libata-replace-sata_settings-with-devslp_timing.patch
@@ -0,0 +1,131 @@
+From 803739d25c2343da6d2f95eebdcbc08bf67097d4 Mon Sep 17 00:00:00 2001
+From: Shane Huang <shane.huang@amd.com>
+Date: Mon, 17 Dec 2012 23:18:59 +0800
+Subject: [PATCH] [libata] replace sata_settings with devslp_timing
+
+NCQ capability was used to check availability of SATA Settings page
+from Identify Device Data Log, which contains DevSlp timing variables.
+It does not work on some HDDs and leads to error messages.
+
+IDENTIFY word 78 bit 5(Hardware Feature Control) can't work either
+because it is only the sufficient condition of Identify Device data
+log, not the necessary condition.
+
+This patch replaced ata_device->sata_settings with ->devslp_timing
+to only save DevSlp timing variables(8 bytes), instead of the whole
+SATA Settings page(512 bytes).
+
+Addresses https://bugzilla.kernel.org/show_bug.cgi?id=51881
+
+Reported-by: Borislav Petkov <bp@alien8.de>
+Signed-off-by: Shane Huang <shane.huang@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+---
+ drivers/ata/libahci.c | 6 +++---
+ drivers/ata/libata-core.c | 22 +++++++++++++---------
+ include/linux/ata.h | 8 +++++---
+ include/linux/libata.h | 4 ++--
+ 4 files changed, 23 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index 320712a..6cd7805 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -1951,13 +1951,13 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
+ /* Use the nominal value 10 ms if the read MDAT is zero,
+ * the nominal value of DETO is 20 ms.
+ */
+- if (dev->sata_settings[ATA_LOG_DEVSLP_VALID] &
++ if (dev->devslp_timing[ATA_LOG_DEVSLP_VALID] &
+ ATA_LOG_DEVSLP_VALID_MASK) {
+- mdat = dev->sata_settings[ATA_LOG_DEVSLP_MDAT] &
++ mdat = dev->devslp_timing[ATA_LOG_DEVSLP_MDAT] &
+ ATA_LOG_DEVSLP_MDAT_MASK;
+ if (!mdat)
+ mdat = 10;
+- deto = dev->sata_settings[ATA_LOG_DEVSLP_DETO];
++ deto = dev->devslp_timing[ATA_LOG_DEVSLP_DETO];
+ if (!deto)
+ deto = 20;
+ } else {
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 9e8b99a..46cd3f4 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -2325,24 +2325,28 @@ int ata_dev_configure(struct ata_device *dev)
+ }
+ }
+
+- /* check and mark DevSlp capability */
+- if (ata_id_has_devslp(dev->id))
+- dev->flags |= ATA_DFLAG_DEVSLP;
+-
+- /* Obtain SATA Settings page from Identify Device Data Log,
+- * which contains DevSlp timing variables etc.
+- * Exclude old devices with ata_id_has_ncq()
++ /* Check and mark DevSlp capability. Get DevSlp timing variables
++ * from SATA Settings page of Identify Device Data Log.
+ */
+- if (ata_id_has_ncq(dev->id)) {
++ if (ata_id_has_devslp(dev->id)) {
++ u8 sata_setting[ATA_SECT_SIZE];
++ int i, j;
++
++ dev->flags |= ATA_DFLAG_DEVSLP;
+ err_mask = ata_read_log_page(dev,
+ ATA_LOG_SATA_ID_DEV_DATA,
+ ATA_LOG_SATA_SETTINGS,
+- dev->sata_settings,
++ sata_setting,
+ 1);
+ if (err_mask)
+ ata_dev_dbg(dev,
+ "failed to get Identify Device Data, Emask 0x%x\n",
+ err_mask);
++ else
++ for (i = 0; i < ATA_LOG_DEVSLP_SIZE; i++) {
++ j = ATA_LOG_DEVSLP_OFFSET + i;
++ dev->devslp_timing[i] = sata_setting[j];
++ }
+ }
+
+ dev->cdb_len = 16;
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+index 408da95..8f7a3d6 100644
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -297,10 +297,12 @@ enum {
+ ATA_LOG_SATA_NCQ = 0x10,
+ ATA_LOG_SATA_ID_DEV_DATA = 0x30,
+ ATA_LOG_SATA_SETTINGS = 0x08,
+- ATA_LOG_DEVSLP_MDAT = 0x30,
++ ATA_LOG_DEVSLP_OFFSET = 0x30,
++ ATA_LOG_DEVSLP_SIZE = 0x08,
++ ATA_LOG_DEVSLP_MDAT = 0x00,
+ ATA_LOG_DEVSLP_MDAT_MASK = 0x1F,
+- ATA_LOG_DEVSLP_DETO = 0x31,
+- ATA_LOG_DEVSLP_VALID = 0x37,
++ ATA_LOG_DEVSLP_DETO = 0x01,
++ ATA_LOG_DEVSLP_VALID = 0x07,
+ ATA_LOG_DEVSLP_VALID_MASK = 0x80,
+
+ /* READ/WRITE LONG (obsolete) */
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index 83ba0ab..649e5f8 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -652,8 +652,8 @@ struct ata_device {
+ u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
+ };
+
+- /* Identify Device Data Log (30h), SATA Settings (page 08h) */
+- u8 sata_settings[ATA_SECT_SIZE];
++ /* DEVSLP Timing Variables from Identify Device Data Log */
++ u8 devslp_timing[ATA_LOG_DEVSLP_SIZE];
+
+ /* error history */
+ int spdn_cnt;
+--
+1.7.7.6
+
OpenPOWER on IntegriCloud