Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Apr 2010 13:18:38 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 177212 for review
Message-ID:  <201004221318.o3MDIc72014625@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@177212?ac=10

Change 177212 by mav@mav_mavtest on 2010/04/22 13:18:08

	Improve Asynchronous Notifications support.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#9 edit

Differences ...

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

@@ -232,12 +232,21 @@
 mvs_ch_resume(device_t dev)
 {
 	struct mvs_channel *ch = device_get_softc(dev);
+	uint32_t reg;
 
 	/* Disable port interrupts */
 	ATA_OUTL(ch->r_mem, EDMA_IEM, 0);
 	/* Stop EDMA */
 	ch->curr_mode = MVS_EDMA_UNKNOWN;
 	mvs_set_edma_mode(dev, MVS_EDMA_OFF);
+	/* Clear and configure FIS interrupts. */
+	ATA_OUTL(ch->r_mem, SATA_FISIC, 0);
+	reg = ATA_INL(ch->r_mem, SATA_FISC);
+	reg |= SATA_FISC_FISWAIT4HOSTRDYEN_B1;
+	ATA_OUTL(ch->r_mem, SATA_FISC, reg);
+	reg = ATA_INL(ch->r_mem, SATA_FISIM);
+	reg |= SATA_FISC_FISWAIT4HOSTRDYEN_B1;
+	ATA_OUTL(ch->r_mem, SATA_FISC, reg);
 	/* Clear SATA error register. */
 	ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff);
 	/* Clear any outstanding error interrupts. */
@@ -534,22 +543,24 @@
 }
 
 static void
-mvs_notify_events(device_t dev, u_int32_t status)
+mvs_notify_events(device_t dev)
 {
 	struct mvs_channel *ch = device_get_softc(dev);
 	struct cam_path *dpath;
-	int i;
+	uint32_t fis;
+	int d;
 
+	fis = ATA_INL(ch->r_mem, SATA_FISDW0);
+	if ((fis & 0x80ff) == 0x80a1)
+		d = (fis & 0x0f00) >> 8;
+	else
+		d = ch->pm_present ? 15 : 0;
 	if (bootverbose)
-		device_printf(dev, "SNTF 0x%04x\n", status);
-	for (i = 0; i < 16; i++) {
-		if ((status & (1 << i)) == 0)
-			continue;
-		if (xpt_create_path(&dpath, NULL,
-		    xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) {
-			xpt_async(AC_SCSI_AEN, dpath, NULL);
-			xpt_free_path(dpath);
-		}
+		device_printf(dev, "SNTF %d\n", d);
+	if (xpt_create_path(&dpath, NULL,
+	    xpt_path_path_id(ch->path), d, 0) == CAM_REQ_CMP) {
+		xpt_async(AC_SCSI_AEN, dpath, NULL);
+		xpt_free_path(dpath);
 	}
 }
 
@@ -592,7 +603,7 @@
 	struct mvs_channel *ch = device_get_softc(dev);
 	uint32_t iec, serr = 0, fisic = 0;
 	enum mvs_err_type et;
-	int i, ccs, port = -1;
+	int i, ccs, port = -1, selfdis = 0;
 	int edma = (ch->numtslots != 0 || ch->numdslots != 0);
 
 //device_printf(dev, "irq cause %02x EDMA %d IEC %08x\n",
@@ -608,12 +619,19 @@
 			ATA_OUTL(ch->r_mem, SATA_SE, serr);
 device_printf(dev, "SERR %08x\n", serr);
 		}
+		if (iec & EDMA_IE_ESELFDIS)
+			selfdis = 1;
 		if (iec & EDMA_IE_ETRANSINT) {
-			fisic = ATA_INL(ch->r_mem, SATA_FISIC);
-device_printf(dev, "FISC %08x\n", ATA_INL(ch->r_mem, SATA_FISC));
+			if (ch->quirks & MVS_Q_GENI)
+				selfdis = 1;
+			else if (ch->quirks & MVS_Q_GENII)
+				fisic = SATA_FISC_FISWAIT4HOSTRDYEN_B1;
+			else
+				fisic = ATA_INL(ch->r_mem, SATA_FISIC);
 device_printf(dev, "FISIC %08x\n", fisic);
-device_printf(dev, "FISIM %08x\n", ATA_INL(ch->r_mem, SATA_FISIM));
 		}
+		if (selfdis)
+			ch->curr_mode = MVS_EDMA_OFF;
 		ATA_OUTL(ch->r_mem, EDMA_IEC, ~iec);
 		/* Interface errors or Device error. */
 		if (iec & (0xfc1e9000 | EDMA_IE_EDEVERR)) {
@@ -641,7 +659,7 @@
 					/* If several ports were active and EDMA still enabled - 
 					 * other ports are probably unaffected and may continue.
 					 */
-					if (port == -2 && (iec & EDMA_IE_ESELFDIS) == 0) {
+					if (port == -2 && !selfdis) {
 						uint16_t p = ATA_INL(ch->r_mem, SATA_SATAITC) >> 16;
 						port = ffs(p) - 1;
 						if (port != (fls(p) - 1))
@@ -684,15 +702,13 @@
 				mvs_end_transaction(&ch->slot[i], et);
 			}
 		}
+		if (fisic & SATA_FISC_FISWAIT4HOSTRDYEN_B1)
+			mvs_notify_events(dev);
 		if (fisic)
 			ATA_OUTL(ch->r_mem, SATA_FISIC, ~fisic);
-		if (iec & EDMA_IE_ESELFDIS)
-			ch->curr_mode = MVS_EDMA_OFF;
 		if ((iec & (EDMA_IE_EDEVDIS | EDMA_IE_EDEVCON)) ||
 		    (serr & ATA_SE_PHY_CHANGED))
 			mvs_phy_check_events(dev, serr);
-		if (fisic & SATA_FISC_FISWAIT4HOSTRDYEN_B1)
-			mvs_notify_events(dev, ch->pm_present ? 0x8000 : 0x0001);
 	}
 	if ((arg->cause & 2) && !edma)
 		mvs_legacy_intr(dev);



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