Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Nov 2009 00:43:13 +0900 (JST)
From:      Tomokazu HARADA <tharada@oucrc.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/140251: [atapci] Intel SCH UDMA5 support
Message-ID:  <200911031543.nA3FhD7Y000973@fit.md.ayatan.org>
Resent-Message-ID: <200911031620.nA3GK2TU090814@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         140251
>Category:       kern
>Synopsis:       [atapci] Intel SCH UDMA5 support
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 03 16:20:02 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Tomokazu HARADA
>Release:        FreeBSD 8.0-RC2 i386
>Organization:
>Environment:
System: FreeBSD fit.md.ayatan.org 8.0-RC2 FreeBSD 8.0-RC2 #6: Wed Nov 4 00:06:43 JST 2009 root@fit.md.ayatan.org:/usr/obj/usr/src/sys/GENERIC i386

This is a fit-PC2 C1100, Atom Z510 with Intel US15W chipsets

>Description:
I made a patch for ata-intel.
After this patch applied, Intel SCH can UDMA5.

 - timing registers are differnt from PIIX or ICHs
 - secondary channel not exists
 - no cable-report registers

--- ata-pci.h.orig	2009-11-04 00:06:06.622342000 +0900
+++ ata-pci.h	2009-11-04 00:38:09.000000000 +0900
@@ -196,6 +196,7 @@
 #define ATA_I82801JD_R1         0x3a058086
 #define ATA_I82801JD_S2         0x3a068086
 #define ATA_I31244              0x32008086
+#define ATA_ISCH                0x811a8086
 
 #define ATA_ITE_ID              0x1283
 #define ATA_IT8211F             0x82111283
--- chipsets/ata-intel.c.orig	2009-11-04 00:06:01.785689000 +0900
+++ chipsets/ata-intel.c	2009-11-04 00:38:25.000000000 +0900
@@ -57,6 +57,7 @@
 static void ata_intel_reset(device_t dev);
 static void ata_intel_old_setmode(device_t dev, int mode);
 static void ata_intel_new_setmode(device_t dev, int mode);
+static void ata_intel_sch_setmode(device_t dev, int mode);
 static void ata_intel_sata_setmode(device_t dev, int mode);
 static int ata_intel_31244_ch_attach(device_t dev);
 static int ata_intel_31244_ch_detach(device_t dev);
@@ -136,6 +137,7 @@
      { ATA_I82801JD_R1,  0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
      { ATA_I82801JD_S2,  0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
      { ATA_I31244,       0,          0, 2, ATA_SA150, "31244" },
+     { ATA_ISCH,         0,          0, 1, ATA_UDMA5, "SCH" },
      { 0, 0, 0, 0, 0, 0}};
 
     if (pci_get_vendor(dev) != ATA_INTEL_ID)
@@ -179,6 +181,14 @@
 	ctlr->setmode = ata_sata_setmode;
     }
 
+    /* SCH */
+    else if (ctlr->chip->chipid == ATA_ISCH) {
+	ctlr->channels = 1;
+	ctlr->ch_attach = ata_intel_ch_attach;
+	ctlr->ch_detach = ata_pci_ch_detach;
+	ctlr->setmode = ata_intel_sch_setmode;
+    }
+
     /* non SATA intel chips goes here */
     else if (ctlr->chip->max_dma < ATA_SA150) {
 	ctlr->channels = ctlr->chip->cfg2;
@@ -364,6 +374,43 @@
 }
 
 static void
+ata_intel_sch_setmode(device_t dev, int mode)
+{
+    device_t gparent = GRANDPARENT(dev);
+    struct ata_pci_controller *ctlr = device_get_softc(gparent);
+    struct ata_device *atadev = device_get_softc(dev);
+    u_int8_t dtim = 0x80 + (atadev->unit << 2);
+    u_int32_t tim = pci_read_config(gparent, dtim, 4);
+    int error;
+
+    mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
+
+    error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+
+    if (bootverbose)
+	device_printf(dev, "%ssetting %s on %s chip\n",
+		      (error) ? "FAILURE " : "",
+		      ata_mode2str(mode), ctlr->chip->text);
+    if (!error) {
+	if (mode >= ATA_UDMA0) {
+	    tim |= (0x1 << 31);
+	    tim |= ((mode & ATA_MODE_MASK) << 16);
+	}
+	else if (mode >= ATA_WDMA0) {
+	    tim &= ~(0x1 << 31);
+	    tim |= ((mode & ATA_MODE_MASK) << 8);
+	}
+	else if (mode >= ATA_PIO0) {
+	    tim |= (mode - ATA_PIO0);
+	}
+
+	pci_write_config(gparent, dtim, tim, 4);
+
+	atadev->mode = mode;
+    }
+}
+
+static void
 ata_intel_sata_setmode(device_t dev, int mode)
 {
     struct ata_device *atadev = device_get_softc(dev);

>How-To-Repeat:
N/A

>Fix:

before patch:
> atapci0: <Intel ATA controller> port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0x1810-0x181f at device 31.1 on pci0
> ata0: <ATA channel 0> on atapci0
> ata0: [ITHREAD]
> ata1: <ATA channel 1> on atapci0
> ata1: [ITHREAD]
> ad0: 76319MB <INTEL SSDSA2M080G2GC 2CV102G9> at ata0-master UDMA33

after patch:
> atapci0: <Intel SCH UDMA100 controller> port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0x1810-0x181f at device 31.1 on pci0
> ata0: <ATA channel 0> on atapci0
> ata0: [ITHREAD]
> ad0: 76319MB <INTEL SSDSA2M080G2GC 2CV102G9> at ata0-master UDMA100

# pciconf -r pci0:0:31:1 0x00:0x83
811a8086 00000005 01018007 00000000
00000000 00000000 00000000 00000000
00001811 00000000 00000000 81198086
00000000 00000000 00000000 000000ff
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
80050204

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911031543.nA3FhD7Y000973>