On Tue, Mar 23, 2010 at 12:28:00AM +0100, Dominik Brodowski wrote: > On Mon, Mar 22, 2010 at 04:11:33PM -0700, Bjorn Helgaas wrote: > > > (1) The root PCI bus has _CRS I/O 0000-0cf7; 0d00-ffff "produced"; > > > > > > the (transparent) PCI-PCI bridge offers, as bus resources, to > > > downstream users 0x4000-0x4fff plus everything else because of > > > subtractive decoding; > > > > > > there is a yenta-style PCI-CardBus/PCMCIA bridge below this > > > PCI-PCI bridge. > > > > > > (2) There are some I/O ports which react rather unfriendly to being read or > > > written. Let's assume they're at 0x100-0x10f; and let's also assume that > > > the BIOS writers forgot to mention them at all in the ACPI _CRS > > > settings; no other part of the kernel knows about it. > > > > > > 0000-0cf7 : PCI Bus 0000:00 > > > ... > > > 00f0-00ff : fpu > > > 0170-0177 : 0000:00:1f.2 > > > > > > > > > (3) A PCMCIA card is inserted. It needs an I/O port resource of size 8. The > > > PCMCIA subsystem looks in its own resource database which I/O ports it > > > may use; there, it finds not only 0x4000-0x4fff but (with a small > > > exception) 0x0000-0xffff; as 0x0000-0x00ff are already assigned, it > > > happily assigns the first free area -- 0x100-0x108 -- to the PCMCIA > > > card. > > > > > > 0000-0cf7 : PCI Bus 0000:00 > > > ... > > > 00f0-00ff : fpu > > > 0100-0108 : pcmcia0.0 > > > 0170-0177 : 0000:00:1f.2 > > > > > > (4) The PCMCIA card and the PCMCIA driver are set up to work with an IO > > > resource at 0x100-0x108. As soon as they attempt to use this resource, > > > bad things happen (lockups, etc.) because of the reasons spelled out at > > > (2). > > > > We'd have exactly the same situation if we assigned I/O port 0x100 > > to a PCI device. Why can't we use the same strategy PCI uses to > > avoid it? > > Well, PCI devices have three advantages: > > - they can more easily be "enumerated" (and their resource needs reflected) > by ACPI or the BIOS. > > - they usually don't conflict with ISA-style hardware(?) > > - they usually work happily with any (even high) I/O ports. > > > > => It is only an issue if the ACPI resource descriptions are incomplete. It > > > is worse for PCMCIA because it happily assigns resources below 0x1000, where > > > such system/platform devices usually listen to. And usecrs worsens the > > > situation also in another regard: on my own laptop (a pre-2008 model), > > > pci=use_crs makes the PCI-PCI bridge to be marked as "transparent", while > > > pci=nocrs means the PCI-PCI bridge is assumed to be "non-transparent". > > > > Sorry to be slow again... The pci=use_crs and pci=nocrs options only > > affect the PCI host bridge; they don't affect PCI-PCI bridges at all, > > except that they change the set of resources available for subtractive- > > decode PCI-PCI bridges to forward. (Strictly speaking, they don't > > affect the *behavior* of the PCI-PCI bridges, they only affect our > > *idea* of what they're doing.) > > > > I'm thinking of the code in pci_setup_device() where we set dev->transparent > > based on the bridge's class code. Obviously, you must be thinking > > of something else. > > > > My intention was that on pre-2008 systems like your laptop, my patches > > would not change any behavior at all, unless you boot with "pci=use_crs". > > Are you seeing an unexpected change on your system? > > No, that's excactly what I'm seeing here. On pre-2008 system, the behavior > is still the same; no unexpected change; all fine unless I boot with > "pci=use_crs". > > In contrast, on post-2008 systems like Komuros system, we now trust to > ACPI report _all_ resource users. If ACPI gets this right, I don't see a > real problem (but I might add a safety check to avoid any I/O ports < 0x0100 > anyway). The remaining question: can we safely trust BIOS authors to get it > right? From: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx> Date: Tue, 23 Mar 2010 16:05:00 +0100 Subject: [PATCH] pcmcia: do not use ioports < 0x100 on x86 On x86 systems using ACPI _CRS information -- now the default for post-2008 systems -- the PCI root bus no longer pretends to be offering the root ioport_resource. To avoid accidentally hitting some platform / system device, use only I/O ports >= 0x100 for PCMCIA devices on x86. Also, use %pR, while we're there. Reported-by: Komuro <komurojun-mbn@xxxxxxxxx> CC: Bjorn Helgaas <bjorn.helgaas@xxxxxx> Signed-off-by: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx> diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 4663b3f..7ae5b0f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -864,13 +864,21 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) continue; if (res->flags & IORESOURCE_IO) { + +#if defined(CONFIG_X86) + /* on x86, avoid anything < 0x100 for it is often + * used for legacy platform devices + */ + if (res->start < 0x100) + res->start = 0x100; + if (res->start >= res->end) + continue; +#endif + if (res == &ioport_resource) continue; - dev_printk(KERN_INFO, &s->cb_dev->dev, - "pcmcia: parent PCI bridge I/O " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_info(&s->cb_dev->dev, "pcmcia: parent PCI bridge " + "window: %pR\n", res); if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_IO; @@ -879,11 +887,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_MEM) { if (res == &iomem_resource) continue; - dev_printk(KERN_INFO, &s->cb_dev->dev, - "pcmcia: parent PCI bridge Memory " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_info(&s->cb_dev->dev, "pcmcia: parent PCI bridge " + "window: %pR\n", res); if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_MEM; } -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html