> Date: Mon, 15 Sep 2014 09:37:56 +0200
> From: Thierry Deval <[email protected]>
> 
> On Mon, Sep 15, 2014 at 12:25:19AM +0200, Mark Kettenis wrote:
> >> Date: Sun, 14 Sep 2014 23:57:09 +0200
> >> From: Thierry Deval <[email protected]>
> >>
> >> Hi,
> >>
> >> When I put a CF to PCCard adapter (not CardBus) in my laptop to work on a 
> >> CF
> >> boot image, I was surprised by this kernel message :
> >>
> >> ** wdc2 at pcmcia0 function 0 "SanDisk, SDP, 5/3 0.6": can't handle card 
> >> info
> >>
> >> And the card was not working at all, as weren't any other PCCard I tried
> >> afterwards.
> >>
> >> After digging and enabling as much debugging as I could, I found that the
> >> cardbus bridge (TI PCI7xx1 CardBus) couldn't allocate any IO or mem range
> >> for the cards.
> >>
> >> Digging deeper to understand how the allocation should work, I noticed
> >> a comment in dev/pci/ppb.c talking about handling substractive (or is it
> >> really 'subtractive' as in the comment ? ) decode scheme for more than the
> >> Intel 82801 PCI bridge.
> >> So, as a test, I included the ATI SB400 PCI bridge (behind which the TI
> >> PCI7xx1 CardBus bridge was lying) to the substractive decode treatment.
> >> I was rewarded by a working CF card.
> >>
> >> ** ppb2 at pci0 dev 20 function 4 "ATI SB400 PCI" rev 0x00
> >> ** pci3 at ppb2 bus 6
> >> ** cbb0 at pci3 dev 9 function 0 "TI PCI7XX1 CardBus" rev 0x00: apic 1 int 
> >> 23
> >> ** cardslot0 at cbb0 slot 0 flags 0
> >> ** cardbus0 at cardslot0: bus 7 device 0 cacheline 0x8, lattimer 0x20
> >> ** pcmcia0 at cardslot0
> >> ** wdc2 at pcmcia0 function 0 "SanDisk, SDP, 5/3 0.6" port 0xa000/16
> >> ** wd1 at wdc2 channel 0 drive 0: <SanDisk SDCFB-64>
> >> ** wd1: 1-sector PIO, LBA, 61MB, 125440 sectors
> >> ** wd1(wdc2:0:0): using BIOS timings
> >> ** wd1 detached
> >> ** wdc2 detached
> >>
> >> I don't know if anybody else have seen the same problem but I would be glad
> >> to have a confirmation of the fix.
> >>
> >> Here's the diff:
> >>
> >> Index: ppb.c
> >> ===================================================================
> >> RCS file: /cvs/src/sys/dev/pci/ppb.c,v
> >> retrieving revision 1.58
> >> diff -u -p -u -p -r1.58 ppb.c
> >> --- ppb.c  12 Jul 2014 18:48:52 -0000      1.58
> >> +++ ppb.c  14 Sep 2014 17:00:40 -0000
> >> @@ -286,9 +286,11 @@ ppbattach(struct device *parent, struct
> >>             * XXX We probably should handle subtractive decode bridges
> >>             * in general.
> >>             */
> >> -  if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
> >> +  if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
> >>                (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BA_HPB ||
> >> -      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB)) {
> >> +       PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB)) ||
> >> +      (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI &&
> >> +       PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB400_PCI)){
> >>                    if (sc->sc_ioex == NULL)
> >>                            sc->sc_ioex = pa->pa_ioex;
> >>                    if (sc->sc_memex == NULL)
> >>
> >> I hope this could go in, at least as a first step.
> >> I plan on looking further about what this substractive decode means, and
> >> if there could be a generic way of enabling it where supported...
> >
> >Can you send pcidump -vxxx output for that machine?
> 
> Sure Mark, here it is.

Thanks.  So your PCI bridge properly advertises itself as subtractive
decode.  Can you try the diff below?

Thanks,

Mark

Index: ppbreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/ppbreg.h,v
retrieving revision 1.4
diff -u -p -r1.4 ppbreg.h
--- ppbreg.h    19 Nov 2009 20:43:32 -0000      1.4
+++ ppbreg.h    15 Sep 2014 09:14:53 -0000
@@ -40,6 +40,11 @@
  */
 
 /*
+ * PCI Programming Interface register.
+ */
+#define        PPB_INTERFACE_SUBTRACTIVE       0x01
+
+/*
  * Register offsets
  */
 #define        PPB_REG_BASE0           0x10            /* Base Addr Reg. 0 */
Index: ppb.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/ppb.c,v
retrieving revision 1.58
diff -u -p -r1.58 ppb.c
--- ppb.c       12 Jul 2014 18:48:52 -0000      1.58
+++ ppb.c       15 Sep 2014 09:14:53 -0000
@@ -146,6 +146,7 @@ ppbattach(struct device *parent, struct 
        struct pci_attach_args *pa = aux;
        pci_chipset_tag_t pc = pa->pa_pc;
        struct pcibus_attach_args pba;
+       pci_interface_t interface;
        pci_intr_handle_t ih;
        pcireg_t busdata, reg, blr;
        char *name;
@@ -206,9 +207,18 @@ ppbattach(struct device *parent, struct 
 
        printf("\n");
 
-       if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
-           (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BA_HPB &&
-           PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BAM_HPB))
+       interface = PCI_INTERFACE(pa->pa_class);
+
+       /*
+        * The Intel 82801BAM Hub-to-PCI can decode subtractively but
+        * doesn't advertise itself as such.
+        */
+       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BA_HPB ||
+           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB))
+               interface = PPB_INTERFACE_SUBTRACTIVE;
+
+       if (interface != PPB_INTERFACE_SUBTRACTIVE)
                ppb_alloc_resources(sc, pa);
 
        for (pin = PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_D; pin++) {
@@ -281,14 +291,7 @@ ppbattach(struct device *parent, struct 
                }
        }
 
-       /*
-        * The Intel 82801BAM Hub-to-PCI can decode subtractively.
-        * XXX We probably should handle subtractive decode bridges
-        * in general.
-        */
-       if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
-           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BA_HPB ||
-           PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB)) {
+       if (interface == PPB_INTERFACE_SUBTRACTIVE) {
                if (sc->sc_ioex == NULL)
                        sc->sc_ioex = pa->pa_ioex;
                if (sc->sc_memex == NULL)

Reply via email to