Patch for Intel ATA to try (was Re: Has anyone seen the ATA driver timeout issue again?)

Matthew Dillon dillon at apollo.backplane.com
Wed Jun 23 09:44:22 PDT 2004


    Jonathon, if you could try this patch I'd appreciate it.  I tried to
    hack in fixes from freebsd-5 to the intel chipset initialization 
    code.

					-Matt
					Matthew Dillon 
					<dillon at xxxxxxxxxxxxx>

Index: ata-dma.c
===================================================================
RCS file: /cvs/src/sys/dev/disk/ata/ata-dma.c,v
retrieving revision 1.23
diff -u -r1.23 ata-dma.c
--- ata-dma.c	23 Jun 2004 16:15:24 -0000	1.23
+++ ata-dma.c	23 Jun 2004 16:33:13 -0000
@@ -218,26 +218,63 @@
     case 0x71998086:	/* Intel PIIX4e */
     case 0x24218086:	/* Intel ICH0 */
 	if (udmamode >= 2) {
-	    int32_t mask48, new48;
+	    int16_t word54;
+	    u_int32_t reg40 = pci_read_config(parent, 0x40, 4);
+	    u_int8_t reg44 = pci_read_config(parent, 0x44, 1);
+	    u_int8_t reg48 = pci_read_config(parent, 0x48, 1);
+	    u_int16_t reg4a = pci_read_config(parent, 0x4a, 2);
+	    u_int16_t reg54 = pci_read_config(parent, 0x54, 2);
+	    u_int32_t mask40 = 0, new40 = 0;
+	    u_int8_t mask44 = 0, new44 = 0;
 
-	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
-				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
-	    if (bootverbose)
-		ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n",
-			   (error) ? "failed" : "success");
-	    if (!error) {
-		mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
-		new48 = (1 << devno) + (2 << (16 + (devno << 2)));
-		pci_write_config(parent, 0x48, 
-				 (pci_read_config(parent, 0x48, 4) &
-				 ~mask48) | new48, 4);
-		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
-		return;
+	    word54 = pci_read_config(parent, 0x54, 2);
+	    if (word54 & (0x10 << devno)) {
+		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
+			    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    pci_write_config(parent, 0x48, 
+				    reg48 | (0x0001 << devno), 2);
+		    pci_write_config(parent, 0x4a, 
+				    (reg4a & ~(0x3 << (devno<<2))) |
+				    (0x01 + !(udmamode & 0x01)), 2);
+		    pci_write_config(parent, 0x54, 
+				    reg54 | (0x1 << devno), 2);
+		    pci_write_config(parent, 0x54,
+				    reg54 & ~(0x10000 << devno), 2);
+		    reg40 &= ~0x00ff00ff;
+		    reg40 |= 0x40774077;
+		    if (atadev->unit == ATA_MASTER) {
+			mask40 = 0x3300;
+			new40 = 0x23 << 8;	/* UDMA2 timing */
+		    } else {
+			mask44 = 0x0f;
+			new44 = ((0x23 & 0x30) >> 2) | (0x23 & 0x03); /*timing*/
+		    }
+		    if (atadev->channel->unit) {
+			mask40 <<= 16;
+			new40 <<= 16;
+			mask44 <<= 4;
+			new44 <<= 4;
+		    }
+		    pci_write_config(parent, 0x40, 
+				    (reg40 & ~mask40) | new40, 4);
+		    pci_write_config(parent, 0x44, 
+				    (reg44 & ~mask44) | new44, 1);
+
+		    ata_dmacreate(atadev, apiomode, ATA_UDMA2);
+		    return;
+		}
 	    }
 	}
 	/* make sure eventual ATA33 mode from the BIOS is disabled */
 	pci_write_config(parent, 0x48, 
-			 pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4);
+		pci_read_config(parent, 0x48, 2) & ~(1 << devno), 2);
+	pci_write_config(parent, 0x4a, 
+		pci_read_config(parent, 0x4a, 2) & ~(0x3 << (devno << 2)), 2);
+
 	/* FALLTHROUGH */
 
     case 0x70108086:	/* Intel PIIX3 */





More information about the Kernel mailing list