PERFORCE change 177181 for review

Alexander Motin mav at FreeBSD.org
Wed Apr 21 17:34:48 UTC 2010


http://p4web.freebsd.org/@@177181?ac=10

Change 177181 by mav at mav_mavtest on 2010/04/21 17:34:41

	Some nits to make NCQ really working.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#6 edit
.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#5 edit

Differences ...

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

@@ -306,7 +306,7 @@
 mvs_setup_interrupt(device_t dev)
 {
 	struct mvs_controller *ctlr = device_get_softc(dev);
-	int msi = 1;
+	int msi = 0;
 
 	/* Process hints. */
 	resource_int_value(device_get_name(dev),
@@ -352,7 +352,7 @@
 	u_int32_t ic, aic;
 
 	ic = ATA_INL(ctlr->r_mem, CHIP_MIC);
-device_printf(ctlr->dev, "irq MIC:%08x\n", ic);
+//device_printf(ctlr->dev, "irq MIC:%08x\n", ic);
 	if (ic & IC_ALL_PORTS_COAL_DONE)
 		ATA_OUTL(ctlr->r_mem, CHIP_MIC, ~IC_ALL_PORTS_COAL_DONE);
 	for (p = 0; p < ctlr->channels; p++) {
@@ -656,7 +656,7 @@
 	/* Clear any outstanding error interrupts. */
 	ATA_OUTL(ch->r_mem, EDMA_IEC, 0);
 	/* Unmask all error interrupts */
-	ATA_OUTL(ch->r_mem, EDMA_IEM, 0xffffffff);
+	ATA_OUTL(ch->r_mem, EDMA_IEM, ~EDMA_IE_TRANSIENT);
 	return (0);
 }
 
@@ -825,7 +825,7 @@
 {
 	struct mvs_channel *ch = device_get_softc(dev);
 	int timeout;
-	uint32_t reg;
+	uint32_t ecfg, fcfg, hc, ltm;
 
 	if (mode == ch->curr_mode)
 		return;
@@ -848,29 +848,53 @@
 	if (mode == MVS_EDMA_OFF)
 		return;
 	/* Configure new mode. */
-	reg = EDMA_CFG_RESERVED | EDMA_CFG_RESERVED2 | EDMA_CFG_EHOSTQUEUECACHEEN;
+	ecfg = EDMA_CFG_RESERVED | EDMA_CFG_RESERVED2 | EDMA_CFG_EHOSTQUEUECACHEEN;
 	if (ch->pm_present) {
-		reg |= EDMA_CFG_EMASKRXPM;
+		ecfg |= EDMA_CFG_EMASKRXPM;
 		if (ch->quirks & MVS_Q_GENIIE) {
-			reg |= EDMA_CFG_EEDMAFBS | EDMA_CFG_EDMAFBS;
+			ecfg |= EDMA_CFG_EEDMAFBS;// | EDMA_CFG_EDMAFBS;
 			ch->fbs_enabled = 1;
 		}
 	}
-	reg |= 1 << 24;
-//	reg |= 1 << 22;
-	reg &= ~(EDMA_CFG_ESATANATVCMDQUE | EDMA_CFG_EQUE);
+	ecfg |= 1 << 24;
+//	ecfg |= 1 << 22;
+	ecfg &= ~(EDMA_CFG_ESATANATVCMDQUE | EDMA_CFG_EQUE);
 	if (mode == MVS_EDMA_QUEUED) {
-		reg |= EDMA_CFG_EQUE;
+		ecfg |= EDMA_CFG_EQUE;
 	} else if (mode == MVS_EDMA_NCQ) {
-		reg |= EDMA_CFG_ESATANATVCMDQUE;
+		ecfg |= EDMA_CFG_ESATANATVCMDQUE;
 	}
-	ATA_OUTL(ch->r_mem, EDMA_CFG, reg);
+	ATA_OUTL(ch->r_mem, EDMA_CFG, ecfg);
 	mvs_setup_edma_queues(dev);
 	/* Configure FBS */
-//	device_printf(dev, "fisc %08x\n",ATA_INL(ch->r_mem, SATA_FISC));
-//	device_printf(dev, "ltmode %08x\n",ATA_INL(ch->r_mem, SATA_LTM));
-//	device_printf(dev, "edmacfg %08x\n",ATA_INL(ch->r_mem, EDMA_CFG));
-//	device_printf(dev, "haltcond %08x\n",ATA_INL(ch->r_mem, EDMA_HC));
+	if (ch->quirks & MVS_Q_GENIIE) {
+		fcfg = ATA_INL(ch->r_mem, SATA_FISC);
+		ltm = ATA_INL(ch->r_mem, SATA_LTM);
+		hc = ATA_INL(ch->r_mem, EDMA_HC);
+		if (ch->fbs_enabled) {
+			fcfg |= SATA_FISC_FISDMAACTIVATESYNCRESP;
+			if (mode == MVS_EDMA_NCQ) {
+				fcfg &= ~SATA_FISC_FISWAIT4HOSTRDYEN_B0;
+				hc &= ~EDMA_IE_EDEVERR;
+			} else {
+				fcfg |= SATA_FISC_FISWAIT4HOSTRDYEN_B0;
+				hc |= EDMA_IE_EDEVERR;
+			}
+			ltm |= (1 << 8);
+		} else {
+			fcfg &= ~SATA_FISC_FISDMAACTIVATESYNCRESP;
+			fcfg &= ~SATA_FISC_FISWAIT4HOSTRDYEN_B0;
+			hc |= EDMA_IE_EDEVERR;
+			ltm &= ~(1 << 8);
+		}
+		ATA_OUTL(ch->r_mem, SATA_FISC, fcfg);
+		ATA_OUTL(ch->r_mem, SATA_LTM, ltm);
+		ATA_OUTL(ch->r_mem, EDMA_HC, hc);
+	}
+	device_printf(dev, "fisc %08x\n",ATA_INL(ch->r_mem, SATA_FISC));
+	device_printf(dev, "ltmode %08x\n",ATA_INL(ch->r_mem, SATA_LTM));
+	device_printf(dev, "edmacfg %08x\n",ATA_INL(ch->r_mem, EDMA_CFG));
+	device_printf(dev, "haltcond %08x\n",ATA_INL(ch->r_mem, EDMA_HC));
 	/* Run EDMA. */
 	ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EENEDMA);
 }
@@ -989,6 +1013,8 @@
 		mvs_crbq_intr(dev);
 	if (arg->cause & 1) {
 		iec = ATA_INL(ch->r_mem, EDMA_IEC);
+device_printf(dev, "irq cause %02x EDMA %d IEC %08x\n",
+    arg->cause, edma, iec);
 		if (iec & EDMA_IE_SERRINT) {
 			serr = ATA_INL(ch->r_mem, SATA_SE);
 			ATA_OUTL(ch->r_mem, SATA_SE, serr);
@@ -1002,7 +1028,7 @@
 		}
 		ATA_OUTL(ch->r_mem, EDMA_IEC, ~iec);
 		/* Interface errors or Device error. */
-		if (iec & (0xfffff000 | EDMA_IE_EDEVERR)) {
+		if (iec & (0xfc1e9000 | EDMA_IE_EDEVERR)) {
 			port = -1;
 			if (ch->numpslots != 0) {
 				ccs = 0;
@@ -1060,7 +1086,7 @@
 					et = MVS_ERR_TFE;
 					ch->fatalerr = 1;
 				    }
-				} else if (iec & 0xfffff000) {
+				} else if (iec & 0xfc1e9000) {
 					if (ch->numtslots == 0 && i != ccs && port != -2)
 						et = MVS_ERR_INNOCENT;
 					else
@@ -1115,7 +1141,7 @@
 //	device_printf(dev, "Legacy intr status %02x\n",
 //	    status);
 	if (slot->state < MVS_SLOT_RUNNING) {
-	    device_printf(dev, "Stray irq\n");
+//	    device_printf(dev, "Stray irq\n");
 	    return;
 	}
 	port = ccb->ccb_h.target_id & 0x0f;
@@ -1291,42 +1317,46 @@
 	struct mvs_channel *ch = device_get_softc(dev);
 	struct mvs_crpb *crpb;
 	union ccb *ccb;
-	int in_idx, slot;
+	int in_idx, cin_idx, slot;
 	uint16_t flags;
 
 	in_idx = (ATA_INL(ch->r_mem, EDMA_RESQIP) & EDMA_RESQP_ERPQP_MASK) >>
 	    EDMA_RESQP_ERPQP_SHIFT;
 	bus_dmamap_sync(ch->dma.workrp_tag, ch->dma.workrp_map,
 	    BUS_DMASYNC_POSTREAD);
-	while (in_idx != ch->in_idx) {
+	cin_idx = ch->in_idx;
+	ch->in_idx = in_idx;
+	while (in_idx != cin_idx) {
 		crpb = (struct mvs_crpb *)
-		    (ch->dma.workrp + MVS_CRPB_OFFSET + (MVS_CRPB_SIZE * ch->in_idx));
+		    (ch->dma.workrp + MVS_CRPB_OFFSET + (MVS_CRPB_SIZE * cin_idx));
 		slot = le16toh(crpb->id) & MVS_CRPB_TAG_MASK;
 		flags = le16toh(crpb->rspflg);
-//device_printf(dev, "CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+//device_printf(dev, "CRPB %d %d %04x\n", cin_idx, slot, flags);
 		/*
 		 * Handle only successfull completions.
 		 * Errors will be handled by main intr handler.
 		 */
 		if (ch->numtslots != 0 || (flags & EDMA_IE_EDEVERR) == 0) {
 if ((flags >> 8) & ATA_S_ERROR)
-device_printf(dev, "ERROR STATUS CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+device_printf(dev, "ERROR STATUS CRPB %d %d %04x\n", cin_idx, slot, flags);
 			if (ch->slot[slot].state >= MVS_SLOT_RUNNING) {
 				ccb = ch->slot[slot].ccb;
 				ccb->ataio.res.status = (flags & MVS_CRPB_ATASTS_MASK) >>
 				    MVS_CRPB_ATASTS_SHIFT;
 				mvs_end_transaction(&ch->slot[slot], MVS_ERR_NONE);
 			} else 
-device_printf(dev, "EMPTY CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+device_printf(dev, "EMPTY CRPB %d (->%d) %d %04x\n", cin_idx, in_idx, slot, flags);
 		} else
-device_printf(dev, "ERROR FLAGS CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+device_printf(dev, "ERROR FLAGS CRPB %d %d %04x\n", cin_idx, slot, flags);
 
-		ch->in_idx = (ch->in_idx + 1) & (MVS_MAX_SLOTS - 1);
+		cin_idx = (cin_idx + 1) & (MVS_MAX_SLOTS - 1);
 	}
 	bus_dmamap_sync(ch->dma.workrp_tag, ch->dma.workrp_map,
 	    BUS_DMASYNC_PREREAD);
-	ATA_OUTL(ch->r_mem, EDMA_RESQOP,
-	    ch->dma.workrp_bus | (ch->in_idx << EDMA_RESQP_ERPQP_SHIFT));
+	if (cin_idx == in_idx) {
+		ATA_OUTL(ch->r_mem, EDMA_RESQOP,
+		    ch->dma.workrp_bus | (cin_idx << EDMA_RESQP_ERPQP_SHIFT));
+	}
 }
 
 /* Must be called with channel locked. */
@@ -1633,8 +1663,8 @@
 	int port = ccb->ccb_h.target_id & 0x0f;
 	int i;
 
-	device_printf(dev, "%d EDMA command %02x size %d (%p) slot %d tag %d\n",
-	    port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len, ccb->ataio.data_ptr, slot->slot, slot->tag);
+//	device_printf(dev, "%d EDMA command %02x size %d slot %d tag %d\n",
+//	    port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len, slot->slot, slot->tag);
 	/* Get address of the prepared EPRD */
 	eprd = ch->dma.workrq_bus + MVS_EPRD_OFFSET + (MVS_EPRD_SIZE * slot->slot);
 	/* Prepare CRQB. Gen IIe uses different CRQB format. */
@@ -1807,7 +1837,7 @@
 	struct mvs_channel *ch = device_get_softc(dev);
 	union ccb *ccb = slot->ccb;
 
-device_printf(dev, "cmd done status %d\n", et);
+//device_printf(dev, "cmd done status %d\n", et);
 	bus_dmamap_sync(ch->dma.workrq_tag, ch->dma.workrq_map,
 	    BUS_DMASYNC_POSTWRITE);
 	/* Read result registers to the result struct
@@ -2136,7 +2166,7 @@
 		ch->devices = 0;
 		ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff);
 		ATA_OUTL(ch->r_mem, EDMA_IEC, 0);
-		ATA_OUTL(ch->r_mem, EDMA_IEM, 0xffffffff);
+		ATA_OUTL(ch->r_mem, EDMA_IEM, ~EDMA_IE_TRANSIENT);
 		xpt_release_simq(ch->sim, TRUE);
 		return;
 	}
@@ -2148,7 +2178,7 @@
 	ch->devices = 1;
 	ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff);
 	ATA_OUTL(ch->r_mem, EDMA_IEC, 0);
-	ATA_OUTL(ch->r_mem, EDMA_IEM, 0xffffffff);
+	ATA_OUTL(ch->r_mem, EDMA_IEM, ~EDMA_IE_TRANSIENT);
 	if (bootverbose)
 		device_printf(dev, "MVS reset done: device found\n");
 	xpt_release_simq(ch->sim, TRUE);

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

@@ -127,6 +127,8 @@
 #define EDMA_IE_LINKCTLTXERR(x)		((x) << 21)	/* Link Ctrl Tx Error */
 #define EDMA_IE_LINKDATATXERR(x)	((x) << 26)	/* Link Data Tx Error */
 #define EDMA_IE_TRANSPROTERR		(1 << 31)	/* Transport Proto E */
+#define EDMA_IE_TRANSIENT		(EDMA_IE_LINKCTLRXERR(0x0b) | \
+					 EDMA_IE_LINKCTLTXERR(0x1f))	/* Non-fatal Errors */
 #define EDMA_REQQBAH		0x10	/* Request Queue Base Address High */
 #define EDMA_REQQIP		0x14	/* Request Queue In-Pointer */
 #define EDMA_REQQOP		0x18	/* Request Queue Out-Pointer */


More information about the p4-projects mailing list