Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Apr 2011 20:40:00 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r220869 - stable/8/sys/dev/ahci
Message-ID:  <201104192040.p3JKe04k021454@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Tue Apr 19 20:40:00 2011
New Revision: 220869
URL: http://svn.freebsd.org/changeset/base/220869

Log:
  MFC r220777:
   - Tune different wait loops to cut some more milliseconds from reset time.
   - Do not call ahci_start() before device signature received. It is required
  by the specification and caused non-fatal reset timeouts on AMD chipsets.

Modified:
  stable/8/sys/dev/ahci/ahci.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/ahci/ahci.c
==============================================================================
--- stable/8/sys/dev/ahci/ahci.c	Tue Apr 19 20:38:50 2011	(r220868)
+++ stable/8/sys/dev/ahci/ahci.c	Tue Apr 19 20:40:00 2011	(r220869)
@@ -1741,11 +1741,11 @@ ahci_execute_transaction(struct ahci_slo
 	if (ccb->ccb_h.func_code == XPT_ATA_IO &&
 	    (ccb->ataio.cmd.command == ATA_DEVICE_RESET ||
 	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL))) {
-		int count, timeout = ccb->ccb_h.timeout;
+		int count, timeout = ccb->ccb_h.timeout * 100;
 		enum ahci_err_type et = AHCI_ERR_NONE;
 
 		for (count = 0; count < timeout; count++) {
-			DELAY(1000);
+			DELAY(10);
 			if (!(ATA_INL(ch->r_mem, AHCI_P_CI) & (1 << slot->slot)))
 				break;
 			if (ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) {
@@ -1781,7 +1781,7 @@ ahci_execute_transaction(struct ahci_slo
 		    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
 		    (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
 			while ((val = fis[2]) & (ATA_S_BUSY | ATA_S_DRQ)) {
-				DELAY(1000);
+				DELAY(10);
 				if (count++ >= timeout) {
 					device_printf(dev, "device is not "
 					    "ready after soft-reset: "
@@ -2299,8 +2299,8 @@ ahci_stop(device_t dev)
 	/* Wait for activity stop. */
 	timeout = 0;
 	do {
-		DELAY(1000);
-		if (timeout++ > 1000) {
+		DELAY(10);
+		if (timeout++ > 50000) {
 			device_printf(dev, "stopping AHCI engine failed\n");
 			break;
 		}
@@ -2322,8 +2322,8 @@ ahci_clo(device_t dev)
 		ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd);
 		timeout = 0;
 		do {
-			DELAY(1000);
-			if (timeout++ > 1000) {
+			DELAY(10);
+			if (timeout++ > 50000) {
 			    device_printf(dev, "executing CLO failed\n");
 			    break;
 			}
@@ -2344,8 +2344,8 @@ ahci_stop_fr(device_t dev)
 	/* Wait for FIS reception stop. */
 	timeout = 0;
 	do {
-		DELAY(1000);
-		if (timeout++ > 1000) {
+		DELAY(10);
+		if (timeout++ > 50000) {
 			device_printf(dev, "stopping AHCI FR engine failed\n");
 			break;
 		}
@@ -2402,11 +2402,11 @@ ahci_reset_to(void *arg)
 	if (ahci_wait_ready(dev, ch->resetting == 0 ? -1 : 0,
 	    (310 - ch->resetting) * 100) == 0) {
 		ch->resetting = 0;
+		ahci_start(dev, 1);
 		xpt_release_simq(ch->sim, TRUE);
 		return;
 	}
 	if (ch->resetting == 0) {
-		ahci_stop(dev);
 		ahci_clo(dev);
 		ahci_start(dev, 1);
 		xpt_release_simq(ch->sim, TRUE);
@@ -2489,7 +2489,6 @@ ahci_reset(device_t dev)
 		else
 			ch->resetting = 310;
 	}
-	ahci_start(dev, 1);
 	ch->devices = 1;
 	/* Enable wanted port interrupts */
 	ATA_OUTL(ch->r_mem, AHCI_P_IE,
@@ -2501,8 +2500,10 @@ ahci_reset(device_t dev)
 	      AHCI_P_IX_DS | AHCI_P_IX_PS | (ctlr->ccc ? 0 : AHCI_P_IX_DHR)));
 	if (ch->resetting)
 		callout_reset(&ch->reset_timer, hz / 10, ahci_reset_to, dev);
-	else
+	else {
+		ahci_start(dev, 1);
 		xpt_release_simq(ch->sim, TRUE);
+	}
 }
 
 static int
@@ -2563,7 +2564,7 @@ ahci_sata_connect(struct ahci_channel *c
 	int timeout;
 
 	/* Wait up to 100ms for "connect well" */
-	for (timeout = 0; timeout < 100 ; timeout++) {
+	for (timeout = 0; timeout < 1000 ; timeout++) {
 		status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
 		if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
 		    ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
@@ -2576,9 +2577,9 @@ ahci_sata_connect(struct ahci_channel *c
 			}
 			return (0);
 		}
-		DELAY(1000);
+		DELAY(100);
 	}
-	if (timeout >= 100) {
+	if (timeout >= 1000) {
 		if (bootverbose) {
 			device_printf(ch->dev, "SATA connect timeout status=%08x\n",
 			    status);
@@ -2586,8 +2587,8 @@ ahci_sata_connect(struct ahci_channel *c
 		return (0);
 	}
 	if (bootverbose) {
-		device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
-		    timeout, status);
+		device_printf(ch->dev, "SATA connect time=%dus status=%08x\n",
+		    timeout * 100, status);
 	}
 	/* Clear SATA error register */
 	ATA_OUTL(ch->r_mem, AHCI_P_SERR, 0xffffffff);
@@ -2619,11 +2620,10 @@ ahci_sata_phy_reset(device_t dev)
 	ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
 	    ATA_SC_DET_RESET | val |
 	    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER);
-	DELAY(5000);
+	DELAY(1000);
 	ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
 	    ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
 	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
-	DELAY(5000);
 	if (!ahci_sata_connect(ch)) {
 		if (ch->caps & AHCI_CAP_SSS) {
 			val = ATA_INL(ch->r_mem, AHCI_P_CMD);



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