[kernel/f18] Fix libata settings bug (rhbz 902523)

Josh Boyer jwboyer at fedoraproject.org
Tue Jan 22 18:41:38 UTC 2013


commit 56666ff9ae1ef1ac4119177d0eaab5051e634cb0
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Tue Jan 22 13:40:20 2013 -0500

    Fix libata settings bug (rhbz 902523)

 kernel.spec                                        |   11 ++-
 ...-replace-sata_settings-with-devslp_timing.patch |  131 ++++++++++++++++++++
 2 files changed, 141 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index d8d3bf0..9fce006 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 201
+%global baserelease 202
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -777,6 +777,9 @@ Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch
 #rhbz 886946
 Patch21234: iwlegacy-fix-IBSS-cleanup.patch
 
+#rhbz 902523
+Patch21236: libata-replace-sata_settings-with-devslp_timing.patch
+
 # END OF PATCH DEFINITIONS
 
 %endif
@@ -1485,6 +1488,9 @@ ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch
 #rhbz 886948
 ApplyPatch iwlegacy-fix-IBSS-cleanup.patch
 
+#rhbz 902523
+ApplyPatch libata-replace-sata_settings-with-devslp_timing.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2341,6 +2347,9 @@ fi
 #                 ||----w |
 #                 ||     ||
 %changelog
+* Tue Jan 22 2013 Josh Boyer <jwboyer at redhat.com>
+- Fix libata settings bug (rhbz 902523)
+
 * Mon Jan 21 2013 Josh Boyer <jwboyer at redhat.com> - 3.7.4-201
 - Linux v3.7.4
 
diff --git a/libata-replace-sata_settings-with-devslp_timing.patch b/libata-replace-sata_settings-with-devslp_timing.patch
new file mode 100644
index 0000000..f620a20
--- /dev/null
+++ b/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 at 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 at alien8.de>
+Signed-off-by: Shane Huang <shane.huang at amd.com>
+Cc: stable at vger.kernel.org
+Signed-off-by: Jeff Garzik <jgarzik at 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
+


More information about the scm-commits mailing list