kern/129784: [patch] SATA port multiplier disk detect bugs in -current (svn186316)

James R. Van Artsdalen james at jrv.org
Sat Dec 20 02:30:01 PST 2008


>Number:         129784
>Category:       kern
>Synopsis:       [patch] SATA port multiplier disk detect bugs in -current (svn186316)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Dec 20 10:30:00 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     James R. Van Artsdalen
>Release:        FreeBSD 8 -current, svn186316
>Organization:
Institute for Applied Stellar Nucleosynthesis
>Environment:
System: FreeBSD fearless 8 -current svn186316 #0: Fri Dec 24 01:47:55 CST 2004 james at jrv.org:/usr/src/sys/amd64/compile/GENERIC amd64

>Description:

This only affects Silicon Image host controllers.  It was only tested with a 3132.

I have found two bugs in the port multiplier code and a place where an added delay is both necessary and sufficient to make my setup work, even though I can't explain why.

With the included patch my setup, with a Sil3132 host controller, always detects the drives in my Sil3726 based port-multiplier enclosures.  There are other problems trying to format and use the disks, but at least this may let people get past disk detection.

>How-To-Repeat:

Attach a port multiplier enclosure to a Silicon Image host adapter.  Some or all disks in the enclosure may not be seen.

>Fix:

The first change in ata_siiprb_issue_cmd() increases the timeout count from 10,000 to 31,000 counts.  When a soft reset is issued to a port multiplier disk port this loop may have to wait for the hard disk to spin up.  I consistently saw 15,000 counts as needed by experiment; assuming counts are milliseconds then 31,000 is what ATA calls for.  Note that currently empty disk ports behind a port multiplier are detected by letting this loop time out; i.e., an empty port multiplier enclosure can lengthen boot by 2.5 minutes.  Some other strategy for disk detection might be needed later (the PHY probably is a good approach).

The second change in ata_siiprb_issue_cmd() fixes a typo: failure was being returned if a command took more than 1,000 counts, even if it completed within the allotted 10,000 counts.

The last change in ata_siiprb_softreset() is a delay that is mysteriously turns out to be necessary.  I don't know why, how much or how little is needed.  Hardware is like that sometimes.

/usr/src-current# svn di
Index: sys/dev/ata/chipsets/ata-siliconimage.c
===================================================================
--- sys/dev/ata/chipsets/ata-siliconimage.c     (revision 186316)
+++ sys/dev/ata/chipsets/ata-siliconimage.c     (working copy)
@@ -679,7 +679,7 @@
     ATA_OUTL(ctlr->r_res2, 0x1c04 + offset, prb_bus >> 32);
 
     /* poll for command finished */
-    for (timeout = 0; timeout < 10000; timeout++) {
+    for (timeout = 0; timeout < 31000; timeout++) {
         DELAY(1000);
         if ((status = ATA_INL(ctlr->r_res2, 0x1008 + offset)) & 0x00010000)
             break;
@@ -687,7 +687,7 @@
     // SOS XXX ATA_OUTL(ctlr->r_res2, 0x1008 + offset, 0x00010000);
     ATA_OUTL(ctlr->r_res2, 0x1008 + offset, 0x08ff08ff);
 
-    if (timeout >= 1000)
+    if (timeout >= 31000)
        return EIO;
 
     if (bootverbose)
@@ -761,6 +761,18 @@
     prb->control = htole16(0x0080);
     prb->fis[1] = port & 0x0f;
 
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+    ata_udelay(150000);
+
     /* issue soft reset */
     if (ata_siiprb_issue_cmd(dev))
        return -1;
/usr/src-current# 
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list