>Number:         183294
>Category:       kern
>Synopsis:       VIA VX900 - SATA hang
>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:   Fri Oct 25 07:30:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Alexandre Martins
>Release:        RELEASE 9.2
>Organization:
NETASQ
>Environment:
FreeBSD machine.netasq.com 9.2-RELEASE FreeBSD 9.2-RELEASE #0: Wed Sep 25 
11:48:26 CEST 2013     
[email protected]:/usr/obj/usr/src/sys/GENERIC i386
>Description:
The VIA VX900, SATA controler, hang during its initialization, resulting hard 
drives not seen by kernel.

The hang is due to the reset commands that not wait previous reset command 
completion.

Depending on the speed of the hard drive initilization, the reset command can 
take more time.
>How-To-Repeat:
It's depending on how many and the kind of hard drives drive plugged.
>Fix:
Wait the controller have finished the reset command before send another one.

The attached patch show two kinds of waiting, but i don't know which is the 
better one.

Patch attached with submission follows:

--- dev/ata/chipsets/ata-via.c.orig     2013-10-24 09:32:45.000000000 +0000
+++ dev/ata/chipsets/ata-via.c  2013-10-24 09:39:51.000000000 +0000
@@ -459,6 +459,7 @@
                devs = ata_sata_phy_reset(dev, 0, 0);
                DELAY(10000);
                devs += ata_sata_phy_reset(dev, 1, 0);
+               DELAY(10000);
        } else
                devs = 1;
        if (devs)
--- dev/ata/chipsets/ata-via.c.orig     2013-10-24 13:39:17.000000000 +0000
+++ dev/ata/chipsets/ata-via.c  2013-10-24 09:24:04.000000000 +0000
@@ -456,11 +456,29 @@
 {
        struct ata_channel *ch = device_get_softc(dev);
        int devs;
+       u_int8_t status;
+       int count;
 
        if (ch->unit == 0) {
                devs = ata_sata_phy_reset(dev, 0, 0);
-               DELAY(10000);
+               count = 0;
+               do
+               {
+                       ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | 
ATA_DEV(ATA_MASTER));
+                       DELAY(1000);
+                       status = ATA_IDX_INB(ch, ATA_STATUS);
+                       count++;
+               } while (status & ATA_S_BUSY && count < 100);
+
                devs += ata_sata_phy_reset(dev, 1, 0);
+               count = 0;
+               do
+               {
+                       ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | 
ATA_DEV(ATA_SLAVE));
+                       DELAY(1000);
+                       status = ATA_IDX_INB(ch, ATA_STATUS);
+                       count++;
+               } while (status & ATA_S_BUSY && count < 100);
        } else
                devs = 1;
        if (devs)


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to