Subject: kern/17908: hpt 372 support
To: None <gnats-bugs@gnats.netbsd.org>
From: None <stephen@degler.net>
List: netbsd-bugs
Date: 08/10/2002 18:47:01
>Number:         17908
>Category:       kern
>Synopsis:       patch to add support for HPT 372 ide controller
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Aug 10 15:48:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Stephen Degler
>Release:        NetBSD 1.6F
>Organization:
	Very little, at best.
>Environment:
	
	
>Description:
	The attached patch adds support for the HPT 372 ide controller
	present on many pc motherboards and pci add on cards.
	No support for the bogus HPT raid is included.
	
>How-To-Repeat:
	Try to boot/use drives on HPT372 - doesn't work.
	
>Fix:
	Apply included patches and recompile.
	This has been tested with one drive and UDMA 100.

Index: pciide_hpt_reg.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pciide_hpt_reg.h,v
retrieving revision 1.8
diff -u -r1.8 pciide_hpt_reg.h
--- pciide_hpt_reg.h	2002/06/01 12:47:20	1.8
+++ pciide_hpt_reg.h	2002/08/10 22:28:17
@@ -46,6 +46,7 @@
 #define HPT366_REV 0x01
 #define HPT370_REV 0x03
 #define HPT370A_REV 0x04
+#define HPT372_REV 0x05
 #define HPT374_REV 0x07
 
 #define HPT_IDETIM(chan, drive) (0x40 + ((drive) * 4) + ((chan) * 8))
@@ -137,6 +138,14 @@
 static const u_int32_t hpt370_udma[] __attribute__((__unused__)) =
 	{0x16514e31, 0x164d4e31, 0x16494e31, 0x166d4e31, 0x16454e31,
 	 0x1a85f442};
+
+static const u_int32_t hpt372_pio[] __attribute__((__unused__)) =
+	{0x0d029d5e, 0x0d029d26, 0x0c829ca6, 0x0c829c84, 0x0c829c62};
+static const u_int32_t hpt372_dma[] __attribute__((__unused__)) =
+	{0x2c829d2e, 0x2c829c66, 0x2829c62};
+static const u_int32_t hpt372_udma[] __attribute__((__unused__)) =
+	{0x1c829c62, 0x1c9a9c62, 0x1c929c62, 0x1c8e9c62, 0x1c8a9c62,
+	 0x1cae9c62, 0x1c869c62};
 
 static u_int32_t hpt374_pio[] __attribute__((__unused__)) =
 	{0x0ac1f48a, 0x0ac1f465, 0x0a81f454, 0x0a81f443, 0x0a81f442};

Index: pciide.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pciide.c,v
retrieving revision 1.163
diff -u -r1.163 pciide.c
--- pciide.c	2002/07/30 21:01:57	1.163
+++ pciide.c	2002/08/10 22:27:55
@@ -3448,7 +3453,9 @@
 	if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
 		printf("HPT374 IDE Controller\n");
 	else if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366) {
-		if (revision == HPT370_REV)
+		if (revision == HPT372_REV)
+			printf("HPT372 IDE Controller\n");
+		else if (revision == HPT370_REV)
 			printf("HPT370 IDE Controller\n");
 		else if (revision == HPT370A_REV)
 			printf("HPT370A IDE Controller\n");
@@ -3470,7 +3477,8 @@
 		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
 		    PCIIDE_INTERFACE_PCI(0);
 		if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
-		    (revision == HPT370_REV || revision == HPT370A_REV)) ||
+		    (revision == HPT370_REV || revision == HPT370A_REV ||
+		    revision == HPT372_REV )) ||
 		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
 			interface |= PCIIDE_INTERFACE_PCI(1);
 	}
@@ -3511,7 +3519,9 @@
 		sc->sc_wdcdev.nchannels = 1;
 	} else {
 		sc->sc_wdcdev.nchannels = 2;
-		if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
+		if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 && 
+		     revision == HPT372_REV ) || 
+		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
 			sc->sc_wdcdev.UDMA_cap = 6;
 		else
 			sc->sc_wdcdev.UDMA_cap = 5;
@@ -3544,7 +3554,8 @@
 		hpt_setup_channel(&cp->wdc_channel);
 	}
 	if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
-	    (revision == HPT370_REV || revision == HPT370A_REV)) || 
+	    (revision == HPT370_REV || revision == HPT370A_REV || 
+	     revision == HPT372_REV)) || 
 	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374) {
 		/*
 		 * HPT370_REV and highter has a bit to disable interrupts,
@@ -3555,7 +3566,9 @@
 		    ~HPT_CSEL_IRQDIS);
 	}
 	/* set clocks, etc (mandatory on 374, optional otherwise) */
-	if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
+	if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
+	     revision == HPT372_REV ) ||
+	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
 		pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_SC2,
 		    (pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_SC2) &
 		     HPT_SC2_MAEN) | HPT_SC2_OSC_EN);
@@ -3597,11 +3610,26 @@
 			if ((cable & HPT_CSEL_CBLID(chp->channel)) != 0 &&
 			    drvp->UDMA_mode > 2)
 				drvp->UDMA_mode = 2;
-			after = (sc->sc_wdcdev.nchannels == 2) ?
-			    ( (sc->sc_wdcdev.UDMA_cap == 6) ?
-			    hpt374_udma[drvp->UDMA_mode] :
-			    hpt370_udma[drvp->UDMA_mode]) :
-			    hpt366_udma[drvp->UDMA_mode];
+
+			if ( sc->sc_pp->ide_product == 
+			     PCI_PRODUCT_TRIONES_HPT374 )
+			    after = hpt374_udma[drvp->UDMA_mode];
+			else
+			    switch (PCI_REVISION(pci_conf_read(sc->sc_pc,
+							       sc->sc_tag,
+							       PCI_CLASS_REG))){
+			    case HPT372_REV:
+			      after = hpt372_udma[drvp->UDMA_mode];
+			      break;
+			    case HPT370_REV:
+			    case HPT370A_REV:
+			      after = hpt370_udma[drvp->UDMA_mode];
+			      break;
+			    case HPT366_REV:
+			    default:
+			      after = hpt366_udma[drvp->UDMA_mode];
+			      break;
+			    }
 			idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
 		} else if (drvp->drive_flags & DRIVE_DMA) {
 			/*
@@ -3613,19 +3641,47 @@
 			    (drvp->DMA_mode + 2) > drvp->PIO_mode) {
 				drvp->DMA_mode = drvp->PIO_mode - 2;
 			}
-			after = (sc->sc_wdcdev.nchannels == 2) ?
-			    ( (sc->sc_wdcdev.UDMA_cap == 6) ?
-			    hpt374_dma[drvp->DMA_mode] :
-			    hpt370_dma[drvp->DMA_mode]) :
-			    hpt366_dma[drvp->DMA_mode];
+			if ( sc->sc_pp->ide_product == 
+			     PCI_PRODUCT_TRIONES_HPT374 )
+			    after = hpt374_dma[drvp->DMA_mode];
+			else
+			    switch (PCI_REVISION(pci_conf_read(sc->sc_pc,
+							       sc->sc_tag,
+							       PCI_CLASS_REG))){
+			    case HPT372_REV:
+			      after = hpt372_dma[drvp->DMA_mode];
+			      break;
+			    case HPT370_REV:
+			    case HPT370A_REV:
+			      after = hpt370_dma[drvp->DMA_mode];
+			      break;
+			    case HPT366_REV:
+			    default:
+			      after = hpt366_dma[drvp->DMA_mode];
+			      break;
+			    }
 			idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
 		} else {
 			/* PIO only */
-			after = (sc->sc_wdcdev.nchannels == 2) ?
-			    ( (sc->sc_wdcdev.UDMA_cap == 6) ?
-			    hpt374_pio[drvp->PIO_mode] :
-			    hpt370_pio[drvp->PIO_mode]) :
-			    hpt366_pio[drvp->PIO_mode];
+			if ( sc->sc_pp->ide_product == 
+			     PCI_PRODUCT_TRIONES_HPT374 )
+			    after = hpt374_pio[drvp->PIO_mode];
+			else
+			    switch (PCI_REVISION(pci_conf_read(sc->sc_pc,
+							       sc->sc_tag,
+							       PCI_CLASS_REG))){
+			    case HPT372_REV:
+			      after = hpt372_pio[drvp->PIO_mode];
+			      break;
+			    case HPT370_REV:
+			    case HPT370A_REV:
+			      after = hpt370_pio[drvp->PIO_mode];
+			      break;
+			    case HPT366_REV:
+			    default:
+			      after = hpt366_pio[drvp->PIO_mode];
+			      break;
+			    }
 		}
 		pci_conf_write(sc->sc_pc, sc->sc_tag,
 		    HPT_IDETIM(chp->channel, drive), after);

>Release-Note:
>Audit-Trail:
>Unformatted:
 	
 	
 >System: NetBSD kashmir.degler.net 1.6F NetBSD 1.6F (BAUHAUS-$Revision: 1.500 $) #1188: Sat Aug 10 18:20:51 EDT 2002 sdegler@kashmir.degler.net:/vol1/NetBSD/kernels/KASHMIR i386
 >Architecture: i386
 >Machine: i386