PERFORCE change 163665 for review

Alexander Motin mav at FreeBSD.org
Sat Jun 6 21:21:21 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163665

Change 163665 by mav at mav_mavbook on 2009/06/06 21:20:54

	Add minimal SATA PHY events handling.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#13 edit

Differences ...

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

@@ -638,6 +638,30 @@
 DRIVER_MODULE(ahcich, ahci, ahcich_driver, ahci_devclass, 0, 0);
 
 static void
+ahci_phy_check_events(device_t dev)
+{
+    struct ahci_channel *ch = device_get_softc(dev);
+    u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR);
+
+    /* clear error bits/interrupt */
+    ATA_IDX_OUTL(ch, ATA_SERROR, error);
+
+    /* if we have a connection event deal with it */
+    if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
+	if (bootverbose) {
+	    u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS);
+	    if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
+		((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+		((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) {
+		    device_printf(dev, "CONNECT requested\n");
+	    } else
+		    device_printf(dev, "DISCONNECT requested\n");
+	}
+//	taskqueue_enqueue(taskqueue_thread, &ch->conntask);
+    }
+}
+
+static void
 ahci_ch_intr(void *data)
 {
 	device_t dev = (device_t)data;
@@ -657,8 +681,8 @@
 	ATA_OUTL(ch->r_mem, AHCI_P_IS, istatus);
 
 	/* Process PHY events */
-//	if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
-//	    ata_sata_phy_check_events(dev);
+	if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
+		ahci_phy_check_events(dev);
 
 #define AHCI_STATBITS \
 	(AHCI_P_IX_IF|AHCI_P_IX_HBD|AHCI_P_IX_HBF|AHCI_P_IX_TFE)
@@ -1581,75 +1605,72 @@
 static int
 ata_sata_connect(struct ahci_channel *ch)
 {
-    u_int32_t status;
-    int timeout;
+	u_int32_t status;
+	int timeout;
 
-    /* wait up to 1 second for "connect well" */
-    for (timeout = 0; timeout < 100 ; timeout++) {
-	status = ATA_IDX_INL(ch, ATA_SSTATUS);
-	if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
-	    (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
-	    break;
-	DELAY(10000);
-    }
-    if (timeout >= 100) {
+	/* wait up to 1 second for "connect well" */
+	for (timeout = 0; timeout < 100 ; timeout++) {
+		status = ATA_IDX_INL(ch, ATA_SSTATUS);
+		if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
+		    ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+		    ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE))
+			break;
+		DELAY(10000);
+	}
+	if (timeout >= 100) {
+		if (bootverbose) {
+			device_printf(ch->dev, "SATA connect timeout status=%08x\n",
+			    status);
+		}
+		return (0);
+	}
 	if (bootverbose) {
-		device_printf(ch->dev, "SATA connect timeout status=%08x\n",
-		    status);
+		device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
+		    timeout * 10, status);
 	}
-	return 0;
-    }
-    if (bootverbose) {
-	    device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
-		timeout * 10, status);
-    }
 
-    /* clear SATA error register */
-    ATA_IDX_OUTL(ch, ATA_SERROR, 0xffffffff);
-
-    return 1;
+	/* clear SATA error register */
+	ATA_IDX_OUTL(ch, ATA_SERROR, 0xffffffff);
+	return (1);
 }
 
 static int
 ata_sata_phy_reset(device_t dev, int quick)
 {
-    struct ahci_channel *ch = device_get_softc(dev);
-    int loop, retry;
-    uint32_t val;
+	struct ahci_channel *ch = device_get_softc(dev);
+	int loop, retry;
+	uint32_t val;
 
-    if (quick) {
-	val = ATA_IDX_INL(ch, ATA_SCONTROL);
-	    return (0);
-	if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
-	    return ata_sata_connect(ch);
-    }
+	if (quick) {
+		val = ATA_IDX_INL(ch, ATA_SCONTROL);
+		if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
+			return (ata_sata_connect(ch));
+	}
 
-    if (bootverbose) {
-	    device_printf(dev, "hardware reset ...\n");
-    }
-    for (retry = 0; retry < 10; retry++) {
-	for (loop = 0; loop < 10; loop++) {
-	    ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
-	    DELAY(100);
-	    val = ATA_IDX_INL(ch, ATA_SCONTROL);
-	    if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
-		break;
+	if (bootverbose)
+		device_printf(dev, "hardware reset ...\n");
+	for (retry = 0; retry < 10; retry++) {
+		for (loop = 0; loop < 10; loop++) {
+			ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET);
+			DELAY(100);
+			val = ATA_IDX_INL(ch, ATA_SCONTROL);
+			if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
+				break;
+		}
+		DELAY(5000);
+		for (loop = 0; loop < 10; loop++) {
+			ATA_IDX_OUTL(ch, ATA_SCONTROL,
+			    ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
+			    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER));
+			DELAY(100);
+			val = ATA_IDX_INL(ch, ATA_SCONTROL);
+			if ((val & ATA_SC_DET_MASK) == 0)
+				return (ata_sata_connect(ch));
+		}
 	}
-	DELAY(5000);
-	for (loop = 0; loop < 10; loop++) {
-	    ATA_IDX_OUTL(ch, ATA_SCONTROL,
-		    ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
-		    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER));
-	    DELAY(100);
-	    val = ATA_IDX_INL(ch, ATA_SCONTROL);
-	    if ((val & ATA_SC_DET_MASK) == 0)
-		return ata_sata_connect(ch);
-	}
-    }
-    return 0;
+	return (0);
 }
 
-
 static void
 ahciaction(struct cam_sim *sim, union ccb *ccb)
 {


More information about the p4-projects mailing list