Bug 32421

Summary: patch to support ATA66 Mode (UDMA4) on SiS 630 chipset
Product: Base System Reporter: John L. Utz III <john>
Component: kernAssignee: Søren Schmidt <sos>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.4-RELEASE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff
none
file.diff none

Description John L. Utz III 2001-12-01 06:20:01 UTC
The SiS 630 integrated chipset contains an ATA66 controller that is currently recognized as an older SiS 5591 ATA33 device.

This is suboptimal because we like our disks to be read/written to as quickly as possible.

Fix: following patches to ata-all.c and ata-dma.c
How-To-Repeat: boot 4.4-RELEASE kernel on a SiS630 based computer
Comment 1 hattori 2001-12-01 08:13:25 UTC
I have another patch to ata-all.c and ata-dma.c.

This patch supports ATA100 mode on SiS630S/633/635/730/733/735 chipsets.

--- ata-all.c.orig	Wed Aug 29 02:56:14 2001
+++ ata-all.c	Sat Nov 10 12:47:09 2001
@@ -228,8 +228,7 @@
 	child = children[i];
 
 	/* check that it's on the same silicon and the device we want */
-	if (pci_get_slot(dev) == pci_get_slot(child) &&
-	    pci_get_vendor(child) == (type & 0xffff) &&
+	if (pci_get_vendor(child) == (type & 0xffff) &&
 	    pci_get_device(child) == ((type & 0xffff0000) >> 16) &&
 	    pci_get_revid(child) >= revid) {
 	    free(children, M_TEMP);
@@ -291,6 +290,18 @@
 	return "VIA Apollo ATA controller";
 
     case 0x55131039:
+	if (ata_find_dev(dev, 0x06301039, 0x30) ||
+	    ata_find_dev(dev, 0x06331039, 0x00) ||
+	    ata_find_dev(dev, 0x06351039, 0x00) ||
+	    ata_find_dev(dev, 0x07301039, 0x00) ||
+	    ata_find_dev(dev, 0x07331039, 0x00) ||
+	    ata_find_dev(dev, 0x07351039, 0x00))
+	    return "SiS 5591 ATA100 controller";
+	if (ata_find_dev(dev, 0x05301039, 0x00) ||
+	    ata_find_dev(dev, 0x05401039, 0x00) ||
+	    ata_find_dev(dev, 0x06201039, 0x00) ||
+	    ata_find_dev(dev, 0x06301039, 0x00))
+	    return "SiS 5591 ATA66 controller";
 	return "SiS 5591 ATA33 controller";
 
     case 0x06491095:
--- ata-dma.c.orig	Wed Aug 29 02:56:14 2001
+++ ata-dma.c	Sat Nov 10 12:57:54 2001
@@ -514,18 +514,107 @@
 	/* we could set PIO mode timings, but we assume the BIOS did that */
 	break;
 
-    case 0x55131039:	/* SiS 5591 */
-	if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) {
-	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
-				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
-	    if (bootverbose)
-		ata_printf(scp, device,
-			   "%s setting UDMA2 on SiS chip\n",
-			   (error) ? "failed" : "success");
-	    if (!error) {
-		pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
-		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
-		return;
+    case 0x55131039:	/* SiS 5591, 530/540, 620/630/633/635, 730/733/735 */
+	if (ata_find_dev(parent, 0x06301039, 0x30) || 	/* SiS630S */
+	    ata_find_dev(parent, 0x06331039, 0x00) || 	/* SiS633 */
+	    ata_find_dev(parent, 0x06351039, 0x00) || 	/* SiS635 */
+	    ata_find_dev(parent, 0x07301039, 0x00) || 	/* SiS730 */
+	    ata_find_dev(parent, 0x07331039, 0x00) || 	/* SiS733 */
+	    ata_find_dev(parent, 0x07351039, 0x00)) { 	/* SiS735 */
+ 	    int16_t reg = 0;
+	    if (udmamode >= 5) {
+		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+				    ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_printf(scp, device, 
+			       "%s setting UDMA5 on SiS chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    reg = pci_read_config(parent, 0x40 + (devno << 1), 2);
+		    reg &= 0x0fff;
+		    pci_write_config(parent, 0x40 + (devno << 1), reg|0x8000, 2);
+		    scp->mode[ATA_DEV(device)] = ATA_UDMA5;
+		    return;
+		}
+	    }
+	    if (udmamode >= 4) {
+		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_printf(scp, device, 
+			       "%s setting UDMA4 on SiS chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    reg = pci_read_config(parent, 0x40 + (devno << 1), 2);
+		    reg &= 0x0fff;
+		    pci_write_config(parent, 0x40 + (devno << 1), reg|0x9000, 2);
+		    scp->mode[ATA_DEV(device)] = ATA_UDMA4;
+		    return;
+		}
+	    }
+	    if (udmamode >= 2) {
+		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_printf(scp, device,
+			       "%s setting UDMA2 on SiS chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    reg = pci_read_config(parent, 0x40 + (devno << 1), 2);
+		    reg &= 0x0fff;
+		    pci_write_config(parent, 0x40 + (devno << 1), reg|0xb000, 2);
+		    scp->mode[ATA_DEV(device)] = ATA_UDMA2;
+		    return;
+		}
+	    }
+	} else if (ata_find_dev(parent, 0x05301039, 0) || /* SiS530 */
+		   ata_find_dev(parent, 0x05401039, 0) || /* SiS540 */
+		   ata_find_dev(parent, 0x06201039, 0) || /* SiS620 */
+		   ata_find_dev(parent, 0x06301039, 0)) { /* SiS630/E */
+ 	    int16_t reg = 0;
+	    if (udmamode >= 4) {
+		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_printf(scp, device, 
+			       "%s setting UDMA4 on SiS chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    reg = pci_read_config(parent, 0x40 + (devno << 1), 2);
+		    reg &= 0x0fff;
+		    pci_write_config(parent, 0x40 + (devno << 1), reg|0xa000, 2);
+		    scp->mode[ATA_DEV(device)] = ATA_UDMA4;
+		    return;
+		}
+	    }
+	    if (udmamode >= 2) {
+		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_printf(scp, device,
+			       "%s setting UDMA2 on SiS chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    reg = pci_read_config(parent, 0x40 + (devno << 1), 2);
+		    reg &= 0x0fff;
+		    pci_write_config(parent, 0x40 + (devno << 1), reg|0xb000, 2);
+		    scp->mode[ATA_DEV(device)] = ATA_UDMA2;
+		    return;
+		}
+	    }
+	} else {
+ 	    if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) {
+		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+		if (bootverbose)
+		    ata_printf(scp, device,
+			       "%s setting UDMA2 on SiS chip\n",
+			       (error) ? "failed" : "success");
+		if (!error) {
+		    pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
+		    scp->mode[ATA_DEV(device)] = ATA_UDMA2;
+		    return;
+		}
 	    }
 	}
 	if (wdmamode >=2 && apiomode >= 4) {
Comment 2 dwmalone freebsd_committer freebsd_triage 2001-12-01 08:51:32 UTC
Responsible Changed
From-To: freebsd-bugs->sos

ATA PR with patches.
Comment 3 Søren Schmidt freebsd_committer freebsd_triage 2001-12-03 12:14:47 UTC
State Changed
From-To: open->analyzed


Support for the new SiS chipsets has been committed to -current, 
the support is based on docs from SiS, and the timing params 
used are different from those in these patches. 
Please test the support in -current, and let me know if it 
works since I dont have any SiS HW here to test on.
Comment 4 Søren Schmidt freebsd_committer freebsd_triage 2002-01-07 19:18:21 UTC
State Changed
From-To: analyzed->closed

Support for even more SiS chipsets than in these patches 
has been added to 4.5