Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Oct 2009 10:53:09 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 169786 for review
Message-ID:  <200910251053.n9PAr9aA092730@repoman.freebsd.org>

index | next in thread | raw e-mail

http://p4web.freebsd.org/chv.cgi?CH=169786

Change 169786 by mav@mav_mavtest on 2009/10/25 10:53:01

	If after device reset we got connect status, but not ready, try
	to do full port reset.
	On full port reset keep PMP presence information. It could be not
	needed if XPT do full bus reinitialization, but now it doesn't.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/siis/siis.c#11 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/dev/siis/siis.c#11 (text+ko) ====

@@ -511,7 +511,10 @@
 	/* Get port out of reset state. */
 	ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET);
 	ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT);
-	ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
+	if (ch->pm_present)
+		ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME);
+	else
+		ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
 	/* Enable port interrupts */
 	ATA_OUTL(ch->r_mem, SIIS_P_IESET, SIIS_P_IX_ENABLED);
 	return (0);
@@ -1296,7 +1299,7 @@
 siis_reset(device_t dev)
 {
 	struct siis_channel *ch = device_get_softc(dev);
-	int i;
+	int i, retry = 0;
 	uint32_t val;
 
 	if (bootverbose)
@@ -1336,6 +1339,7 @@
 	ATA_OUTL(ch->r_mem, SIIS_P_SCTL,
 	    ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
 	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
+retry:
 	siis_devreset(dev);
 	/* Reset and reconnect PHY, */
 	if (!siis_sata_connect(ch)) {
@@ -1350,8 +1354,25 @@
 		return;
 	}
 	/* Wait for clearing busy status. */
-	if (siis_wait_ready(dev, 10000))
+	if (siis_wait_ready(dev, 10000)) {
 		device_printf(dev, "device ready timeout\n");
+		if (!retry) {
+			device_printf(dev, "trying full port reset ...\n");
+			/* Get port to the reset state. */
+			ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PORT_RESET);
+			DELAY(10000);
+			/* Get port out of reset state. */
+			ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PORT_RESET);
+			ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_32BIT);
+			if (ch->pm_present)
+				ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME);
+			else
+				ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
+			siis_wait_ready(dev, 5000);
+			retry = 1;
+			goto retry;
+		}
+	}
 	ch->devices = 1;
 	/* Enable port interrupts */
 	ATA_OUTL(ch->r_mem, SIIS_P_IS, 0xFFFFFFFF);
@@ -1487,7 +1508,8 @@
 		struct	ccb_trans_settings *cts = &ccb->cts;
 
 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) {
-			if (cts->xport_specific.sata.pm_present)
+			ch->pm_present = cts->xport_specific.sata.pm_present;
+			if (ch->pm_present)
 				ATA_OUTL(ch->r_mem, SIIS_P_CTLSET, SIIS_P_CTL_PME);
 			else
 				ATA_OUTL(ch->r_mem, SIIS_P_CTLCLR, SIIS_P_CTL_PME);
@@ -1522,9 +1544,7 @@
 			cts->xport_specific.sata.bitrate = 150000;
 			cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
 		}
-		cts->xport_specific.sata.pm_present =
-			(ATA_INL(ch->r_mem, SIIS_P_STS) & SIIS_P_CTL_PME) ?
-			    1 : 0;
+		cts->xport_specific.sata.pm_present = ch->pm_present;
 		cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM;
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);


help

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