[patch 18/26] [AGPGART] Fix serverworks TLB flush.

Greg KH
2005-12-13T08:25:19Z

[-- Attachment #1: fix-serverworks-tlb-flush..patch --]
[-- Type: text/plain, Size: 1640 bytes --]

-stable review patch. If anyone has any objections, please let us know.

------------------
From: Dave Jones <davej@redhat.com>

[AGPGART] Fix serverworks TLB flush.
Go back to what 2.4 kernels used to do here, as if this hits,
the kernel just hangs indefinitly.

Actually an improvement over 2.4 - we now break; out of the loop
instead of just printing messages on timeouts.

Signed-off-by: Dave Jones <davej@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
drivers/char/agp/sworks-agp.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

--- linux-2.6.14.3.orig/drivers/char/agp/sworks-agp.c
+++ linux-2.6.14.3/drivers/char/agp/sworks-agp.c
@@ -242,13 +242,27 @@ static int serverworks_fetch_size(void)
*/
static void serverworks_tlbflush(struct agp_memory *temp)
{
+ unsigned long timeout;
+
writeb(1, serverworks_private.registers+SVWRKS_POSTFLUSH);
- while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1)
+ timeout = jiffies + 3*HZ;
+ while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) {
cpu_relax();
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR PFX "TLB post flush took more than 3 seconds\n");
+ break;
+ }
+ }

writel(1, serverworks_private.registers+SVWRKS_DIRFLUSH);
- while(readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1)
+ timeout = jiffies + 3*HZ;
+ while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) {
cpu_relax();
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR PFX "TLB Dir flush took more than 3 seconds\n");
+ break;
+ }
+ }
}

static int serverworks_configure(void)

--