rpms/kernel/F-8 linux-2.6-libata-it821x-improve-emulation-handling.patch, NONE, 1.1 kernel.spec, 1.387, 1.388

Chuck Ebbert (cebbert) fedora-extras-commits at redhat.com
Tue Mar 18 16:04:30 UTC 2008


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv10364

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-libata-it821x-improve-emulation-handling.patch 
Log Message:
* Tue Mar 18 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.24.3-42
- Fix broken it821x adapter drive detection (#434864)


linux-2.6-libata-it821x-improve-emulation-handling.patch:

--- NEW FILE linux-2.6-libata-it821x-improve-emulation-handling.patch ---
From: Alan Cox <alan at lxorguk.ukuu.org.uk>
Date: Thu, 25 Oct 2007 13:21:16 +0000 (+0100)
Subject: libata/pata_it821x: Improve handling of poorly compatible emulations
X-Git-Tag: v2.6.25-rc1~1233^2~22
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=c5038fc05d4aa4ae0671776199459690e4c973cb

libata/pata_it821x: Improve handling of poorly compatible emulations

Some it821x RAID firmwares return 0 for the err return off both devices.
A similar issue occurs with the slave returning 0 not 1 if you plug a
gigabyte sata ramdisk into a controller that fakes two SATA ports as
master/slave on an SFF channel.

The patch does the following

- Allow the 'failed diagnostics' case on both master and slave
- Move the HORKAGE_DIAGNOSTIC check after ->dev_config

This second change also allows IT821x to fix up a problem where we report
drive diagnostic failures when in fact the drive is fine but the
microcontroller firmware doesn't appear to get it right. IT821x clears
the flag again to avoid giving the user bogus warnings about their disk.

The other IT821x change is a bit ugly, we slightly abuse the cable type
hook to fiddle with the identify data for the devices. We could add a new
hook for this but as we have only one offender and no more seeming likely
it seems better to keep libata-core clean.

Please let this sit in -mm briefly, just in case the relaxed checking
breaks some other emulated interface.

Signed-off-by: Alan Cox <alan at redhat.com>
Signed-off-by: Jeff Garzik <jgarzik at redhat.com>
---

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ee72994..627703c 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -950,8 +950,8 @@ unsigned int ata_dev_try_classify(struct ata_device *dev, int present,
 	if (r_err)
 		*r_err = err;
 
-	/* see if device passed diags: if master then continue and warn later */
-	if (err == 0 && dev->devno == 0)
+	/* see if device passed diags: continue and warn later */
+	if (err == 0)
 		/* diagnostic fail : do nothing _YET_ */
 		dev->horkage |= ATA_HORKAGE_DIAGNOSTIC;
 	else if (err == 1)
@@ -2262,19 +2262,8 @@ int ata_dev_configure(struct ata_device *dev)
 			dev->flags |= ATA_DFLAG_DIPM;
 	}
 
-	if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
-		/* Let the user know. We don't want to disallow opens for
-		   rescue purposes, or in case the vendor is just a blithering
-		   idiot */
-		if (print_info) {
-			ata_dev_printk(dev, KERN_WARNING,
-"Drive reports diagnostics failure. This may indicate a drive\n");
-			ata_dev_printk(dev, KERN_WARNING,
-"fault or invalid emulation. Contact drive vendor for information.\n");
-		}
-	}
-
-	/* limit bridge transfers to udma5, 200 sectors */
+	/* Limit PATA drive on SATA cable bridge transfers to udma5,
+	   200 sectors */
 	if (ata_dev_knobble(dev)) {
 		if (ata_msg_drv(ap) && print_info)
 			ata_dev_printk(dev, KERN_INFO,
@@ -2303,6 +2292,21 @@ int ata_dev_configure(struct ata_device *dev)
 	if (ap->ops->dev_config)
 		ap->ops->dev_config(dev);
 
+	if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
+		/* Let the user know. We don't want to disallow opens for
+		   rescue purposes, or in case the vendor is just a blithering
+		   idiot. Do this after the dev_config call as some controllers
+		   with buggy firmware may want to avoid reporting false device
+		   bugs */
+
+		if (print_info) {
+			ata_dev_printk(dev, KERN_WARNING,
+"Drive reports diagnostics failure. This may indicate a drive\n");
+			ata_dev_printk(dev, KERN_WARNING,
+"fault or invalid emulation. Contact drive vendor for information.\n");
+		}
+	}
+
 	if (ata_msg_probe(ap))
 		ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
 			__FUNCTION__, ata_chk_status(ap));
@@ -3066,7 +3070,7 @@ static int ata_dev_set_mode(struct ata_device *dev)
 
 	/* Early MWDMA devices do DMA but don't allow DMA mode setting.
 	   Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */
-	if (dev->xfer_shift == ATA_SHIFT_MWDMA && 
+	if (dev->xfer_shift == ATA_SHIFT_MWDMA &&
 	    dev->dma_mode == XFER_MW_DMA_0 &&
 	    (dev->id[63] >> 8) & 1)
 		err_mask &= ~AC_ERR_DEV;
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index ca9aae0..109ddd4 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -430,7 +430,7 @@ static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc)
 			return ata_qc_issue_prot(qc);
 	}
 	printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
-	return AC_ERR_INVALID;
+	return AC_ERR_DEV;
 }
 
 /**
@@ -516,6 +516,37 @@ static void it821x_dev_config(struct ata_device *adev)
 			printk("(%dK stripe)", adev->id[146]);
 		printk(".\n");
 	}
+	/* This is a controller firmware triggered funny, don't
+	   report the drive faulty! */
+	adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC;
+}
+
+/**
+ *	it821x_ident_hack	-	Hack identify data up
+ *	@ap: Port
+ *
+ *	Walk the devices on this firmware driven port and slightly
+ *	mash the identify data to stop us and common tools trying to
+ *	use features not firmware supported. The firmware itself does
+ *	some masking (eg SMART) but not enough.
+ *
+ *	This is a bit of an abuse of the cable method, but it is the
+ *	only method called at the right time. We could modify the libata
+ *	core specifically for ident hacking but while we have one offender
+ *	it seems better to keep the fallout localised.
+ */
+
+static int it821x_ident_hack(struct ata_port *ap)
+{
+	struct ata_device *adev;
+	ata_link_for_each_dev(adev, &ap->link) {
+		if (ata_dev_enabled(adev)) {
+			adev->id[84] &= ~(1 << 6);	/* No FUA */
+			adev->id[85] &= ~(1 << 10);	/* No HPA */
+			adev->id[76] = 0;		/* No NCQ/AN etc */
+		}
+	}
+	return ata_cable_unknown(ap);
 }
 
 
@@ -634,7 +665,7 @@ static struct ata_port_operations it821x_smart_port_ops = {
 	.thaw		= ata_bmdma_thaw,
 	.error_handler	= ata_bmdma_error_handler,
 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
-	.cable_detect	= ata_cable_unknown,
+	.cable_detect	= it821x_ident_hack,
 
 	.bmdma_setup 	= ata_bmdma_setup,
 	.bmdma_start 	= ata_bmdma_start,


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-8/kernel.spec,v
retrieving revision 1.387
retrieving revision 1.388
diff -u -r1.387 -r1.388
--- kernel.spec	18 Mar 2008 15:19:36 -0000	1.387
+++ kernel.spec	18 Mar 2008 16:03:39 -0000	1.388
@@ -658,6 +658,7 @@
 Patch660: linux-2.6-libata-ali-atapi-dma.patch
 Patch670: linux-2.6-ata-quirk.patch
 Patch671: linux-2.6-libata-fix-hpt-svw-dma-masking.patch
+Patch672: linux-2.6-libata-it821x-improve-emulation-handling.patch
 
 Patch680: linux-2.6-wireless.patch
 Patch681: linux-2.6-wireless-pending.patch
@@ -1229,6 +1230,8 @@
 ApplyPatch linux-2.6-ata-quirk.patch
 # actually mask the intended DMA modes from the blacklist
 ApplyPatch linux-2.6-libata-fix-hpt-svw-dma-masking.patch
+# fix some broken it821x adapters that have broken emulation
+ApplyPatch linux-2.6-libata-it821x-improve-emulation-handling.patch
 
 # wireless patches headed for 2.6.25
 ApplyPatch linux-2.6-wireless.patch
@@ -1917,6 +1920,9 @@
 
 
 %changelog
+* Tue Mar 18 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.24.3-42
+- Fix broken it821x adapter drive detection (#434864)
+
 * Tue Mar 18 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.24.3-41
 - Make the i686 kernel work on compatible processors, take 2. (#435609)
 




More information about the fedora-extras-commits mailing list