From nobody@FreeBSD.org  Fri Oct 25 07:24:02 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTP id 47542188
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 25 Oct 2013 07:24:02 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id 1B798230A
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 25 Oct 2013 07:24:02 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r9P7O1pQ045106
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 25 Oct 2013 07:24:01 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r9P7O1Sr045102;
	Fri, 25 Oct 2013 07:24:01 GMT
	(envelope-from nobody)
Message-Id: <201310250724.r9P7O1Sr045102@oldred.freebsd.org>
Date: Fri, 25 Oct 2013 07:24:01 GMT
From: Alexandre Martins <alexandre.martins@netasq.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: VIA VX900 - SATA hang
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>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     alexandrem@machine.netasq.com:/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:
