> 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)