From 2edce226fdb88b81e12f914f73263fef2bf1d4e5 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 6 Jul 2007 02:39:54 -0700 Subject: [PATCH] --- yaml --- r: 58225 b: refs/heads/master c: 41a5311465b9de6d18e78b733a2c6e1b33e89be8 h: refs/heads/master i: 58223: 3b3e2bbf727c6b52d53222d2ca0c2aaa0703ac9a v: v3 --- [refs] | 2 +- trunk/drivers/pnp/quirks.c | 63 ++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index ac696cfe83d5..e56fde634d43 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d57d973101e87b2e30ccfa899fe36c4b2e32d217 +refs/heads/master: 41a5311465b9de6d18e78b733a2c6e1b33e89be8 diff --git a/trunk/drivers/pnp/quirks.c b/trunk/drivers/pnp/quirks.c index 967a8e22b2da..7c3236690cc3 100644 --- a/trunk/drivers/pnp/quirks.c +++ b/trunk/drivers/pnp/quirks.c @@ -136,11 +136,10 @@ static int quirk_smc_fir_enabled(struct pnp_dev *dev) static void quirk_smc_enable(struct pnp_dev *dev) { - /* - * If the BIOS left the device disabled, or it is enabled and - * responding correctly, we're in good shape. - */ - if (!dev->active || quirk_smc_fir_enabled(dev)) + struct resource fir, sir, irq; + + pnp_activate_dev(dev); + if (quirk_smc_fir_enabled(dev)) return; /* @@ -152,16 +151,62 @@ static void quirk_smc_enable(struct pnp_dev *dev) * this. Fortunately, they do fix things up if we auto-configure * the device using its _PRS and _SRS methods. */ - dev_err(&dev->dev, "%s device not responding, auto-configuring " - "resources\n", dev->id->id); + dev_err(&dev->dev, "%s not responding at SIR 0x%lx, FIR 0x%lx; " + "auto-configuring\n", dev->id->id, + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); pnp_disable_dev(dev); pnp_init_resource_table(&dev->res); pnp_auto_config_dev(dev); pnp_activate_dev(dev); + if (quirk_smc_fir_enabled(dev)) { + dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n", + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); + return; + } + + /* + * The Toshiba Portege 4000 _CRS reports the FIR region first, + * followed by the SIR region. The BIOS will configure the bridge, + * but only if we call _SRS with SIR first, then FIR. It also + * reports the IRQ as active high, when it is really active low. + */ + dev_err(&dev->dev, "not responding at SIR 0x%lx, FIR 0x%lx; " + "swapping SIR/FIR and reconfiguring\n", + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); + + /* + * Clear IORESOURCE_AUTO so pnp_activate_dev() doesn't reassign + * these resources any more. + */ + fir = dev->res.port_resource[0]; + sir = dev->res.port_resource[1]; + fir.flags &= ~IORESOURCE_AUTO; + sir.flags &= ~IORESOURCE_AUTO; + + irq = dev->res.irq_resource[0]; + irq.flags &= ~IORESOURCE_AUTO; + irq.flags &= ~IORESOURCE_BITS; + irq.flags |= IORESOURCE_IRQ_LOWEDGE; + + pnp_disable_dev(dev); + dev->res.port_resource[0] = sir; + dev->res.port_resource[1] = fir; + dev->res.irq_resource[0] = irq; + pnp_activate_dev(dev); + + if (quirk_smc_fir_enabled(dev)) { + dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n", + (unsigned long) pnp_port_start(dev, 0), + (unsigned long) pnp_port_start(dev, 1)); + return; + } - if (!quirk_smc_fir_enabled(dev)) - dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\"\n"); + dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\" and " + "email bjorn.helgaas@hp.com\n"); }