Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3798

kernel-2.6.18-194.11.1.el5.src.rpm

From: Pete Zaitcev <zaitcev@redhat.com>
Date: Mon, 23 Feb 2009 23:26:13 -0700
Subject: [usb] sb600/sb700: workaround for hang
Message-id: 20090223232613.17545d2c.zaitcev@redhat.com
O-Subject: [RHEL 5.4 Patch] Workaround for USB hang in SB600/SB700
Bugzilla: 471972
RH-Acked-by: Jon Masters <jcm@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Peter Martuccelli <peterm@redhat.com>
RH-Acked-by: Brian Maly <bmaly@redhat.com>

This patch addresses bz#471972. AMD requested us to apply a workaround
for SB600 and early SB700 for an issue that makes EHCI to hang. It is
upstream, and the backport (by Evan McNabb) is more direct for RHEL 5
than what I've done for RHEL 4. Basically, a copy-paste of these two
commits:

b09bc6cbae4dd3a2d35722668ef2c502a7b8b093
0a99e8ac430a27825bd055719765fd0d65cd797f

I think the patch is quite safe. Why, I have an SB600 laptop and
it seems to have no ill effects. Other chips should not be affected
at all.

Please ack.

-- Pete

diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index f1e0315..e7bd8ef 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -68,6 +68,8 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
+	struct pci_dev		*p_smbus;
+	u8			rev;
 	u32			temp;
 	int			retval;
 
@@ -139,6 +141,28 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 			break;
 		}
 		break;
+	case PCI_VENDOR_ID_ATI:
+		/* SB600 and old version of SB700 have a bug in EHCI controller,
+		 * which causes usb devices lose response in some cases.
+		 */
+		if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
+			p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
+						 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
+						 NULL);
+			if (!p_smbus)
+				break;
+			rev = p_smbus->revision;
+			if ((pdev->device == 0x4386) || (rev == 0x3a)
+			    || (rev == 0x3b)) {
+				u8 tmp;
+				ehci_info(ehci, "applying AMD SB600/SB700 USB "
+					"freeze workaround\n");
+				pci_read_config_byte(pdev, 0x53, &tmp);
+				pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
+			}
+			pci_dev_put(p_smbus);
+		}
+		break;
 	}
 
 	if (ehci_is_TDI(ehci))