Module Name:    src
Committed By:   jdolecek
Date:           Sat Jun 24 14:33:06 UTC 2017

Modified Files:
        src/sys/dev/ata [jdolecek-ncq]: TODO.ncq
        src/sys/dev/ic [jdolecek-ncq]: mvsata.c mvsatavar.h

Log Message:
fix dump on mvsata - there was misplaced mvsata_bio_intr() call causing
diagnostic panic, and we also need to switch controller to appropriate
DMA mode (NCQ vs. non-NCQ DMA)

while here, also reduce delay for the polled command wait to 100 us, same
as siisata(4) and ahcisata(4)


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.25 -r1.1.2.26 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.35.6.14 -r1.35.6.15 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.2.48.1 -r1.2.48.2 src/sys/dev/ic/mvsatavar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ata/TODO.ncq
diff -u src/sys/dev/ata/TODO.ncq:1.1.2.25 src/sys/dev/ata/TODO.ncq:1.1.2.26
--- src/sys/dev/ata/TODO.ncq:1.1.2.25	Sat Jun 24 00:23:39 2017
+++ src/sys/dev/ata/TODO.ncq	Sat Jun 24 14:33:06 2017
@@ -1,9 +1,6 @@
 Bugs
 ----
 
-fix crashdump for mvsata - request times out (maybe same as HEAD?)
-- HEAD crash due to KASSERT(chp->ch_queue->active_xfer != NULL)
-
 siisata - fix all new XXX and unmergable bits
 
 test wd* at umass?, confirm the ata_channel kludge works

Index: src/sys/dev/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.14 src/sys/dev/ic/mvsata.c:1.35.6.15
--- src/sys/dev/ic/mvsata.c:1.35.6.14	Wed Jun 21 19:38:43 2017
+++ src/sys/dev/ic/mvsata.c	Sat Jun 24 14:33:06 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.14 2017/06/21 19:38:43 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.14 2017/06/21 19:38:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -182,7 +182,7 @@ static uint32_t mvsata_softreset(struct 
 static void mvsata_edma_reset_qptr(struct mvsata_port *);
 static inline void mvsata_edma_enable(struct mvsata_port *);
 static int mvsata_edma_disable(struct mvsata_port *, int, int);
-static void mvsata_edma_config(struct mvsata_port *, int);
+static void mvsata_edma_config(struct mvsata_port *, enum mvsata_edmamode);
 
 static void mvsata_edma_setup_crqb(struct mvsata_port *, int,
 				   struct ata_xfer *);
@@ -501,7 +501,7 @@ mvsata_error(struct mvsata_port *mvport)
 #ifndef MVSATA_WITHOUTDMA
 	if ((sc->sc_gen == gen1 && cause & EDMA_IE_ETRANSINT) ||
 	    (sc->sc_gen != gen1 && cause & EDMA_IE_ESELFDIS)) {
-		switch (mvport->port_edmamode) {
+		switch (mvport->port_edmamode_curr) {
 		case dma:
 		case queued:
 		case ncq:
@@ -653,7 +653,7 @@ mvsata_reset_channel(struct ata_channel 
 
 	ata_kill_active(chp, KILL_RESET, flags);
 
-	mvsata_edma_config(mvport, mvport->port_edmamode);
+	mvsata_edma_config(mvport, mvport->port_edmamode_curr);
 	mvsata_edma_reset_qptr(mvport);
 	mvsata_edma_enable(mvport);
 	return;
@@ -1093,7 +1093,6 @@ mvsata_bio_start(struct ata_channel *chp
 		if (drvp->n_xfers <= NXFER)
 			drvp->n_xfers++;
 
-again:
 	/*
 	 *
 	 * When starting a multi-sector transfer, or doing single-sector
@@ -1129,9 +1128,16 @@ again:
 			/* Transfer is okay now. */
 		}
 		if (xfer->c_flags & C_DMA) {
+			enum mvsata_edmamode dmamode;
+
 			ata_bio->nblks = nblks;
 			ata_bio->nbytes = xfer->c_bcount;
 
+			/* switch to appropriate dma mode if necessary */
+			dmamode = (xfer->c_flags & C_NCQ) ? ncq : dma;
+			if (mvport->port_edmamode_curr != dmamode)
+				mvsata_edma_config(mvport, dmamode);
+
 			if (xfer->c_flags & C_POLL)
 				sc->sc_enable_intr(mvport, 0 /*off*/);
 			error = mvsata_edma_enqueue(mvport, xfer);
@@ -1201,7 +1207,7 @@ do_pio:
 			    WDCC_READ : WDCC_WRITE;
 
 		/* EDMA disable, if enabled this channel. */
-		if (mvport->port_edmamode != nodma)
+		if (mvport->port_edmamode_curr != nodma)
 			mvsata_edma_disable(mvport, 10 /* ms */, wait_flags);
 
 		mvsata_pmp_select(mvport, xfer->c_drive);
@@ -1300,9 +1306,8 @@ intr:
 			sc->sc_enable_intr(mvport, 1 /*on*/);
 			chp->ch_flags &= ~ATACH_DMA_WAIT;
 		}
-		mvsata_bio_intr(chp, xfer, 0);
 		if ((ata_bio->flags & ATA_ITSDONE) == 0)
-			goto again;
+			mvsata_bio_intr(chp, xfer, 0);
 	}
 	return;
 
@@ -1421,7 +1426,7 @@ mvsata_bio_kill_xfer(struct ata_channel 
 	    device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive));
 
 	/* EDMA restart, if enabled */
-	if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode != nodma) {
+	if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode_curr != nodma) {
 		mvsata_edma_reset_qptr(mvport);
 		mvsata_edma_enable(mvport);
 	}
@@ -1460,7 +1465,7 @@ mvsata_bio_done(struct ata_channel *chp,
 	callout_stop(&xfer->c_timo_callout);
 
 	/* EDMA restart, if enabled */
-	if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode != nodma) {
+	if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode_curr != nodma) {
 		mvsata_edma_reset_qptr(mvport);
 		mvsata_edma_enable(mvport);
 	}
@@ -1598,7 +1603,7 @@ mvsata_wdc_cmd_start(struct ata_channel 
 	    device_xname(MVSATA_DEV2(mvport)), chp->ch_channel, drive));
 
 	/* First, EDMA disable, if enabled this channel. */
-	if (mvport->port_edmamode != nodma)
+	if (mvport->port_edmamode_curr != nodma)
 		mvsata_edma_disable(mvport, 10 /* ms */, wait_flags);
 
 	mvsata_pmp_select(mvport, drive);
@@ -1854,7 +1859,7 @@ mvsata_wdc_cmd_done_end(struct ata_chann
 	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	/* EDMA restart, if enabled */
-	if (mvport->port_edmamode != nodma) {
+	if (mvport->port_edmamode_curr != nodma) {
 		mvsata_edma_reset_qptr(mvport);
 		mvsata_edma_enable(mvport);
 	}
@@ -1885,7 +1890,7 @@ mvsata_atapi_start(struct ata_channel *c
 	    device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
 	    xfer->c_drive, sc_xfer->xs_control));
 
-	if (mvport->port_edmamode != nodma)
+	if (mvport->port_edmamode_curr != nodma)
 		mvsata_edma_disable(mvport, 10 /* ms */, wait_flags);
 
 	mvsata_pmp_select(mvport, xfer->c_drive);
@@ -2653,13 +2658,12 @@ mvsata_edma_handle(struct mvsata_port *m
 static int
 mvsata_edma_wait(struct mvsata_port *mvport, struct ata_xfer *xfer, int timeout)
 {
-	struct ata_bio *ata_bio = &xfer->c_bio;
 	int xtime;
 
-	for (xtime = 0;  xtime < timeout / 10; xtime++) {
+	for (xtime = 0;  xtime < timeout * 10; xtime++) {
 		if (mvsata_edma_handle(mvport, xfer))
 			return 0;
-		ata_delay(10, "mvsataipl", ata_bio->flags);
+		DELAY(100);
 	}
 
 	DPRINTF(("mvsata_edma_wait: timeout: %p\n", xfer));
@@ -2728,7 +2732,7 @@ mvsata_edma_rqq_remove(struct mvsata_por
 	    sizeof(union mvsata_crqb) * MVSATA_EDMAQ_LEN,
 	    BUS_DMASYNC_POSTWRITE);
 
-	mvsata_edma_config(mvport, mvport->port_edmamode);
+	mvsata_edma_config(mvport, mvport->port_edmamode_curr);
 	mvsata_edma_reset_qptr(mvport);
 	mvsata_edma_enable(mvport);
 
@@ -2833,7 +2837,7 @@ mvsata_port_init(struct mvsata_hc *mvhc,
 
 	mvport->port = port;
 	mvport->port_hc = mvhc;
-	mvport->port_edmamode = nodma;
+	mvport->port_edmamode_negotiated = nodma;
 
 	rv = bus_space_subregion(mvhc->hc_iot, mvhc->hc_ioh,
 	    EDMA_REGISTERS_OFFSET + port * EDMA_REGISTERS_SIZE,
@@ -3317,7 +3321,7 @@ mvsata_edma_disable(struct mvsata_port *
  *       ex. NCQ/TCQ(queued)/non queued.
  */
 static void
-mvsata_edma_config(struct mvsata_port *mvport, int mode)
+mvsata_edma_config(struct mvsata_port *mvport, enum mvsata_edmamode mode)
 {
 	struct mvsata_softc *sc = device_private(MVSATA_DEV2(mvport));
 	uint32_t reg;
@@ -3406,7 +3410,7 @@ mvsata_edma_config(struct mvsata_port *m
 		MVSATA_EDMA_WRITE_4(mvport, SATA_FISC, reg);
 	}
 
-	mvport->port_edmamode = mode;
+	mvport->port_edmamode_curr = mode;
 }
 
 
@@ -3449,7 +3453,7 @@ mvsata_edma_setup_crqb(struct mvsata_por
 	    htole16(rw | CRQB_CHOSTQUETAG(xfer->c_slot) |
 	        CRQB_CPMPORT(xfer->c_drive));
 	i = 0;
-	if (mvport->port_edmamode == dma) {
+	if (mvport->port_edmamode_curr == dma) {
 		if (ata_bio->flags & ATA_LBA48)
 			crqb->atacommand[i++] = htole16(CRQB_ATACOMMAND(
 			    CRQB_ATACOMMAND_SECTORCOUNT, ata_bio->nblks >> 8));

Index: src/sys/dev/ic/mvsatavar.h
diff -u src/sys/dev/ic/mvsatavar.h:1.2.48.1 src/sys/dev/ic/mvsatavar.h:1.2.48.2
--- src/sys/dev/ic/mvsatavar.h:1.2.48.1	Fri Jun  9 20:18:58 2017
+++ src/sys/dev/ic/mvsatavar.h	Sat Jun 24 14:33:06 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsatavar.h,v 1.2.48.1 2017/06/09 20:18:58 jdolecek Exp $	*/
+/*	$NetBSD: mvsatavar.h,v 1.2.48.2 2017/06/24 14:33:06 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -57,18 +57,21 @@ struct _fix_phy_param {
 	void (*_fix_phy)(struct mvsata_port *);
 };
 
+enum mvsata_edmamode {
+	nodma,
+	dma,
+	queued,
+	ncq,
+};
+
 struct mvsata_port {
 	struct ata_channel port_ata_channel;
 
 	int port;
 	struct mvsata_hc *port_hc;
 
-	enum {
-		nodma,
-		dma,
-		queued,
-		ncq,
-	} port_edmamode;
+	enum mvsata_edmamode port_edmamode_negotiated;
+	enum mvsata_edmamode port_edmamode_curr;
 
 	uint32_t port_quetagidx;	/* Host Queue Tag valiable */
 

Reply via email to