2002-08-13 03:25:59

by H. J. Lu

[permalink] [raw]
Subject: PATCH: New fix for CardBus bridge behind a PCI bridge

On Mon, Aug 12, 2002 at 03:48:51PM -0700, dhinds wrote:
> I guess the advantage of your original patch is that I think it should
> never hurt, and will help in any situation where a PCI bridge actually
> is transparent.
>

I was told all PCI_CLASS_BRIDGE_PCI bridges were transparent. The non-
transparent ones have class code PCI_CLASS_BRIDGE_OTHER. This new patch
only checks PCI_CLASS_BRIDGE_PCI and works for me.


H.J.


Attachments:
(No filename) (425.00 B)
linux-2.4.18-yenta-bridge.patch (1.66 kB)
Download all attachments

2002-08-16 15:45:01

by Ivan Kokshaysky

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

On Mon, Aug 12, 2002 at 08:29:42PM -0700, H. J. Lu wrote:
> I was told all PCI_CLASS_BRIDGE_PCI bridges were transparent. The non-
> transparent ones have class code PCI_CLASS_BRIDGE_OTHER. This new patch
> only checks PCI_CLASS_BRIDGE_PCI and works for me.

I guess that info came from Intel ;-) Interesting, but completely wrong.
The devices they call "non-transparent PCI-to-PCI bridges" aren't classic
PCI-to-PCI bridges at all, that's why they are PCI_CLASS_BRIDGE_OTHER.
It's more to do with CPU-to-CPU bridges.
In our terms, "transparent" PCI-to-PCI bridge means subtractive decoding one.
Your previous patch makes much more sense, although a) it should belong to
generic pci code b) is way incomplete.

Please try this one instead.

Ivan.

--- 2.4.19/drivers/pci/quirks.c Sat Aug 3 04:39:44 2002
+++ linux/drivers/pci/quirks.c Fri Aug 16 18:38:52 2002
@@ -471,6 +471,11 @@ static void __init quirk_dunord ( struct
r -> end = 0xffffff;
}

+static void __init quirk_transparent_bridge(struct pci_dev *dev)
+{
+ dev->class |= 1;
+}
+
/*
* The main table of quirks.
*/
@@ -525,6 +530,12 @@ static struct pci_fixup pci_fixups[] __i

{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering },
+ /*
+ * i82380FB mobile docking controller: its PCI-to-PCI bridge
+ * is subtractive decoding (transparent), and does indicate this
+ * in the ProgIf. Unfortunately, in the wrong bit - 7 instead of 0.
+ */
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge },

{ 0 }
};
--- 2.4.19/drivers/pci/pci.c Fri Aug 16 17:05:12 2002
+++ linux/drivers/pci/pci.c Fri Aug 16 19:00:49 2002
@@ -1073,6 +1073,13 @@ void __devinit pci_read_bridge_bases(str
if (!dev) /* It's a host bus, nothing to read */
return;

+ if (dev->class & 1) {
+ printk("Transparent bridge - %s\n", dev->name);
+ for(i=0; i < 3; i++)
+ child->resource[i] = child->parent->resource[i];
+ return;
+ }
+
for(i=0; i<3; i++)
child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];

@@ -1095,13 +1102,6 @@ void __devinit pci_read_bridge_bases(str
res->start = base;
res->end = limit + 0xfff;
res->name = child->name;
- } else {
- /*
- * Ugh. We don't know enough about this bridge. Just assume
- * that it's entirely transparent.
- */
- printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 0);
- child->resource[0] = child->parent->resource[0];
}

res = child->resource[1];
@@ -1114,10 +1114,6 @@ void __devinit pci_read_bridge_bases(str
res->start = base;
res->end = limit + 0xfffff;
res->name = child->name;
- } else {
- /* See comment above. Same thing */
- printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 1);
- child->resource[1] = child->parent->resource[1];
}

res = child->resource[2];
@@ -1145,10 +1141,6 @@ void __devinit pci_read_bridge_bases(str
res->start = base;
res->end = limit + 0xfffff;
res->name = child->name;
- } else {
- /* See comments above */
- printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 2);
- child->resource[2] = child->parent->resource[2];
}
}

--- 2.4.19/arch/i386/kernel/pci-pc.c Sat Aug 3 04:39:42 2002
+++ linux/arch/i386/kernel/pci-pc.c Fri Aug 16 19:08:18 2002
@@ -1245,6 +1245,23 @@ static void __init pci_fixup_via_northbr
}
}

+/*
+ * For some weird reasons Intel decided that certain parts of their
+ * 815, 845 and some other chipsets must look like PCI-to-PCI bridges
+ * while they are obviously not. The 82801xx (AA, AB, BAM/CAM, BA/CA/DB
+ * and E) PCI bridges are actually HUB-to-PCI ones, according to Intel
+ * terminology. These devices do forward all addresses from system to
+ * PCI bus no matter what are their window settings, so they are
+ * "transparent" (or subtractive decoding) from programmers point of view.
+ * Indicate this in ProgIf bit 0.
+ */
+static void __init pci_fixup_transparent_bridge(struct pci_dev *dev)
+{
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ (dev->device & 0xff00) == 0x2400);
+ dev->class |= 1;
+}
+
struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx },
@@ -1259,6 +1276,7 @@ struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810 },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_bridge },
{ 0 }
};

2002-08-17 05:46:02

by H. J. Lu

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

On Fri, Aug 16, 2002 at 07:48:25PM +0400, Ivan Kokshaysky wrote:
> On Mon, Aug 12, 2002 at 08:29:42PM -0700, H. J. Lu wrote:
> > I was told all PCI_CLASS_BRIDGE_PCI bridges were transparent. The non-
> > transparent ones have class code PCI_CLASS_BRIDGE_OTHER. This new patch
> > only checks PCI_CLASS_BRIDGE_PCI and works for me.
>
> I guess that info came from Intel ;-) Interesting, but completely wrong.
> The devices they call "non-transparent PCI-to-PCI bridges" aren't classic
> PCI-to-PCI bridges at all, that's why they are PCI_CLASS_BRIDGE_OTHER.
> It's more to do with CPU-to-CPU bridges.
> In our terms, "transparent" PCI-to-PCI bridge means subtractive decoding one.
> Your previous patch makes much more sense, although a) it should belong to
> generic pci code b) is way incomplete.
>
> Please try this one instead.
>

CardBus works now. But I can no longer load usb-uhci. My X server no
longer works. Your patch is not right.


H.J.

2002-08-17 15:22:17

by Jeff Garzik

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

H. J. Lu wrote:> On Fri, Aug 16, 2002 at 07:48:25PM +0400, Ivan
Kokshaysky wrote:
>
>>On Mon, Aug 12, 2002 at 08:29:42PM -0700, H. J. Lu wrote:
>>
>>>I was told all PCI_CLASS_BRIDGE_PCI bridges were transparent. The non-
>>>transparent ones have class code PCI_CLASS_BRIDGE_OTHER. This new patch
>>>only checks PCI_CLASS_BRIDGE_PCI and works for me.
>>
>>I guess that info came from Intel ;-) Interesting, but completely wrong.
>>The devices they call "non-transparent PCI-to-PCI bridges" aren't classic
>>PCI-to-PCI bridges at all, that's why they are PCI_CLASS_BRIDGE_OTHER.
>>It's more to do with CPU-to-CPU bridges.
>>In our terms, "transparent" PCI-to-PCI bridge means subtractive decoding one.
>>Your previous patch makes much more sense, although a) it should belong to
>>generic pci code b) is way incomplete.
>>
>>Please try this one instead.
>>
>
>
> CardBus works now. But I can no longer load usb-uhci. My X server no
> longer works. Your patch is not right.


I would be willing to bet there is some silliness in the X server, at
least. It's PCI code has always left a lot to be desired...

Jeff




2002-08-17 15:32:14

by H. J. Lu

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

On Sat, Aug 17, 2002 at 11:26:08AM -0400, Jeff Garzik wrote:
> H. J. Lu wrote:> On Fri, Aug 16, 2002 at 07:48:25PM +0400, Ivan
> Kokshaysky wrote:
> >
> >>On Mon, Aug 12, 2002 at 08:29:42PM -0700, H. J. Lu wrote:
> >>
> >>>I was told all PCI_CLASS_BRIDGE_PCI bridges were transparent. The non-
> >>>transparent ones have class code PCI_CLASS_BRIDGE_OTHER. This new patch
> >>>only checks PCI_CLASS_BRIDGE_PCI and works for me.
> >>
> >>I guess that info came from Intel ;-) Interesting, but completely wrong.
> >>The devices they call "non-transparent PCI-to-PCI bridges" aren't classic
> >>PCI-to-PCI bridges at all, that's why they are PCI_CLASS_BRIDGE_OTHER.
> >>It's more to do with CPU-to-CPU bridges.
> >>In our terms, "transparent" PCI-to-PCI bridge means subtractive decoding one.
> >>Your previous patch makes much more sense, although a) it should belong to
> >>generic pci code b) is way incomplete.
> >>
> >>Please try this one instead.
> >>
> >
> >
> > CardBus works now. But I can no longer load usb-uhci. My X server no
> > longer works. Your patch is not right.
>
>
> I would be willing to bet there is some silliness in the X server, at
> least. It's PCI code has always left a lot to be desired...
>

It could be. But I doubt it. At least, I don't think you can treat a
AGP bridge like a 82801BAM/CAM bridge. I think 82801BAM/CAM is a
special case. You really have to read the datasheet to know for sure.


H.J.

2002-08-18 10:26:15

by Ivan Kokshaysky

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

On Fri, Aug 16, 2002 at 10:49:50PM -0700, H. J. Lu wrote:
> CardBus works now. But I can no longer load usb-uhci. My X server no
> longer works. Your patch is not right.

More info, please (probably off-list). Kernel and X error messages, and
'lspci -vvxxx' output from your machine.
Those "transparent" bridges cause too much problems, and I'm just trying
to find a generic solution...

Ivan.

2002-08-18 10:46:14

by Ivan Kokshaysky

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

On Sat, Aug 17, 2002 at 08:36:01AM -0700, H. J. Lu wrote:
> It could be. But I doubt it. At least, I don't think you can treat a
> AGP bridge like a 82801BAM/CAM bridge. I think 82801BAM/CAM is a
> special case. You really have to read the datasheet to know for sure.

You're right by all means. AGP bridges are _always_ positive decoders.
The problems you've seen were caused by the wrong semicolon somehow
sneaked into the patch:

+static void __init pci_fixup_transparent_bridge(struct pci_dev *dev)
+{
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ (dev->device & 0xff00) == 0x2400);
^ Ugh..
+ dev->class |= 1;
+}

Which means that I'm setting bit 0 in the ProgIf for _all_ Intel devices...
I'm really sorry about that.
Thanks for the pci dump - it's very useful anyway.

Ivan.

2002-08-18 14:24:21

by H. J. Lu

[permalink] [raw]
Subject: Re: PATCH: New fix for CardBus bridge behind a PCI bridge

On Sun, Aug 18, 2002 at 02:49:48PM +0400, Ivan Kokshaysky wrote:
> On Sat, Aug 17, 2002 at 08:36:01AM -0700, H. J. Lu wrote:
> > It could be. But I doubt it. At least, I don't think you can treat a
> > AGP bridge like a 82801BAM/CAM bridge. I think 82801BAM/CAM is a
> > special case. You really have to read the datasheet to know for sure.
>
> You're right by all means. AGP bridges are _always_ positive decoders.
> The problems you've seen were caused by the wrong semicolon somehow
> sneaked into the patch:
>
> +static void __init pci_fixup_transparent_bridge(struct pci_dev *dev)
> +{
> + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
> + (dev->device & 0xff00) == 0x2400);
> ^ Ugh..
> + dev->class |= 1;
> +}
>
> Which means that I'm setting bit 0 in the ProgIf for _all_ Intel devices...
> I'm really sorry about that.

Yes. It works now. Thanks.


H.J.