On Saturday 30 June 2007, Bjorn Helgaas wrote: > [patch] PNP SMCf010 quirk: work around Toshiba Portege 4000 ACPI issues > > When we enable the SMCf010 IR device, the Toshiba Portege 4000 BIOS claims > the device is working, but it really isn't configured correctly. The BIOS > *will* configure it, but only if we call _SRS after (1) reversing the order > of the SIR and FIR I/O port regions and (2) changing the IRQ from > active-high to active-low. > > This patch fixes the 2.6.22 regression: > "no irda0 interface (2.6.21 was OK), smsc does not find chip" > does not work, sorry. [ 958.107142] ACPI: bus type pnp registered [ 958.125652] pnp: Device 00:0a activated. [ 958.125710] 00:0a: SMCf010 not responding at SIR 0x2e800000100, FIR 0x2e8def5a6d4; auto-configuring [ 958.127243] pnp: Device 00:0a disabled. [ 958.132808] pnp: Device 00:0a activated. [ 958.132837] 00:0a: not responding at SIR 0x2e800000100, FIR 0xded782bc000002e8; swapping SIR/FIR and reconfiguring [ 958.134350] pnp: Device 00:0a disabled. [ 958.140926] pnp: Device 00:0a activated. [ 958.140954] 00:0a: responds at SIR 0x100000002e8, FIR 0xded782bc000002e8 [ 958.148707] pnp: PnP ACPI: found 12 devices and loading smsc_ircc2 [ 524.423280] pnp: Device 00:0a activated. [ 524.426614] smsc_ircc_present(), addr 0x0100 - no device found! [ 524.426614] pnp: Device 00:0a disabled. as already mentioned, port 100 cannot work: 0100-013f : pcmcia_socket0 {pts/1}% sudo cat /sys/class/pcmcia_socket/pcmcia_socket0/available_resources_io 0x00000100 - 0x000003af 0x000003e0 - 0x000004ff 0x00000820 - 0x000008ff 0x00000a00 - 0x00000aff 0x00000c00 - 0x00000cf7 additinally I get these warnings during compile (and output is bogus): /home/bor/src/linux-git/drivers/pnp/quirks.c: In function ‘quirk_smc_enable’: /home/bor/src/linux-git/drivers/pnp/quirks.c:154: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 5 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:154: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 6 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:163: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 4 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:163: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 5 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:174: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 4 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:174: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 5 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:199: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 4 has type ‘resource_size_t’ /home/bor/src/linux-git/drivers/pnp/quirks.c:199: warning: format ‘%llx’ expects type ‘long long unsigned int’, but argument 5 has type ‘resource_size_t’ -andrey > I tested this on a Portege 4000. The smsc-ircc2 driver correctly detects > the device, and "irattach irda0 -s && irdadump" shows transmitted and > received packets. > > Signed-off-by: Bjorn Helgaas > > Index: w/drivers/pnp/quirks.c > =================================================================== > --- w.orig/drivers/pnp/quirks.c 2007-06-27 20:07:45.000000000 -0600 > +++ w/drivers/pnp/quirks.c 2007-06-29 19:28:02.000000000 -0600 > @@ -136,11 +136,10 @@ > > 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,58 @@ > * 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%llx, FIR 0x%llx; " > + "auto-configuring\n", dev->id->id, > + pnp_port_start(dev, 0), 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%llx, FIR 0x%llx\n", > + pnp_port_start(dev, 0), 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%llx, FIR 0x%llx; " > + "swapping SIR/FIR and reconfiguring\n", > + pnp_port_start(dev, 0), 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%llx, FIR 0x%llx\n", > + pnp_port_start(dev, 0), 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"); > }