There have been a few reports that people with the VIA VT6410 or VT6415
chips do not see any devices attaching, as in:

pciide0 at pci2 dev 0 function 1 "VIA VT6415 IDE" rev 0xa0: ATA133, channel 0 
wired to native-PCI, channel 1 wired to native-PCI
pciide0: channel 0 ignored (disabled)
pciide0: channel 1 ignored (disabled)

This device is found onboard Asus M4A88TD motherboards, and probably not
much anywhere else.

Although documentation for this chip is not available, VIA publishes
some driver source code for Linux. And according to the
  Kernel/2.6.32/pata_via.c
file found in
  http://www.viaarena.com/Driver/via_idepatch_linuxdriverpackage_1.7.0.zip
the 6410 and 6415, unlike other controllers of similar lineage, do not
implement the `channel enable' register, which read as zero (as if both
channels were disabled). This is what causes the driver to skip
attaching devices.

And pcidump indeed shows:
 2:0:1: VIA VT6415 IDE
        0x0000: 04151106 00100107 010185a0 00800010
        0x0010: 0000dc01 0000d481 0000d401 0000d081
        0x0020: 0000d001 00000000 00000000 838f1043
        0x0030: feae0000 00000050 00000000 0000010a
        0x0040: 00000000 000010ff 00000000 00000000
                ^^^^^^^^
        0x0050: e4037001 00000000 00000000 00000000
        0x0060: 00000504 00010022 00000000 00000000
        0x0070: 01809005 00000000 00000000 00000000
        0x0080: 00000000 00000000 00000000 00000000
        0x0090: 00110010 00648000 00192000 00074c11
        0x00a0: 00110040 00000000 00000000 00000000
        0x00b0: 00000000 00000000 00000000 00000000
        0x00c0: b63344a8 00002707 00000000 00000001
        0x00d0: 00090030 00000200 00000102 0002138a
        0x00e0: 0012468e 0002138a 0012468e 00000000
        0x00f0: 00000000 00000000 00000000 00000000

The following diff ought to fix this. It seems to help one M4A88TD
owner; more tests would be welcome.

Index: pciide.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/pciide.c,v
retrieving revision 1.338
diff -u -p -r1.338 pciide.c
--- pciide.c    13 Mar 2012 21:32:42 -0000      1.338
+++ pciide.c    19 Apr 2012 21:22:46 -0000
@@ -3332,7 +3332,7 @@ apollo_chip_map(struct pciide_softc *sc,
 {
        struct pciide_channel *cp;
        pcireg_t interface;
-       int channel;
+       int no_ideconf = 0, channel;
        u_int32_t ideconf;
        bus_size_t cmdsize, ctlsize;
        pcitag_t tag;
@@ -3348,15 +3348,19 @@ apollo_chip_map(struct pciide_softc *sc,
                    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        }
 
-       if ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT6410) ||
-           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT6415) ||
-           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_CX700_IDE) ||
-           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VX700_IDE) ||
-           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VX855_IDE) ||
-           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VX900_IDE)) { 
+       switch (PCI_PRODUCT(pa->pa_id)) {
+       case PCI_PRODUCT_VIATECH_VT6410:
+       case PCI_PRODUCT_VIATECH_VT6415:
+               no_ideconf = 1;
+               /* FALLTHROUGH */
+       case PCI_PRODUCT_VIATECH_CX700_IDE:
+       case PCI_PRODUCT_VIATECH_VX700_IDE:
+       case PCI_PRODUCT_VIATECH_VX855_IDE:
+       case PCI_PRODUCT_VIATECH_VX900_IDE:
                printf(": ATA133");
                sc->sc_wdcdev.UDMA_cap = 6;
-       } else {
+               break;
+       default:
                /* 
                 * Determine the DMA capabilities by looking at the
                 * ISA bridge.
@@ -3421,6 +3425,7 @@ apollo_chip_map(struct pciide_softc *sc,
                        sc->sc_wdcdev.UDMA_cap = 0;
                        break;
                }
+               break;
        }
 
        pciide_mapreg_dma(sc, pa);
@@ -3453,11 +3458,14 @@ apollo_chip_map(struct pciide_softc *sc,
                if (pciide_chansetup(sc, channel, interface) == 0)
                        continue;
 
-               ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF);
-               if ((ideconf & APO_IDECONF_EN(channel)) == 0) {
-                       printf("%s: %s ignored (disabled)\n",
-                           sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
-                       continue;
+               if (no_ideconf == 0) {
+                       ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag,
+                           APO_IDECONF);
+                       if ((ideconf & APO_IDECONF_EN(channel)) == 0) {
+                               printf("%s: %s ignored (disabled)\n",
+                                   sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
+                               continue;
+                       }
                }
                pciide_map_compat_intr(pa, cp, channel, interface);
                if (cp->hw_ok == 0)
@@ -3469,9 +3477,11 @@ apollo_chip_map(struct pciide_softc *sc,
                        goto next;
                }
                if (pciide_chan_candisable(cp)) {
-                       ideconf &= ~APO_IDECONF_EN(channel);
-                       pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF,
-                           ideconf);
+                       if (no_ideconf == 0) {
+                               ideconf &= ~APO_IDECONF_EN(channel);
+                               pci_conf_write(sc->sc_pc, sc->sc_tag,
+                                   APO_IDECONF, ideconf);
+                       }
                }
 
                if (cp->hw_ok == 0)

Reply via email to