Subject: patch for updated VIA and nVidia IDE support
To: None <port-i386@netbsd.org, port-amd64@netbsd.org>
From: Frank van der Linden <fvdl@netbsd.org>
List: port-amd64
Date: 10/22/2003 13:48:54
For anyone who has a VIA or an nVidia nForce3 IDE controller (common on some
of the new Athlon[64] boards): can you perhaps try:

	1) updating your kernel sources
	2) applying the following patch
	3) booting the resulting kernel

..and see if your IDE controller is still properly supported, or
is now properly supported? Reports about older VIA PCI IDE controllers
are also welcome.

The patch makes viaide match the nVidia nForce3 chip (should be no
problem there), and also scans the whole PCI bus the controller
is on, to find the PCI-ISA bridge for VIA IDE controllers. Those
can only be properly identified if you know the ID of that bridge.

- Frank


Index: viaide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/viaide.c,v
retrieving revision 1.4
diff -c -r1.4 viaide.c
*** viaide.c	18 Oct 2003 12:40:09 -0000	1.4
--- viaide.c	22 Oct 2003 11:34:49 -0000
***************
*** 39,44 ****
--- 39,45 ----
  #include <dev/pci/pciidevar.h>
  #include <dev/pci/pciide_apollo_reg.h>
  
+ static int	via_pcib_match(struct pci_attach_args *);
  static void	via_chip_map(struct pciide_softc *, struct pci_attach_args *);
  static void	via_sata_chip_map(struct pciide_softc *,
  		    struct pci_attach_args *);
***************
*** 161,166 ****
--- 162,177 ----
  	pciide_common_attach(sc, pa, pp);
  }
  
+ static int
+ via_pcib_match(struct pci_attach_args *pa)
+ {
+ 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
+ 	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA &&
+ 	    PCI_VENDOR(pa->pa_id == PCI_VENDOR_VIATECH))
+ 		return (1);
+ 	return 0;
+ }
+ 
  static void
  via_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
  {
***************
*** 170,177 ****
  	int channel;
  	u_int32_t ideconf;
  	bus_size_t cmdsize, ctlsize;
- 	pcitag_t pcib_tag;
  	pcireg_t pcib_id, pcib_class;
  
  	if (pciide_chipen(sc, pa) == 0)
  		return;
--- 181,188 ----
  	int channel;
  	u_int32_t ideconf;
  	bus_size_t cmdsize, ctlsize;
  	pcireg_t pcib_id, pcib_class;
+ 	struct pci_attach_args pcib_pa;
  
  	if (pciide_chipen(sc, pa) == 0)
  		return;
***************
*** 179,192 ****
  	switch (vendor) {
  	case PCI_VENDOR_VIATECH:
  		/*
! 		 * get a PCI tag for the ISA bridge (function 0 of the
! 		 * same device)
  		 */
! 		pcib_tag =
! 		    pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0);
! 		/* and read ID and rev of the ISA bridge */
! 		pcib_id = pci_conf_read(sc->sc_pc, pcib_tag, PCI_ID_REG);
! 		pcib_class = pci_conf_read(sc->sc_pc, pcib_tag, PCI_CLASS_REG);
  		aprint_normal("%s: VIA Technologies ",
  		    sc->sc_wdcdev.sc_dev.dv_xname);
  		switch (PCI_PRODUCT(pcib_id)) {
--- 190,203 ----
  	switch (vendor) {
  	case PCI_VENDOR_VIATECH:
  		/*
! 		 * get a PCI tag for the ISA bridge.
  		 */
! 		if (pci_enumerate_bus(
! 		    (struct pci_softc *)sc->sc_wdcdev.sc_dev.dv_parent,
! 		    via_pcib_match, &pcib_pa) == 0)
! 			goto unknown;
! 		pcib_id = pcib_pa.pa_id;
! 		pcib_class = pcib_pa.pa_class;
  		aprint_normal("%s: VIA Technologies ",
  		    sc->sc_wdcdev.sc_dev.dv_xname);
  		switch (PCI_PRODUCT(pcib_id)) {
***************
*** 236,246 ****
--- 247,259 ----
  			aprint_normal("VT8235 ATA133 controller\n");
  			sc->sc_wdcdev.UDMA_cap = 6;
  			break;
+ 		case PCI_PRODUCT_VIATECH_VT8237:
  		case PCI_PRODUCT_VIATECH_VT8237_SATA:
  			aprint_normal("VT8237 ATA133 controller\n");
  			sc->sc_wdcdev.UDMA_cap = 6;
  			break;
  		default:
+ unknown:
  			aprint_normal("unknown VIA ATA controller\n");
  			sc->sc_wdcdev.UDMA_cap = 0;
  		}
***************
*** 264,269 ****
--- 277,283 ----
  			sc->sc_wdcdev.UDMA_cap = 5;
  			break;
  		case PCI_PRODUCT_NVIDIA_NFORCE2_ATA133:
+ 		case PCI_PRODUCT_NVIDIA_NFORCE3_ATA133:
  			sc->sc_wdcdev.UDMA_cap = 6;
  			break;
  		}