CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-10-07 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Oct  7 15:24:36 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c wdvar.h

Log Message:
make usage of NCQ 'high' priority for BPRIO_TIMECRITICAL xfers settable via
sysctl, too


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.35 -r1.428.2.36 src/sys/dev/ata/wd.c
cvs rdiff -u -r1.43.4.9 -r1.43.4.10 src/sys/dev/ata/wdvar.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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.35 src/sys/dev/ata/wd.c:1.428.2.36
--- src/sys/dev/ata/wd.c:1.428.2.35	Thu Sep 28 20:34:23 2017
+++ src/sys/dev/ata/wd.c	Sat Oct  7 15:24:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.36 2017/10/07 15:24:36 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.36 2017/10/07 15:24:36 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -751,7 +751,7 @@ wdstart1(struct wd_softc *wd, struct buf
 		xfer->c_bio.flags |= ATA_LBA48;
 		xfer->c_flags |= C_NCQ;
 
-		if ((wd->drvp->drive_flags & ATA_DRIVE_NCQ_PRIO) &&
+		if (WD_USE_NCQ_PRIO(wd) &&
 		BIO_GETPRIO(bp) == BPRIO_TIMECRITICAL)
 			xfer->c_bio.flags |= ATA_PRIO_HIGH;
 	}
@@ -2360,6 +2360,19 @@ wd_sysctl_attach(struct wd_softc *wd)
 		return;
 	}
 
+	wd->drv_ncq_prio = true;
+	if ((error = sysctl_createv(>nodelog, 0, NULL, NULL,
+CTLFLAG_READWRITE, CTLTYPE_BOOL, "use_ncq_prio",
+SYSCTL_DESCR("use NCQ PRIORITY if supported"),
+NULL, 0, >drv_ncq_prio, 0,
+CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
+!= 0) {
+		aprint_error_dev(wd->sc_dev,
+		"could not create %s.%s.use_ncq_prio sysctl - error %d\n",
+		"hw", device_xname(wd->sc_dev), error);
+		return;
+	}
+
 #ifdef WD_CHAOS_MONKEY
 	wd->drv_chaos_freq = 0;
 	if ((error = sysctl_createv(>nodelog, 0, NULL, NULL,

Index: src/sys/dev/ata/wdvar.h
diff -u src/sys/dev/ata/wdvar.h:1.43.4.9 src/sys/dev/ata/wdvar.h:1.43.4.10
--- src/sys/dev/ata/wdvar.h:1.43.4.9	Thu Sep 28 20:34:23 2017
+++ src/sys/dev/ata/wdvar.h	Sat Oct  7 15:24:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdvar.h,v 1.43.4.9 2017/09/28 20:34:23 jdolecek Exp $	*/
+/*	$NetBSD: wdvar.h,v 1.43.4.10 2017/10/07 15:24:36 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -78,6 +78,9 @@ struct wd_softc {
 	bool drv_ncq;
 #define WD_USE_NCQ(wd)	\
 	((wd)->drv_ncq && ((wd)->drvp->drive_flags & ATA_DRIVE_NCQ))
+	bool drv_ncq_prio;
+#define WD_USE_NCQ_PRIO(wd) \
+	((wd)->drv_ncq_prio && ((wd)->drvp->drive_flags & ATA_DRIVE_NCQ_PRIO))
 #ifdef WD_CHAOS_MONKEY
 	int drv_chaos_freq;		/* frequency of simulated bio errors */
 	int drv_chaos_cnt;		/* count of processed bio read xfers */



CVS commit: [jdolecek-ncq] src/sys/dev

2017-09-30 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Sep 30 21:32:32 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c
src/sys/dev/ic [jdolecek-ncq]: mvsata.c
src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
must drop channel lock before calling ata_dmaerr() to avoid 'locking against
myself' in case of consecutive errors from ata_reset_channel() called via
ata_downgrade_mode()


To generate a diff of this commit:
cvs rdiff -u -r1.105.6.11 -r1.105.6.12 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.35.6.31 -r1.35.6.32 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.123.4.13 -r1.123.4.14 src/sys/dev/scsipi/atapi_wdc.c

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/ata_wdc.c
diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.11 src/sys/dev/ata/ata_wdc.c:1.105.6.12
--- src/sys/dev/ata/ata_wdc.c:1.105.6.11	Tue Sep 26 20:15:36 2017
+++ src/sys/dev/ata/ata_wdc.c	Sat Sep 30 21:32:31 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $	*/
+/*	$NetBSD: ata_wdc.c,v 1.105.6.12 2017/09/30 21:32:31 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.12 2017/09/30 21:32:31 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -718,14 +718,18 @@ wdc_ata_bio_intr(struct ata_channel *chp
 		}
 		if (drv_err != WDC_ATA_ERR)
 			goto end;
-		if (ata_bio->r_error & WDCE_CRC || ata_bio->error == ERR_DMA)
+		if (ata_bio->r_error & WDCE_CRC || ata_bio->error == ERR_DMA) {
+			ata_channel_unlock(chp);
 			ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
+			goto err;
+		}
 	}
 #endif	/* NATA_DMA */
 
 	/* if we had an error, end */
 	if (drv_err == WDC_ATA_ERR) {
 		ata_channel_unlock(chp);
+err:
 		wdc_ata_bio_done(chp, xfer);
 		return 1;
 	}

Index: src/sys/dev/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.31 src/sys/dev/ic/mvsata.c:1.35.6.32
--- src/sys/dev/ic/mvsata.c:1.35.6.31	Wed Sep 27 07:19:34 2017
+++ src/sys/dev/ic/mvsata.c	Sat Sep 30 21:32:31 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.31 2017/09/27 07:19:34 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.32 2017/09/30 21:32:31 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.31 2017/09/27 07:19:34 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.32 2017/09/30 21:32:31 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1426,14 +1426,18 @@ mvsata_bio_intr(struct ata_channel *chp,
 	if (xfer->c_flags & C_DMA) {
 		if (ata_bio->error == NOERROR)
 			goto end;
-		if (ata_bio->error == ERR_DMA)
+		if (ata_bio->error == ERR_DMA) {
+			ata_channel_unlock(chp);
 			ata_dmaerr(drvp,
 			(xfer->c_flags & C_POLL) ? AT_POLL : 0);
+			goto err;
+		}
 	}
 
 	/* if we had an error, end */
 	if (ata_bio->error != NOERROR) {
 		ata_channel_unlock(chp);
+err:
 		mvsata_bio_done(chp, xfer);
 		return 1;
 	}
@@ -2349,10 +2353,10 @@ mvsata_atapi_intr(struct ata_channel *ch
 		aprint_error_dev(atac->atac_dev,
 		"channel %d: device timeout, c_bcount=%d, c_skip=%d\n",
 		chp->ch_channel, xfer->c_bcount, xfer->c_skip);
+		ata_channel_unlock(chp);
 		if (xfer->c_flags & C_DMA)
 			ata_dmaerr(drvp,
 			(xfer->c_flags & C_POLL) ? AT_POLL : 0);
-		ata_channel_unlock(chp);
 		sc_xfer->error = XS_TIMEOUT;
 		mvsata_atapi_reset(chp, xfer);
 		return 1;
@@ -2363,8 +2367,8 @@ mvsata_atapi_intr(struct ata_channel *ch
 	 * and reset device.
 	 */
 	if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) {
-		ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
 		ata_channel_unlock(chp);
+		ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
 		sc_xfer->error = XS_RESET;
 		mvsata_atapi_reset(chp, xfer);
 		return (1);
@@ -2425,10 +2429,10 @@ again:
 			aprint_error_dev(atac->atac_dev,
 			"channel %d drive %d: bad data phase DATAOUT\n",
 			chp->ch_channel, xfer->c_drive);
+			ata_channel_unlock(chp);
 			if (xfer->c_flags & C_DMA)
 ata_dmaerr(drvp,
 (xfer->c_flags & C_POLL) ? AT_POLL : 0);
-			ata_channel_unlock(chp);
 			sc_xfer->error = XS_TIMEOUT;
 			mvsata_atapi_reset(chp, xfer);
 			return 1;
@@ -2461,10 +2465,10 @@ again:
 			aprint_error_dev(atac->atac_dev,
 			"channel %d drive %d: bad data phase DATAIN\n",
 			chp->ch_channel, xfer->c_drive);
+			ata_channel_unlock(chp);
 			if (xfer->c_flags & C_DMA)
 ata_dmaerr(drvp,
 (xfer->c_flags & C_POLL) ? AT_POLL : 0);
-			ata_channel_unlock(chp);
 			sc_xfer->error = XS_TIMEOUT;
 			mvsata_atapi_reset(chp, xfer);
 			return 1;
@@ -2515,10 +2519,10 @@ again:
 			sc_xfer->error = XS_SHORTSENSE;
 			sc_xfer->sense.atapi_sense = 

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Sep 29 20:05:07 UTC 2017

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

Log Message:
introduce ATA_BSIZE and use it instead of DEV_BSIZE for get params and
recovery, where they are by spec 512 bytes and not negotiable


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.46 -r1.1.2.47 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.132.8.38 -r1.132.8.39 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.28 -r1.92.8.29 src/sys/dev/ata/atavar.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.46 src/sys/dev/ata/TODO.ncq:1.1.2.47
--- src/sys/dev/ata/TODO.ncq:1.1.2.46	Thu Sep 28 20:34:23 2017
+++ src/sys/dev/ata/TODO.ncq	Fri Sep 29 20:05:07 2017
@@ -2,10 +2,6 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-stop using DEV_BSIZE when really meaning ATA sector size and revert
- inclusion in:
-cvs rdiff -u -r1.2.30.1 -r1.2.30.2 src/sys/arch/amiga/dev/wdc_xsurf.c
-
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.38 src/sys/dev/ata/ata.c:1.132.8.39
--- src/sys/dev/ata/ata.c:1.132.8.38	Wed Sep 27 19:05:57 2017
+++ src/sys/dev/ata/ata.c	Fri Sep 29 20:05:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.39 2017/09/29 20:05:07 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.39 2017/09/29 20:05:07 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -961,7 +961,7 @@ ata_get_params(struct ata_drive_datas *d
 		return CMD_AGAIN;
 	}
 
-	tb = kmem_zalloc(DEV_BSIZE, KM_SLEEP);
+	tb = kmem_zalloc(ATA_BSIZE, KM_SLEEP);
 	memset(prms, 0, sizeof(struct ataparams));
 
 	if (drvp->drive_type == ATA_DRIVET_ATA) {
@@ -982,7 +982,7 @@ ata_get_params(struct ata_drive_datas *d
 	}
 	xfer->c_ata_c.flags = AT_READ | flags;
 	xfer->c_ata_c.data = tb;
-	xfer->c_ata_c.bcount = DEV_BSIZE;
+	xfer->c_ata_c.bcount = ATA_BSIZE;
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
 		xfer) != ATACMD_COMPLETE) {
 		ATADEBUG_PRINT(("ata_get_parms: wdc_exec_command failed\n"),
@@ -1044,7 +1044,7 @@ ata_get_params(struct ata_drive_datas *d
 
 	rv = CMD_OK;
  out:
-	kmem_free(tb, DEV_BSIZE);
+	kmem_free(tb, ATA_BSIZE);
 	ata_free_xfer(chp, xfer);
 	return rv;
 }
@@ -1110,7 +1110,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0);
 
 	tb = drvp->recovery_blk;
-	memset(tb, 0, DEV_BSIZE);
+	memset(tb, 0, sizeof(drvp->recovery_blk));
 
 	/*
 	 * We could use READ LOG DMA EXT if drive supports it (i.e.
@@ -1128,7 +1128,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	xfer->c_ata_c.flags = AT_READ | AT_LBA | AT_LBA48 | flags;
 	xfer->c_ata_c.timeout = 1000; /* 1s */
 	xfer->c_ata_c.data = tb;
-	xfer->c_ata_c.bcount = DEV_BSIZE;
+	xfer->c_ata_c.bcount = sizeof(drvp->recovery_blk);
 
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
 		xfer) != ATACMD_COMPLETE) {
@@ -1141,7 +1141,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	}
 
 	cksum = 0;
-	for (int i = 0; i < DEV_BSIZE; i++)
+	for (int i = 0; i < sizeof(drvp->recovery_blk); i++)
 		cksum += tb[i];
 	if (cksum != 0) {
 		aprint_error_dev(drvp->drv_softc,

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.28 src/sys/dev/ata/atavar.h:1.92.8.29
--- src/sys/dev/ata/atavar.h:1.92.8.28	Wed Sep 27 19:05:57 2017
+++ src/sys/dev/ata/atavar.h	Fri Sep 29 20:05:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.28 2017/09/27 19:05:57 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.29 2017/09/29 20:05:07 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -207,6 +207,8 @@ struct ata_xfer {
 #define ATA_MAX_OPENINGS	32
 #define ATA_REAL_OPENINGS(op)	((op) > 1 ? (op) - 1 : 1)
 
+#define ATA_BSIZE		512	/* Standard ATA block size (bytes) */
+
 /* Per-channel queue of ata_xfers */
 #ifndef ATABUS_PRIVATE
 struct ata_queue;
@@ -329,7 +331,7 @@ struct ata_drive_datas {
 	daddr_t	badsect[127];	/* 126 plus trailing -1 marker */
 
 	/* Recovery buffer */
-	uint8_t recovery_blk[DEV_BSIZE];
+	uint8_t recovery_blk[ATA_BSIZE];
 };
 
 /* User config flags that force (or disable) the use of a mode */



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-28 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Thu Sep 28 20:34:23 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq wd.c wdvar.h

Log Message:
add sysctls to control if NCQ is being used, and how many max tags;
I have a drive which is significantly slower with NCQ than non-NCQ,
and it's generally useful to have this easily overridable

while here, also move the frequency settings for WD_CHAOS_MONKEY
to a sysctl and make it per-drive


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.45 -r1.1.2.46 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.428.2.34 -r1.428.2.35 src/sys/dev/ata/wd.c
cvs rdiff -u -r1.43.4.8 -r1.43.4.9 src/sys/dev/ata/wdvar.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.45 src/sys/dev/ata/TODO.ncq:1.1.2.46
--- src/sys/dev/ata/TODO.ncq:1.1.2.45	Thu Sep 28 20:25:45 2017
+++ src/sys/dev/ata/TODO.ncq	Thu Sep 28 20:34:23 2017
@@ -32,8 +32,6 @@ set 
   is too much for emergency crash dump code path
 - old bug - kern/16789
 
-add nibble to control number of tags (1==disable NCQ)?
-
 add support for the NCQ TRIM if supported by device?
 
 implement DIOCGCACHE/DIOCCACHESYNC for ld@ataraid? just passthrough, like ccd

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.34 src/sys/dev/ata/wd.c:1.428.2.35
--- src/sys/dev/ata/wd.c:1.428.2.34	Sun Aug 13 15:12:04 2017
+++ src/sys/dev/ata/wd.c	Thu Sep 28 20:34:23 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -116,11 +116,6 @@ int wdcdebug_wd_mask = 0x0;
 #define ATADEBUG_PRINT(args, level)
 #endif
 
-#ifdef WD_CHAOS_MONKEY
-int wdcdebug_wd_cnt = 0;
-int wdcdebug_wd_chaos = 0;
-#endif
-
 int	wdprobe(device_t, cfdata_t, void *);
 void	wdattach(device_t, device_t, void *);
 int	wddetach(device_t, int);
@@ -211,6 +206,9 @@ bool  wd_shutdown(device_t, int);
 int   wd_getcache(struct wd_softc *, int *);
 int   wd_setcache(struct wd_softc *, int);
 
+static void wd_sysctl_attach(struct wd_softc *);
+static void wd_sysctl_detach(struct wd_softc *);
+
 struct dkdriver wddkdriver = {
 	.d_strategy = wdstrategy,
 	.d_minphys = wdminphys
@@ -450,6 +448,8 @@ out:
 
 	if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown))
 		aprint_error_dev(self, "couldn't establish power handler\n");
+
+	wd_sysctl_attach(wd);
 }
 
 static bool
@@ -520,6 +520,8 @@ wddetach(device_t self, int flags)
 
 	pmf_device_deregister(self);
 
+	wd_sysctl_detach(sc);
+
 	/* Unhook the entropy source. */
 	rnd_detach_source(>rnd_source);
 
@@ -663,8 +665,7 @@ wdstart(device_t self)
 	while (bufq_peek(wd->sc_q) != NULL) {
 		/* First try to get xfer. Limit to drive openings iff NCQ. */
 		xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
-		ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ)
-		? wd->drvp->drv_openings : 0);
+		WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0);
 		if (xfer == NULL)
 			break;
 
@@ -708,8 +709,8 @@ wdstart1(struct wd_softc *wd, struct buf
 	 * the command be clipped, or otherwise misinterpreted, by the
 	 * driver or controller.
 	 */
-	if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wdcdebug_wd_cnt > 0 &&
-	(++wdcdebug_wd_chaos % wdcdebug_wd_cnt) == 0) {
+	if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wd->drv_chaos_freq > 0 &&
+	(++wd->drv_chaos_cnt % wd->drv_chaos_freq) == 0) {
 		aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n",
 		__func__, xfer->c_slot);
 		xfer->c_bio.blkno = 777 + wd->sc_capacity;
@@ -745,8 +746,7 @@ wdstart1(struct wd_softc *wd, struct buf
 	 * the semantics - FUA would not be honored. In that case, continue
 	 * retrying with NCQ.
 	 */
-	if (wd->drvp->drive_flags & ATA_DRIVE_NCQ &&
-	(xfer->c_retries < WDIORETRIES_SINGLE ||
+	if (WD_USE_NCQ(wd) && (xfer->c_retries < WDIORETRIES_SINGLE ||
 	(bp->b_flags & B_MEDIA_FUA) != 0)) {
 		xfer->c_bio.flags |= ATA_LBA48;
 		xfer->c_flags |= C_NCQ;
@@ -1856,7 +1856,7 @@ wd_getcache(struct wd_softc *wd, int *bi
 	if (params.atap_cmd1_en & WDC_CMD1_CACHE)
 		*bitsp |= DKCACHE_WRITE;
 
-	if (wd->drvp->drive_flags & (ATA_DRIVE_NCQ|ATA_DRIVE_WFUA))
+	if (WD_USE_NCQ(wd) || (wd->drvp->drive_flags & ATA_DRIVE_WFUA))
 		*bitsp |= DKCACHE_FUA;
 
 	return 0;
@@ -2315,3 +2315,84 @@ out2:
 		bp->b_resid = bp->b_bcount;
 	biodone(bp);
 }
+
+static void
+wd_sysctl_attach(struct wd_softc *wd)
+{
+	const struct sysctlnode *node;
+	int error;
+
+	/* sysctl set-up */
+	if (sysctl_createv(>nodelog, 0, NULL, ,
+0, CTLTYPE_NODE, 

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-28 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Thu Sep 28 20:25:45 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
add note about DEV_BSIZE use


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.44 -r1.1.2.45 src/sys/dev/ata/TODO.ncq

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.44 src/sys/dev/ata/TODO.ncq:1.1.2.45
--- src/sys/dev/ata/TODO.ncq:1.1.2.44	Thu Sep 21 17:15:18 2017
+++ src/sys/dev/ata/TODO.ncq	Thu Sep 28 20:25:45 2017
@@ -2,6 +2,10 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
+stop using DEV_BSIZE when really meaning ATA sector size and revert
+ inclusion in:
+cvs rdiff -u -r1.2.30.1 -r1.2.30.2 src/sys/arch/amiga/dev/wdc_xsurf.c
+
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-27 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 27 19:05:57 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h

Log Message:
restore the atac_claim_hw and atac_free_hw hooks, they are used on atari


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.37 -r1.132.8.38 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.27 -r1.92.8.28 src/sys/dev/ata/atavar.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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.37 src/sys/dev/ata/ata.c:1.132.8.38
--- src/sys/dev/ata/ata.c:1.132.8.37	Mon Sep 25 22:43:46 2017
+++ src/sys/dev/ata/ata.c	Wed Sep 27 19:05:57 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1355,6 +1355,10 @@ again:
 		goto out;
 	}
 
+	if (atac->atac_claim_hw)
+		if (!atac->atac_claim_hw(chp, 0))
+			goto out;
+
 	ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d\n", xfer,
 	chp->ch_channel, xfer->c_drive), DEBUG_XFERS);
 	if (drvp->drive_flags & ATA_DRIVE_RESET) {
@@ -1529,6 +1533,9 @@ ata_free_xfer(struct ata_channel *chp, s
 	}
 #endif
 
+	if (chp->ch_atac->atac_free_hw)
+		chp->ch_atac->atac_free_hw(chp);
+ 
 	KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0);
 	KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0);
 	chq->queue_xfers_avail |= __BIT(xfer->c_slot);

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.27 src/sys/dev/ata/atavar.h:1.92.8.28
--- src/sys/dev/ata/atavar.h:1.92.8.27	Tue Sep 26 20:15:36 2017
+++ src/sys/dev/ata/atavar.h	Wed Sep 27 19:05:57 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.27 2017/09/26 20:15:36 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.28 2017/09/27 19:05:57 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -483,6 +483,13 @@ struct atac_softc {
 	void (*atac_probe)(struct ata_channel *);
 
 	/*
+	 * Optional callbacks to lock/unlock hardware.
+	 * Called with channel mutex held.
+	 */
+	int  (*atac_claim_hw)(struct ata_channel *, int);
+	void (*atac_free_hw)(struct ata_channel *);
+
+	/*
 	 * Optional callbacks to set drive mode.  Required for anything
 	 * but basic PIO operation.
 	 */



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-26 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Sep 26 20:15:36 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c atavar.h

Log Message:
make compile without NATA_DMA


To generate a diff of this commit:
cvs rdiff -u -r1.105.6.10 -r1.105.6.11 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.92.8.26 -r1.92.8.27 src/sys/dev/ata/atavar.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/ata_wdc.c
diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.10 src/sys/dev/ata/ata_wdc.c:1.105.6.11
--- src/sys/dev/ata/ata_wdc.c:1.105.6.10	Thu Sep 21 18:47:21 2017
+++ src/sys/dev/ata/ata_wdc.c	Tue Sep 26 20:15:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $	*/
+/*	$NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -340,9 +340,9 @@ _wdc_ata_bio_start(struct ata_channel *c
 	int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
 	uint16_t cyl;
 	uint8_t head, sect, cmd = 0;
-	int nblks;
+	int nblks, tfd;
 #if NATA_DMA || NATA_PIOBM
-	int error, dma_flags = 0, tfd;
+	int error, dma_flags = 0;
 #endif
 
 	ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.26 src/sys/dev/ata/atavar.h:1.92.8.27
--- src/sys/dev/ata/atavar.h:1.92.8.26	Tue Sep 19 21:06:25 2017
+++ src/sys/dev/ata/atavar.h	Tue Sep 26 20:15:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.26 2017/09/19 21:06:25 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.27 2017/09/26 20:15:36 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -304,9 +304,9 @@ struct ata_drive_datas {
 #define RESET  0
 #define READY  1
 
-#if NATA_DMA
 	uint8_t drv_openings;		/* # of command tags */
 
+#if NATA_DMA
 	/* numbers of xfers and DMA errs. Used by ata_dmaerr() */
 	uint8_t n_dmaerrs;
 	uint32_t n_xfers;



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-26 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Sep 26 17:05:37 UTC 2017

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

Log Message:
make compile without MVSATA_DEBUG


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.29 -r1.35.6.30 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.29 src/sys/dev/ic/mvsata.c:1.35.6.30
--- src/sys/dev/ic/mvsata.c:1.35.6.29	Mon Sep 25 22:50:20 2017
+++ src/sys/dev/ic/mvsata.c	Tue Sep 26 17:05:37 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.30 2017/09/26 17:05:37 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.30 2017/09/26 17:05:37 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1673,7 +1673,6 @@ static int
 mvsata_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = drvp->chnl_softc;
-	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct ata_command *ata_c = >c_ata_c;
 	int rv, s;
 
@@ -1681,7 +1680,8 @@ mvsata_exec_command(struct ata_drive_dat
 	("%s:%d: mvsata_exec_command: drive=%d, bcount=%d,"
 	" r_lba=0x%012"PRIx64", r_count=0x%04x, r_features=0x%04x,"
 	" r_device=0x%02x, r_command=0x%02x\n",
-	device_xname(MVSATA_DEV2(mvport)), chp->ch_channel,
+	device_xname(MVSATA_DEV2((struct mvsata_port *)chp)),
+	chp->ch_channel,
 	drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count,
 	ata_c->r_features, ata_c->r_device, ata_c->r_command));
 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-25 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Sep 25 22:50:20 UTC 2017

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

Log Message:
move mvsata_quetag_get() to the start routines, so that it always matches
the active list of ata queue; important during error recovery, fixes
panics when calling

in mvsata_edma_handle() ignore events for non-active xfers

fix some missing ata_channel_unlock() on error path in mvsata_bio_intr()
and mvsata_atapi_intr(), fixes 'locking against myself' with LOCKDEBUG

with this, mvsata(4) finally survives full fio run with wdcdebug_wd_cnt == 200


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.28 -r1.35.6.29 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.28 src/sys/dev/ic/mvsata.c:1.35.6.29
--- src/sys/dev/ic/mvsata.c:1.35.6.28	Fri Sep 22 20:19:08 2017
+++ src/sys/dev/ic/mvsata.c	Mon Sep 25 22:50:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1086,7 +1086,6 @@ static int
 mvsata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = drvp->chnl_softc;
-	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_bio *ata_bio = >c_bio;
 
@@ -1095,8 +1094,6 @@ mvsata_bio(struct ata_drive_datas *drvp,
 	", bcount=%ld\n", device_xname(atac->atac_dev), chp->ch_channel,
 	drvp->drive, ata_bio->blkno, ata_bio->bcount));
 
-	mvsata_quetag_get(mvport, xfer->c_slot);
-
 	if (atac->atac_cap & ATAC_CAP_NOIRQ)
 		ata_bio->flags |= ATA_POLL;
 	if (ata_bio->flags & ATA_POLL)
@@ -1135,6 +1132,8 @@ mvsata_bio_start(struct ata_channel *chp
 
 	ata_channel_lock_owned(chp);
 
+	mvsata_quetag_get(mvport, xfer->c_slot);
+
 	if (xfer->c_flags & C_DMA)
 		if (drvp->n_xfers <= NXFER)
 			drvp->n_xfers++;
@@ -1410,8 +1409,10 @@ mvsata_bio_intr(struct ata_channel *chp,
 	if (!(xfer->c_flags & C_DMA) &&
 	(wdc_wait_for_unbusy(chp, (irq == 0) ? ATA_DELAY : 0, AT_POLL, )
 			== WDCWAIT_TOUT)) {
-		if (irq && (xfer->c_flags & C_TIMEOU) == 0)
+		if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
+			ata_channel_unlock(chp);
 			return 0;	/* IRQ was not for us */
+		}
 		aprint_error_dev(atac->atac_dev,
 		"channel %d: drive %d timeout, c_bcount=%d, c_skip%d\n",
 		chp->ch_channel, xfer->c_drive, xfer->c_bcount,
@@ -1570,6 +1571,8 @@ mvsata_bio_ready(struct mvsata_port *mvp
 
 	flags |= AT_POLL;	/* XXX */
 
+	ata_channel_lock_owned(chp);
+
 	/*
 	 * disable interrupts, all commands here should be quick
 	 * enough to be able to poll, and we don't go here that often
@@ -1682,8 +1685,6 @@ mvsata_exec_command(struct ata_drive_dat
 	drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count,
 	ata_c->r_features, ata_c->r_device, ata_c->r_command));
 
-	mvsata_quetag_get(mvport, xfer->c_slot);
-
 	if (ata_c->flags & AT_POLL)
 		xfer->c_flags |= C_POLL;
 	if (ata_c->flags & AT_WAIT)
@@ -1736,6 +1737,8 @@ mvsata_wdc_cmd_start(struct ata_channel 
 
 	ata_channel_lock_owned(chp);
 
+	mvsata_quetag_get(mvport, xfer->c_slot);
+
 	/* First, EDMA disable, if enabled this channel. */
 	KASSERT((chp->ch_flags & ATACH_NCQ) == 0);
 	if (mvport->port_edmamode_curr != nodma)
@@ -2050,7 +2053,6 @@ mvsata_atapi_scsipi_request(struct scsip
 	struct atac_softc *atac = >sc_wdcdev.sc_atac;
 	struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
 	struct ata_xfer *xfer;
-	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	int drive, s;
 
 switch (req) {
@@ -2071,8 +2073,6 @@ mvsata_atapi_scsipi_request(struct scsip
 			return;
 		}
 
-		mvsata_quetag_get(mvport, xfer->c_slot);
-
 		if (sc_xfer->xs_control & XS_CTL_POLL)
 			xfer->c_flags |= C_POLL;
 		xfer->c_drive = drive;
@@ -2122,6 +2122,8 @@ mvsata_atapi_start(struct ata_channel *c
 
 	ata_channel_lock_owned(chp);
 
+	mvsata_quetag_get(mvport, xfer->c_slot);
+
 	KASSERT((chp->ch_flags  & ATACH_NCQ) == 0);
 	if (mvport->port_edmamode_curr != nodma)
 		mvsata_edma_disable(mvport, 10 /* ms */, wait_flags);
@@ -2426,6 +2428,7 @@ again:
 			if (xfer->c_flags & C_DMA)
 ata_dmaerr(drvp,
 (xfer->c_flags & C_POLL) ? AT_POLL : 0);
+			ata_channel_unlock(chp);
 			sc_xfer->error = XS_TIMEOUT;
 			mvsata_atapi_reset(chp, xfer);
 			return 1;
@@ -2883,8 +2886,15 @@ mvsata_edma_handle(struct mvsata_port *m
 			mvsata_print_crpb(mvport, erpqop);
 #endif
 		crpb = mvport->port_crpb + erpqop;
+		

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-25 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Sep 25 22:43:46 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
put recovery command on head of active xfers queue, so that drivers using
ata_queue_get_active_xfer() like mvsata(4) will find it and not random other
NCQ xfer

never return NCQ xfer from ata_queue_get_active_xfer(), if the first xfer
is NCQ simply return NULL

adjust ata_timo_xfer_check() to not check the expiring flag in C_WAITTIMO
branch, if we get there we ought to get the timeout handler aborted


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.36 -r1.132.8.37 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.36 src/sys/dev/ata/ata.c:1.132.8.37
--- src/sys/dev/ata/ata.c:1.132.8.36	Sat Sep 23 14:53:26 2017
+++ src/sys/dev/ata/ata.c	Mon Sep 25 22:43:46 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -208,7 +208,8 @@ ata_queue_hwslot_to_xfer(struct ata_chan
 
 	KASSERTMSG(hwslot < chq->queue_openings, "hwslot %d > openings %d",
 	hwslot, chq->queue_openings);
-	KASSERT((chq->active_xfers_used & __BIT(hwslot)) != 0);
+	KASSERTMSG((chq->active_xfers_used & __BIT(hwslot)) != 0,
+	"hwslot %d not active", hwslot);
 
 	/* Usually the first entry will be the one */
 	TAILQ_FOREACH(xfer, >active_xfers, c_activechain) {
@@ -228,8 +229,17 @@ ata_queue_hwslot_to_xfer(struct ata_chan
 static struct ata_xfer *
 ata_queue_get_active_xfer_locked(struct ata_channel *chp)
 {
+	struct ata_xfer *xfer;
+
 	KASSERT(mutex_owned(>ch_lock));
-	return TAILQ_FIRST(>ch_queue->active_xfers);
+	xfer = TAILQ_FIRST(>ch_queue->active_xfers);
+
+	if (xfer && ISSET(xfer->c_flags, C_NCQ)) {
+		/* Spurious call, never return NCQ xfer from this interface */
+		xfer = NULL;
+	}
+
+	return xfer;
 }
 
 /*
@@ -1543,7 +1553,16 @@ ata_activate_xfer_locked(struct ata_chan
 	KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0);
 
 	TAILQ_REMOVE(>queue_xfer, xfer, c_xferchain);
-	TAILQ_INSERT_TAIL(>active_xfers, xfer, c_activechain);
+	if ((xfer->c_flags & C_RECOVERY) == 0)
+		TAILQ_INSERT_TAIL(>active_xfers, xfer, c_activechain);
+	else {
+		/*
+		 * Must go to head, so that ata_queue_get_active_xfer()
+		 * returns the recovery command, and not some other
+		 * random active transfer.
+		 */
+		TAILQ_INSERT_HEAD(>active_xfers, xfer, c_activechain);
+	}
 	chq->active_xfers_used |= __BIT(xfer->c_slot);
 	chq->queue_active++;
 }
@@ -1632,15 +1651,13 @@ ata_timo_xfer_check(struct ata_xfer *xfe
 			return true;
 		}
 
-		/* Handle race vs. callout_stop() in ata_deactivate_xfer() */
-		if (!callout_expired(>c_timo_callout)) {
-			ata_channel_unlock(chp);
+		/* Race vs. callout_stop() in ata_deactivate_xfer() */
+		ata_channel_unlock(chp);
 
-			aprint_normal_dev(drvp->drv_softc,
-			"xfer %d deactivated while invoking timeout\n",
-			xfer->c_slot); 
-			return true;
-		}
+		aprint_normal_dev(drvp->drv_softc,
+		"xfer %d deactivated while invoking timeout\n",
+		xfer->c_slot); 
+		return true;
 	}
 
 	ata_channel_unlock(chp);



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Sep 23 14:53:26 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
note to previous: the KASSERT() insisted actually there is at most one
active xfer, which is false during NCQ error recovery


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.35 -r1.132.8.36 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.35 src/sys/dev/ata/ata.c:1.132.8.36
--- src/sys/dev/ata/ata.c:1.132.8.35	Sat Sep 23 13:13:19 2017
+++ src/sys/dev/ata/ata.c	Sat Sep 23 14:53:26 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $");
 
 #include "opt_ata.h"
 



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Sep 23 13:13:19 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
remove ata_queue_get_active_xfer() KASSERT() about having at least one
active xfer; it can happen we get interrupt while no longer having the cmd
active e.g. during recovery, and all callers handle getting NULL as result

fixes panic in mvsata(4) during error recovery


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.34 -r1.132.8.35 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.34 src/sys/dev/ata/ata.c:1.132.8.35
--- src/sys/dev/ata/ata.c:1.132.8.34	Wed Sep 20 19:39:36 2017
+++ src/sys/dev/ata/ata.c	Sat Sep 23 13:13:19 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -244,10 +244,7 @@ ata_queue_get_active_xfer(struct ata_cha
 	struct ata_xfer *xfer = NULL;
 
 	ata_channel_lock(chp);
-
-	KASSERT(chp->ch_queue->queue_active <= 1);
 	xfer = ata_queue_get_active_xfer_locked(chp);
-
 	ata_channel_unlock(chp);
 
 	return xfer;



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-22 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Sep 22 20:19:08 UTC 2017

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

Log Message:
fix inverted logic for calling atastart()


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.27 -r1.35.6.28 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.27 src/sys/dev/ic/mvsata.c:1.35.6.28
--- src/sys/dev/ic/mvsata.c:1.35.6.27	Wed Sep 20 18:35:37 2017
+++ src/sys/dev/ic/mvsata.c	Fri Sep 22 20:19:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1529,7 +1529,7 @@ mvsata_bio_done(struct ata_channel *chp,
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct ata_bio *ata_bio = >c_bio;
 	int drive = xfer->c_drive;
-	bool iserror = (ata_bio->error == NOERROR);
+	bool iserror = (ata_bio->error != NOERROR);
 
 	DPRINTF(DEBUG_FUNCS|DEBUG_XFERS,
 	("%s:%d: mvsata_bio_done: drive=%d, flags=0x%x\n",
@@ -2689,7 +2689,7 @@ mvsata_atapi_done(struct ata_channel *ch
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
-	bool iserror = (sc_xfer->error == XS_NOERROR);
+	bool iserror = (sc_xfer->error != XS_NOERROR);
 
 	DPRINTF(DEBUG_FUNCS|DEBUG_XFERS,
 	("%s:%d:%d: mvsata_atapi_done: flags 0x%x\n",



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-21 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Thu Sep 21 18:47:21 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c

Log Message:
add missing ata_channel_unlock() in bailout path of wdc_ata_bio_intr()


To generate a diff of this commit:
cvs rdiff -u -r1.105.6.9 -r1.105.6.10 src/sys/dev/ata/ata_wdc.c

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/ata_wdc.c
diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.9 src/sys/dev/ata/ata_wdc.c:1.105.6.10
--- src/sys/dev/ata/ata_wdc.c:1.105.6.9	Sun Sep 10 19:31:15 2017
+++ src/sys/dev/ata/ata_wdc.c	Thu Sep 21 18:47:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_wdc.c,v 1.105.6.9 2017/09/10 19:31:15 jdolecek Exp $	*/
+/*	$NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.9 2017/09/10 19:31:15 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -662,8 +662,10 @@ wdc_ata_bio_intr(struct ata_channel *chp
 
 	/* Ack interrupt done by wdc_wait_for_unbusy */
 	if (wdc_wait_for_unbusy(chp, poll ? ATA_DELAY : 0, AT_POLL, ) < 0) {
-		if (!poll && (xfer->c_flags & C_TIMEOU) == 0)
+		if (!poll && (xfer->c_flags & C_TIMEOU) == 0) {
+			ata_channel_unlock(chp);
 			return 0; /* IRQ was not for us */
+		}
 		printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
 		device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
 		xfer->c_bcount, xfer->c_skip);



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-21 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Thu Sep 21 17:15:18 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
wddone() doesn't need more locking


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.43 -r1.1.2.44 src/sys/dev/ata/TODO.ncq

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.43 src/sys/dev/ata/TODO.ncq:1.1.2.44
--- src/sys/dev/ata/TODO.ncq:1.1.2.43	Wed Sep 20 19:45:37 2017
+++ src/sys/dev/ata/TODO.ncq	Thu Sep 21 17:15:18 2017
@@ -32,8 +32,6 @@ add nibble to control number of tags (1=
 
 add support for the NCQ TRIM if supported by device?
 
-protect more of wddone() with mutex?
-
 implement DIOCGCACHE/DIOCCACHESYNC for ld@ataraid? just passthrough, like ccd
 
 MSI/MSI-X support for AHCI and mvsata(4)



CVS commit: [jdolecek-ncq] src/sys/dev/isa

2017-09-20 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 20 19:59:22 UTC 2017

Modified Files:
src/sys/dev/isa [jdolecek-ncq]: wdc_isa.c

Log Message:
deallocate the channel structures properly in wdc_isa_probe() also when
already the initial bus_space_map() fails


To generate a diff of this commit:
cvs rdiff -u -r1.59.28.2 -r1.59.28.3 src/sys/dev/isa/wdc_isa.c

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/isa/wdc_isa.c
diff -u src/sys/dev/isa/wdc_isa.c:1.59.28.2 src/sys/dev/isa/wdc_isa.c:1.59.28.3
--- src/sys/dev/isa/wdc_isa.c:1.59.28.2	Wed Sep 20 19:44:38 2017
+++ src/sys/dev/isa/wdc_isa.c	Wed Sep 20 19:59:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $ */
+/*	$NetBSD: wdc_isa.c,v 1.59.28.3 2017/09/20 19:59:22 jdolecek Exp $ */
 
 /*-
  * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.3 2017/09/20 19:59:22 jdolecek Exp $");
 
 #include 
 #include 
@@ -143,9 +143,9 @@ wdc_isa_probe(device_t parent, cfdata_t 
 	bus_space_unmap(wdr.ctl_iot, wdr.ctl_ioh, WDC_ISA_AUXREG_NPORTS);
 outunmap:
 	bus_space_unmap(wdr.cmd_iot, wdr.cmd_baseioh, WDC_ISA_REG_NPORTS);
+out:
 	ata_queue_free(ch.ch_queue);
 	ata_channel_destroy();
-out:
 	return (result);
 }
 



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-20 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 20 19:45:37 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
MVSATA_WITHOUTDMA seems to work fine


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.42 -r1.1.2.43 src/sys/dev/ata/TODO.ncq

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.42 src/sys/dev/ata/TODO.ncq:1.1.2.43
--- src/sys/dev/ata/TODO.ncq:1.1.2.42	Tue Sep 19 21:06:25 2017
+++ src/sys/dev/ata/TODO.ncq	Wed Sep 20 19:45:37 2017
@@ -2,8 +2,6 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-mvsata - resest MVSATA_WITHOUTDMA
-
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from



CVS commit: [jdolecek-ncq] src/sys/dev/isa

2017-09-20 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 20 19:44:39 UTC 2017

Modified Files:
src/sys/dev/isa [jdolecek-ncq]: wdc_isa.c

Log Message:
initialize properly ata_channel during probe


To generate a diff of this commit:
cvs rdiff -u -r1.59.28.1 -r1.59.28.2 src/sys/dev/isa/wdc_isa.c

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/isa/wdc_isa.c
diff -u src/sys/dev/isa/wdc_isa.c:1.59.28.1 src/sys/dev/isa/wdc_isa.c:1.59.28.2
--- src/sys/dev/isa/wdc_isa.c:1.59.28.1	Wed Jun 21 19:21:25 2017
+++ src/sys/dev/isa/wdc_isa.c	Wed Sep 20 19:44:38 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc_isa.c,v 1.59.28.1 2017/06/21 19:21:25 jdolecek Exp $ */
+/*	$NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $ */
 
 /*-
  * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.1 2017/06/21 19:21:25 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $");
 
 #include 
 #include 
@@ -107,7 +107,9 @@ wdc_isa_probe(device_t parent, cfdata_t 
 
 	memset(, 0, sizeof(wdc));
 	memset(, 0, sizeof(ch));
+	ata_channel_init();
 	ch.ch_atac = _atac;
+	ch.ch_queue = ata_queue_alloc(1);
 	wdc.regs = 
 
 	wdr.cmd_iot = ia->ia_iot;
@@ -141,6 +143,8 @@ wdc_isa_probe(device_t parent, cfdata_t 
 	bus_space_unmap(wdr.ctl_iot, wdr.ctl_ioh, WDC_ISA_AUXREG_NPORTS);
 outunmap:
 	bus_space_unmap(wdr.cmd_iot, wdr.cmd_baseioh, WDC_ISA_REG_NPORTS);
+	ata_queue_free(ch.ch_queue);
+	ata_channel_destroy();
 out:
 	return (result);
 }



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-20 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 20 19:39:36 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
add forgotten destroy of queue_idle cv in ata_queue_free()


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.33 -r1.132.8.34 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.33 src/sys/dev/ata/ata.c:1.132.8.34
--- src/sys/dev/ata/ata.c:1.132.8.33	Tue Sep 19 21:06:25 2017
+++ src/sys/dev/ata/ata.c	Wed Sep 20 19:39:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06:25 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06:25 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -328,6 +328,7 @@ ata_queue_free(struct ata_queue *chq)
 
 	cv_destroy(>queue_busy);
 	cv_destroy(>queue_drain);
+	cv_destroy(>queue_idle);
 
 	free(chq, M_DEVBUF);
 }



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-20 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 20 18:35:37 UTC 2017

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

Log Message:
make compile again with MVSATA_WITHOUTDMA


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.26 -r1.35.6.27 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.26 src/sys/dev/ic/mvsata.c:1.35.6.27
--- src/sys/dev/ic/mvsata.c:1.35.6.26	Tue Sep 19 21:06:25 2017
+++ src/sys/dev/ic/mvsata.c	Wed Sep 20 18:35:37 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.26 2017/09/19 21:06:25 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.26 2017/09/19 21:06:25 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -107,10 +107,11 @@ int	mvsata_debug = 0;
 
 
 static void mvsata_probe_drive(struct ata_channel *);
+static void mvsata_reset_channel(struct ata_channel *, int);
+
 #ifndef MVSATA_WITHOUTDMA
 static int mvsata_bio(struct ata_drive_datas *, struct ata_xfer *);
 static void mvsata_reset_drive(struct ata_drive_datas *, int, uint32_t *);
-static void mvsata_reset_channel(struct ata_channel *, int);
 static int mvsata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 static int mvsata_addref(struct ata_drive_datas *);
 static void mvsata_delref(struct ata_drive_datas *);
@@ -731,6 +732,7 @@ mvsata_reset_drive(struct ata_drive_data
 
 	return;
 }
+#endif /* MVSATA_WITHOUTDMA */
 
 static void
 mvsata_reset_channel(struct ata_channel *chp, int flags)
@@ -768,16 +770,18 @@ mvsata_reset_channel(struct ata_channel 
 
 	ata_kill_active(chp, KILL_RESET, flags);
 
+#ifndef MVSATA_WITHOUTDMA
 	mvsata_edma_config(mvport, mvport->port_edmamode_curr);
 	mvsata_edma_reset_qptr(mvport);
 	mvsata_edma_enable(mvport);
+#endif
 
 	ata_channel_unlock(chp);
 
 	return;
 }
 
-
+#ifndef MVSATA_WITHOUTDMA
 static int
 mvsata_addref(struct ata_drive_datas *drvp)
 {



CVS commit: [jdolecek-ncq] src/sys/dev

2017-09-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Sep 19 21:06:25 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c atavar.h sata_subr.c
satapmp_subr.c satapmpvar.h
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c

Log Message:
replace all remaining tsleep()/wakeup() calls with condition variables, or
calls to ata_delay(), as appropriate; change ata_delay() to require the
channel lock on entry, and pass the lock to kpause() for unlocking while
sleeping


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.41 -r1.1.2.42 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.132.8.32 -r1.132.8.33 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.25 -r1.92.8.26 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.21 -r1.21.24.1 src/sys/dev/ata/sata_subr.c
cvs rdiff -u -r1.12.24.5 -r1.12.24.6 src/sys/dev/ata/satapmp_subr.c
cvs rdiff -u -r1.3 -r1.3.30.1 src/sys/dev/ata/satapmpvar.h
cvs rdiff -u -r1.57.6.28 -r1.57.6.29 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.35.6.25 -r1.35.6.26 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.30.4.37 -r1.30.4.38 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.283.2.15 -r1.283.2.16 src/sys/dev/ic/wdc.c

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.41 src/sys/dev/ata/TODO.ncq:1.1.2.42
--- src/sys/dev/ata/TODO.ncq:1.1.2.41	Wed Sep 13 19:55:12 2017
+++ src/sys/dev/ata/TODO.ncq	Tue Sep 19 21:06:25 2017
@@ -4,10 +4,6 @@ test wd* at umass?, confirm the ata_chan
 
 mvsata - resest MVSATA_WITHOUTDMA
 
-the changes to lock channel lock cause now mi_switch() with spinlock held
-when invoking ata_delay() (which calls kpause()) or on tsleep, need
-to refactor
-
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.32 src/sys/dev/ata/ata.c:1.132.8.33
--- src/sys/dev/ata/ata.c:1.132.8.32	Mon Sep 11 22:16:18 2017
+++ src/sys/dev/ata/ata.c	Tue Sep 19 21:06:25 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06:25 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06:25 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -279,6 +279,7 @@ ata_xfer_init(struct ata_xfer *xfer, uin
 	xfer->c_slot = slot;
 
 	cv_init(>c_active, "ataact");
+	cv_init(>c_finish, "atafin");
 	callout_init(>c_timo_callout, 0); 	/* XXX MPSAFE */
 	callout_init(>c_retry_callout, 0); 	/* XXX MPSAFE */
 }
@@ -291,6 +292,7 @@ ata_xfer_destroy(struct ata_xfer *xfer)
 	callout_halt(>c_retry_callout, NULL);	/* XXX MPSAFE */
 	callout_destroy(>c_retry_callout);
 	cv_destroy(>c_active);
+	cv_destroy(>c_finish);
 }
 
 struct ata_queue *
@@ -310,6 +312,7 @@ ata_queue_alloc(uint8_t openings)
 
 	cv_init(>queue_busy, "ataqbusy");
 	cv_init(>queue_drain, "atdrn");
+	cv_init(>queue_idle, "qidl");
 
 	for (uint8_t i = 0; i < openings; i++)
 		ata_xfer_init(>queue_xfers[i], i);
@@ -1194,13 +1197,13 @@ ata_dmaerr(struct ata_drive_datas *drvp,
 static void
 ata_channel_idle(struct ata_channel *chp)
 {
-	int s = splbio();
-	ata_channel_freeze(chp);
+	ata_channel_lock(chp);
+	ata_channel_freeze_locked(chp);
 	while (chp->ch_queue->queue_active > 0) {
 		chp->ch_queue->queue_flags |= QF_IDLE_WAIT;
-		tsleep(>ch_queue->queue_flags, PRIBIO, "qidl", 0);
+		cv_timedwait(>ch_queue->queue_idle, >ch_lock, 1);
 	}
-	splx(s);
+	ata_channel_unlock(chp);
 }
 
 /*
@@ -1246,6 +1249,8 @@ ata_exec_xfer(struct ata_channel *chp, s
 			 * while we were waiting.
 			 */
 			if ((xfer->c_flags & (C_FREE|C_WAITTIMO)) == C_FREE) {
+ata_channel_unlock(chp);
+
 ata_free_xfer(chp, xfer);
 return;
 			}
@@ -1305,7 +1310,7 @@ again:
 	if (__predict_false(!recovery && chq->queue_freeze > 0)) {
 		if (chq->queue_flags & QF_IDLE_WAIT) {
 			chq->queue_flags &= ~QF_IDLE_WAIT;
-			wakeup(>queue_flags);
+			cv_signal(>ch_queue->queue_idle);
 		}
 		goto out; /* queue frozen */
 	}
@@ -1673,7 +1678,7 @@ out:
 /*
  * Kill off all active xfers for a ata_channel.
  *
- * Must be called at splbio().
+ * Must be called with channel lock held.
  */
 void
 ata_kill_active(struct ata_channel *chp, int reason, int flags)
@@ -1681,6 +1686,8 @@ ata_kill_active(struct ata_channel *chp,
 	struct ata_queue * const chq = chp->ch_queue;
 	struct ata_xfer *xfer, *xfernext;
 
+	KASSERT(mutex_owned(>ch_lock));
+
 	TAILQ_FOREACH_SAFE(xfer, >active_xfers, c_activechain, xfernext) {
 		(*xfer->c_kill_xfer)(xfer->c_chp, xfer, reason);
 	}
@@ -2000,7 +2007,7 @@ ata_probe_caps(struct 

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Sep 19 17:52:52 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c

Log Message:
seems the CMD/CCS slot is always zero at least under QEMU for successful
polled commands, so go back to using it only on error path; while the value
seems good on real hardware, there is no good reason for register read anyway


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.27 -r1.57.6.28 src/sys/dev/ic/ahcisata_core.c

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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.27 src/sys/dev/ic/ahcisata_core.c:1.57.6.28
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.27	Sun Sep 10 19:31:15 2017
+++ src/sys/dev/ic/ahcisata_core.c	Tue Sep 19 17:52:52 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.27 2017/09/10 19:31:15 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.28 2017/09/19 17:52:52 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.27 2017/09/10 19:31:15 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.28 2017/09/19 17:52:52 jdolecek Exp $");
 
 #include 
 #include 
@@ -568,7 +568,7 @@ ahci_intr_port(struct ahci_softc *sc, st
 	uint32_t is, tfd, sact;
 	struct ata_channel *chp = >ata_channel;
 	struct ata_xfer *xfer;
-	int slot;
+	int slot = -1;
 	bool recover = false;
 
 	is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
@@ -585,12 +585,9 @@ ahci_intr_port(struct ahci_softc *sc, st
 	if ((chp->ch_flags & ATACH_NCQ) == 0) {
 		/* Non-NCQ operation */
 		sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel));
-		slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))
-			& AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT;
 	} else {
 		/* NCQ operation */
 		sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));
-		slot = -1;
 	}
 
 	/* Handle errors */
@@ -600,6 +597,14 @@ ahci_intr_port(struct ahci_softc *sc, st
 		if (is & AHCI_P_IX_TFES) {
 			tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
 
+			if ((chp->ch_flags & ATACH_NCQ) == 0) {
+/* Slot valid only for Non-NCQ operation */
+slot = (AHCI_READ(sc,
+AHCI_P_CMD(chp->ch_channel))
+& AHCI_P_CMD_CCS_MASK)
+>> AHCI_P_CMD_CCS_SHIFT;
+			}
+
 			aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n",
 			AHCINAME(sc), chp->ch_channel, sact, is, tfd);
 		} else {
@@ -657,7 +662,7 @@ ahci_intr_port(struct ahci_softc *sc, st
 			if ((aslots & __BIT(slot)) != 0 &&
 			(sact & __BIT(slot)) == 0) {
 xfer = ata_queue_hwslot_to_xfer(chp, slot);
-xfer->c_intr(chp, xfer, 0);
+xfer->c_intr(chp, xfer, tfd);
 			}
 		}
 	}



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-13 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Sep 13 19:55:12 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
two more - mvsata MVSATA_WITHOUTDMA seems to be broken, and latest channel lock
changes introduced panic in mi_switch() on code paths which kpause/tsleep


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.40 -r1.1.2.41 src/sys/dev/ata/TODO.ncq

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.40 src/sys/dev/ata/TODO.ncq:1.1.2.41
--- src/sys/dev/ata/TODO.ncq:1.1.2.40	Mon Sep 11 22:31:42 2017
+++ src/sys/dev/ata/TODO.ncq	Wed Sep 13 19:55:12 2017
@@ -2,6 +2,12 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
+mvsata - resest MVSATA_WITHOUTDMA
+
+the changes to lock channel lock cause now mi_switch() with spinlock held
+when invoking ata_delay() (which calls kpause()) or on tsleep, need
+to refactor
+
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-11 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Sep 11 22:31:42 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
doesn't seem the freeze/thaw in error recovery can cause the thread to panic,
all commands within are executed as polled and hence thread is not invoked


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.39 -r1.1.2.40 src/sys/dev/ata/TODO.ncq

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.39 src/sys/dev/ata/TODO.ncq:1.1.2.40
--- src/sys/dev/ata/TODO.ncq:1.1.2.39	Mon Sep 11 22:30:05 2017
+++ src/sys/dev/ata/TODO.ncq	Mon Sep 11 22:31:42 2017
@@ -2,8 +2,6 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-reconsider freeze/thaw in error recovery - can it screw up with thread?
-
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-11 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Sep 11 22:30:05 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
atastart() rechecked - it's okay to call it even in error path in those
several cases we do, it's just optimization to skip the call; I'm not even
very convinced it's useful to have this conditional, but keeping for now
until proven harmful


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.38 -r1.1.2.39 src/sys/dev/ata/TODO.ncq

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.38 src/sys/dev/ata/TODO.ncq:1.1.2.39
--- src/sys/dev/ata/TODO.ncq:1.1.2.38	Sun Sep 10 19:31:15 2017
+++ src/sys/dev/ata/TODO.ncq	Mon Sep 11 22:30:05 2017
@@ -2,11 +2,6 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-revise calls to atastart() - now called alsoafter ATASTART_ABORT(), call
-only from intr routine
-- wdc.c never calls atastart() (start always false)
-- ata_wdc.c calls atastart() regardless if error
-
 reconsider freeze/thaw in error recovery - can it screw up with thread?
 
 Other random notes (do outside the NCQ branch):



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-11 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Sep 11 22:19:23 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: wdc.c

Log Message:
fix condition for calling atastart() when command is done


To generate a diff of this commit:
cvs rdiff -u -r1.283.2.14 -r1.283.2.15 src/sys/dev/ic/wdc.c

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/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.283.2.14 src/sys/dev/ic/wdc.c:1.283.2.15
--- src/sys/dev/ic/wdc.c:1.283.2.14	Sun Sep 10 19:31:15 2017
+++ src/sys/dev/ic/wdc.c	Mon Sep 11 22:19:23 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.283.2.14 2017/09/10 19:31:15 jdolecek Exp $ */
+/*	$NetBSD: wdc.c,v 1.283.2.15 2017/09/11 22:19:23 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.14 2017/09/10 19:31:15 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.15 2017/09/11 22:19:23 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -1589,7 +1589,7 @@ __wdccommand_done(struct ata_channel *ch
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct wdc_regs *wdr = >regs[chp->ch_channel];
 	struct ata_command *ata_c = >c_ata_c;
-	bool start = false;
+	bool start = true;
 
 	ATADEBUG_PRINT(("__wdccommand_done %s:%d:%d flags 0x%x\n",
 	device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-11 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Sep 11 22:16:18 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
move debug printf where it belongs


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.31 -r1.132.8.32 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.31 src/sys/dev/ata/ata.c:1.132.8.32
--- src/sys/dev/ata/ata.c:1.132.8.31	Sun Sep 10 19:31:15 2017
+++ src/sys/dev/ata/ata.c	Mon Sep 11 22:16:18 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1230,8 +1230,6 @@ ata_exec_xfer(struct ata_channel *chp, s
 	else
 		TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer,
 		c_xferchain);
-	ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n",
-	chp->ch_flags), DEBUG_XFERS);
 
 	/*
 	 * if polling and can sleep, wait for the xfer to be at head of queue
@@ -1256,6 +1254,8 @@ ata_exec_xfer(struct ata_channel *chp, s
 
 	ata_channel_unlock(chp);
 
+	ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n",
+	chp->ch_flags), DEBUG_XFERS);
 	atastart(chp);
 }
 



CVS commit: [jdolecek-ncq] src/sys/dev

2017-09-10 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Sep 10 19:31:15 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c
src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
refactor code so that xfer c_start() hook is called with channel mutex held,
and hence the controller submit code no longer relies on spl

tested all the affected drivers - wdc (via piixide), ahci, mvsata, siisata,
both disk and atapi I/O


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.37 -r1.1.2.38 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.132.8.30 -r1.132.8.31 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.105.6.8 -r1.105.6.9 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.92.8.24 -r1.92.8.25 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.57.6.26 -r1.57.6.27 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.35.6.24 -r1.35.6.25 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.30.4.36 -r1.30.4.37 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.283.2.13 -r1.283.2.14 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.123.4.12 -r1.123.4.13 src/sys/dev/scsipi/atapi_wdc.c

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.37 src/sys/dev/ata/TODO.ncq:1.1.2.38
--- src/sys/dev/ata/TODO.ncq:1.1.2.37	Tue Aug 29 13:38:38 2017
+++ src/sys/dev/ata/TODO.ncq	Sun Sep 10 19:31:15 2017
@@ -2,11 +2,13 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-c_start() needs to be called on splbio to avoid spurious irq during reset,
-is not e.g. in ata thread and may not in atastart() neither
+revise calls to atastart() - now called alsoafter ATASTART_ABORT(), call
+only from intr routine
 - wdc.c never calls atastart() (start always false)
 - ata_wdc.c calls atastart() regardless if error
 
+reconsider freeze/thaw in error recovery - can it screw up with thread?
+
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.30 src/sys/dev/ata/ata.c:1.132.8.31
--- src/sys/dev/ata/ata.c:1.132.8.30	Sun Sep 10 19:22:56 2017
+++ src/sys/dev/ata/ata.c	Sun Sep 10 19:31:15 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -130,8 +130,12 @@ static bool atabus_suspend(device_t, con
 static void atabusconfig_thread(void *);
 
 static void ata_channel_idle(struct ata_channel *);
+static void ata_channel_thaw_locked(struct ata_channel *);
 static void ata_activate_xfer_locked(struct ata_channel *, struct ata_xfer *);
 static void ata_channel_freeze_locked(struct ata_channel *);
+static struct ata_xfer *ata_queue_get_active_xfer_locked(struct ata_channel *);
+static void ata_thread_wake_locked(struct ata_channel *);
+
 /*
  * atabus_init:
  *
@@ -200,7 +204,7 @@ ata_queue_hwslot_to_xfer(struct ata_chan
 	struct ata_queue *chq = chp->ch_queue;
 	struct ata_xfer *xfer = NULL;
 
-	mutex_enter(>ch_lock);
+	ata_channel_lock(chp);
 
 	KASSERTMSG(hwslot < chq->queue_openings, "hwslot %d > openings %d",
 	hwslot, chq->queue_openings);
@@ -212,7 +216,7 @@ ata_queue_hwslot_to_xfer(struct ata_chan
 			break;
 	}
 
-	mutex_exit(>ch_lock);
+	ata_channel_unlock(chp);
 
 	KASSERTMSG((xfer != NULL),
 	"%s: xfer with slot %d not found (active %x)", __func__,
@@ -221,6 +225,13 @@ ata_queue_hwslot_to_xfer(struct ata_chan
 	return xfer;
 }
 
+static struct ata_xfer *
+ata_queue_get_active_xfer_locked(struct ata_channel *chp)
+{
+	KASSERT(mutex_owned(>ch_lock));
+	return TAILQ_FIRST(>ch_queue->active_xfers);
+}
+
 /*
  * This interface is supposed only to be used when there is exactly
  * one outstanding command, when there is no information about the slot,
@@ -232,12 +243,12 @@ ata_queue_get_active_xfer(struct ata_cha
 {
 	struct ata_xfer *xfer = NULL;
 
-	mutex_enter(>ch_lock);
+	ata_channel_lock(chp);
 
 	KASSERT(chp->ch_queue->queue_active <= 1);
-	xfer = TAILQ_FIRST(>ch_queue->active_xfers);
+	xfer = ata_queue_get_active_xfer_locked(chp);
 
-	mutex_exit(>ch_lock);
+	ata_channel_unlock(chp);
 
 	return xfer;
 }
@@ -247,7 +258,7 @@ ata_queue_drive_active_xfer(struct ata_c
 {
 	struct ata_xfer *xfer = NULL;
 
-	mutex_enter(>ch_lock);
+	ata_channel_lock(chp);
 
 	TAILQ_FOREACH(xfer, >ch_queue->active_xfers, c_activechain) {
 		if (xfer->c_drive == drive)
@@ -255,7 +266,7 @@ 

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-10 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Sep 10 19:22:57 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
fix regression in atabus_thread() when it was converted from spl to mutex -
the reset and c_start() routines expect to run on splbio; wrap the calls
insite splbio/splx() again for now, since we can't hold the mutex while calling
them

fixes problem experienced by Jonathan, where drive setup triggered
an spurious interrupt and panic due to state < READY


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.29 -r1.132.8.30 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.29 src/sys/dev/ata/ata.c:1.132.8.30
--- src/sys/dev/ata/ata.c:1.132.8.29	Tue Aug 15 11:21:32 2017
+++ src/sys/dev/ata/ata.c	Sun Sep 10 19:22:56 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -586,7 +586,7 @@ atabus_thread(void *arg)
 	struct ata_channel *chp = sc->sc_chan;
 	struct ata_queue *chq = chp->ch_queue;
 	struct ata_xfer *xfer;
-	int i;
+	int i, s;
 
 	mutex_enter(>ch_lock);
 	chp->ch_flags |= ATACH_TH_RUN;
@@ -630,7 +630,9 @@ atabus_thread(void *arg)
 			 */
 			mutex_exit(>ch_lock);
 			ata_channel_thaw(chp);
+			s = splbio();
 			ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags);
+			splx(s);
 			mutex_enter(>ch_lock);
 		} else if (chq->queue_active > 0 && chq->queue_freeze == 1) {
 			/*
@@ -644,7 +646,9 @@ atabus_thread(void *arg)
 			ata_channel_thaw(chp);
 			xfer = ata_queue_get_active_xfer(chp);
 			KASSERT(xfer != NULL);
+			s = splbio();
 			(*xfer->c_start)(xfer->c_chp, xfer);
+			splx(s);
 			mutex_enter(>ch_lock);
 		} else if (chq->queue_freeze > 1)
 			panic("%s: queue_freeze", __func__);



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-09-10 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Sep 10 18:37:21 UTC 2017

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

Log Message:
move mvsata_bio(), mvsata_exec_command() and mvsata_atapi_scsipi_request()
just before their respective hook functions


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.23 -r1.35.6.24 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.23 src/sys/dev/ic/mvsata.c:1.35.6.24
--- src/sys/dev/ic/mvsata.c:1.35.6.23	Sun Aug 13 11:48:53 2017
+++ src/sys/dev/ic/mvsata.c	Sun Sep 10 18:37:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.24 2017/09/10 18:37:21 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.24 2017/09/10 18:37:21 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -688,38 +688,6 @@ mvsata_probe_drive(struct ata_channel *c
 }
 
 #ifndef MVSATA_WITHOUTDMA
-static int
-mvsata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
-{
-	struct ata_channel *chp = drvp->chnl_softc;
-	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	struct atac_softc *atac = chp->ch_atac;
-	struct ata_bio *ata_bio = >c_bio;
-
-	DPRINTF(DEBUG_FUNCS|DEBUG_XFERS,
-	("%s:%d: mvsata_bio: drive=%d, blkno=%" PRId64
-	", bcount=%ld\n", device_xname(atac->atac_dev), chp->ch_channel,
-	drvp->drive, ata_bio->blkno, ata_bio->bcount));
-
-	mvsata_quetag_get(mvport, xfer->c_slot);
-
-	if (atac->atac_cap & ATAC_CAP_NOIRQ)
-		ata_bio->flags |= ATA_POLL;
-	if (ata_bio->flags & ATA_POLL)
-		xfer->c_flags |= C_POLL;
-	if ((drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) &&
-	(ata_bio->flags & ATA_SINGLE) == 0)
-		xfer->c_flags |= C_DMA;
-	xfer->c_drive = drvp->drive;
-	xfer->c_databuf = ata_bio->databuf;
-	xfer->c_bcount = ata_bio->bcount;
-	xfer->c_start = mvsata_bio_start;
-	xfer->c_intr = mvsata_bio_intr;
-	xfer->c_kill_xfer = mvsata_bio_kill_xfer;
-	ata_exec_xfer(chp, xfer);
-	return (ata_bio->flags & ATA_ITSDONE) ? ATACMD_COMPLETE : ATACMD_QUEUED;
-}
-
 static void
 mvsata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp)
 {
@@ -794,55 +762,6 @@ mvsata_reset_channel(struct ata_channel 
 
 
 static int
-mvsata_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
-{
-	struct ata_channel *chp = drvp->chnl_softc;
-	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	struct ata_command *ata_c = >c_ata_c;
-	int rv, s;
-
-	DPRINTF(DEBUG_FUNCS|DEBUG_XFERS,
-	("%s:%d: mvsata_exec_command: drive=%d, bcount=%d,"
-	" r_lba=0x%012"PRIx64", r_count=0x%04x, r_features=0x%04x,"
-	" r_device=0x%02x, r_command=0x%02x\n",
-	device_xname(MVSATA_DEV2(mvport)), chp->ch_channel,
-	drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count,
-	ata_c->r_features, ata_c->r_device, ata_c->r_command));
-
-	mvsata_quetag_get(mvport, xfer->c_slot);
-
-	if (ata_c->flags & AT_POLL)
-		xfer->c_flags |= C_POLL;
-	if (ata_c->flags & AT_WAIT)
-		xfer->c_flags |= C_WAIT;
-	xfer->c_drive = drvp->drive;
-	xfer->c_databuf = ata_c->data;
-	xfer->c_bcount = ata_c->bcount;
-	xfer->c_start = mvsata_wdc_cmd_start;
-	xfer->c_intr = mvsata_wdc_cmd_intr;
-	xfer->c_kill_xfer = mvsata_wdc_cmd_kill_xfer;
-	s = splbio();
-	ata_exec_xfer(chp, xfer);
-#ifdef DIAGNOSTIC
-	if ((ata_c->flags & AT_POLL) != 0 &&
-	(ata_c->flags & AT_DONE) == 0)
-		panic("mvsata_exec_command: polled command not done");
-#endif
-	if (ata_c->flags & AT_DONE)
-		rv = ATACMD_COMPLETE;
-	else {
-		if (ata_c->flags & AT_WAIT) {
-			while ((ata_c->flags & AT_DONE) == 0)
-tsleep(ata_c, PRIBIO, "mvsatacmd", 0);
-			rv = ATACMD_COMPLETE;
-		} else
-			rv = ATACMD_QUEUED;
-	}
-	splx(s);
-	return rv;
-}
-
-static int
 mvsata_addref(struct ata_drive_datas *drvp)
 {
 
@@ -899,68 +818,6 @@ mvsata_atapibus_attach(struct atabus_sof
 }
 
 static void
-mvsata_atapi_scsipi_request(struct scsipi_channel *chan,
-			scsipi_adapter_req_t req, void *arg)
-{
-	struct scsipi_adapter *adapt = chan->chan_adapter;
-	struct scsipi_periph *periph;
-	struct scsipi_xfer *sc_xfer;
-	struct mvsata_softc *sc = device_private(adapt->adapt_dev);
-	struct atac_softc *atac = >sc_wdcdev.sc_atac;
-	struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
-	struct ata_xfer *xfer;
-	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	int drive, s;
-
-switch (req) {
-	case ADAPTER_REQ_RUN_XFER:
-		sc_xfer = arg;
-		periph = sc_xfer->xs_periph;
-		drive = periph->periph_target;
-
-		if (!device_is_active(atac->atac_dev)) {
-			sc_xfer->error = XS_DRIVER_STUFFUP;
-			scsipi_done(sc_xfer);
-			return;
-		}
-		

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-09-02 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Sep  2 12:01:25 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wdvar.h

Log Message:
include opt_wd.h instead of opt_wd_softbadsect.h, the option doesn't have 
private file any more


To generate a diff of this commit:
cvs rdiff -u -r1.43.4.7 -r1.43.4.8 src/sys/dev/ata/wdvar.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/wdvar.h
diff -u src/sys/dev/ata/wdvar.h:1.43.4.7 src/sys/dev/ata/wdvar.h:1.43.4.8
--- src/sys/dev/ata/wdvar.h:1.43.4.7	Wed Jul 19 19:39:28 2017
+++ src/sys/dev/ata/wdvar.h	Sat Sep  2 12:01:25 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdvar.h,v 1.43.4.7 2017/07/19 19:39:28 jdolecek Exp $	*/
+/*	$NetBSD: wdvar.h,v 1.43.4.8 2017/09/02 12:01:25 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -28,7 +28,7 @@
 #define	_DEV_ATA_WDVAR_H_
 
 #ifdef _KERNEL_OPT
-#include "opt_wd_softbadsect.h"
+#include "opt_wd.h"
 #endif
 
 #include 



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug 29 13:38:38 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
some notes around c_start/atastart()


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.36 -r1.1.2.37 src/sys/dev/ata/TODO.ncq

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.36 src/sys/dev/ata/TODO.ncq:1.1.2.37
--- src/sys/dev/ata/TODO.ncq:1.1.2.36	Sun Aug 13 11:46:32 2017
+++ src/sys/dev/ata/TODO.ncq	Tue Aug 29 13:38:38 2017
@@ -2,6 +2,11 @@ Bugs
 
 test wd* at umass?, confirm the ata_channel kludge works
 
+c_start() needs to be called on splbio to avoid spurious irq during reset,
+is not e.g. in ata thread and may not in atastart() neither
+- wdc.c never calls atastart() (start always false)
+- ata_wdc.c calls atastart() regardless if error
+
 Other random notes (do outside the NCQ branch):
 -
 do biodone() in wddone() starting the dump to not leak bufs when dumping from



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-15 Thread Jonathan A. Kollasch
Module Name:src
Committed By:   jakllsch
Date:   Tue Aug 15 20:12:29 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
Use ata_queue_free() instead of free() to deallocate chp->ch_queue during 
detach.


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.35 -r1.30.4.36 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.35 src/sys/dev/ic/siisata.c:1.30.4.36
--- src/sys/dev/ic/siisata.c:1.30.4.35	Sat Aug 12 22:12:04 2017
+++ src/sys/dev/ic/siisata.c	Tue Aug 15 20:12:28 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.36 2017/08/15 20:12:28 jakllsch Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.36 2017/08/15 20:12:28 jakllsch Exp $");
 
 #include 
 #include 
@@ -426,7 +426,8 @@ siisata_detach(struct siisata_softc *sc,
 		bus_dmamem_free(sc->sc_dmat,
 		>sch_prb_seg, schp->sch_prb_nseg);
 
-		free(chp->ch_queue, M_DEVBUF);
+		ata_queue_free(chp->ch_queue);
+		chp->ch_queue = NULL;
 		chp->atabus = NULL;
 
 		ata_channel_detach(chp);



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-15 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug 15 11:21:32 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
explicitly do not try to activate any further commands when running recovery
xfer; it was kind of implied since the code would not queue another non-NCQ
command when non-NCQ command is active, but this is better for readibility


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.28 -r1.132.8.29 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.28 src/sys/dev/ata/ata.c:1.132.8.29
--- src/sys/dev/ata/ata.c:1.132.8.28	Sat Aug 12 22:31:50 2017
+++ src/sys/dev/ata/ata.c	Tue Aug 15 11:21:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1249,7 +1249,7 @@ atastart(struct ata_channel *chp)
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_queue *chq = chp->ch_queue;
 	struct ata_xfer *xfer, *axfer;
-	bool immediate;
+	bool recovery;
 
 #ifdef ATA_DEBUG
 	int spl1, spl2;
@@ -1276,10 +1276,10 @@ again:
 	if ((xfer = TAILQ_FIRST(>ch_queue->queue_xfer)) == NULL)
 		goto out;
 
-	immediate = ISSET(xfer->c_flags, C_RECOVERY);
+	recovery = ISSET(xfer->c_flags, C_RECOVERY);
 
 	/* is the queue frozen? */
-	if (__predict_false(!immediate && chq->queue_freeze > 0)) {
+	if (__predict_false(!recovery && chq->queue_freeze > 0)) {
 		if (chq->queue_flags & QF_IDLE_WAIT) {
 			chq->queue_flags &= ~QF_IDLE_WAIT;
 			wakeup(>queue_flags);
@@ -1298,7 +1298,7 @@ again:
 	 * Need only check first xfer.
 	 * XXX FIS-based switching - revisit
 	 */
-	if (!immediate && (axfer = TAILQ_FIRST(>ch_queue->active_xfers))) {
+	if (!recovery && (axfer = TAILQ_FIRST(>ch_queue->active_xfers))) {
 		if (!ISSET(xfer->c_flags, C_NCQ) ||
 		!ISSET(axfer->c_flags, C_NCQ) ||
 		xfer->c_drive != axfer->c_drive)
@@ -1344,8 +1344,8 @@ again:
 	 */
 	xfer->c_start(chp, xfer);
 
-	/* Queue more commands if possible */
-	if (chq->queue_active < chq->queue_openings)
+	/* Queue more commands if possible, but not during recovery */
+	if (!recovery && chq->queue_active < chq->queue_openings)
 		goto again;
 
 	return;



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-13 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Aug 13 15:12:04 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
by default make the chaos monkey do nothing, so it's easier to have this
compiled in all the time for testing; the vars can be set via DDB
when needed


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.33 -r1.428.2.34 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.33 src/sys/dev/ata/wd.c:1.428.2.34
--- src/sys/dev/ata/wd.c:1.428.2.33	Sun Aug 13 11:40:25 2017
+++ src/sys/dev/ata/wd.c	Sun Aug 13 15:12:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -117,7 +117,7 @@ int wdcdebug_wd_mask = 0x0;
 #endif
 
 #ifdef WD_CHAOS_MONKEY
-int wdcdebug_wd_cnt = 200;
+int wdcdebug_wd_cnt = 0;
 int wdcdebug_wd_chaos = 0;
 #endif
 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-13 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Aug 13 11:48:53 UTC 2017

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

Log Message:
put the non-NCQ KASSERT() before edma disable for bio PIO, we are not supposed
to get there with NCQ command even on retries any more


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.22 -r1.35.6.23 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.22 src/sys/dev/ic/mvsata.c:1.35.6.23
--- src/sys/dev/ic/mvsata.c:1.35.6.22	Sat Aug 12 22:43:22 2017
+++ src/sys/dev/ic/mvsata.c	Sun Aug 13 11:48:53 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1339,6 +1339,7 @@ do_pio:
 			WDCC_READ : WDCC_WRITE;
 
 		/* EDMA disable, if enabled this channel. */
+		KASSERT((chp->ch_flags & ATACH_NCQ) == 0);
 		if (mvport->port_edmamode_curr != nodma)
 			mvsata_edma_disable(mvport, 10 /* ms */, wait_flags);
 



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-13 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Aug 13 11:46:32 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
move the dump note to post-merge, it's not new
siisata seems to be fine, no longer holds the merge

remove the kill active transfers after software drive reset - not relevant

now only the wd* at umass? stays as new item, but I won't hold the merge
for this, as I don't have the hardware and it is contained enough to be
resolved on HEAD


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.35 -r1.1.2.36 src/sys/dev/ata/TODO.ncq

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.35 src/sys/dev/ata/TODO.ncq:1.1.2.36
--- src/sys/dev/ata/TODO.ncq:1.1.2.35	Sat Aug 12 22:43:22 2017
+++ src/sys/dev/ata/TODO.ncq	Sun Aug 13 11:46:32 2017
@@ -1,19 +1,13 @@
 Bugs
 
-
-siisata - fix all new XXX and unmergable bits
-
 test wd* at umass?, confirm the ata_channel kludge works
 
+Other random notes (do outside the NCQ branch):
+-
 do biodone() in wddone() starting the dump to not leak bufs when dumping from
 active system? make sure to not trigger atastart()
 - call ata_kill_active() + ata_kill_pending() when dumping
 
-kill active transfers after software drive reset - race timeout vs.
-error recovery
-
-Other random notes (do outside the NCQ branch):
--
 implement support for PM FIS-based switching, remove restriction in atastart()
 for hw which supports it, adjust error handling in controller drivers to handle
 xfers for several different drives



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-13 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Aug 13 11:40:25 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
restore the fallback to non-NCQ on retries, do this after WDIORETRIES_SINGLE
retries, but only for non-FUA I/O; also only do the ATA_SINGLE fallback
when non-FUA

this makes sure that bio with ATA_SINGLE is not attempted as NCQ -
the ATA_SINGLE I/O is usually done using PIO by drivers which
actually support it, and thus are not compatible with DMA-only NCQ


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.32 -r1.428.2.33 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.32 src/sys/dev/ata/wd.c:1.428.2.33
--- src/sys/dev/ata/wd.c:1.428.2.32	Sat Aug 12 22:12:04 2017
+++ src/sys/dev/ata/wd.c	Sun Aug 13 11:40:25 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -720,9 +720,12 @@ wdstart1(struct wd_softc *wd, struct buf
 	/*
 	 * If we're retrying, retry in single-sector mode. This will give us
 	 * the sector number of the problem, and will eventually allow the
-	 * transfer to succeed.
+	 * transfer to succeed. If FUA is requested, we can't actually
+	 * do this, as ATA_SINGLE is usually executed as PIO transfer by drivers
+	 * which support it, and that isn't compatible with NCQ/FUA.
 	 */
-	if (xfer->c_retries >= WDIORETRIES_SINGLE)
+	if (xfer->c_retries >= WDIORETRIES_SINGLE &&
+	(bp->b_flags & B_MEDIA_FUA) == 0)
 		xfer->c_bio.flags = ATA_SINGLE;
 	else
 		xfer->c_bio.flags = 0;
@@ -734,10 +737,17 @@ wdstart1(struct wd_softc *wd, struct buf
 		xfer->c_bio.flags |= ATA_LBA48;
 
 	/*
-	 * If NCQ was negotiated, always use it. Some drives return random
-	 * errors when switching between NCQ and non-NCQ I/O too often. 
+	 * If NCQ was negotiated, always use it for the first several attempts.
+	 * Since device cancels all outstanding requests on error, downgrade
+	 * to non-NCQ on retry, so that the retried transfer would not cause
+	 * cascade failure for the other transfers if it fails again.
+	 * If FUA was requested, we can't downgrade, as that would violate
+	 * the semantics - FUA would not be honored. In that case, continue
+	 * retrying with NCQ.
 	 */
-	if (wd->drvp->drive_flags & ATA_DRIVE_NCQ) {
+	if (wd->drvp->drive_flags & ATA_DRIVE_NCQ &&
+	(xfer->c_retries < WDIORETRIES_SINGLE ||
+	(bp->b_flags & B_MEDIA_FUA) != 0)) {
 		xfer->c_bio.flags |= ATA_LBA48;
 		xfer->c_flags |= C_NCQ;
 



CVS commit: [jdolecek-ncq] src/sys/dev

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 22:43:22 UTC 2017

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

Log Message:
add NCQ error recovery for mvsata(4)

fix wait flags for mvsata_bio_start(), AT_* constants are only valid for cmd

change the debug logging to similar form as ahcisata/siisata, so it's
easier to selectively show


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.34 -r1.1.2.35 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.35.6.21 -r1.35.6.22 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.2.48.3 -r1.2.48.4 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.34 src/sys/dev/ata/TODO.ncq:1.1.2.35
--- src/sys/dev/ata/TODO.ncq:1.1.2.34	Sat Aug 12 14:41:54 2017
+++ src/sys/dev/ata/TODO.ncq	Sat Aug 12 22:43:22 2017
@@ -5,9 +5,6 @@ siisata - fix all new XXX and unmergable
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-do proper NCQ error recovery
-- update mvsata to do same as ahcisata/siisata (read log ext, timeouts, et.al)
-
 do biodone() in wddone() starting the dump to not leak bufs when dumping from
 active system? make sure to not trigger atastart()
 - call ata_kill_active() + ata_kill_pending() when dumping

Index: src/sys/dev/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.21 src/sys/dev/ic/mvsata.c:1.35.6.22
--- src/sys/dev/ic/mvsata.c:1.35.6.21	Sat Aug 12 14:41:54 2017
+++ src/sys/dev/ic/mvsata.c	Sat Aug 12 22:43:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.21 2017/08/12 14:41:54 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.21 2017/08/12 14:41:54 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -86,12 +86,16 @@ __KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1
 	SHADOW_REG_BLOCK_OFFSET + (reg), (val))
 
 #ifdef MVSATA_DEBUG
-#define DPRINTF(x)	if (mvsata_debug) printf x
-#define	DPRINTFN(n,x)	if (mvsata_debug >= (n)) printf x
-int	mvsata_debug = 2;
+
+#define DEBUG_INTR   0x01
+#define DEBUG_XFERS  0x02
+#define DEBUG_FUNCS  0x08
+#define DEBUG_PROBE  0x10
+
+#define	DPRINTF(n,x)	if (mvsata_debug & (n)) printf x
+int	mvsata_debug = 0;
 #else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
+#define DPRINTF(n,x)
 #endif
 
 #define ATA_DELAY		1	/* 10s for a drive I/O */
@@ -160,6 +164,7 @@ static void mvsata_bdma_start(struct mvs
 #endif
 
 static int mvsata_nondma_handle(struct mvsata_port *);
+static void mvsata_channel_recover(struct mvsata_port *);
 
 static int mvsata_port_init(struct mvsata_hc *, int);
 static int mvsata_wdc_reg_init(struct mvsata_port *, struct wdc_regs *);
@@ -398,7 +403,7 @@ mvsata_intr(struct mvsata_hc *mvhc)
 
 	cause = MVSATA_HC_READ_4(mvhc, SATAHC_IC);
 
-	DPRINTFN(3, ("%s:%d: mvsata_intr: cause=0x%08x\n",
+	DPRINTF(DEBUG_INTR, ("%s:%d: mvsata_intr: cause=0x%08x\n",
 	device_xname(MVSATA_DEV(sc)), mvhc->hc, cause));
 
 	if (cause & SATAHC_IC_SAINTCOAL)
@@ -432,22 +437,23 @@ mvsata_nondma_handle(struct mvsata_port 
 {
 	struct ata_channel *chp = >port_ata_channel;
 	struct ata_xfer *xfer;
-	int ret, quetag;
+	int ret;
 
 	/*
 	 * The chip doesn't support several pending non-DMA commands,
 	 * and the ata middle layer never issues several non-NCQ commands,
 	 * so there must be exactly one active command at this moment.
 	 */
-	for (quetag = 0; quetag < MVSATA_EDMAQ_LEN; quetag++) {
-		if ((mvport->port_quetagidx & __BIT(quetag)) == 0)
-			continue;
-
-		break;
+	xfer = ata_queue_get_active_xfer(chp);
+	if (xfer == NULL) {
+		/* Can happen after error recovery, ignore */
+		DPRINTF(DEBUG_FUNCS|DEBUG_XFERS,
+		("%s:%d: %s: intr without xfer\n",
+		device_xname(MVSATA_DEV2(mvport)), chp->ch_channel,
+		__func__));
+		return 0;
 	}
-	KASSERT(quetag < MVSATA_EDMAQ_LEN);
 
-	xfer = ata_queue_hwslot_to_xfer(chp, quetag);
 	ret = xfer->c_intr(chp, xfer, 1);
 	return (ret);
 }
@@ -473,7 +479,7 @@ mvsata_error(struct mvsata_port *mvport)
 	}
 	MVSATA_EDMA_WRITE_4(mvport, EDMA_IEC, ~cause);
 
-	DPRINTFN(3, ("%s:%d:%d:"
+	DPRINTF(DEBUG_INTR, ("%s:%d:%d:"
 	" mvsata_error: cause=0x%08x, mask=0x%08x, status=0x%08x\n",
 	device_xname(MVSATA_DEV2(mvport)), mvport->port_hc->hc,
 	mvport->port, cause, MVSATA_EDMA_READ_4(mvport, EDMA_IEM),
@@ -492,8 +498,9 @@ mvsata_error(struct mvsata_port *mvport)
 		if (sc->sc_gen == gen1)
 			mvsata_devconn_gen1(mvport);
 
-		DPRINTFN(3, ("device connected\n"));
+		DPRINTF(DEBUG_INTR, ("device connected\n"));
 	}
+
 #ifndef MVSATA_WITHOUTDMA
 	if ((sc->sc_gen == gen1 && cause & EDMA_IE_ETRANSINT) ||
 	(sc->sc_gen != gen1 && 

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 22:31:50 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
use AT_LBA48 flag for the READ LOG EXT - it's required so that e.g. mvsata()
executes the command using wdccommandext(), it fails when executed using
wdccommand()


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.27 -r1.132.8.28 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.27 src/sys/dev/ata/ata.c:1.132.8.28
--- src/sys/dev/ata/ata.c:1.132.8.27	Sat Aug 12 15:08:38 2017
+++ src/sys/dev/ata/ata.c	Sat Aug 12 22:31:50 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1091,7 +1091,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	xfer->c_ata_c.r_st_pmask = WDCS_DRDY;
 	xfer->c_ata_c.r_count = 1;
 	xfer->c_ata_c.r_device = WDSD_LBA;
-	xfer->c_ata_c.flags = AT_READ | AT_LBA | flags;
+	xfer->c_ata_c.flags = AT_READ | AT_LBA | AT_LBA48 | flags;
 	xfer->c_ata_c.timeout = 1000; /* 1s */
 	xfer->c_ata_c.data = tb;
 	xfer->c_ata_c.bcount = DEV_BSIZE;



CVS commit: [jdolecek-ncq] src/sys/dev

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 22:12:04 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: atavar.h wd.c
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c siisata.c

Log Message:
do not reset drive after successful NCQ error recovery


To generate a diff of this commit:
cvs rdiff -u -r1.92.8.23 -r1.92.8.24 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.428.2.31 -r1.428.2.32 src/sys/dev/ata/wd.c
cvs rdiff -u -r1.57.6.25 -r1.57.6.26 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.30.4.34 -r1.30.4.35 src/sys/dev/ic/siisata.c

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/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.23 src/sys/dev/ata/atavar.h:1.92.8.24
--- src/sys/dev/ata/atavar.h:1.92.8.23	Sat Aug 12 14:41:54 2017
+++ src/sys/dev/ata/atavar.h	Sat Aug 12 22:12:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.23 2017/08/12 14:41:54 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.24 2017/08/12 22:12:04 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -184,6 +184,7 @@ struct ata_xfer {
 #define C_RECOVERY	0x0200		/* executed as part of recovery */
 #define C_WAITTIMO	0x0400		/* race vs. timeout */
 #define C_CHAOS		0x0800		/* forced error xfer */
+#define C_RECOVERED	0x1000		/* error recovered, no need for reset */
 
 /* reasons for c_kill_xfer() */
 #define KILL_GONE 1		/* device is gone while xfer was active */

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.31 src/sys/dev/ata/wd.c:1.428.2.32
--- src/sys/dev/ata/wd.c:1.428.2.31	Sun Jul 30 20:16:29 2017
+++ src/sys/dev/ata/wd.c	Sat Aug 12 22:12:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -819,7 +819,8 @@ wddone(device_t self, struct ata_xfer *x
 		errmsg = "error";
 		do_perror = 1;
 retry:		/* Just reset and retry. Can we do more ? */
-		(*wd->atabus->ata_reset_drive)(wd->drvp, AT_POLL, NULL);
+		if ((xfer->c_flags & C_RECOVERED) == 0)
+			(*wd->atabus->ata_reset_drive)(wd->drvp, AT_POLL, NULL);
 retry2:
 		mutex_enter(>sc_lock);
 

Index: src/sys/dev/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.25 src/sys/dev/ic/ahcisata_core.c:1.57.6.26
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.25	Tue Aug  1 22:02:32 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sat Aug 12 22:12:04 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.26 2017/08/12 22:12:04 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.26 2017/08/12 22:12:04 jdolecek Exp $");
 
 #include 
 #include 
@@ -1592,6 +1592,7 @@ ahci_channel_recover(struct ahci_softc *
 		/* Error out the particular NCQ xfer, then requeue the others */
 		if ((achp->ahcic_cmds_active & (1 << eslot)) != 0) {
 			xfer = ata_queue_hwslot_to_xfer(chp, eslot);
+			xfer->c_flags |= C_RECOVERED;
 			xfer->c_intr(chp, xfer,
 			(err << AHCI_P_TFD_ERR_SHIFT) | st);
 		}

Index: src/sys/dev/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.34 src/sys/dev/ic/siisata.c:1.30.4.35
--- src/sys/dev/ic/siisata.c:1.30.4.34	Fri Aug 11 18:20:13 2017
+++ src/sys/dev/ic/siisata.c	Sat Aug 12 22:12:04 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $");
 
 #include 
 #include 
@@ -653,6 +653,7 @@ siisata_channel_recover(struct ata_chann
 		/* Error out the particular NCQ xfer, then requeue the others */
 		if ((schp->sch_active_slots & (1 << eslot)) != 0) {
 			xfer = ata_queue_hwslot_to_xfer(chp, eslot);
+			xfer->c_flags |= C_RECOVERED;
 			xfer->c_intr(chp, xfer, ATACH_ERR_ST(err, st));
 		}
 		break;



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 15:08:38 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
take atabus_qlock while inserting into atabus_initq_head to avoid race
in attach and rescan; just cleanup, noticed this while doing the thread
locking, don't think there is realistic way to trigger this


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.26 -r1.132.8.27 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.26 src/sys/dev/ata/ata.c:1.132.8.27
--- src/sys/dev/ata/ata.c:1.132.8.26	Sat Aug 12 14:41:54 2017
+++ src/sys/dev/ata/ata.c	Sat Aug 12 15:08:38 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -711,7 +711,9 @@ atabus_attach(device_t parent, device_t 
 
 	initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK);
 	initq->atabus_sc = sc;
+	mutex_enter(_qlock);
 	TAILQ_INSERT_TAIL(_initq_head, initq, atabus_initq);
+	mutex_exit(_qlock);
 	config_pending_incr(sc->sc_dev);
 
 	if ((error = kthread_create(PRI_NONE, 0, NULL, atabus_thread, sc,
@@ -2390,7 +2392,9 @@ atabus_rescan(device_t self, const char 
 
 	initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK);
 	initq->atabus_sc = sc;
+	mutex_enter(_qlock);
 	TAILQ_INSERT_TAIL(_initq_head, initq, atabus_initq);
+	mutex_exit(_qlock);
 	config_pending_incr(sc->sc_dev);
 
 	mutex_enter(>ch_lock);



CVS commit: [jdolecek-ncq] src/sys/dev

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 14:41:54 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h
src/sys/dev/ic [jdolecek-ncq]: mvsata.c wdc.c
src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
convert the atabus thread to use the channel lock and a condvar, adjust
code which sets the relevant channel flags to take the lock while doing so


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.33 -r1.1.2.34 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.132.8.25 -r1.132.8.26 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.105.6.7 -r1.105.6.8 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.92.8.22 -r1.92.8.23 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.35.6.20 -r1.35.6.21 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.283.2.12 -r1.283.2.13 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.123.4.11 -r1.123.4.12 src/sys/dev/scsipi/atapi_wdc.c

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.33 src/sys/dev/ata/TODO.ncq:1.1.2.34
--- src/sys/dev/ata/TODO.ncq:1.1.2.33	Sat Aug 12 09:52:28 2017
+++ src/sys/dev/ata/TODO.ncq	Sat Aug 12 14:41:54 2017
@@ -15,8 +15,6 @@ active system? make sure to not trigger 
 kill active transfers after software drive reset - race timeout vs.
 error recovery
 
-atabus_thread() protect run by mutex/condvar
-
 Other random notes (do outside the NCQ branch):
 -
 implement support for PM FIS-based switching, remove restriction in atastart()

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.25 src/sys/dev/ata/ata.c:1.132.8.26
--- src/sys/dev/ata/ata.c:1.132.8.25	Sat Aug 12 09:52:28 2017
+++ src/sys/dev/ata/ata.c	Sat Aug 12 14:41:54 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52:28 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52:28 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -131,7 +131,7 @@ static void atabusconfig_thread(void *);
 
 static void ata_channel_idle(struct ata_channel *);
 static void ata_activate_xfer_locked(struct ata_channel *, struct ata_xfer *);
-
+static void ata_channel_freeze_locked(struct ata_channel *);
 /*
  * atabus_init:
  *
@@ -322,6 +322,7 @@ void
 ata_channel_init(struct ata_channel *chp)
 {
 	mutex_init(>ch_lock, MUTEX_DEFAULT, IPL_BIO);
+	cv_init(>ch_thr_idle, "atath");
 }
 
 /*
@@ -347,6 +348,7 @@ void
 ata_channel_destroy(struct ata_channel *chp)
 {
 	mutex_destroy(>ch_lock);
+	cv_destroy(>ch_thr_idle);
 }
 
 /*
@@ -369,12 +371,12 @@ atabusconfig(struct atabus_softc *atabus
 	struct ata_channel *chp = atabus_sc->sc_chan;
 	struct atac_softc *atac = chp->ch_atac;
 	struct atabus_initq *atabus_initq = NULL;
-	int i, s, error;
+	int i, error;
 
 	/* we are in the atabus's thread context */
-	s = splbio();
+	mutex_enter(>ch_lock);
 	chp->ch_flags |= ATACH_TH_RUN;
-	splx(s);
+	mutex_exit(>ch_lock);
 
 	/*
 	 * Probe for the drives attached to controller, unless a PMP
@@ -391,9 +393,9 @@ atabusconfig(struct atabus_softc *atabus
 	}
 
 	/* next operations will occurs in a separate thread */
-	s = splbio();
+	mutex_enter(>ch_lock);
 	chp->ch_flags &= ~ATACH_TH_RUN;
-	splx(s);
+	mutex_exit(>ch_lock);
 
 	/* Make sure the devices probe in atabus order to avoid jitter. */
 	mutex_enter(_qlock);
@@ -405,6 +407,8 @@ atabusconfig(struct atabus_softc *atabus
 	}
 	mutex_exit(_qlock);
 
+	mutex_enter(>ch_lock);
+
 	/* If no drives, abort here */
 	if (chp->ch_drive == NULL)
 		goto out;
@@ -419,6 +423,8 @@ atabusconfig(struct atabus_softc *atabus
 	if (chp->ch_flags & ATACH_SHUTDOWN)
 		goto out;
 
+	mutex_exit(>ch_lock);
+
 	if ((error = kthread_create(PRI_NONE, 0, NULL, atabusconfig_thread,
 	atabus_sc, _cfg_lwp,
 	"%scnf", device_xname(atac->atac_dev))) != 0)
@@ -427,6 +433,8 @@ atabusconfig(struct atabus_softc *atabus
 	return;
 
  out:
+	mutex_exit(>ch_lock);
+
 	mutex_enter(_qlock);
 	TAILQ_REMOVE(_initq_head, atabus_initq, atabus_initq);
 	cv_broadcast(_qcv);
@@ -578,9 +586,9 @@ atabus_thread(void *arg)
 	struct ata_channel *chp = sc->sc_chan;
 	struct ata_queue *chq = chp->ch_queue;
 	struct ata_xfer *xfer;
-	int i, s;
+	int i;
 
-	s = splbio();
+	mutex_enter(>ch_lock);
 	chp->ch_flags |= ATACH_TH_RUN;
 
 	/*
@@ -594,32 +602,36 @@ atabus_thread(void *arg)
 		chp->ch_drive[i].drive_flags = 0;
 		chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
 	}
-	splx(s);
+	mutex_exit(>ch_lock);
 
 	atabusconfig(sc);
 
-	s = splbio();
+	mutex_enter(>ch_lock);
 	for (;;) {
 		if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 &&
 		(chq->queue_active 

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 13:41:46 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: wdc.c

Log Message:
remove debug printf


To generate a diff of this commit:
cvs rdiff -u -r1.283.2.11 -r1.283.2.12 src/sys/dev/ic/wdc.c

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/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.283.2.11 src/sys/dev/ic/wdc.c:1.283.2.12
--- src/sys/dev/ic/wdc.c:1.283.2.11	Sat Aug 12 09:52:28 2017
+++ src/sys/dev/ic/wdc.c	Sat Aug 12 13:41:46 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.283.2.11 2017/08/12 09:52:28 jdolecek Exp $ */
+/*	$NetBSD: wdc.c,v 1.283.2.12 2017/08/12 13:41:46 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.11 2017/08/12 09:52:28 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.12 2017/08/12 13:41:46 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -1254,7 +1254,6 @@ wdcwait(struct ata_channel *chp, int mas
  */
 ata_channel_freeze(chp);
 wakeup(>ch_thread);
-printf("wdcwait_thr");
 return(WDCWAIT_THR);
 			}
 		}



CVS commit: [jdolecek-ncq] src/sys/dev

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 09:52:29 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h
src/sys/dev/ic [jdolecek-ncq]: mvsata.c wdc.c wdcvar.h
src/sys/dev/pci [jdolecek-ncq]: pciide_common.c
src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
remove all logic around ATACH_IRQ_WAIT and channel-global ch_error/ch_status,
so that there is less hidden state shared by commands; primary intent is
to make the NCQ and non-NCQ paths more similar, and remove possibility
of incorrect handling for the NCQ commands

tested both disk and ATAPI - piixide(4) on QEMU, and siisata(4),
ahcisata(4), mvsata(4) on real hw


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.32 -r1.1.2.33 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.132.8.24 -r1.132.8.25 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.105.6.6 -r1.105.6.7 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.92.8.21 -r1.92.8.22 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.35.6.19 -r1.35.6.20 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.283.2.10 -r1.283.2.11 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.97.26.1 -r1.97.26.2 src/sys/dev/ic/wdcvar.h
cvs rdiff -u -r1.62.4.1 -r1.62.4.2 src/sys/dev/pci/pciide_common.c
cvs rdiff -u -r1.123.4.10 -r1.123.4.11 src/sys/dev/scsipi/atapi_wdc.c

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.32 src/sys/dev/ata/TODO.ncq:1.1.2.33
--- src/sys/dev/ata/TODO.ncq:1.1.2.32	Tue Aug  1 22:04:48 2017
+++ src/sys/dev/ata/TODO.ncq	Sat Aug 12 09:52:28 2017
@@ -7,9 +7,6 @@ test wd* at umass?, confirm the ata_chan
 
 do proper NCQ error recovery
 - update mvsata to do same as ahcisata/siisata (read log ext, timeouts, et.al)
-- update also ic/wdc.c, scsipi/atapi_wdc.c, ata/ata_wdc.c to not use
-  ch_status/ch_error/ATACH_IRQ_WAIT
-- retest ATAPI
 
 do biodone() in wddone() starting the dump to not leak bufs when dumping from
 active system? make sure to not trigger atastart()
@@ -18,6 +15,8 @@ active system? make sure to not trigger 
 kill active transfers after software drive reset - race timeout vs.
 error recovery
 
+atabus_thread() protect run by mutex/condvar
+
 Other random notes (do outside the NCQ branch):
 -
 implement support for PM FIS-based switching, remove restriction in atastart()

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.24 src/sys/dev/ata/ata.c:1.132.8.25
--- src/sys/dev/ata/ata.c:1.132.8.24	Tue Aug  1 21:41:25 2017
+++ src/sys/dev/ata/ata.c	Sat Aug 12 09:52:28 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41:25 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52:28 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41:25 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52:28 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -622,15 +622,16 @@ atabus_thread(void *arg)
 			ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags);
 		} else if (chq->queue_active > 0 && chq->queue_freeze == 1) {
 			/*
-			 * Caller has bumped queue_freeze, decrease it.
+			 * Caller has bumped queue_freeze, decrease it. This
+			 * flow shalt never be executed for NCQ commands.
 			 */
+			KASSERT((chp->ch_flags & ATACH_NCQ) == 0);
+			KASSERT(chq->queue_active == 1);
+
 			ata_channel_thaw(chp);
-			u_int active __diagused = 0;
-			TAILQ_FOREACH(xfer, >active_xfers, c_activechain) {
-(*xfer->c_start)(xfer->c_chp, xfer);
-active++;
-			}
-			KASSERT(active == chq->queue_active);
+			xfer = ata_queue_get_active_xfer(chp);
+			KASSERT(xfer != NULL);
+			(*xfer->c_start)(xfer->c_chp, xfer);
 		} else if (chq->queue_freeze > 1)
 			panic("ata_thread: queue_freeze");
 	}
@@ -1430,7 +1431,7 @@ ata_free_xfer(struct ata_channel *chp, s
 		/* finish the busmastering PIO */
 		(*wdc->piobm_done)(wdc->dma_arg,
 		chp->ch_channel, xfer->c_drive);
-		chp->ch_flags &= ~(ATACH_DMA_WAIT | ATACH_PIOBM_WAIT | ATACH_IRQ_WAIT);
+		chp->ch_flags &= ~(ATACH_DMA_WAIT | ATACH_PIOBM_WAIT);
 	}
 #endif
 
@@ -1521,7 +1522,7 @@ ata_waitdrain_xfer_check(struct ata_chan
 /*
  * Check for race of normal transfer handling vs. timeout.
  */
-static bool
+bool
 ata_timo_xfer_check(struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = xfer->c_chp;

Index: src/sys/dev/ata/ata_wdc.c
diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.6 src/sys/dev/ata/ata_wdc.c:1.105.6.7
--- src/sys/dev/ata/ata_wdc.c:1.105.6.6	Tue Jun 27 18:36:03 2017
+++ src/sys/dev/ata/ata_wdc.c	Sat Aug 12 09:52:28 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_wdc.c,v 1.105.6.6 2017/06/27 18:36:03 jdolecek Exp $	*/
+/*	$NetBSD: ata_wdc.c,v 1.105.6.7 2017/08/12 09:52:28 jdolecek Exp $	*/
 
 /*
  * Copyright 

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-12 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug 12 09:38:58 UTC 2017

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

Log Message:
fix condition for switching to kernel thread for ATAPI and bio reset recovery
to match atapi_wdc.c, __wdcwait() postpones to the thread whenever neither
AT_POLL nor AT_WAIT flags are present

fixes spurious 'timeout' for the command on mvsata, followed by 'unexpected'
interrupt


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.18 -r1.35.6.19 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.18 src/sys/dev/ic/mvsata.c:1.35.6.19
--- src/sys/dev/ic/mvsata.c:1.35.6.18	Wed Jun 28 19:59:36 2017
+++ src/sys/dev/ic/mvsata.c	Sat Aug 12 09:38:58 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.19 2017/08/12 09:38:58 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.19 2017/08/12 09:38:58 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1222,7 +1222,8 @@ do_pio:
 			 * If it's not a polled command, we need the kernel
 			 * thread
 			 */
-			if ((xfer->c_flags & C_POLL) == 0 && cpu_intr_p()) {
+			if ((xfer->c_flags & C_POLL) == 0 &&
+			(chp->ch_flags & ATACH_TH_RUN) == 0) {
 ata_channel_freeze(chp);
 wakeup(>ch_thread);
 return;
@@ -1910,7 +1911,8 @@ mvsata_atapi_start(struct ata_channel *c
 	/* Do control operations specially. */
 	if (__predict_false(drvp->state < READY)) {
 		/* If it's not a polled command, we need the kernel thread */
-		if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 && cpu_intr_p()) {
+		if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 &&
+		(chp->ch_flags & ATACH_TH_RUN) == 0) {
 			ata_channel_freeze(chp);
 			wakeup(>ch_thread);
 			return;



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-11 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Aug 11 18:20:13 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
replace magic 3100 with locall defined WDC_RESET_WAIT


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.33 -r1.30.4.34 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.33 src/sys/dev/ic/siisata.c:1.30.4.34
--- src/sys/dev/ic/siisata.c:1.30.4.33	Fri Aug  4 20:53:46 2017
+++ src/sys/dev/ic/siisata.c	Fri Aug 11 18:20:13 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $");
 
 #include 
 #include 
@@ -109,6 +109,7 @@ int siisata_debug_mask = 0;
 #endif
 
 #define ATA_DELAY 1		/* 10s for a drive I/O */
+#define WDC_RESET_WAIT 31000	/* 31s for drive reset */
 
 #ifndef __BUS_SPACE_HAS_STREAM_METHODS
 #if _BYTE_ORDER == _LITTLE_ENDIAN
@@ -721,6 +722,7 @@ siisata_reset_drive(struct ata_drive_dat
 	struct ata_xfer *xfer;
 	uint32_t pss, pis;
 	int i;
+	bool timed_out;
 
 	siisata_reinit_port(chp, drvp->drive);
 
@@ -737,10 +739,13 @@ siisata_reset_drive(struct ata_drive_dat
 
 	siisata_activate_prb(schp, xfer->c_slot);
 
-	for(i = 0; i < 3100; i++) {
+	timed_out = true;
+	for(i = 0; i < WDC_RESET_WAIT / 10; i++) {
 		pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
-		if ((pss & PR_PXSS(xfer->c_slot)) == 0)
+		if ((pss & PR_PXSS(xfer->c_slot)) == 0) {
+			timed_out = false;
 			break;
+		}
 		if (pss & PR_PSS_ATTENTION)
 			break;
 		ata_delay(10, "siiprb", flags);
@@ -764,7 +769,7 @@ siisata_reset_drive(struct ata_drive_dat
 
 	siisata_enable_port_interrupt(chp);
 
-	if (i == 3100) {
+	if (timed_out) {
 		/* timeout */
 		siisata_device_reset(chp);	/* XXX is this right? */
 		if (sigp)
@@ -888,7 +893,7 @@ siisata_probe_drive(struct ata_channel *
 		siisata_activate_prb(schp, xfer->c_slot);
 
 		timed_out = 1;
-		for(i = 0; i < 3100; i++) {
+		for(i = 0; i < WDC_RESET_WAIT / 10; i++) {
 			if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) &
 			PR_PXSS(xfer->c_slot)) == 0) {
 /* prb completed */



CVS commit: [jdolecek-ncq] src/sys/dev/pci

2017-08-05 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Aug  5 13:22:01 UTC 2017

Modified Files:
src/sys/dev/pci [jdolecek-ncq]: acardide.c

Log Message:
kill dead code


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.31.18.1 src/sys/dev/pci/acardide.c

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/pci/acardide.c
diff -u src/sys/dev/pci/acardide.c:1.31 src/sys/dev/pci/acardide.c:1.31.18.1
--- src/sys/dev/pci/acardide.c:1.31	Mon Oct  7 19:51:55 2013
+++ src/sys/dev/pci/acardide.c	Sat Aug  5 13:22:01 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: acardide.c,v 1.31 2013/10/07 19:51:55 jakllsch Exp $	*/
+/*	$NetBSD: acardide.c,v 1.31.18.1 2017/08/05 13:22:01 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 2001 Izumi Tsutsui.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.31 2013/10/07 19:51:55 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.31.18.1 2017/08/05 13:22:01 jdolecek Exp $");
 
 #include 
 #include 
@@ -292,41 +292,3 @@ acard_setup_channel(struct ata_channel *
 		pci_conf_write(sc->sc_pc, sc->sc_tag, ATP860_UDMA, udma_mode);
 	}
 }
-
-#if 0 /* XXX !! */
-static int
-acard_pci_intr(void *arg)
-{
-	struct pciide_softc *sc = arg;
-	struct pciide_channel *cp;
-	struct ata_channel *wdc_cp;
-	int rv = 0;
-	int dmastat, i, crv;
-
-	for (i = 0; i < sc->sc_wdcdev.sc_atac.atac_nchannels; i++) {
-		cp = >pciide_channels[i];
-		dmastat = bus_space_read_1(sc->sc_dma_iot,
-		cp->dma_iohs[IDEDMA_CTL], 0);
-		if ((dmastat & IDEDMA_CTL_INTR) == 0)
-			continue;
-		wdc_cp = >ata_channel;
-		if ((wdc_cp->ch_flags & ATACH_IRQ_WAIT) == 0) {
-			(void)wdcintr(wdc_cp);
-			bus_space_write_1(sc->sc_dma_iot,
-			cp->dma_iohs[IDEDMA_CTL], 0, dmastat);
-			continue;
-		}
-		crv = wdcintr(wdc_cp);
-		if (crv == 0) {
-			printf("%s:%d: bogus intr\n",
-			device_xname(sc->sc_wdcdev.sc_atac.atac_dev), i);
-			bus_space_write_1(sc->sc_dma_iot,
-			cp->dma_iohs[IDEDMA_CTL], 0, dmastat);
-		} else if (crv == 1)
-			rv = 1;
-		else if (rv == 0)
-			rv = crv;
-	}
-	return rv;
-}
-#endif



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-04 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Aug  4 20:53:47 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
prb_control need to add (or) PRB_CF_INTERRUPT_MASK for polled commands,
rather that set - the field may be nonzero for ATAPI or for protocol override


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.32 -r1.30.4.33 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.32 src/sys/dev/ic/siisata.c:1.30.4.33
--- src/sys/dev/ic/siisata.c:1.30.4.32	Fri Aug  4 20:49:24 2017
+++ src/sys/dev/ic/siisata.c	Fri Aug  4 20:53:46 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $");
 
 #include 
 #include 
@@ -1039,7 +1039,7 @@ siisata_cmd_start(struct ata_channel *ch
 
 	if (xfer->c_flags & C_POLL) {
 		/* polled command, disable interrupts */
-		prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK);
+		prb->prb_control |= htole16(PRB_CF_INTERRUPT_MASK);
 		siisata_disable_port_interrupt(chp);
 	}
 
@@ -1256,7 +1256,7 @@ siisata_bio_start(struct ata_channel *ch
 
 	if (xfer->c_flags & C_POLL) {
 		/* polled command, disable interrupts */
-		prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK);
+		prb->prb_control |= htole16(PRB_CF_INTERRUPT_MASK);
 		siisata_disable_port_interrupt(chp);
 	}
 
@@ -1849,7 +1849,7 @@ siisata_atapi_start(struct ata_channel *
 
 	if (xfer->c_flags & C_POLL) {
 		/* polled command, disable interrupts */
-		prbp->prb_control = htole16(PRB_CF_INTERRUPT_MASK);
+		prbp->prb_control |= htole16(PRB_CF_INTERRUPT_MASK);
 		siisata_disable_port_interrupt(chp);
 	}
 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-04 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Aug  4 20:49:24 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
restore part of what was removed in 1.30.4.30 - the success of command
needs to be driven by PSS so that it works also for polled commands, apparently
PR_PIS_CMDCMPL is not set in that case; now do error handling again only when
PSS_ATTENTION is set

this fixes timeout for polled commands like standby on shutdown,
and (ehm ehm), READ LOG EXT on NCQ error recovery


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.31 -r1.30.4.32 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.31 src/sys/dev/ic/siisata.c:1.30.4.32
--- src/sys/dev/ic/siisata.c:1.30.4.31	Tue Aug  1 22:02:32 2017
+++ src/sys/dev/ic/siisata.c	Fri Aug  4 20:49:24 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.31 2017/08/01 22:02:32 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.31 2017/08/01 22:02:32 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $");
 
 #include 
 #include 
@@ -262,9 +262,12 @@ siisata_init_port(struct siisata_softc *
 	schp = >sc_channels[port];
 	chp = (struct ata_channel *)schp;
 
-	/* come out of reset, 64-bit activation */
+	/*
+	 * Come out of reset. Disable no clearing of PR_PIS_CMDCMPL on read
+	 * of PR_PSS. Disable 32-bit PRB activation, we use 64-bit activation.
+	 */
 	PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC),
-	PR_PC_32BA | PR_PC_PORT_RESET);
+	PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET);
 	/* initialize port */
 	siisata_reinit_port(chp, -1);
 	/* enable CmdErrr+CmdCmpl interrupting */
@@ -478,22 +481,22 @@ siisata_intr_port(struct siisata_channel
 	uint32_t pss, pis, tfd = 0;
 	bool recover = false;
 
-	pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
+	/* get slot status, clearing completion interrupt */
+	pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
 
-	SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ",
-	SIISATANAME(sc), __func__, chp->ch_channel, pis),
+	SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x ",
+	SIISATANAME(sc), __func__, chp->ch_channel, pss),
 	DEBUG_INTR);
 
-	if (pis & PR_PIS_CMDCMPL) {
-		/* get slot status, clearing completion interrupt */
-		pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
-
-		SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR);
-	} else {
-		/* commands will be killed after recovery */
-		pss = 0x;
+	if (__predict_true((pss & PR_PSS_ATTENTION) == 0)) {
+		SIISATA_DEBUG_PRINT(("no attention"), DEBUG_INTR);
+		goto process;
 	}
 
+	pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
+
+	SIISATA_DEBUG_PRINT(("pis 0x%x\n", pss), DEBUG_INTR);
+
 	if (pis & PR_PIS_CMDERRR) {
 		uint32_t ec;
 
@@ -552,6 +555,7 @@ siisata_intr_port(struct siisata_channel
 	if (__predict_false(recover))
 		ata_channel_freeze(chp);
 
+process:
 	if (xfer != NULL) {
 		xfer->c_intr(chp, xfer, tfd);
 	} else {



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-01 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug  1 22:04:48 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
another one down


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.31 -r1.1.2.32 src/sys/dev/ata/TODO.ncq

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.31 src/sys/dev/ata/TODO.ncq:1.1.2.32
--- src/sys/dev/ata/TODO.ncq:1.1.2.31	Mon Jul 31 20:11:17 2017
+++ src/sys/dev/ata/TODO.ncq	Tue Aug  1 22:04:48 2017
@@ -18,12 +18,6 @@ active system? make sure to not trigger 
 kill active transfers after software drive reset - race timeout vs.
 error recovery
 
-multi-pmp disk open+i/o on siisata fails - track down and fix
-#!/bin/sh
-for disk in $disks; do
-(echo $disk; for i in `seq 0 3`; do dd if=/dev/r${disk}d bs=16m of=/dev/null count=1; done)&
-done;
-
 Other random notes (do outside the NCQ branch):
 -
 implement support for PM FIS-based switching, remove restriction in atastart()



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-01 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug  1 22:02:32 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c ahcisatavar.h
mvsatavar.h siisata.c siisatavar.h

Log Message:
fix logic bug in processing of finished commands - mask of active
commands can change during the loop as c_intr() callback can queue
new commands, so the interrupt routine should only mark as finished
those which were actually active before the loop started; otherwise
the code marked as finished commands which were just started, and
being executed by HBA, leading to all sorts of data corruption

while here mark the active mask volatile, as it is modified from
interrupt context

this fixes for good the random crashes, short reads, and fatal command
errors which I've been tracing down for past couple weeks

thanks to Jonathan (jakllsch@) for testing, and a script to easily
triggered the condition, and led to this bug being finally found and squashed


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.24 -r1.57.6.25 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.17.6.2 -r1.17.6.3 src/sys/dev/ic/ahcisatavar.h
cvs rdiff -u -r1.2.48.2 -r1.2.48.3 src/sys/dev/ic/mvsatavar.h
cvs rdiff -u -r1.30.4.30 -r1.30.4.31 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.6.48.2 -r1.6.48.3 src/sys/dev/ic/siisatavar.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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.24 src/sys/dev/ic/ahcisata_core.c:1.57.6.25
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.24	Sat Jul 29 16:50:32 2017
+++ src/sys/dev/ic/ahcisata_core.c	Tue Aug  1 22:02:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $");
 
 #include 
 #include 
@@ -559,7 +559,7 @@ ahci_intr(void *v)
 static void
 ahci_intr_port(struct ahci_softc *sc, struct ahci_channel *achp)
 {
-	uint32_t is, tfd, active;
+	uint32_t is, tfd, sact;
 	struct ata_channel *chp = >ata_channel;
 	struct ata_xfer *xfer;
 	int slot;
@@ -578,12 +578,12 @@ ahci_intr_port(struct ahci_softc *sc, st
 
 	if ((chp->ch_flags & ATACH_NCQ) == 0) {
 		/* Non-NCQ operation */
-		active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel));
+		sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel));
 		slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))
 			& AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT;
 	} else {
 		/* NCQ operation */
-		active = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));
+		sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));
 		slot = -1;
 	}
 
@@ -595,7 +595,7 @@ ahci_intr_port(struct ahci_softc *sc, st
 			tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
 
 			aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n",
-			AHCINAME(sc), chp->ch_channel, active, is, tfd);
+			AHCINAME(sc), chp->ch_channel, sact, is, tfd);
 		} else {
 			/* mark an error, and set BSY */
 			tfd = (WDCE_ABRT << AHCI_P_TFD_ERR_SHIFT) |
@@ -630,8 +630,8 @@ ahci_intr_port(struct ahci_softc *sc, st
 		ata_channel_freeze(chp);
 
 	if (slot >= 0) {
-		if ((achp->ahcic_cmds_active & (1 << slot)) != 0 &&
-		(active & (1 << slot)) == 0) {
+		if ((achp->ahcic_cmds_active & __BIT(slot)) != 0 &&
+		(sact & __BIT(slot)) == 0) {
 			xfer = ata_queue_hwslot_to_xfer(chp, slot);
 			xfer->c_intr(chp, xfer, tfd);
 		}
@@ -641,10 +641,15 @@ ahci_intr_port(struct ahci_softc *sc, st
 		 * and any further D2H FISes are ignored until the error
 		 * condition is cleared. Hence if a command is inactive,
 		 * it means it actually already finished successfully.
+		 * Note: active slots can change as c_intr() callback
+		 * can activate another command(s), so must only process
+		 * commands active before we start processing.
 		 */
+		uint32_t aslots = achp->ahcic_cmds_active;
+
 		for (slot=0; slot < sc->sc_ncmds; slot++) {
-			if ((achp->ahcic_cmds_active & (1 << slot)) != 0 &&
-			(active & (1 << slot)) == 0) {
+			if ((aslots & __BIT(slot)) != 0 &&
+			(sact & __BIT(slot)) == 0) {
 xfer = ata_queue_hwslot_to_xfer(chp, slot);
 xfer->c_intr(chp, xfer, 0);
 			}

Index: src/sys/dev/ic/ahcisatavar.h
diff -u src/sys/dev/ic/ahcisatavar.h:1.17.6.2 src/sys/dev/ic/ahcisatavar.h:1.17.6.3
--- src/sys/dev/ic/ahcisatavar.h:1.17.6.2	Sat Jul 29 15:07:46 2017
+++ src/sys/dev/ic/ahcisatavar.h	Tue Aug  1 22:02:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisatavar.h,v 1.17.6.2 2017/07/29 15:07:46 jdolecek Exp $	*/
+/*	$NetBSD: ahcisatavar.h,v 1.17.6.3 2017/08/01 22:02:32 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -82,7 +82,7 @@ struct 

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-08-01 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug  1 21:43:49 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
adjust code to be closer to HEAD to it's easier to compare and find
regressions, undoing some changes which were actually not necessary


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.29 -r1.30.4.30 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.29 src/sys/dev/ic/siisata.c:1.30.4.30
--- src/sys/dev/ic/siisata.c:1.30.4.29	Sun Jul 30 20:46:31 2017
+++ src/sys/dev/ic/siisata.c	Tue Aug  1 21:43:49 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.30 2017/08/01 21:43:49 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.30 2017/08/01 21:43:49 jdolecek Exp $");
 
 #include 
 #include 
@@ -245,7 +245,10 @@ siisata_enable_port_interrupt(struct ata
 {
 	struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 
-	/* enable CmdErrr+CmdCmpl interrupting */
+	/* clear any interrupts */
+	(void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
+	PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0x);
+	/* and enable CmdErrr+CmdCmpl interrupting */
 	PRWRITE(sc, PRX(chp->ch_channel, PRO_PIES),
 	PR_PIS_CMDERRR | PR_PIS_CMDCMPL);
 }
@@ -259,12 +262,9 @@ siisata_init_port(struct siisata_softc *
 	schp = >sc_channels[port];
 	chp = (struct ata_channel *)schp;
 
-	/*
-	 * Come out of reset. Disable no clearing of PR_PIS_CMDCMPL on read
-	 * of PR_PSS. Disable 32-bit PRB activation, we use 64-bit activation.
-	 */
+	/* come out of reset, 64-bit activation */
 	PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC),
-	PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET);
+	PR_PC_32BA | PR_PC_PORT_RESET);
 	/* initialize port */
 	siisata_reinit_port(chp, -1);
 	/* enable CmdErrr+CmdCmpl interrupting */
@@ -474,29 +474,25 @@ siisata_intr_port(struct siisata_channel
 	struct siisata_softc *sc =
 	(struct siisata_softc *)schp->ata_channel.ch_atac;
 	struct ata_channel *chp = >ata_channel;
-	struct ata_xfer *xfer;
-	int slot = -1;
+	struct ata_xfer *xfer = NULL;
 	uint32_t pss, pis, tfd = 0;
 	bool recover = false;
 
-	/* get slot status, clearing completion interrupt (PR_PIS_CMDCMPL) */
-	pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
-
-	SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x\n",
-	SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR);
-
-	/* if no errors, just process finished commands and we're done */
-	if (__predict_true((pss & PR_PSS_ATTENTION) == 0))
-		goto process;
-
 	pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
 
 	SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ",
 	SIISATANAME(sc), __func__, chp->ch_channel, pis),
 	DEBUG_INTR);
 
-	/* clear */
-	PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis);
+	if (pis & PR_PIS_CMDCMPL) {
+		/* get slot status, clearing completion interrupt */
+		pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
+
+		SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR);
+	} else {
+		/* commands will be killed after recovery */
+		pss = 0x;
+	}
 
 	if (pis & PR_PIS_CMDERRR) {
 		uint32_t ec;
@@ -510,15 +506,12 @@ siisata_intr_port(struct siisata_channel
 		if (ec <= PR_PCE_DATAFISERROR) {
 			if (ec == PR_PCE_DEVICEERROR
 			&& (chp->ch_flags & ATACH_NCQ) == 0) {
-uint32_t ps = PRREAD(sc,
-PRX(chp->ch_channel, PRO_PS));
-/* This is only relevant for non-NCQ commands */
-slot = PR_PS_ACTIVE_SLOT(ps);
+xfer = ata_queue_get_active_xfer(chp);
 
 /* read in specific information about error */
 uint32_t prbfis = bus_space_read_stream_4(
 sc->sc_prt, sc->sc_prh,
-PRSX(chp->ch_channel, slot,
+PRSX(chp->ch_channel, xfer->c_slot,
 PRSO_FIS));
 
 /* get status and error */
@@ -528,30 +521,39 @@ siisata_intr_port(struct siisata_channel
 if (ATACH_ST(ntfd) & WDCS_ERR)
 	tfd = ntfd;
 			}
+
+			/*
+			 * We don't expect the recovery to trigger error,
+			 * but handle this just in case.
+			 */
+			if (!schp->sch_recovering) 
+recover = true;
+			else {
+aprint_error_dev(sc->sc_atac.atac_dev,
+"error ec %x while recovering\n", ec);
+
+/* Command will be marked as errored out */
+pss = 0;
+			}
 		} else {
 			aprint_error_dev(sc->sc_atac.atac_dev, "fatal error %d"
 			" on channel %d (ctx 0x%x), resetting\n",
 			ec, chp->ch_channel,
 			PRREAD(sc, PRX(chp->ch_channel, PRO_PCR)));
 
-			tfd |= ATACH_ERR_ST(0, WDCS_BSY);
+			/* okay, we have a "Fatal Error" */
+			siisata_device_reset(chp);
 		}
-
-		if (!schp->sch_recovering)
-			recover = true;
-	} else {

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-01 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug  1 21:41:26 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
make atastart() schedule as many commands as possible, instead of always
only one; makes it able to pick up pace again after processing non-NCQ command


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.23 -r1.132.8.24 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.23 src/sys/dev/ata/ata.c:1.132.8.24
--- src/sys/dev/ata/ata.c:1.132.8.23	Tue Aug  1 21:39:51 2017
+++ src/sys/dev/ata/ata.c	Tue Aug  1 21:41:25 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39:51 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41:25 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39:51 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41:25 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1240,6 +1240,7 @@ atastart(struct ata_channel *chp)
 	splx(spl1);
 #endif /* ATA_DEBUG */
 
+again:
 	mutex_enter(>ch_lock);
 
 	KASSERT(chq->queue_active <= chq->queue_openings);
@@ -1318,6 +1319,11 @@ atastart(struct ata_channel *chp)
 	 * routine for polled commands.
 	 */
 	xfer->c_start(chp, xfer);
+
+	/* Queue more commands if possible */
+	if (chq->queue_active < chq->queue_openings)
+		goto again;
+
 	return;
 
 out:



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-08-01 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Aug  1 21:39:51 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h

Log Message:
move the drive recovery block to drive struct, it's inherently per-drive


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.22 -r1.132.8.23 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.20 -r1.92.8.21 src/sys/dev/ata/atavar.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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.22 src/sys/dev/ata/ata.c:1.132.8.23
--- src/sys/dev/ata/ata.c:1.132.8.22	Sat Jul 29 12:58:29 2017
+++ src/sys/dev/ata/ata.c	Tue Aug  1 21:39:51 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39:51 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39:51 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1051,7 +1051,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 
 	xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0);
 
-	tb = chp->ch_recovery;
+	tb = drvp->recovery_blk;
 	memset(tb, 0, DEV_BSIZE);
 
 	/*

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.20 src/sys/dev/ata/atavar.h:1.92.8.21
--- src/sys/dev/ata/atavar.h:1.92.8.20	Sat Jul 29 12:58:29 2017
+++ src/sys/dev/ata/atavar.h	Tue Aug  1 21:39:51 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.20 2017/07/29 12:58:29 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.21 2017/08/01 21:39:51 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -321,6 +321,9 @@ struct ata_drive_datas {
 	struct disklabel *lp;	/* pointer to drive's label info */
 	uint8_t		multi;	/* # of blocks to transfer in multi-mode */
 	daddr_t	badsect[127];	/* 126 plus trailing -1 marker */
+
+	/* Recovery buffer */
+	uint8_t recovery_blk[DEV_BSIZE];
 };
 
 /* User config flags that force (or disable) the use of a mode */
@@ -425,9 +428,6 @@ struct ata_channel {
 
 	/* Number of sata PMP ports, if any */
 	int ch_satapmp_nports;
-
-	/* Recovery buffer */
-	uint8_t ch_recovery[DEV_BSIZE];
 };
 
 /*



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-31 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Jul 31 20:11:17 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
some more notes


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.30 -r1.1.2.31 src/sys/dev/ata/TODO.ncq

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.30 src/sys/dev/ata/TODO.ncq:1.1.2.31
--- src/sys/dev/ata/TODO.ncq:1.1.2.30	Wed Jul 19 20:26:52 2017
+++ src/sys/dev/ata/TODO.ncq	Mon Jul 31 20:11:17 2017
@@ -11,8 +11,18 @@ do proper NCQ error recovery
   ch_status/ch_error/ATACH_IRQ_WAIT
 - retest ATAPI
 
-ahcisata - use dynamic xfer in ahci_do_reset_drive() instead of hardcoding
-0, which can clash on drive reset after command failure
+do biodone() in wddone() starting the dump to not leak bufs when dumping from
+active system? make sure to not trigger atastart()
+- call ata_kill_active() + ata_kill_pending() when dumping
+
+kill active transfers after software drive reset - race timeout vs.
+error recovery
+
+multi-pmp disk open+i/o on siisata fails - track down and fix
+#!/bin/sh
+for disk in $disks; do
+(echo $disk; for i in `seq 0 3`; do dd if=/dev/r${disk}d bs=16m of=/dev/null count=1; done)&
+done;
 
 Other random notes (do outside the NCQ branch):
 -



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-30 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Jul 30 20:46:31 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
undo debug code


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.28 -r1.30.4.29 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.28 src/sys/dev/ic/siisata.c:1.30.4.29
--- src/sys/dev/ic/siisata.c:1.30.4.28	Sun Jul 30 20:24:45 2017
+++ src/sys/dev/ic/siisata.c	Sun Jul 30 20:46:31 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $");
 
 #include 
 #include 
@@ -288,7 +288,7 @@ siisata_attach_port(struct siisata_softc
 	sc->sc_chanarray[port] = chp;
 	chp->ch_channel = port;
 	chp->ch_atac = >sc_atac;
-	chp->ch_queue = ata_queue_alloc(4) ; //SIISATA_MAX_SLOTS);
+	chp->ch_queue = ata_queue_alloc(SIISATA_MAX_SLOTS);
 	if (chp->ch_queue == NULL) {
 		aprint_error_dev(sc->sc_atac.atac_dev,
 		"port %d: can't allocate memory "



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-30 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Jul 30 20:24:45 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
adjust error recovery to similar shape as ahcisata; also switch to using
siisata_reset_channel(), as that seems more reliably get the HBA to running
state again after some errors

besides this, change several places checking PORT_READY to use
siisata_reinit_port() and properly timeout - seen several cases
where it would just loop there indefinitely on some errors with no
way to get into ddb and no error message, due to the tight DELAY() loop


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.27 -r1.30.4.28 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.27 src/sys/dev/ic/siisata.c:1.30.4.28
--- src/sys/dev/ic/siisata.c:1.30.4.27	Wed Jul 19 20:24:59 2017
+++ src/sys/dev/ic/siisata.c	Sun Jul 30 20:24:45 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $");
 
 #include 
 #include 
@@ -157,12 +157,12 @@ int siisata_bio_complete(struct ata_chan
 void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 
-static void siisata_reinit_port(struct ata_channel *);
+static void siisata_reinit_port(struct ata_channel *, int);
 static void siisata_device_reset(struct ata_channel *);
 static void siisata_activate_prb(struct siisata_channel *, int);
 static void siisata_deactivate_prb(struct siisata_channel *, int);
 static int siisata_dma_setup(struct ata_channel *, int, void *, size_t, int);
-static void siisata_channel_recover(struct ata_channel *, int, int);
+void siisata_channel_recover(struct ata_channel *, uint32_t);
 
 #if NATAPIBUS > 0
 void siisata_atapibus_attach(struct atabus_softc *);
@@ -266,7 +266,7 @@ siisata_init_port(struct siisata_softc *
 	PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC),
 	PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET);
 	/* initialize port */
-	siisata_reinit_port(chp);
+	siisata_reinit_port(chp, -1);
 	/* enable CmdErrr+CmdCmpl interrupting */
 	siisata_enable_port_interrupt(chp);
 	/* enable port interrupt */
@@ -288,7 +288,7 @@ siisata_attach_port(struct siisata_softc
 	sc->sc_chanarray[port] = chp;
 	chp->ch_channel = port;
 	chp->ch_atac = >sc_atac;
-	chp->ch_queue = ata_queue_alloc(SIISATA_MAX_SLOTS);
+	chp->ch_queue = ata_queue_alloc(4) ; //SIISATA_MAX_SLOTS);
 	if (chp->ch_queue == NULL) {
 		aprint_error_dev(sc->sc_atac.atac_dev,
 		"port %d: can't allocate memory "
@@ -471,54 +471,29 @@ siisata_intr(void *v)
 static void
 siisata_intr_port(struct siisata_channel *schp)
 {
-	struct siisata_softc *sc;
-	struct ata_channel *chp;
+	struct siisata_softc *sc =
+	(struct siisata_softc *)schp->ata_channel.ch_atac;
+	struct ata_channel *chp = >ata_channel;
 	struct ata_xfer *xfer;
-	u_int slot;
-	uint32_t pss, pis;
-
-	sc = (struct siisata_softc *)schp->ata_channel.ch_atac;
-	chp = >ata_channel;
+	int slot = -1;
+	uint32_t pss, pis, tfd = 0;
+	bool recover = false;
 
 	/* get slot status, clearing completion interrupt (PR_PIS_CMDCMPL) */
 	pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
+
 	SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x\n",
 	SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR);
 
-	for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) {
-		if (((schp->sch_active_slots >> slot) & 1) == 0) {
-			/* there's nothing executing here, skip */
-			continue;
-		}
-		if (((pss >> slot) & 1) != 0) {
-			/* execution is incomplete or unsuccessful, skip
-			 * for now */
-			continue;
-		}
-		xfer = ata_queue_hwslot_to_xfer(chp, slot);
-		if (xfer->c_intr == NULL) {
-			wakeup(schp);
-			continue;
-		}
-		KASSERT(xfer != NULL);
-		KASSERT(xfer->c_intr != NULL);
-		xfer->c_intr(chp, xfer, 0);
-	}
-	/* if no errors, we're done now */
-	if ((pss & PR_PSS_ATTENTION) == 0) {
-		pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
-		pis &= 0x;
-		if (pis) {
-			PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS),
-			pis & 0xfffcfffc);
-		}
-		return;
-	}
+	/* if no errors, just process finished commands and we're done */
+	if (__predict_true((pss & PR_PSS_ATTENTION) == 0))
+		goto process;
 
 	pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
 
-	SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc),
-	__func__, chp->ch_channel, pis), DEBUG_INTR);
+	SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ",
+	SIISATANAME(sc), __func__, chp->ch_channel, pis),
+	

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-30 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Jul 30 20:16:29 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
actually change the retry to also use NCQ - with one drive I see
very frequent fatal errors on siisata when switching often between
NCQ and non-NCQ I/O commands with chaos monkey (basically, always
the next NCQ command on a slot which had non-NCQ I/O throws fatal
error); they completely vanish when just using NCQ all the time


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.30 -r1.428.2.31 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.30 src/sys/dev/ata/wd.c:1.428.2.31
--- src/sys/dev/ata/wd.c:1.428.2.30	Sat Jul 29 12:51:22 2017
+++ src/sys/dev/ata/wd.c	Sun Jul 30 20:16:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -734,16 +734,10 @@ wdstart1(struct wd_softc *wd, struct buf
 		xfer->c_bio.flags |= ATA_LBA48;
 
 	/*
-	 * If NCQ was negotiated, always use it for the first attempt.
-	 * Since device cancels all outstanding requests on error, downgrade
-	 * to non-NCQ on retry, so that the retried transfer would not cause
-	 * cascade failure for the other transfers if it fails again.
-	 * If FUA was requested, we can't downgrade, as that would violate
-	 * the semantics - FUA would not be honored. In that case, continue
-	 * retrying with NCQ.
+	 * If NCQ was negotiated, always use it. Some drives return random
+	 * errors when switching between NCQ and non-NCQ I/O too often. 
 	 */
-	if (wd->drvp->drive_flags & ATA_DRIVE_NCQ &&
-	(xfer->c_retries == 0 || (bp->b_flags & B_MEDIA_FUA))) {
+	if (wd->drvp->drive_flags & ATA_DRIVE_NCQ) {
 		xfer->c_bio.flags |= ATA_LBA48;
 		xfer->c_flags |= C_NCQ;
 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 22:40:04 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisatareg.h

Log Message:
add macro for getting the slot from context register, just for reference for now


To generate a diff of this commit:
cvs rdiff -u -r1.7.42.3 -r1.7.42.4 src/sys/dev/ic/siisatareg.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/ic/siisatareg.h
diff -u src/sys/dev/ic/siisatareg.h:1.7.42.3 src/sys/dev/ic/siisatareg.h:1.7.42.4
--- src/sys/dev/ic/siisatareg.h:1.7.42.3	Wed Jul 19 20:03:29 2017
+++ src/sys/dev/ic/siisatareg.h	Sat Jul 29 22:40:04 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisatareg.h,v 1.7.42.3 2017/07/19 20:03:29 jdolecek Exp $ */
+/* $NetBSD: siisatareg.h,v 1.7.42.4 2017/07/29 22:40:04 jdolecek Exp $ */
 
 /*
  * Copyright (c) 2007, 2008, 2009, 2010, 2011 Jonathan A. Kollasch.
@@ -188,6 +188,7 @@ struct siisata_prb {
 #define PRO_CARX(p,s) (PRX(p, PRO_CAR) + (s) * sizeof(uint64_t))
 
 #define PRO_PCR		0x1e04		/* port context register */
+#define PRO_PCR_SLOT(x)	(((x) & __BITS(4, 0)) >> 0) /* Slot */
 #define PRO_PCR_PMP(x)	(((x) & __BITS(8, 5)) >> 5) /* PM Port */
 #define PRO_SCONTROL	0x1f00		/* SControl */
 #define PRO_SSTATUS	0x1f04		/* SStatus */



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 16:50:32 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c

Log Message:
whitespace


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.23 -r1.57.6.24 src/sys/dev/ic/ahcisata_core.c

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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.23 src/sys/dev/ic/ahcisata_core.c:1.57.6.24
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.23	Sat Jul 29 15:07:46 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sat Jul 29 16:50:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $");
 
 #include 
 #include 
@@ -1609,7 +1609,6 @@ ahci_channel_recover(struct ahci_softc *
 		/*
 		 * Failed to get resources to run the recovery command, must
 		 * reset the drive. This will also kill all still outstanding
-
 		 * transfers.
 		 */
 reset:



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 15:07:46 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c ahcisatavar.h

Log Message:
make compile without AHCI_DEBUG


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.22 -r1.57.6.23 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.17.6.1 -r1.17.6.2 src/sys/dev/ic/ahcisatavar.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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.22 src/sys/dev/ic/ahcisata_core.c:1.57.6.23
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.22	Sat Jul 29 14:50:58 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sat Jul 29 15:07:46 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $");
 
 #include 
 #include 
@@ -967,9 +967,9 @@ ahci_exec_command(struct ata_drive_datas
 	int ret;
 	int s;
 
-	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	AHCIDEBUG_PRINT(("ahci_exec_command port %d CI 0x%x\n",
-	chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
+	chp->ch_channel,
+	AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))),
 	DEBUG_XFERS);
 	if (ata_c->flags & AT_POLL)
 		xfer->c_flags |= C_POLL;
@@ -1007,17 +1007,17 @@ ahci_exec_command(struct ata_drive_datas
 static void
 ahci_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer)
 {
-	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
+	struct ahci_softc *sc = AHCI_CH2SC(chp);
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
 	struct ata_command *ata_c = >c_ata_c;
 	int slot = xfer->c_slot;
 	struct ahci_cmd_tbl *cmd_tbl;
 	struct ahci_cmd_header *cmd_h;
 	int i;
-	int channel = chp->ch_channel;
 
 	AHCIDEBUG_PRINT(("ahci_cmd_start CI 0x%x timo %d\n slot %d",
-	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)), ata_c->timeout, slot),
+	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)),
+	ata_c->timeout, slot),
 	DEBUG_XFERS);
 
 	KASSERT((achp->ahcic_cmds_active & (1 << slot)) == 0);
@@ -1072,11 +1072,14 @@ ahci_cmd_start(struct ata_channel *chp, 
 		ahci_intr_port(sc, achp);
 		ata_delay(10, "ahcipl", ata_c->flags);
 	}
-	AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), channel, 
+	AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel, 
 	AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS),
-	AHCI_READ(sc, AHCI_P_CLBU(channel)), AHCI_READ(sc, AHCI_P_CLB(channel)),
-	AHCI_READ(sc, AHCI_P_FBU(channel)), AHCI_READ(sc, AHCI_P_FB(channel)),
-	AHCI_READ(sc, AHCI_P_CMD(channel)), AHCI_READ(sc, AHCI_P_CI(channel))),
+	AHCI_READ(sc, AHCI_P_CLBU(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_CLB(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_FBU(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_FB(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
 	DEBUG_XFERS);
 	if ((ata_c->flags & AT_DONE) == 0) {
 		ata_c->flags |= AT_TIMEOU;
@@ -1127,12 +1130,12 @@ static int
 ahci_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int tfd)
 {
 	struct ata_command *ata_c = >c_ata_c;
-	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
 
 	AHCIDEBUG_PRINT(("ahci_cmd_complete channel %d CMD 0x%x CI 0x%x\n",
-	chp->ch_channel, AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)),
-	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
+	chp->ch_channel,
+	AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CMD(chp->ch_channel)),
+	AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))),
 	DEBUG_FUNCS);
 
 	if (ata_waitdrain_xfer_check(chp, xfer))
@@ -1217,9 +1220,9 @@ ahci_ata_bio(struct ata_drive_datas *drv
 	struct ata_channel *chp = drvp->chnl_softc;
 	struct ata_bio *ata_bio = >c_bio;
 
-	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	AHCIDEBUG_PRINT(("ahci_ata_bio port %d CI 0x%x\n",
-	chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
+	chp->ch_channel,
+	AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))),
 	DEBUG_XFERS);
 	if (ata_bio->flags & ATA_POLL)
 		xfer->c_flags |= C_POLL;
@@ -1242,7 +1245,6 @@ ahci_bio_start(struct ata_channel *chp, 
 	struct ahci_cmd_tbl *cmd_tbl;
 	struct ahci_cmd_header *cmd_h;
 	int i;
-	int channel = chp->ch_channel;
 
 	AHCIDEBUG_PRINT(("ahci_bio_start CI 0x%x\n",
 	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS);
@@ -1297,11 

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 14:50:58 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c

Log Message:
make ahci_channel_recover() non-static, so that it's visible in backtrace,
and can set a separate breakpoint there


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.21 -r1.57.6.22 src/sys/dev/ic/ahcisata_core.c

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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.21 src/sys/dev/ic/ahcisata_core.c:1.57.6.22
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.21	Sat Jul 29 13:02:50 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sat Jul 29 14:50:58 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $");
 
 #include 
 #include 
@@ -77,8 +77,7 @@ static void ahci_bio_kill_xfer(struct at
 static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int);
 static void ahci_channel_start(struct ahci_softc *, struct ata_channel *,
 int, int);
-static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *,
-int);
+void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, int);
 static int  ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
 
 #if NATAPIBUS > 0
@@ -627,7 +626,7 @@ ahci_intr_port(struct ahci_softc *sc, st
 		tfd = 0;
 	}
 
-	if (recover)
+	if (__predict_false(recover))
 		ata_channel_freeze(chp);
 
 	if (slot >= 0) {
@@ -652,7 +651,7 @@ ahci_intr_port(struct ahci_softc *sc, st
 		}
 	}
 
-	if (recover) {
+	if (__predict_false(recover)) {
 		ata_channel_thaw(chp);
 		ahci_channel_recover(sc, chp, tfd);
 	}



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 13:04:43 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisatareg.h

Log Message:
fix AHCI_P_CMD_CCS_SHIFT - must shift only by 8, otherwise the result would
be always 0


To generate a diff of this commit:
cvs rdiff -u -r1.12.26.1 -r1.12.26.2 src/sys/dev/ic/ahcisatareg.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/ic/ahcisatareg.h
diff -u src/sys/dev/ic/ahcisatareg.h:1.12.26.1 src/sys/dev/ic/ahcisatareg.h:1.12.26.2
--- src/sys/dev/ic/ahcisatareg.h:1.12.26.1	Wed Jul 19 20:21:42 2017
+++ src/sys/dev/ic/ahcisatareg.h	Sat Jul 29 13:04:43 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisatareg.h,v 1.12.26.1 2017/07/19 20:21:42 jdolecek Exp $	*/
+/*	$NetBSD: ahcisatareg.h,v 1.12.26.2 2017/07/29 13:04:43 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -234,8 +234,8 @@ struct ahci_r_fis {
 #define		AHCI_P_CMD_CR	0x8000 /* command list running */
 #define		AHCI_P_CMD_FR	0x4000 /* FIS receive running */
 #define		AHCI_P_CMD_MPSS	0x2000 /* mechanical switch state */
-#define		AHCI_P_CMD_CCS_MASK 0x1f00 /* current command slot */
-#define		AHCI_P_CMD_CCS_SHIFT 12
+#define		AHCI_P_CMD_CCS_MASK __BITS(12, 8) /* current command slot */
+#define		AHCI_P_CMD_CCS_SHIFT 8
 #define		AHCI_P_CMD_FRE	0x0010 /* FIS receive enable */
 #define		AHCI_P_CMD_CLO	0x0008 /* command list override */
 #define		AHCI_P_CMD_POD	0x0004 /* power on device */



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 13:02:50 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c

Log Message:
do not do the drive reset on non-fatal recovery - spec explicitely says
says the READ LOG EXT should only be done when neither COMRESET nor software
reset was done, and indeed it returns junk in this case

use C_RECOVERY slot for drive reset, so that it now will always succeed
in getting a slot, in cases when it would be necessary

adjust code and comments on the recovery path to explain better what's going on

with this AHCI error recovery works with real hardware without timeouts again


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.20 -r1.57.6.21 src/sys/dev/ic/ahcisata_core.c

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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.20 src/sys/dev/ic/ahcisata_core.c:1.57.6.21
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.20	Sun Jul 23 14:14:43 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sat Jul 29 13:02:50 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $");
 
 #include 
 #include 
@@ -568,10 +568,12 @@ ahci_intr_port(struct ahci_softc *sc, st
 
 	is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is);
-	AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x TFD 0x%x\n",
+	AHCIDEBUG_PRINT((
+	"ahci_intr_port %s port %d is 0x%x CI 0x%x SACT 0x%x TFD 0x%x\n",
 	AHCINAME(sc),
 	chp->ch_channel, is,
 	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)),
 	AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))),
 	DEBUG_INTR);
 
@@ -613,8 +615,9 @@ ahci_intr_port(struct ahci_softc *sc, st
 		tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
 
 		/* D2H Register FIS or Set Device Bits */
-		if ((tfd & WDCS_ERR) != 0 && !achp->ahcic_recovering) {
-			recover = true;
+		if ((tfd & WDCS_ERR) != 0) {
+			if (!achp->ahcic_recovering)
+recover = true;
 
 			aprint_error("%s port %d: transfer aborted 0x%x\n",
 			AHCINAME(sc), chp->ch_channel, tfd);
@@ -757,11 +760,7 @@ again:
 
 	/* polled command, assume interrupts are disabled */
 	/* use available slot to send reset, if none available fail */
-	xfer = ata_get_xfer_ext(chp, false, 0);
-	if (xfer == NULL) {
-		printf("%s: no xfer\n", __func__);
-		return 1;
-	}
+	xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0);
 
 	cmd_h = >ahcic_cmdh[xfer->c_slot];
 	cmd_tbl = achp->ahcic_cmd_tbl[xfer->c_slot];
@@ -1556,22 +1555,16 @@ ahci_channel_recover(struct ahci_softc *
 
 	/*
 	 * If BSY or DRQ bits are set, must execute COMRESET to return
-	 * device to idle state. Otherwise, commands can be reissued
-	 * after resetting CMD.ST. After resetting CMD.ST, need to execute
-	 * READ LOG EXT for NCQ to unblock device processing if COMRESET
-	 * was not done.
+	 * device to idle state. If drive is idle, it's enough to just
+	 * reset CMD.ST, it's not necessary to do software reset.
+	 * After resetting CMD.ST, need to execute READ LOG EXT for NCQ
+	 * to unblock device processing if COMRESET was not done.
 	 */
 	if (reset || (AHCI_TFD_ST(tfd) & (WDCS_BSY|WDCS_DRQ)) != 0)
 		goto reset;
 
 	KASSERT(drive >= 0);
 	ahci_channel_stop(sc, chp, AT_POLL);
-	if (ahci_do_reset_drive(chp, drive, AT_POLL, NULL) != 0) {
-reset:
-		/* This will also kill all still outstanding transfers */
-		ahci_reset_channel(chp, AT_POLL);
-		goto out;
-	}
 	ahci_channel_start(sc, chp, AT_POLL,
	(sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0);
 
@@ -1585,18 +1578,48 @@ reset:
 
 	ahci_unhold(achp);
 
-	if (error == 0) {
+	switch (error) {
+	case 0:
 		/* Error out the particular NCQ xfer, then requeue the others */
-		xfer = ata_queue_hwslot_to_xfer(chp, eslot);
-		xfer->c_intr(chp, xfer, (err << AHCI_P_TFD_ERR_SHIFT) | st);
-	} else if (error == EOPNOTSUPP) {
-		/* command already processed before entering recovery */
-		KASSERT(achp->ahcic_cmds_active == 0);
-	} else {
+		if ((achp->ahcic_cmds_active & (1 << eslot)) != 0) {
+			xfer = ata_queue_hwslot_to_xfer(chp, eslot);
+			xfer->c_intr(chp, xfer,
+			(err << AHCI_P_TFD_ERR_SHIFT) | st);
+		}
+		break;
+
+	case EOPNOTSUPP:
+		/*
+		 * Non-NCQ command error, just find the slot and end with
+		 * the error.
+		 */
+		for (slot = 0; slot < sc->sc_ncmds; slot++) {
+			if ((achp->ahcic_cmds_active & (1 << slot)) != 0) {
+xfer = ata_queue_hwslot_to_xfer(chp, slot);
+xfer->c_intr(chp, xfer, tfd);
+			}
+		}
+		break;
+
+	

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 12:58:30 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h

Log Message:
reserve the highest slot for error recovery, and also have ata_channel
include space for the READ LOG EXT sector, so that it's not necessary
to allocate memory on the error handling path; now ata_read_log_ext_ncq()
will never fail due to resource shortage


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.21 -r1.132.8.22 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.19 -r1.92.8.20 src/sys/dev/ata/atavar.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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.21 src/sys/dev/ata/ata.c:1.132.8.22
--- src/sys/dev/ata/ata.c:1.132.8.21	Sat Jul 22 22:02:21 2017
+++ src/sys/dev/ata/ata.c	Sat Jul 29 12:58:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -191,7 +191,7 @@ ata_queue_reset(struct ata_queue *chq)
 	chq->queue_freeze = 0;
 	chq->queue_active = 0;
 	chq->active_xfers_used = 0;
-	chq->queue_xfers_avail = (1 << chq->queue_openings) - 1;
+	chq->queue_xfers_avail = __BIT(chq->queue_openings) - 1;
 }
 
 struct ata_xfer *
@@ -202,7 +202,8 @@ ata_queue_hwslot_to_xfer(struct ata_chan
 
 	mutex_enter(>ch_lock);
 
-	KASSERT(hwslot < chq->queue_openings);
+	KASSERTMSG(hwslot < chq->queue_openings, "hwslot %d > openings %d",
+	hwslot, chq->queue_openings);
 	KASSERT((chq->active_xfers_used & __BIT(hwslot)) != 0);
 
 	/* Usually the first entry will be the one */
@@ -1048,20 +1049,9 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	(drvp->drive_flags & ATA_DRIVE_NCQ) == 0)
 		return EOPNOTSUPP;
 
-	xfer = ata_get_xfer_ext(chp, false, 0);
-	if (xfer == NULL) {
-		ATADEBUG_PRINT(("%s: no xfer\n", __func__),
-		DEBUG_FUNCS|DEBUG_XFERS);
-		return EAGAIN;
-	}
+	xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0);
 
-	tb = malloc(DEV_BSIZE, M_DEVBUF, M_NOWAIT);
-	if (tb == NULL) {
-		ATADEBUG_PRINT(("%s: memory allocation failed\n", __func__),
-		DEBUG_FUNCS|DEBUG_XFERS);
-		rv = EAGAIN;
-		goto out;
-	}
+	tb = chp->ch_recovery;
 	memset(tb, 0, DEV_BSIZE);
 
 	/*
@@ -1070,14 +1060,14 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	 * and to make this a little faster. Realistically, it
 	 * should not matter.
 	 */
-	xfer->c_flags |= C_IMMEDIATE;
+	xfer->c_flags |= C_RECOVERY;
 	xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT;
 	xfer->c_ata_c.r_lba = page = WDCC_LOG_PAGE_NCQ;
 	xfer->c_ata_c.r_st_bmask = WDCS_DRDY;
 	xfer->c_ata_c.r_st_pmask = WDCS_DRDY;
 	xfer->c_ata_c.r_count = 1;
 	xfer->c_ata_c.r_device = WDSD_LBA;
-	xfer->c_ata_c.flags = AT_READ | AT_LBA | AT_LBA48 | flags;
+	xfer->c_ata_c.flags = AT_READ | AT_LBA | flags;
 	xfer->c_ata_c.timeout = 1000; /* 1s */
 	xfer->c_ata_c.data = tb;
 	xfer->c_ata_c.bcount = DEV_BSIZE;
@@ -1085,11 +1075,11 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
 		xfer) != ATACMD_COMPLETE) {
 		rv = EAGAIN;
-		goto out2;
+		goto out;
 	}
 	if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		rv = EINVAL;
-		goto out2;
+		goto out;
 	}
 
 	cksum = 0;
@@ -1100,23 +1090,26 @@ ata_read_log_ext_ncq(struct ata_drive_da
 		"invalid checksum %x for READ LOG EXT page %x\n",
 		cksum, page);
 		rv = EINVAL;
-		goto out2;
+		goto out;
 	}
 
 	if (tb[0] & WDCC_LOG_NQ) {
 		/* not queued command */
 		rv = EOPNOTSUPP;
-		goto out2;
+		goto out;
 	}
 
 	*slot = tb[0] & 0x1f;
 	*status = tb[2];
 	*err = tb[3];
 
+	KASSERTMSG((*status & WDCS_ERR),
+	"%s: non-error command slot %d reported by READ LOG EXT page %x: "
+	"err %x status %x\n",
+	device_xname(drvp->drv_softc), *slot, page, *err, *status);
+
 	rv = 0;
 
-out2:
-	free(tb, DEV_BSIZE);
 out:
 	ata_free_xfer(chp, xfer);
 	return rv;
@@ -1180,12 +1173,15 @@ ata_exec_xfer(struct ata_channel *chp, s
 
 	mutex_enter(>ch_lock);
 
-	/* insert at the end of command list unless specially requested */
-	if (xfer->c_flags & C_IMMEDIATE)
-		TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer,
+	/*
+	 * Standard commands are added to the end of command list, but
+	 * recovery commands must be run immediatelly.
+	 */
+	if ((xfer->c_flags & C_RECOVERY) == 0)
+		TAILQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer,
 		c_xferchain);
 	else
-		TAILQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer,
+		TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer,
 		c_xferchain);
 	ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n",
 	chp->ch_flags), 

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 12:51:22 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
actually count the REQUEUE as retry also, so that it will be retried
as non-NCQ, will not be subject to chaos monkey, and reported as fixed
once finished, too


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.29 -r1.428.2.30 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.29 src/sys/dev/ata/wd.c:1.428.2.30
--- src/sys/dev/ata/wd.c:1.428.2.29	Sun Jul 23 13:50:43 2017
+++ src/sys/dev/ata/wd.c	Sat Jul 29 12:51:22 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -662,7 +662,7 @@ wdstart(device_t self)
 
 	while (bufq_peek(wd->sc_q) != NULL) {
 		/* First try to get xfer. Limit to drive openings iff NCQ. */
-		xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false,
+		xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
 		ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ)
 		? wd->drvp->drv_openings : 0);
 		if (xfer == NULL)
@@ -839,17 +839,11 @@ retry2:
 			wdperror(wd, xfer);
 
 		if (xfer->c_retries < WDIORETRIES) {
-			int timo;
+			xfer->c_retries++;
 
-			if (xfer->c_bio.error == REQUEUE) {
-/* rerun ASAP, and do not count as retry */
-timo = 1;
-			} else {
-xfer->c_retries++;
-timo = RECOVERYTIME;
-			}
-
-			callout_reset(>c_retry_callout, timo,
+			/* Rerun ASAP if just requeued */
+			callout_reset(>c_retry_callout,
+			(xfer->c_bio.error == REQUEUE) ? 1 : RECOVERYTIME,
 			wdbiorestart, xfer);
 
 			mutex_exit(>sc_lock);
@@ -894,7 +888,7 @@ out:
 	case NOERROR:
 noerror:	if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0)
 			aprint_error_dev(wd->sc_dev,
-			"soft error (corrected)\n");
+			"soft error (corrected) slot %d\n", xfer->c_slot);
 #ifdef WD_CHAOS_MONKEY
 		KASSERT((xfer->c_flags & C_CHAOS) == 0);
 #endif
@@ -1692,7 +1686,7 @@ wddump(dev_t dev, daddr_t blkno, void *v
 		wd->drvp->state = RESET;
 	}
 
-	xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, 0);
+	xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0, 0);
 	if (xfer == NULL) {
 		printf("%s: no xfer\n", __func__);
 		return EAGAIN;



CVS commit: [jdolecek-ncq] src/sys/dev/scsipi

2017-07-29 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 29 09:04:39 UTC 2017

Modified Files:
src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
do not use freed xfer in error message in wdc_atapi_get_params()


To generate a diff of this commit:
cvs rdiff -u -r1.123.4.9 -r1.123.4.10 src/sys/dev/scsipi/atapi_wdc.c

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/scsipi/atapi_wdc.c
diff -u src/sys/dev/scsipi/atapi_wdc.c:1.123.4.9 src/sys/dev/scsipi/atapi_wdc.c:1.123.4.10
--- src/sys/dev/scsipi/atapi_wdc.c:1.123.4.9	Tue Jun 27 18:36:03 2017
+++ src/sys/dev/scsipi/atapi_wdc.c	Sat Jul 29 09:04:39 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atapi_wdc.c,v 1.123.4.9 2017/06/27 18:36:03 jdolecek Exp $	*/
+/*	$NetBSD: atapi_wdc.c,v 1.123.4.10 2017/07/29 09:04:39 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.9 2017/06/27 18:36:03 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.10 2017/07/29 09:04:39 jdolecek Exp $");
 
 #ifndef ATADEBUG
 #define ATADEBUG
@@ -242,9 +242,9 @@ wdc_atapi_get_params(struct scsipi_chann
 	delay(5000);
 	if (ata_get_params(>ch_drive[drive], AT_WAIT, id) != 0) {
 		ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_IDENTIFY_DEVICE "
-		"failed for drive %s:%d:%d: error 0x%x\n",
-		device_xname(atac->atac_dev), chp->ch_channel, drive,
-		xfer->c_ata_c.r_error), DEBUG_PROBE);
+		"failed for drive %s:%d:%d\n",
+		device_xname(atac->atac_dev), chp->ch_channel, drive),
+		DEBUG_PROBE);
 		rv = -1;
 		goto out;
 	}



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-26 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 26 18:12:12 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: satapmp_subr.c

Log Message:
write the device and channel for port multiplier attach (not just the atabus),
so it's easier to check


To generate a diff of this commit:
cvs rdiff -u -r1.12.24.4 -r1.12.24.5 src/sys/dev/ata/satapmp_subr.c

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/satapmp_subr.c
diff -u src/sys/dev/ata/satapmp_subr.c:1.12.24.4 src/sys/dev/ata/satapmp_subr.c:1.12.24.5
--- src/sys/dev/ata/satapmp_subr.c:1.12.24.4	Tue Jun 20 20:58:22 2017
+++ src/sys/dev/ata/satapmp_subr.c	Wed Jul 26 18:12:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: satapmp_subr.c,v 1.12.24.4 2017/06/20 20:58:22 jdolecek Exp $	*/
+/*	$NetBSD: satapmp_subr.c,v 1.12.24.5 2017/07/26 18:12:12 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2012 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.4 2017/06/20 20:58:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.5 2017/07/26 18:12:12 jdolecek Exp $");
 
 #include 
 #include 
@@ -274,8 +274,10 @@ satapmp_attach(struct ata_channel *chp)
 		return;
 	}
 
-	aprint_normal_dev(chp->atabus,
-	"SATA port multiplier, %d ports\n", PMP_INF_NPORTS(inf));
+	aprint_normal("%s at %s channel %d: SATA port multiplier, %d ports\n",
+	device_xname(chp->atabus),
+	device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
+	PMP_INF_NPORTS(inf));
 	aprint_verbose_dev(chp->atabus,
 	"vendor 0x%04x, product 0x%04x",
 	PMP_ID_VEND(id), PMP_ID_DEV(id));



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Jul 23 14:14:44 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c

Log Message:
rework the error handling and recovery, so that errors during the recovery
are handled correctly, and the recovery more closely follows the spec

this fixes e.g. NCQ error handling under QEMU, which doesn't implement
READ LOG EXT - previous code actually made the call 'succeed', returning bogus
(zero) slot/error/status

finished xfers are still handled before entering recovery (with channel frozen)
to avoid unnecessary retries


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.19 -r1.57.6.20 src/sys/dev/ic/ahcisata_core.c

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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.19 src/sys/dev/ic/ahcisata_core.c:1.57.6.20
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.19	Fri Jul 21 18:36:47 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sun Jul 23 14:14:43 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $");
 
 #include 
 #include 
@@ -77,7 +77,8 @@ static void ahci_bio_kill_xfer(struct at
 static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int);
 static void ahci_channel_start(struct ahci_softc *, struct ata_channel *,
 int, int);
-static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *);
+static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *,
+int);
 static int  ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
 
 #if NATAPIBUS > 0
@@ -563,6 +564,7 @@ ahci_intr_port(struct ahci_softc *sc, st
 	struct ata_channel *chp = >ata_channel;
 	struct ata_xfer *xfer;
 	int slot;
+	bool recover = false;
 
 	is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is);
@@ -573,34 +575,30 @@ ahci_intr_port(struct ahci_softc *sc, st
 	AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))),
 	DEBUG_INTR);
 
-	active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))
-		| AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));
-
-	/* Complete all successful commands first */
-	for (slot=0; slot < sc->sc_ncmds; slot++) {
-		if ((achp->ahcic_cmds_active & (1 << slot)) == 0)
-			continue;
-		if ((active & (1 << slot)) == 0) {
-			xfer = ata_queue_hwslot_to_xfer(chp, slot);
-			xfer->c_intr(chp, xfer, 0);
-		}
+	if ((chp->ch_flags & ATACH_NCQ) == 0) {
+		/* Non-NCQ operation */
+		active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel));
+		slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))
+			& AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT;
+	} else {
+		/* NCQ operation */
+		active = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));
+		slot = -1;
 	}
 
 	/* Handle errors */
 	if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS |
 	AHCI_P_IX_IFS | AHCI_P_IX_OFS | AHCI_P_IX_UFS)) {
+		/* Fatal errors */
 		if (is & AHCI_P_IX_TFES) {
 			tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
 
-			if ((AHCI_TFD_ST(tfd) & (WDCS_DRQ|WDCS_BSY)) == 0 &&
-			!achp->ahcic_recovering)
-goto recover;
-
 			aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n",
 			AHCINAME(sc), chp->ch_channel, active, is, tfd);
 		} else {
-			/* emulate a CRC error */
-			tfd = (WDCE_CRC << AHCI_P_TFD_ERR_SHIFT) | WDCS_ERR;
+			/* mark an error, and set BSY */
+			tfd = (WDCE_ABRT << AHCI_P_TFD_ERR_SHIFT) |
+			WDCS_ERR | WDCS_BSY;
 		}
 
 		if (is & AHCI_P_IX_IFS) {
@@ -609,29 +607,52 @@ ahci_intr_port(struct ahci_softc *sc, st
 			AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel)));
 		}
 
-		/* Request channel reset */
-		ata_reset_channel(chp, 0);
-		return;
+		if (!achp->ahcic_recovering)
+			recover = true;
 	} else if (is & (AHCI_P_IX_DHRS|AHCI_P_IX_SDBS)) {
-		/* D2H Register FIS or Set Device Bits */
 		tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
+
+		/* D2H Register FIS or Set Device Bits */
 		if ((tfd & WDCS_ERR) != 0 && !achp->ahcic_recovering) {
-recover:
+			recover = true;
+
 			aprint_error("%s port %d: transfer aborted 0x%x\n",
 			AHCINAME(sc), chp->ch_channel, tfd);
 
-			/*
-			 * Device indicated transfer aborted without any fatal
-			 * error. Transfers can be reissued after resetting
-			 * CMD.ST. Need to execute READ LOG EXT for NCQ
-			 * commands.
-			 */
-			ahci_channel_stop(sc, chp, AT_POLL);
-			ahci_channel_start(sc, chp, AT_POLL,
-			(sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0);
-			ahci_channel_recover(sc, chp);
+		}
+	} else {
+		tfd = 0;
+	}
+
+	if (recover)
+		

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Jul 23 13:50:43 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
for wd, only call disk_busy() on the first try, do not call it on retries,
as unbusy is called just once when the xfer is finished

also noticed in PR kern/43169 by Matthias Pfaller, but contrary to suggested
fix done in way to keep the disk marked busy during the timeouts, as I think
it's more correct


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.28 -r1.428.2.29 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.28 src/sys/dev/ata/wd.c:1.428.2.29
--- src/sys/dev/ata/wd.c:1.428.2.28	Fri Jul 21 17:32:27 2017
+++ src/sys/dev/ata/wd.c	Sun Jul 23 13:50:43 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -766,7 +766,8 @@ wdstart1(struct wd_softc *wd, struct buf
 	}
 
 	/* Instrumentation. */
-	disk_busy(>sc_dk);
+	if (xfer->c_retries == 0)
+		disk_busy(>sc_dk);
 	switch (wd->atabus->ata_bio(wd->drvp, xfer)) {
 	case ATACMD_TRY_AGAIN:
 		panic("wdstart1: try again");



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-22 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jul 22 22:02:21 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h

Log Message:
provide channel flag when executing NCQ commands, so that e.g. intr
handler can use this for handling decisions without checking xfer


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.20 -r1.132.8.21 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.18 -r1.92.8.19 src/sys/dev/ata/atavar.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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.20 src/sys/dev/ata/ata.c:1.132.8.21
--- src/sys/dev/ata/ata.c:1.132.8.20	Fri Jul 21 18:12:37 2017
+++ src/sys/dev/ata/ata.c	Sat Jul 22 22:02:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1305,6 +1305,11 @@ atastart(struct ata_channel *chp)
 		drvp->state = 0;
 	}
 
+	if (ISSET(xfer->c_flags, C_NCQ))
+		SET(chp->ch_flags, ATACH_NCQ);
+	else
+		CLR(chp->ch_flags, ATACH_NCQ);
+
 	ata_activate_xfer_locked(chp, xfer);
 
 	if (atac->atac_cap & ATAC_CAP_NOIRQ)

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.18 src/sys/dev/ata/atavar.h:1.92.8.19
--- src/sys/dev/ata/atavar.h:1.92.8.18	Fri Jul 21 17:32:27 2017
+++ src/sys/dev/ata/atavar.h	Sat Jul 22 22:02:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.18 2017/07/21 17:32:27 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.19 2017/07/22 22:02:21 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -394,6 +394,7 @@ struct ata_channel {
 #define ATACH_TH_RUN   0x100	/* the kernel thread is working */
 #define ATACH_TH_RESET 0x200	/* someone ask the thread to reset */
 #define ATACH_TH_RESCAN 0x400	/* rescan requested */
+#define ATACH_NCQ	0x800	/* channel executing NCQ commands */
 #if 1 /* for now */
 	uint8_t ch_status;	/* copy of status register */
 	uint8_t ch_error;	/* copy of error register */



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-21 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Jul 21 18:36:47 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c

Log Message:
use free slot for drive reset, rather than always using slot zero; if we can't
get the slot, fallback to channel reset as usual

note this increases the odds of not being able to do the reset, when all slots
happen to be active

this is in same area as problem reported by PR kern/52372 but I
don't believe that this change actually make any change for it - during
probe/attach there shouldn't be any paralell request with drive reset


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.18 -r1.57.6.19 src/sys/dev/ic/ahcisata_core.c

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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.18 src/sys/dev/ic/ahcisata_core.c:1.57.6.19
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.18	Wed Jul 19 20:21:42 2017
+++ src/sys/dev/ic/ahcisata_core.c	Fri Jul 21 18:36:47 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $");
 
 #include 
 #include 
@@ -650,7 +650,7 @@ ahci_reset_drive(struct ata_drive_datas 
 
 /* return error code from ata_bio */
 static int
-ahci_exec_fis(struct ata_channel *chp, int timeout, int flags)
+ahci_exec_fis(struct ata_channel *chp, int timeout, int flags, int slot)
 {
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
@@ -667,11 +667,13 @@ ahci_exec_fis(struct ata_channel *chp, i
 	else
 		timeout = timeout / 10;
 
-	AHCI_CMDH_SYNC(sc, achp, 0, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	AHCI_CMDH_SYNC(sc, achp, slot,
+	BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	/* start command */
-	AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << 0);
+	AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << slot);
 	for (i = 0; i < timeout; i++) {
-		if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & 1 << 0) == 0)
+		if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & (1 << slot)) ==
+		0)
 			return 0;
 		is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
 		if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS |
@@ -708,6 +710,7 @@ ahci_do_reset_drive(struct ata_channel *
 	struct ahci_cmd_header *cmd_h;
 	int i;
 	uint32_t sig;
+	struct ata_xfer *xfer = NULL;
 
 	KASSERT((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) == 0);
 again:
@@ -732,9 +735,15 @@ again:
 		goto skip_reset;
 
 	/* polled command, assume interrupts are disabled */
-	/* use slot 0 to send reset, the channel is idle */
-	cmd_h = >ahcic_cmdh[0];
-	cmd_tbl = achp->ahcic_cmd_tbl[0];
+	/* use available slot to send reset, if none available fail */
+	xfer = ata_get_xfer_ext(chp, false, 0);
+	if (xfer == NULL) {
+		printf("%s: no xfer\n", __func__);
+		return 1;
+	}
+
+	cmd_h = >ahcic_cmdh[xfer->c_slot];
+	cmd_tbl = achp->ahcic_cmd_tbl[xfer->c_slot];
 	cmd_h->cmdh_flags = htole16(AHCI_CMDH_F_RST | AHCI_CMDH_F_CBSY |
 	RHD_FISLEN / 4 | (drive << AHCI_CMDH_F_PMP_SHIFT));
 	cmd_h->cmdh_prdbc = 0;
@@ -742,7 +751,7 @@ again:
 	cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE;
 	cmd_tbl->cmdt_cfis[rhd_c] = drive;
 	cmd_tbl->cmdt_cfis[rhd_control] = WDCTL_RST;
-	switch(ahci_exec_fis(chp, 100, flags)) {
+	switch(ahci_exec_fis(chp, 100, flags, xfer->c_slot)) {
 	case ERR_DF:
 	case TIMEOUT:
 		aprint_error("%s channel %d: setting WDCTL_RST failed "
@@ -760,7 +769,7 @@ again:
 	cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE;
 	cmd_tbl->cmdt_cfis[rhd_c] = drive;
 	cmd_tbl->cmdt_cfis[rhd_control] = 0;
-	switch(ahci_exec_fis(chp, 310, flags)) {
+	switch(ahci_exec_fis(chp, 310, flags, xfer->c_slot)) {
 	case ERR_DF:
 	case TIMEOUT:
 		if ((sc->sc_ahci_quirks & AHCI_QUIRK_BADPMPRESET) != 0 &&
@@ -811,6 +820,8 @@ skip_reset:
 	AHCINAME(sc), chp->ch_channel, sig,
 	AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE);
 end:
+	if (xfer != NULL)
+		ata_free_xfer(chp, xfer);
 	ahci_channel_stop(sc, chp, flags);
 	ata_delay(500, "ahcirst", flags);
 	/* clear port interrupt register */



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-21 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Jul 21 18:12:37 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
add checksum verification for data returned by READ LOG EXT; this is mostly
just paranoia for eventual driver/hw DMA bugs

this doesn't make difference for QEMU, as there the command actually always
just fails (it's not implemented)


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.19 -r1.132.8.20 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.19 src/sys/dev/ata/ata.c:1.132.8.20
--- src/sys/dev/ata/ata.c:1.132.8.19	Wed Jul 19 19:39:28 2017
+++ src/sys/dev/ata/ata.c	Fri Jul 21 18:12:37 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1039,7 +1039,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	int rv;
 	struct ata_channel *chp = drvp->chnl_softc;
 	struct atac_softc *atac = chp->ch_atac;
-	uint8_t *tb;
+	uint8_t *tb, cksum, page;
 
 	ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS);
 
@@ -1072,12 +1072,12 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	 */
 	xfer->c_flags |= C_IMMEDIATE;
 	xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT;
-	xfer->c_ata_c.r_lba = WDCC_LOG_PAGE_NCQ;
+	xfer->c_ata_c.r_lba = page = WDCC_LOG_PAGE_NCQ;
 	xfer->c_ata_c.r_st_bmask = WDCS_DRDY;
 	xfer->c_ata_c.r_st_pmask = WDCS_DRDY;
 	xfer->c_ata_c.r_count = 1;
 	xfer->c_ata_c.r_device = WDSD_LBA;
-	xfer->c_ata_c.flags = AT_READ | AT_LBA | flags;
+	xfer->c_ata_c.flags = AT_READ | AT_LBA | AT_LBA48 | flags;
 	xfer->c_ata_c.timeout = 1000; /* 1s */
 	xfer->c_ata_c.data = tb;
 	xfer->c_ata_c.bcount = DEV_BSIZE;
@@ -1092,10 +1092,19 @@ ata_read_log_ext_ncq(struct ata_drive_da
 		goto out2;
 	}
 
-	/* XXX verify checksum and refuse if not correct (QEMU) */
+	cksum = 0;
+	for (int i = 0; i < DEV_BSIZE; i++)
+		cksum += tb[i];
+	if (cksum != 0) {
+		aprint_error_dev(drvp->drv_softc,
+		"invalid checksum %x for READ LOG EXT page %x\n",
+		cksum, page);
+		rv = EINVAL;
+		goto out2;
+	}
 
 	if (tb[0] & WDCC_LOG_NQ) {
-		/* not a NCQ command */
+		/* not queued command */
 		rv = EOPNOTSUPP;
 		goto out2;
 	}



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-21 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Jul 21 17:32:27 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: atavar.h wd.c

Log Message:
KASSERT() that chaosed xfer actually ends up with error; might end up being
returned as successful due to bugs in error recovery code


To generate a diff of this commit:
cvs rdiff -u -r1.92.8.17 -r1.92.8.18 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.428.2.27 -r1.428.2.28 src/sys/dev/ata/wd.c

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/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.17 src/sys/dev/ata/atavar.h:1.92.8.18
--- src/sys/dev/ata/atavar.h:1.92.8.17	Wed Jul 19 19:39:28 2017
+++ src/sys/dev/ata/atavar.h	Fri Jul 21 17:32:27 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.17 2017/07/19 19:39:28 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.18 2017/07/21 17:32:27 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -186,6 +186,7 @@ struct ata_xfer {
 #define	C_NCQ		0x0100		/* command is queued  */
 #define C_IMMEDIATE	0x0200		/* execute command without queuing */
 #define C_WAITTIMO	0x0400		/* race vs. timeout */
+#define C_CHAOS		0x0800		/* forced error xfer */
 
 /* reasons for c_kill_xfer() */
 #define KILL_GONE 1		/* device is gone while xfer was active */

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.27 src/sys/dev/ata/wd.c:1.428.2.28
--- src/sys/dev/ata/wd.c:1.428.2.27	Wed Jul 19 19:46:52 2017
+++ src/sys/dev/ata/wd.c	Fri Jul 21 17:32:27 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -713,6 +713,7 @@ wdstart1(struct wd_softc *wd, struct buf
 		aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n",
 		__func__, xfer->c_slot);
 		xfer->c_bio.blkno = 777 + wd->sc_capacity;
+		xfer->c_flags |= C_CHAOS;
 	}
 #endif
 
@@ -893,6 +894,9 @@ out:
 noerror:	if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0)
 			aprint_error_dev(wd->sc_dev,
 			"soft error (corrected)\n");
+#ifdef WD_CHAOS_MONKEY
+		KASSERT((xfer->c_flags & C_CHAOS) == 0);
+#endif
 		break;
 	case ERR_NODEV:
 		bp->b_error = EIO;



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 20:26:52 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
update to note remaining work

move some stuff to 'after-merge'


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.29 -r1.1.2.30 src/sys/dev/ata/TODO.ncq

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.29 src/sys/dev/ata/TODO.ncq:1.1.2.30
--- src/sys/dev/ata/TODO.ncq:1.1.2.29	Mon Jul  3 18:17:01 2017
+++ src/sys/dev/ata/TODO.ncq	Wed Jul 19 20:26:52 2017
@@ -5,26 +5,24 @@ siisata - fix all new XXX and unmergable
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-test non-NCQ device error handling
-- test retry code paths, locking
-- channel reset on fatal errors
-
-do proper NCQ error recovery (currently not even really attempted)
-- if fatal error, do channel reset
-- if tranfer error (both TFD.STS.BSY and DRQ is 0), need READ LOG EXT log
-  page 10h to read tag which caused the error, and reset the device to idle
-- need to cancel and restart the other active transfers in a way to not
-  increase retry count, and not trigger drive reset
+do proper NCQ error recovery
+- update mvsata to do same as ahcisata/siisata (read log ext, timeouts, et.al)
+- update also ic/wdc.c, scsipi/atapi_wdc.c, ata/ata_wdc.c to not use
+  ch_status/ch_error/ATACH_IRQ_WAIT
+- retest ATAPI
 
-maybe do device error handling in not-interrupt-context (maybe this should be
-done on a mpata branch?)
-
-in atastart(), restrict NCQ commands to commands for the same drive? it's
-fine for fis-based switching to have outstanding for several drives, but
-not non-FIS
+ahcisata - use dynamic xfer in ahci_do_reset_drive() instead of hardcoding
+0, which can clash on drive reset after command failure
 
 Other random notes (do outside the NCQ branch):
 -
+implement support for PM FIS-based switching, remove restriction in atastart()
+for hw which supports it, adjust error handling in controller drivers to handle
+xfers for several different drives
+
+maybe do device error handling in not-interrupt-context (maybe this should be
+done on a mpata branch?)
+
 queue is allocated regardless if there are any drives, fix? 
 
 change wd(4) to use dksubr



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 20:24:59 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
forced commit to get into history - previous commit removed also
the siisata-specific downgrade of SATA channel speed on CRC, as it
doesn't really fit with error/state not being available after
c_intr(); as noted this handling should be in generic code, and
it's overly harsh to do this after single error anyway, particularly
since there is no way to get back


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.26 -r1.30.4.27 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.26 src/sys/dev/ic/siisata.c:1.30.4.27
--- src/sys/dev/ic/siisata.c:1.30.4.26	Wed Jul 19 20:02:40 2017
+++ src/sys/dev/ic/siisata.c	Wed Jul 19 20:24:59 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $");
 
 #include 
 #include 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 20:21:42 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c ahcisatareg.h
ahcisatavar.h

Log Message:
update error handling:
- switch to ata_timeout()
- stop using ch_status/ch_error for passing state/error, stop setting
  ATACH_IRQ_WAIT in ch_flags; pass the state via the last parameter
  to c_intr() routine
- add NCQ recovery and KILL_REQUEUE
- only call atastart() in c_intr() if there was no error

ahcisata-specific tweaks:
- add some handling for PM in the error recovery using FBS register,
  according to spec it should be independant of actual FBSS feature; untested
  as my hw doesn't support PM


To generate a diff of this commit:
cvs rdiff -u -r1.57.6.17 -r1.57.6.18 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.12 -r1.12.26.1 src/sys/dev/ic/ahcisatareg.h
cvs rdiff -u -r1.17 -r1.17.6.1 src/sys/dev/ic/ahcisatavar.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/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.17 src/sys/dev/ic/ahcisata_core.c:1.57.6.18
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.17	Tue Jun 27 18:36:03 2017
+++ src/sys/dev/ic/ahcisata_core.c	Wed Jul 19 20:21:42 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.17 2017/06/27 18:36:03 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.17 2017/06/27 18:36:03 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $");
 
 #include 
 #include 
@@ -68,7 +68,7 @@ static void ahci_killpending(struct ata_
 
 static void ahci_cmd_start(struct ata_channel *, struct ata_xfer *);
 static int  ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
-static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *);
+static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int);
 static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *);
 static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 static void ahci_bio_start(struct ata_channel *, struct ata_xfer *);
@@ -77,7 +77,7 @@ static void ahci_bio_kill_xfer(struct at
 static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int);
 static void ahci_channel_start(struct ahci_softc *, struct ata_channel *,
 int, int);
-static void ahci_timeout(void *);
+static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *);
 static int  ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
 
 #if NATAPIBUS > 0
@@ -566,8 +566,11 @@ ahci_intr_port(struct ahci_softc *sc, st
 
 	is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is);
-	AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x\n", AHCINAME(sc),
-	chp->ch_channel, is, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
+	AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x TFD 0x%x\n",
+	AHCINAME(sc),
+	chp->ch_channel, is,
+	AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)),
+	AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))),
 	DEBUG_INTR);
 
 	active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))
@@ -584,38 +587,50 @@ ahci_intr_port(struct ahci_softc *sc, st
 	}
 
 	/* Handle errors */
-	if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_IFS |
-	AHCI_P_IX_OFS | AHCI_P_IX_UFS)) {
-		/* stop channel */
-		ahci_channel_stop(sc, chp, 0);
+	if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS |
+	AHCI_P_IX_IFS | AHCI_P_IX_OFS | AHCI_P_IX_UFS)) {
 		if (is & AHCI_P_IX_TFES) {
 			tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
-			chp->ch_error =
-			(tfd & AHCI_P_TFD_ERR_MASK) >> AHCI_P_TFD_ERR_SHIFT;
-			chp->ch_status = (tfd & 0xff);
+
+			if ((AHCI_TFD_ST(tfd) & (WDCS_DRQ|WDCS_BSY)) == 0 &&
+			!achp->ahcic_recovering)
+goto recover;
+
+			aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n",
+			AHCINAME(sc), chp->ch_channel, active, is, tfd);
 		} else {
 			/* emulate a CRC error */
-			chp->ch_error = WDCE_CRC;
-			chp->ch_status = WDCS_ERR;
+			tfd = (WDCE_CRC << AHCI_P_TFD_ERR_SHIFT) | WDCS_ERR;
 		}
+
 		if (is & AHCI_P_IX_IFS) {
 			aprint_error("%s port %d: SERR 0x%x\n",
 			AHCINAME(sc), chp->ch_channel,
 			AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel)));
 		}
-		/* complete all pending commands with error statuses */
-		for (slot=0; slot < sc->sc_ncmds; slot++) {
-			if ((achp->ahcic_cmds_active & (1 << slot)) == 0)
-continue;
-			if ((active & (1 << slot)) == 1) {
-xfer = ata_queue_hwslot_to_xfer(chp, slot);
-xfer->c_intr(chp, xfer, is);
-			}
+
+		/* Request channel reset */
+		ata_reset_channel(chp, 0);
+		return;
+	} else if (is & (AHCI_P_IX_DHRS|AHCI_P_IX_SDBS)) {
+	

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 20:03:29 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisatareg.h siisatavar.h

Log Message:
header changes for siisata switch to new error handling world order


To generate a diff of this commit:
cvs rdiff -u -r1.7.42.2 -r1.7.42.3 src/sys/dev/ic/siisatareg.h
cvs rdiff -u -r1.6.48.1 -r1.6.48.2 src/sys/dev/ic/siisatavar.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/ic/siisatareg.h
diff -u src/sys/dev/ic/siisatareg.h:1.7.42.2 src/sys/dev/ic/siisatareg.h:1.7.42.3
--- src/sys/dev/ic/siisatareg.h:1.7.42.2	Mon Jun 12 23:51:40 2017
+++ src/sys/dev/ic/siisatareg.h	Wed Jul 19 20:03:29 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisatareg.h,v 1.7.42.2 2017/06/12 23:51:40 jakllsch Exp $ */
+/* $NetBSD: siisatareg.h,v 1.7.42.3 2017/07/19 20:03:29 jdolecek Exp $ */
 
 /*
  * Copyright (c) 2007, 2008, 2009, 2010, 2011 Jonathan A. Kollasch.
@@ -164,6 +164,8 @@ struct siisata_prb {
 #define PRSO_RTC	0x04		/* recieved transfer count */
 #define PRSO_FIS	0x08		/* base of FIS */
 
+#define PRO_PMPSTS(i)	(0x0f80 + i * 8)
+#define PRO_PMPQACT(i)	(0x0f80 + i * 8 + 4)
 #define PRO_PCS		0x1000		/* (write) port control set */
 #define PRO_PS		PRO_PCS		/* (read) port status */
 #define PRO_PCC		0x1004		/* port control clear */
@@ -186,6 +188,7 @@ struct siisata_prb {
 #define PRO_CARX(p,s) (PRX(p, PRO_CAR) + (s) * sizeof(uint64_t))
 
 #define PRO_PCR		0x1e04		/* port context register */
+#define PRO_PCR_PMP(x)	(((x) & __BITS(8, 5)) >> 5) /* PM Port */
 #define PRO_SCONTROL	0x1f00		/* SControl */
 #define PRO_SSTATUS	0x1f04		/* SStatus */
 #define PRO_SERROR	0x1f08		/* SError */

Index: src/sys/dev/ic/siisatavar.h
diff -u src/sys/dev/ic/siisatavar.h:1.6.48.1 src/sys/dev/ic/siisatavar.h:1.6.48.2
--- src/sys/dev/ic/siisatavar.h:1.6.48.1	Tue Jun 13 00:02:19 2017
+++ src/sys/dev/ic/siisatavar.h	Wed Jul 19 20:03:29 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisatavar.h,v 1.6.48.1 2017/06/13 00:02:19 jakllsch Exp $ */
+/* $NetBSD: siisatavar.h,v 1.6.48.2 2017/07/19 20:03:29 jdolecek Exp $ */
 
 /* from ahcisatavar.h */
 
@@ -101,6 +101,8 @@ struct siisata_softc {
 		bus_dmamap_t sch_datad[SIISATA_MAX_SLOTS];
 
 		uint32_t sch_active_slots;
+		uint32_t sch_hold_slots;
+		bool sch_recovering;
 	} sc_channels[SIISATA_MAX_PORTS];
 };
 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 20:02:40 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
convert over to new error handling world order:
- switch to ata_timeout()
- stop using ch_status/ch_error for passing state/error, stop setting
  ATACH_IRQ_WAIT in ch_flags; pass the state via the last parameter
  to c_intr() routine
- add NCQ recovery and KILL_REQUEUE
- only call atastart() in c_intr() if there was no error

several siisata specific tweaks:
- improve reset to better handle PM - need to reset couple more registers
- add timeouts for unbusy wait - ATA_DELAY (10s)
- siisata_bio_complete() do not use PRSO_RTC for byte count for NCQ transfers,
  they never return partial reads; and that register might contain some random
  junk, at least that's the case with ahcisata cmdh_prdbc


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.25 -r1.30.4.26 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.25 src/sys/dev/ic/siisata.c:1.30.4.26
--- src/sys/dev/ic/siisata.c:1.30.4.25	Tue Jun 27 20:13:56 2017
+++ src/sys/dev/ic/siisata.c	Wed Jul 19 20:02:40 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $");
 
 #include 
 #include 
@@ -148,7 +148,7 @@ void siisata_killpending(struct ata_driv
 
 void siisata_cmd_start(struct ata_channel *, struct ata_xfer *);
 int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
-void siisata_cmd_done(struct ata_channel *, struct ata_xfer *);
+void siisata_cmd_done(struct ata_channel *, struct ata_xfer *, int);
 static void siisata_cmd_done_end(struct ata_channel *, struct ata_xfer *);
 void siisata_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 
@@ -157,14 +157,12 @@ int siisata_bio_complete(struct ata_chan
 void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 
-void siisata_timeout(void *);
-
 static void siisata_reinit_port(struct ata_channel *);
 static void siisata_device_reset(struct ata_channel *);
 static void siisata_activate_prb(struct siisata_channel *, int);
 static void siisata_deactivate_prb(struct siisata_channel *, int);
-static int siisata_dma_setup(struct ata_channel *chp, int, void *,
-size_t, int);
+static int siisata_dma_setup(struct ata_channel *, int, void *, size_t, int);
+static void siisata_channel_recover(struct ata_channel *, int, int);
 
 #if NATAPIBUS > 0
 void siisata_atapibus_attach(struct atabus_softc *);
@@ -478,7 +476,6 @@ siisata_intr_port(struct siisata_channel
 	struct ata_xfer *xfer;
 	u_int slot;
 	uint32_t pss, pis;
-	uint32_t prbfis;
 
 	sc = (struct siisata_softc *)schp->ata_channel.ch_atac;
 	chp = >ata_channel;
@@ -489,12 +486,15 @@ siisata_intr_port(struct siisata_channel
 	SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR);
 
 	for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) {
-		if (((schp->sch_active_slots >> slot) & 1) == 0)
+		if (((schp->sch_active_slots >> slot) & 1) == 0) {
 			/* there's nothing executing here, skip */
 			continue;
-		if (((pss >> slot) & 1) != 0)
-			/* execution is incomplete or unsuccessful, skip for now */
+		}
+		if (((pss >> slot) & 1) != 0) {
+			/* execution is incomplete or unsuccessful, skip
+			 * for now */
 			continue;
+		}
 		xfer = ata_queue_hwslot_to_xfer(chp, slot);
 		if (xfer->c_intr == NULL) {
 			wakeup(schp);
@@ -520,54 +520,145 @@ siisata_intr_port(struct siisata_channel
 	SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc),
 	__func__, chp->ch_channel, pis), DEBUG_INTR);
 
+	/* clear */
+	PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis);
+
 	if (pis & PR_PIS_CMDERRR) {
 		uint32_t ec;
-		uint32_t ps;
 
-		ps = PRREAD(sc, PRX(chp->ch_channel, PRO_PS));
 		ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE));
 		SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR);
 
-		slot = PR_PS_ACTIVE_SLOT(ps); /* XXX invalid for NCQ? */
-
 		/* emulate a CRC error by default */
-		chp->ch_status = WDCS_ERR;
-		chp->ch_error = WDCE_CRC;
+		int tfd = ATACH_ERR_ST(WDCE_CRC, WDCS_ERR);
 
-		if (ec <= PR_PCE_DATAFISERROR) {
-			if (ec == PR_PCE_DEVICEERROR) {
-/* read in specific information about error */
-prbfis = bus_space_read_stream_4(
-sc->sc_prt, sc->sc_prh,
-				PRSX(chp->ch_channel, slot,
-PRSO_FIS));
-/* set ch_status and ch_error */
-satafis_rdh_parse(chp, (uint8_t *));
-			}
-			

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 19:46:52 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: files.ata wd.c

Log Message:
defflag WD_CHAOS_MONKEY into opt_wd.h together with WD_SOFTBADSECT to set/unset
this more easily


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.24.28.1 src/sys/dev/ata/files.ata
cvs rdiff -u -r1.428.2.26 -r1.428.2.27 src/sys/dev/ata/wd.c

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/files.ata
diff -u src/sys/dev/ata/files.ata:1.24 src/sys/dev/ata/files.ata:1.24.28.1
--- src/sys/dev/ata/files.ata:1.24	Tue Jul 31 15:50:34 2012
+++ src/sys/dev/ata/files.ata	Wed Jul 19 19:46:52 2017
@@ -1,4 +1,4 @@
-#	$NetBSD: files.ata,v 1.24 2012/07/31 15:50:34 bouyer Exp $
+#	$NetBSD: files.ata,v 1.24.28.1 2017/07/19 19:46:52 jdolecek Exp $
 #
 # Config file and device description for machine-independent devices
 # which attach to ATA busses.  Included by ports that need it.  Ports
@@ -11,7 +11,8 @@ attach	wd at ata_hl
 file	dev/ata/wd.c			wd			needs-flag
 file	dev/ata/ata_wdc.c		wd & atabus & wdc_common
 
-defflag	WD_SOFTBADSECT
+defflag	opt_wd.h	WD_SOFTBADSECT
+defflag	opt_wd.h	WD_CHAOS_MONKEY
 
 file	dev/ata/ata.c			(ata_hl | atapi) & atabus
 

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.26 src/sys/dev/ata/wd.c:1.428.2.27
--- src/sys/dev/ata/wd.c:1.428.2.26	Wed Jul 19 19:39:28 2017
+++ src/sys/dev/ata/wd.c	Wed Jul 19 19:46:52 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.26 2017/07/19 19:39:28 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,9 +54,10 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.26 2017/07/19 19:39:28 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $");
 
 #include "opt_ata.h"
+#include "opt_wd.h"
 
 #include 
 #include 



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-19 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jul 19 19:39:28 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c atareg.h atavar.h satafis_subr.c
satafisvar.h wd.c wdvar.h

Log Message:
tighen and expand error handling, mostly for NCQ use cases:
- make retry timeout callout per xfer, i.e. retry separately
- zero whole bio struct on retry to avoid more stale state
- add a REQUEUE option, which doesn't bump retry count
- add ata_read_log_ext_ncq() for NCQ recovery
- adjust logic for activating xfers - allow next command only when
  it's for same drive, several concurrent are only supported when HBA
  and driver support FIS-based switching
- add new ata_timeout() which handles race between callout_stop()
  and the invokation, add appropriate handling on deactivate/free paths
- stop using ch_status/ch_error in non-wdc code; later it will be dropped
  completely


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.18 -r1.132.8.19 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.43.18.2 -r1.43.18.3 src/sys/dev/ata/atareg.h
cvs rdiff -u -r1.92.8.16 -r1.92.8.17 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.7.28.2 -r1.7.28.3 src/sys/dev/ata/satafis_subr.c
cvs rdiff -u -r1.3 -r1.3.50.1 src/sys/dev/ata/satafisvar.h
cvs rdiff -u -r1.428.2.25 -r1.428.2.26 src/sys/dev/ata/wd.c
cvs rdiff -u -r1.43.4.6 -r1.43.4.7 src/sys/dev/ata/wdvar.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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.18 src/sys/dev/ata/ata.c:1.132.8.19
--- src/sys/dev/ata/ata.c:1.132.8.18	Tue Jun 27 18:36:03 2017
+++ src/sys/dev/ata/ata.c	Wed Jul 19 19:39:28 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -241,14 +241,34 @@ ata_queue_get_active_xfer(struct ata_cha
 	return xfer;
 }
 
+struct ata_xfer *
+ata_queue_drive_active_xfer(struct ata_channel *chp, int drive)
+{
+	struct ata_xfer *xfer = NULL;
+
+	mutex_enter(>ch_lock);
+
+	TAILQ_FOREACH(xfer, >ch_queue->active_xfers, c_activechain) {
+		if (xfer->c_drive == drive)
+			break;
+	}
+	KASSERT(xfer != NULL);
+
+	mutex_exit(>ch_lock);
+
+	return xfer;
+}
+
 static void
-ata_xfer_init(struct ata_xfer *xfer, bool zero)
+ata_xfer_init(struct ata_xfer *xfer, uint8_t slot)
 {
-	if (zero)
-		memset(xfer, 0, sizeof(*xfer));
+	memset(xfer, 0, sizeof(*xfer));
+
+	xfer->c_slot = slot;
 
 	cv_init(>c_active, "ataact");
 	callout_init(>c_timo_callout, 0); 	/* XXX MPSAFE */
+	callout_init(>c_retry_callout, 0); 	/* XXX MPSAFE */
 }
 
 static void
@@ -256,6 +276,8 @@ ata_xfer_destroy(struct ata_xfer *xfer)
 {
 	callout_halt(>c_timo_callout, NULL);	/* XXX MPSAFE */
 	callout_destroy(>c_timo_callout);
+	callout_halt(>c_retry_callout, NULL);	/* XXX MPSAFE */
+	callout_destroy(>c_retry_callout);
 	cv_destroy(>c_active);
 }
 
@@ -278,7 +300,7 @@ ata_queue_alloc(uint8_t openings)
 	cv_init(>queue_drain, "atdrn");
 
 	for (uint8_t i = 0; i < openings; i++)
-		ata_xfer_init(>queue_xfers[i], false);
+		ata_xfer_init(>queue_xfers[i], i);
 
 	return chq;
 }
@@ -1009,6 +1031,88 @@ out:
 	return rv;
 }
 
+int
+ata_read_log_ext_ncq(struct ata_drive_datas *drvp, uint8_t flags,
+uint8_t *slot, uint8_t *status, uint8_t *err)
+{
+	struct ata_xfer *xfer;
+	int rv;
+	struct ata_channel *chp = drvp->chnl_softc;
+	struct atac_softc *atac = chp->ch_atac;
+	uint8_t *tb;
+
+	ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS);
+
+	/* Only NCQ ATA drives support/need this */
+	if (drvp->drive_type != ATA_DRIVET_ATA ||
+	(drvp->drive_flags & ATA_DRIVE_NCQ) == 0)
+		return EOPNOTSUPP;
+
+	xfer = ata_get_xfer_ext(chp, false, 0);
+	if (xfer == NULL) {
+		ATADEBUG_PRINT(("%s: no xfer\n", __func__),
+		DEBUG_FUNCS|DEBUG_XFERS);
+		return EAGAIN;
+	}
+
+	tb = malloc(DEV_BSIZE, M_DEVBUF, M_NOWAIT);
+	if (tb == NULL) {
+		ATADEBUG_PRINT(("%s: memory allocation failed\n", __func__),
+		DEBUG_FUNCS|DEBUG_XFERS);
+		rv = EAGAIN;
+		goto out;
+	}
+	memset(tb, 0, DEV_BSIZE);
+
+	/*
+	 * We could use READ LOG DMA EXT if drive supports it (i.e.
+	 * when it supports Streaming feature) to avoid PIO command,
+	 * and to make this a little faster. Realistically, it
+	 * should not matter.
+	 */
+	xfer->c_flags |= C_IMMEDIATE;
+	xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT;
+	xfer->c_ata_c.r_lba = WDCC_LOG_PAGE_NCQ;
+	xfer->c_ata_c.r_st_bmask = WDCS_DRDY;
+	xfer->c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer->c_ata_c.r_count = 1;
+	xfer->c_ata_c.r_device = WDSD_LBA;
+	xfer->c_ata_c.flags = AT_READ | AT_LBA | flags;
+	xfer->c_ata_c.timeout = 1000; /* 1s 

CVS commit: [jdolecek-ncq] src/sys/dev/usb

2017-07-16 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sun Jul 16 21:41:47 UTC 2017

Modified Files:
src/sys/dev/usb [jdolecek-ncq]: umass_isdata.c

Log Message:
fix comment


To generate a diff of this commit:
cvs rdiff -u -r1.33.4.6 -r1.33.4.7 src/sys/dev/usb/umass_isdata.c

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/usb/umass_isdata.c
diff -u src/sys/dev/usb/umass_isdata.c:1.33.4.6 src/sys/dev/usb/umass_isdata.c:1.33.4.7
--- src/sys/dev/usb/umass_isdata.c:1.33.4.6	Sat Jun 24 00:23:39 2017
+++ src/sys/dev/usb/umass_isdata.c	Sun Jul 16 21:41:47 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $	*/
+/*	$NetBSD: umass_isdata.c,v 1.33.4.7 2017/07/16 21:41:47 jdolecek Exp $	*/
 
 /*
  * TODO:
@@ -37,7 +37,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.7 2017/07/16 21:41:47 jdolecek Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -556,7 +556,7 @@ uisdata_get_params(struct ata_drive_data
 	xfer->c_ata_c.data = tb;
 	xfer->c_ata_c.bcount = DEV_BSIZE;
 	if (uisdata_exec_command(drvp, xfer) != ATACMD_COMPLETE) {
-		DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n"));
+		DPRINTF(("uisdata_get_parms: uisdata_exec_command failed\n"));
 		rv = CMD_AGAIN;
 		goto out;
 	}



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-03 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Jul  3 19:54:44 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
reset xfer c_flags before retry, to clear flags like C_TIMEOU, or C_NCQ,
so that retry, and no-NCQ downgrade logic actually works - drivers
typically doesn't reset this field

print number of retries to make it easier to spot the same xfer being
retried several times

in wddone(), hold the wd lock only when reading/changing wd softc
structures, and not e.g. when calling malloc(), rnd_add_uint32() or
ata_free_xfer(), which have their own locks; initially done to fix
diagnostic assertion about held spin lock in kpause() within
ata_reset_drive hook, but need to run that hook with AT_POLL anyway,
since wddone() is typically invoked from interrupt context

fix another interrupt context bug for WD_SOFTBADSECT - the malloc() needs
to be called with M_NOWAIT


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.24 -r1.428.2.25 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.24 src/sys/dev/ata/wd.c:1.428.2.25
--- src/sys/dev/ata/wd.c:1.428.2.24	Mon Jul  3 19:31:16 2017
+++ src/sys/dev/ata/wd.c	Mon Jul  3 19:54:44 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.25 2017/07/03 19:54:44 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.25 2017/07/03 19:54:44 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -695,6 +695,10 @@ wdstart1(struct wd_softc *wd, struct buf
 	KASSERT(bp == xfer->c_bio.bp || xfer->c_bio.bp == NULL);
 	xfer->c_bio.bp = bp;
 
+	/* Reset state flags, so that retries don't use stale info */
+	KASSERT((xfer->c_flags & (C_WAITACT|C_FREE)) == 0);
+	xfer->c_flags = 0;
+
 #ifdef WD_CHAOS_MONKEY
 	/*
 	 * Override blkno to be over device capacity to trigger error,
@@ -787,8 +791,6 @@ wddone(device_t self, struct ata_xfer *x
 		return;
 	}
 
-	mutex_enter(>sc_lock);
-
 	bp = xfer->c_bio.bp;
 	KASSERT(bp != NULL);
 
@@ -814,12 +816,14 @@ wddone(device_t self, struct ata_xfer *x
 		errmsg = "error";
 		do_perror = 1;
 retry:		/* Just reset and retry. Can we do more ? */
-		(*wd->atabus->ata_reset_drive)(wd->drvp, 0, NULL);
+		(*wd->atabus->ata_reset_drive)(wd->drvp, AT_POLL, NULL);
 retry2:
+		mutex_enter(>sc_lock);
+
 		diskerr(bp, "wd", errmsg, LOG_PRINTF,
 		xfer->c_bio.blkdone, wd->sc_dk.dk_label);
 		if (xfer->c_bio.retries < WDIORETRIES)
-			printf(", retrying");
+			printf(", retrying %d", xfer->c_bio.retries + 1);
 		printf("\n");
 		if (do_perror)
 			wdperror(wd, xfer);
@@ -841,6 +845,8 @@ retry2:
 			return;
 		}
 
+		mutex_exit(>sc_lock);
+
 #ifdef WD_SOFTBADSECT
 		/*
 		 * Not all errors indicate a failed block but those that do,
@@ -853,14 +859,24 @@ retry2:
 		 (wd->drvp->ata_vers < 4 && xfer->c_bio.r_error & 192))) {
 			struct disk_badsectors *dbs;
 
-			dbs = malloc(sizeof *dbs, M_TEMP, M_WAITOK);
+			dbs = malloc(sizeof *dbs, M_TEMP, M_NOWAIT);
+			if (dbs == NULL) {
+aprint_error_dev(wd->sc_dev,
+"failed to add bad block to list\n");
+goto out;
+			}
+
 			dbs->dbs_min = bp->b_rawblkno;
 			dbs->dbs_max = dbs->dbs_min +
 			(bp->b_bcount /wd->sc_blksize) - 1;
 			microtime(>dbs_failedat);
+
+			mutex_enter(>sc_lock);
 			SLIST_INSERT_HEAD(>sc_bslist, dbs, dbs_next);
 			wd->sc_bscount++;
+			mutex_exit(>sc_lock);
 		}
+out:
 #endif
 		bp->b_error = EIO;
 		break;
@@ -885,7 +901,6 @@ noerror:	if ((xfer->c_bio.flags & ATA_CO
 	(bp->b_flags & B_READ));
 	rnd_add_uint32(>rnd_source, bp->b_blkno);
 	ata_free_xfer(wd->drvp->chnl_softc, xfer);
-	mutex_exit(>sc_lock);
 	biodone(bp);
 	ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive);
 }



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-03 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Jul  3 19:31:16 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: wd.c

Log Message:
introduce some code to test retry paths


To generate a diff of this commit:
cvs rdiff -u -r1.428.2.23 -r1.428.2.24 src/sys/dev/ata/wd.c

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/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.23 src/sys/dev/ata/wd.c:1.428.2.24
--- src/sys/dev/ata/wd.c:1.428.2.23	Sat Jun 24 00:00:10 2017
+++ src/sys/dev/ata/wd.c	Mon Jul  3 19:31:16 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -115,6 +115,10 @@ int wdcdebug_wd_mask = 0x0;
 #define ATADEBUG_PRINT(args, level)
 #endif
 
+#ifdef WD_CHAOS_MONKEY
+int wdcdebug_wd_chaos = 0;
+#endif
+
 int	wdprobe(device_t, cfdata_t, void *);
 void	wdattach(device_t, device_t, void *);
 int	wddetach(device_t, int);
@@ -691,6 +695,20 @@ wdstart1(struct wd_softc *wd, struct buf
 	KASSERT(bp == xfer->c_bio.bp || xfer->c_bio.bp == NULL);
 	xfer->c_bio.bp = bp;
 
+#ifdef WD_CHAOS_MONKEY
+	/*
+	 * Override blkno to be over device capacity to trigger error,
+	 * but only if it's read, to avoid trashing disk contents should
+	 * the command be clipped, or otherwise misinterpreted, by the
+	 * driver or controller.
+	 */
+	if (BUF_ISREAD(bp) && (++wdcdebug_wd_chaos % WD_CHAOS_MONKEY) == 0) {
+		aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n",
+		__func__, xfer->c_slot);
+		xfer->c_bio.blkno = 777 + wd->sc_capacity;
+	}
+#endif
+
 	/*
 	 * If we're retrying, retry in single-sector mode. This will give us
 	 * the sector number of the problem, and will eventually allow the



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-07-03 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Jul  3 18:17:01 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
expand what needs to be done with error handling


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.28 -r1.1.2.29 src/sys/dev/ata/TODO.ncq

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.28 src/sys/dev/ata/TODO.ncq:1.1.2.29
--- src/sys/dev/ata/TODO.ncq:1.1.2.28	Wed Jun 28 19:54:38 2017
+++ src/sys/dev/ata/TODO.ncq	Mon Jul  3 18:17:01 2017
@@ -5,9 +5,16 @@ siisata - fix all new XXX and unmergable
 
 test wd* at umass?, confirm the ata_channel kludge works
 
-test device error handling (currently appears to not work well, at least in NCQ case)
+test non-NCQ device error handling
+- test retry code paths, locking
+- channel reset on fatal errors
 
 do proper NCQ error recovery (currently not even really attempted)
+- if fatal error, do channel reset
+- if tranfer error (both TFD.STS.BSY and DRQ is 0), need READ LOG EXT log
+  page 10h to read tag which caused the error, and reset the device to idle
+- need to cancel and restart the other active transfers in a way to not
+  increase retry count, and not trigger drive reset
 
 maybe do device error handling in not-interrupt-context (maybe this should be
 done on a mpata branch?)



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-06-28 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jun 28 19:59:36 UTC 2017

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

Log Message:
enable ATAPI on mvsata(4); it seems to work fine for my cdrom


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.17 -r1.35.6.18 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.17 src/sys/dev/ic/mvsata.c:1.35.6.18
--- src/sys/dev/ic/mvsata.c:1.35.6.17	Tue Jun 27 18:36:03 2017
+++ src/sys/dev/ic/mvsata.c	Wed Jun 28 19:59:36 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.17 2017/06/27 18:36:03 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.17 2017/06/27 18:36:03 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -760,10 +760,8 @@ mvsata_atapibus_attach(struct atabus_sof
 	chan->chan_ntargets = 1;
 	chan->chan_nluns = 1;
 
-#if 0 /* XXX ATAPI implementation not finished. */
 	chp->atapibus =
 	config_found_ia(ata_sc->sc_dev, "atapi", chan, atapiprint);
-#endif
 }
 
 static void



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-06-28 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Wed Jun 28 19:54:38 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
ATAPI on siisata(4), ahcisata(4) tested


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.27 -r1.1.2.28 src/sys/dev/ata/TODO.ncq

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.27 src/sys/dev/ata/TODO.ncq:1.1.2.28
--- src/sys/dev/ata/TODO.ncq:1.1.2.27	Tue Jun 27 18:16:50 2017
+++ src/sys/dev/ata/TODO.ncq	Wed Jun 28 19:54:38 2017
@@ -3,8 +3,6 @@ Bugs
 
 siisata - fix all new XXX and unmergable bits
 
-test ATAPI on siisata, ahcisata
-
 test wd* at umass?, confirm the ata_channel kludge works
 
 test device error handling (currently appears to not work well, at least in NCQ case)



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-06-27 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Jun 27 20:13:56 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
need to explicitely call siisata_timeout() also for polled bio command when
it times out to clean up; this should avoid the 'polled command has been
queued' panic from wddump()


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.24 -r1.30.4.25 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.24 src/sys/dev/ic/siisata.c:1.30.4.25
--- src/sys/dev/ic/siisata.c:1.30.4.24	Tue Jun 27 18:36:04 2017
+++ src/sys/dev/ic/siisata.c	Tue Jun 27 20:13:56 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.24 2017/06/27 18:36:04 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.24 2017/06/27 18:36:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $");
 
 #include 
 #include 
@@ -1169,6 +1169,10 @@ siisata_bio_start(struct ata_channel *ch
 		DELAY(100);
 	}
 
+	if ((ata_bio->flags & ATA_ITSDONE) == 0) {
+		siisata_timeout(xfer);
+	}
+
 	siisata_enable_port_interrupt(chp);
 out:
 	SIISATA_DEBUG_PRINT(("%s: %s: done\n",



CVS commit: [jdolecek-ncq] src/sys/dev

2017-06-27 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Jun 27 18:36:04 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c ata_wdc.c atavar.h
src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c
src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
attend error paths, more strict asserts and code consistency

- atastart() and ata_kill_pending() now KASSERT() that all xfers on queue
  have same channel
- inactive xfers are killed via new reason KILL_GONE_INACTIVE, controller
  code must not call any resource deactivation in that case
- c_intr() must call ata_waitdrain_xfer_check() as first thing, and must not
  further touch any xfer structures on exit path; any resource cleanup
  is supposed to be done in c_kill_xfer()
- c_kill_xfer() should never call atastart()
- ata_waitdrain_check() removed, replaced by ata_waitdrain_xfer_check()
- ATA_DRIVE_WAITDRAIN handling converted to use condvar
- removed unused ata_c callback


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.17 -r1.132.8.18 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.105.6.5 -r1.105.6.6 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.92.8.15 -r1.92.8.16 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.57.6.16 -r1.57.6.17 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.35.6.16 -r1.35.6.17 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.30.4.23 -r1.30.4.24 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.283.2.9 -r1.283.2.10 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.123.4.8 -r1.123.4.9 src/sys/dev/scsipi/atapi_wdc.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.17 src/sys/dev/ata/ata.c:1.132.8.18
--- src/sys/dev/ata/ata.c:1.132.8.17	Sat Jun 24 14:57:17 2017
+++ src/sys/dev/ata/ata.c	Tue Jun 27 18:36:03 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -275,6 +275,7 @@ ata_queue_alloc(uint8_t openings)
 	ata_queue_reset(chq);
 
 	cv_init(>queue_busy, "ataqbusy");
+	cv_init(>queue_drain, "atdrn");
 
 	for (uint8_t i = 0; i < openings; i++)
 		ata_xfer_init(>queue_xfers[i], false);
@@ -288,6 +289,9 @@ ata_queue_free(struct ata_queue *chq)
 	for (uint8_t i = 0; i < chq->queue_openings; i++)
 		ata_xfer_destroy(>queue_xfers[i]);
 
+	cv_destroy(>queue_busy);
+	cv_destroy(>queue_drain);
+
 	free(chq, M_DEVBUF);
 }
 
@@ -1140,6 +1144,9 @@ atastart(struct ata_channel *chp)
 	if ((xfer = TAILQ_FIRST(>ch_queue->queue_xfer)) == NULL)
 		goto out;
 
+	/* all xfers on same queue must belong to the same channel */
+	KASSERT(xfer->c_chp == chp);
+
 	/*
 	 * Can only take NCQ command if there are no current active
 	 * commands, or if the active commands are NCQ. Need only check
@@ -1149,10 +1156,6 @@ atastart(struct ata_channel *chp)
 	if (axfer && (axfer->c_flags & C_NCQ) == 0)
 		goto out;
 
-	/* adjust chp, in case we have a shared queue */
-	chp = xfer->c_chp;
-	KASSERT(chp->ch_queue == chq);
-
 	struct ata_drive_datas * const drvp = >ch_drive[xfer->c_drive];
 
 	/*
@@ -1322,29 +1325,37 @@ ata_deactivate_xfer(struct ata_channel *
 	mutex_exit(>ch_lock);
 }
 
-
-bool
-ata_waitdrain_check(struct ata_channel *chp, int drive)
-{
-	if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) {
-		chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN;
-		wakeup(>ch_queue->active_xfers);
-		return true;
-	}
-	return false;
-}
-
+/*
+ * Called in c_intr hook. Must be called before before any deactivations
+ * are done - if there is drain pending, it calls c_kill_xfer hook which
+ * deactivates the xfer.
+ * Calls c_kill_xfer with channel lock free.
+ * Returns true if caller should just exit without further processing.
+ * Caller must not further access any part of xfer or any related controller
+ * structures in that case, it should just return.
+ */
 bool
 ata_waitdrain_xfer_check(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	int drive = xfer->c_drive;
+	bool draining = false;
+
+	mutex_enter(>ch_lock);
+
 	if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) {
+		mutex_exit(>ch_lock);
+
 		(*xfer->c_kill_xfer)(chp, xfer, KILL_GONE);
+
+		mutex_enter(>ch_lock);
 		chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN;
-		wakeup(>ch_queue->active_xfers);
-		return true;
+		cv_signal(>ch_queue->queue_drain);
+		draining = true;
 	}
-	return false;
+
+	mutex_exit(>ch_lock);
+
+	return draining;
 }
 
 /*
@@ -1367,38 +1378,58 @@ ata_kill_active(struct ata_channel *chp,
 }
 
 /*
- * Kill off all pending xfers for a ata_channel.
- *
- * Must be 

CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-06-27 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Tue Jun 27 18:16:50 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq

Log Message:
note ATAPI on siisata, ahcisata needs to be tested


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.26 -r1.1.2.27 src/sys/dev/ata/TODO.ncq

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.26 src/sys/dev/ata/TODO.ncq:1.1.2.27
--- src/sys/dev/ata/TODO.ncq:1.1.2.26	Sat Jun 24 14:33:06 2017
+++ src/sys/dev/ata/TODO.ncq	Tue Jun 27 18:16:50 2017
@@ -3,6 +3,8 @@ Bugs
 
 siisata - fix all new XXX and unmergable bits
 
+test ATAPI on siisata, ahcisata
+
 test wd* at umass?, confirm the ata_channel kludge works
 
 test device error handling (currently appears to not work well, at least in NCQ case)



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-06-26 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Mon Jun 26 20:36:14 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
when reducing DELAY(), it's necessary to appropriately increase number
of iteration, or command can timeout too soon

adjust also siisata_atapi_start() to use DELAY(100) for the polled command,
mostly for consistency, ATAPI devices are quite slow so likely won't have
real effect


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.22 -r1.30.4.23 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.22 src/sys/dev/ic/siisata.c:1.30.4.23
--- src/sys/dev/ic/siisata.c:1.30.4.22	Sat Jun 24 11:34:33 2017
+++ src/sys/dev/ic/siisata.c	Mon Jun 26 20:36:14 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.23 2017/06/26 20:36:14 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.23 2017/06/26 20:36:14 jdolecek Exp $");
 
 #include 
 #include 
@@ -944,7 +944,7 @@ siisata_cmd_start(struct ata_channel *ch
 	/*
 	 * polled command
 	 */
-	for (i = 0; i < ata_c->timeout / 10; i++) {
+	for (i = 0; i < ata_c->timeout * 10; i++) {
 		if (ata_c->flags & AT_DONE)
 			break;
 		siisata_intr_port(schp);
@@ -1148,7 +1148,7 @@ siisata_bio_start(struct ata_channel *ch
 	/*
 	 * polled command
 	 */
-	for (i = 0; i < ATA_DELAY / 10; i++) {
+	for (i = 0; i < ATA_DELAY * 10; i++) {
 		if (ata_bio->flags & ATA_ITSDONE)
 			break;
 		siisata_intr_port(schp);
@@ -1693,11 +1693,11 @@ siisata_atapi_start(struct ata_channel *
 	/*
 	 * polled command
 	 */
-	for (i = 0; i < ATA_DELAY / 10; i++) {
+	for (i = 0; i < ATA_DELAY * 10; i++) {
 		if (sc_xfer->xs_status & XS_STS_DONE)
 			break;
 		siisata_intr_port(schp);
-		DELAY(1000);
+		DELAY(100);
 	}
 	if ((sc_xfer->xs_status & XS_STS_DONE) == 0) {
 		siisata_timeout(xfer);



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-06-24 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jun 24 14:59:10 UTC 2017

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

Log Message:
fix confusion around AT_WAIT vs AT_POLL for mvsata_edma_disable(), and switch
all the tsleep()/delay() ifs to just use ata_delay()


To generate a diff of this commit:
cvs rdiff -u -r1.35.6.15 -r1.35.6.16 src/sys/dev/ic/mvsata.c

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/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.15 src/sys/dev/ic/mvsata.c:1.35.6.16
--- src/sys/dev/ic/mvsata.c:1.35.6.15	Sat Jun 24 14:33:06 2017
+++ src/sys/dev/ic/mvsata.c	Sat Jun 24 14:59:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.16 2017/06/24 14:59:10 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.16 2017/06/24 14:59:10 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -1081,7 +1081,7 @@ mvsata_bio_start(struct ata_channel *chp
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct ata_bio *ata_bio = >c_bio;
 	struct ata_drive_datas *drvp = >ch_drive[xfer->c_drive];
-	int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
+	int wait_flags =  ata_bio->flags & AT_WAIT;
 	u_int16_t cyl;
 	u_int8_t head, sect, cmd = 0;
 	int nblks, error;
@@ -3206,10 +3206,10 @@ mvsata_reset_hc(struct mvsata_hc *mvhc)
 #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
 
 static uint32_t
-mvsata_softreset(struct mvsata_port *mvport, int waitok)
+mvsata_softreset(struct mvsata_port *mvport, int flags)
 {
 	uint32_t sig0 = ~0;
-	int timeout, nloop;
+	int timeout;
 	uint8_t st0;
 
 	MVSATA_WDC_WRITE_1(mvport, SRB_CAS, WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
@@ -3218,13 +3218,8 @@ mvsata_softreset(struct mvsata_port *mvp
 	MVSATA_WDC_WRITE_1(mvport, SRB_CAS, WDCTL_IDS | WDCTL_4BIT);
 	delay(10);
 
-	if (!waitok)
-		nloop = WDCNDELAY_RST;
-	else
-		nloop = WDC_RESET_WAIT * hz / 1000;
-
 	/* wait for BSY to deassert */
-	for (timeout = 0; timeout < nloop; timeout++) {
+	for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
 		st0 = MVSATA_WDC_READ_1(mvport, SRB_CS);
 
 		if ((st0 & WDCS_BSY) == 0) {
@@ -3234,10 +3229,7 @@ mvsata_softreset(struct mvsata_port *mvp
 			sig0 |= MVSATA_WDC_READ_1(mvport, SRB_LBAH) << 24;
 			goto out;
 		}
-		if (!waitok)
-			delay(WDCDELAY);
-		else
-			tsleep(, PRIBIO, "atarst", 1);
+		ata_delay(WDCDELAY, "atarst", flags);
 	}
 	
 out:
@@ -3270,7 +3262,7 @@ mvsata_edma_enable(struct mvsata_port *m
 }
 
 static int
-mvsata_edma_disable(struct mvsata_port *mvport, int timeout, int waitok)
+mvsata_edma_disable(struct mvsata_port *mvport, int timeout, int wflags)
 {
 	uint32_t status, command;
 	int ms;
@@ -3280,11 +3272,7 @@ mvsata_edma_disable(struct mvsata_port *
 			status = MVSATA_EDMA_READ_4(mvport, EDMA_S);
 			if (status & EDMA_S_EDMAIDLE)
 break;
-			if (waitok)
-tsleep(, PRIBIO, "mvsata_edma1",
-mstohz(1));
-			else
-delay(1000);
+			ata_delay(1, "mvsata_edma1", wflags);
 		}
 		if (ms == timeout) {
 			aprint_error("%s:%d:%d: unable to disable EDMA\n",
@@ -3300,11 +3288,7 @@ mvsata_edma_disable(struct mvsata_port *
 			command = MVSATA_EDMA_READ_4(mvport, EDMA_CMD);
 			if (!(command & EDMA_CMD_EENEDMA))
 break;
-			if (waitok)
-tsleep(, PRIBIO, "mvsata_edma2",
-mstohz(1));
-			else
-delay(1000);
+			ata_delay(1, "mvsata_edma2", wflags);
 		}
 		if (ms == timeout) {
 			aprint_error("%s:%d:%d: unable to re-enable EDMA\n",



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-06-24 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jun 24 14:57:17 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: ata.c

Log Message:
change ata_delay() to tsleep for 1 hz rather than indefinitely if
provided ms is lower than 1 hz


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.16 -r1.132.8.17 src/sys/dev/ata/ata.c

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/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.16 src/sys/dev/ata/ata.c:1.132.8.17
--- src/sys/dev/ata/ata.c:1.132.8.16	Fri Jun 23 20:40:51 2017
+++ src/sys/dev/ata/ata.c	Sat Jun 24 14:57:17 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.16 2017/06/23 20:40:51 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.16 2017/06/23 20:40:51 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -2110,7 +2110,8 @@ ata_delay(int ms, const char *msg, int f
 		 */
 		delay(ms * 1000);
 	} else {
-		kpause(msg, false, mstohz(ms), NULL);
+		int pause = mstohz(ms);
+		kpause(msg, false, pause > 0 ? pause : 1, NULL);
 	}
 }
 



CVS commit: [jdolecek-ncq] src/sys/dev

2017-06-24 Thread Jaromir Dolecek
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 
-__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(>c_timo_callout);
 
 	/* EDMA restart, if enabled */
-	if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode != 

CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-06-24 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jun 24 11:34:33 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
reduce the polling interval also for siisata_cmd_start()


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.21 -r1.30.4.22 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.21 src/sys/dev/ic/siisata.c:1.30.4.22
--- src/sys/dev/ic/siisata.c:1.30.4.21	Fri Jun 23 23:49:20 2017
+++ src/sys/dev/ic/siisata.c	Sat Jun 24 11:34:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $");
 
 #include 
 #include 
@@ -948,7 +948,7 @@ siisata_cmd_start(struct ata_channel *ch
 		if (ata_c->flags & AT_DONE)
 			break;
 		siisata_intr_port(schp);
-		DELAY(1000);
+		DELAY(100);
 	}
 
 	if ((ata_c->flags & AT_DONE) == 0) {



CVS commit: [jdolecek-ncq] src/sys/dev

2017-06-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jun 24 00:23:39 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq
src/sys/dev/usb [jdolecek-ncq]: umass.c umass_isdata.c umass_isdata.h

Log Message:
add detach code for umass_isdata; compile-tested only


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.24 -r1.1.2.25 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.157 -r1.157.4.1 src/sys/dev/usb/umass.c
cvs rdiff -u -r1.33.4.5 -r1.33.4.6 src/sys/dev/usb/umass_isdata.c
cvs rdiff -u -r1.3 -r1.3.6.1 src/sys/dev/usb/umass_isdata.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.24 src/sys/dev/ata/TODO.ncq:1.1.2.25
--- src/sys/dev/ata/TODO.ncq:1.1.2.24	Sat Jun 24 00:00:10 2017
+++ src/sys/dev/ata/TODO.ncq	Sat Jun 24 00:23:39 2017
@@ -7,7 +7,6 @@ fix crashdump for mvsata - request times
 siisata - fix all new XXX and unmergable bits
 
 test wd* at umass?, confirm the ata_channel kludge works
-+ add detach code (channel detach, free queue)
 
 test device error handling (currently appears to not work well, at least in NCQ case)
 

Index: src/sys/dev/usb/umass.c
diff -u src/sys/dev/usb/umass.c:1.157 src/sys/dev/usb/umass.c:1.157.4.1
--- src/sys/dev/usb/umass.c:1.157	Mon Nov 21 08:27:30 2016
+++ src/sys/dev/usb/umass.c	Sat Jun 24 00:23:39 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: umass.c,v 1.157 2016/11/21 08:27:30 skrll Exp $	*/
+/*	$NetBSD: umass.c,v 1.157.4.1 2017/06/24 00:23:39 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -124,7 +124,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.157 2016/11/21 08:27:30 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.157.4.1 2017/06/24 00:23:39 jdolecek Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -819,6 +819,21 @@ umass_detach(device_t self, int flags)
 	if (scbus != NULL) {
 		if (scbus->sc_child != NULL)
 			rv = config_detach(scbus->sc_child, flags);
+
+		switch (sc->sc_cmd) {
+		case UMASS_CPROTO_ISD_ATA:
+#if NWD > 0
+			umass_isdata_detach(sc);
+#else
+			aprint_error_dev(self, "isdata not configured\n");
+#endif
+			break;
+
+		default:
+			/* nothing to do */
+			break;
+		}
+
 		free(scbus, M_DEVBUF);
 		sc->bus = NULL;
 	}

Index: src/sys/dev/usb/umass_isdata.c
diff -u src/sys/dev/usb/umass_isdata.c:1.33.4.5 src/sys/dev/usb/umass_isdata.c:1.33.4.6
--- src/sys/dev/usb/umass_isdata.c:1.33.4.5	Wed Jun 21 19:38:43 2017
+++ src/sys/dev/usb/umass_isdata.c	Sat Jun 24 00:23:39 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: umass_isdata.c,v 1.33.4.5 2017/06/21 19:38:43 jdolecek Exp $	*/
+/*	$NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $	*/
 
 /*
  * TODO:
@@ -37,7 +37,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.5 2017/06/21 19:38:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -233,6 +233,16 @@ umass_isdata_attach(struct umass_softc *
 	return 0;
 }
 
+void
+umass_isdata_detach(struct umass_softc *sc)
+{
+	struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
+
+	ata_queue_free(scbus->sc_channel.ch_queue);
+	scbus->sc_channel.ch_queue = NULL;
+
+	ata_channel_destroy(>sc_channel);
+}
 
 void
 uisdata_bio_cb(struct umass_softc *sc, void *priv, int residue, int status)

Index: src/sys/dev/usb/umass_isdata.h
diff -u src/sys/dev/usb/umass_isdata.h:1.3 src/sys/dev/usb/umass_isdata.h:1.3.6.1
--- src/sys/dev/usb/umass_isdata.h:1.3	Sat Apr 23 10:15:32 2016
+++ src/sys/dev/usb/umass_isdata.h	Sat Jun 24 00:23:39 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: umass_isdata.h,v 1.3 2016/04/23 10:15:32 skrll Exp $	*/
+/*	$NetBSD: umass_isdata.h,v 1.3.6.1 2017/06/24 00:23:39 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -31,3 +31,4 @@
  */
 
 int umass_isdata_attach(struct umass_softc *);
+void umass_isdata_detach(struct umass_softc *);



CVS commit: [jdolecek-ncq] src/sys/dev/ata

2017-06-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Sat Jun 24 00:00:10 UTC 2017

Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq wd.c

Log Message:
only limit the openings for I/O xfer if the drive actually supports NCQ; if
it's non-NCQ drive, the tag is not going to be used, so we can use any xfer


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.23 -r1.1.2.24 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.428.2.22 -r1.428.2.23 src/sys/dev/ata/wd.c

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.23 src/sys/dev/ata/TODO.ncq:1.1.2.24
--- src/sys/dev/ata/TODO.ncq:1.1.2.23	Fri Jun 23 23:49:20 2017
+++ src/sys/dev/ata/TODO.ncq	Sat Jun 24 00:00:10 2017
@@ -16,9 +16,6 @@ do proper NCQ error recovery (currently 
 maybe do device error handling in not-interrupt-context (maybe this should be
 done on a mpata branch?)
 
-do not limit openings for xfers for non-NCQ drives in wdstart(), the tag
-will not be used so can use any xfer
-
 in atastart(), restrict NCQ commands to commands for the same drive? it's
 fine for fis-based switching to have outstanding for several drives, but
 not non-FIS

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.22 src/sys/dev/ata/wd.c:1.428.2.23
--- src/sys/dev/ata/wd.c:1.428.2.22	Fri Jun 23 23:45:09 2017
+++ src/sys/dev/ata/wd.c	Sat Jun 24 00:00:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.22 2017/06/23 23:45:09 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.22 2017/06/23 23:45:09 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -659,9 +659,10 @@ wdstart(device_t self)
 		goto out;
 
 	while (bufq_peek(wd->sc_q) != NULL) {
-		/* First try to get command */
+		/* First try to get xfer. Limit to drive openings iff NCQ. */
 		xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false,
-		wd->drvp->drv_openings);
+		ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ)
+		? wd->drvp->drv_openings : 0);
 		if (xfer == NULL)
 			break;
 



CVS commit: [jdolecek-ncq] src/sys/dev

2017-06-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Jun 23 23:49:20 UTC 2017

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

Log Message:
fix dump for siisata(4) to work - need to call drv_done() callback in order to
not leak xfers

while here, reduce the DELAY() for polled bio to make it go much faster,
same value as used in ahcisata(4)

needs also rev. 1.252 src/sys/arch/x86/x86/pmap.c to not trigger the
assertion, the pmap.c fix committed only on HEAD


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.22 -r1.1.2.23 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.30.4.20 -r1.30.4.21 src/sys/dev/ic/siisata.c

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.22 src/sys/dev/ata/TODO.ncq:1.1.2.23
--- src/sys/dev/ata/TODO.ncq:1.1.2.22	Fri Jun 23 20:40:51 2017
+++ src/sys/dev/ata/TODO.ncq	Fri Jun 23 23:49:20 2017
@@ -6,12 +6,6 @@ fix crashdump for mvsata - request times
 
 siisata - fix all new XXX and unmergable bits
 
-test crashdump with siisata
-- fails with recursive panic via pmap_kremove_local() regardless if
-  drive connected via PMP or direct (failed KASSERT(panicstr != NULL))
-- HEAD crashes same as branch
-- see kern/49610 for potential fix
-
 test wd* at umass?, confirm the ata_channel kludge works
 + add detach code (channel detach, free queue)
 
@@ -31,6 +25,8 @@ not non-FIS
 
 Other random notes (do outside the NCQ branch):
 -
+queue is allocated regardless if there are any drives, fix? 
+
 change wd(4) to use dksubr
 
 dump to unopened disk fails (e.g. dump do wd1b when wd1a not mounted), due

Index: src/sys/dev/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.20 src/sys/dev/ic/siisata.c:1.30.4.21
--- src/sys/dev/ic/siisata.c:1.30.4.20	Fri Jun 23 23:45:56 2017
+++ src/sys/dev/ic/siisata.c	Fri Jun 23 23:49:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $");
 
 #include 
 #include 



CVS commit: [jdolecek-ncq] src/sys/dev/ic

2017-06-23 Thread Jaromir Dolecek
Module Name:src
Committed By:   jdolecek
Date:   Fri Jun 23 23:45:56 UTC 2017

Modified Files:
src/sys/dev/ic [jdolecek-ncq]: siisata.c

Log Message:
ata/TODO.ncq


To generate a diff of this commit:
cvs rdiff -u -r1.30.4.19 -r1.30.4.20 src/sys/dev/ic/siisata.c

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/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.19 src/sys/dev/ic/siisata.c:1.30.4.20
--- src/sys/dev/ic/siisata.c:1.30.4.19	Wed Jun 21 19:38:43 2017
+++ src/sys/dev/ic/siisata.c	Fri Jun 23 23:45:56 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.19 2017/06/21 19:38:43 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.19 2017/06/21 19:38:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $");
 
 #include 
 #include 
@@ -590,6 +590,7 @@ siisata_reset_drive(struct ata_drive_dat
 	 */
 	xfer = ata_get_xfer_ext(chp, false, 0);
 	if (xfer == NULL) {
+		printf("%s: no xfer\n", __func__);
 		siisata_reset_channel(chp, flags);
 		return;
 	}
@@ -1151,7 +1152,7 @@ siisata_bio_start(struct ata_channel *ch
 		if (ata_bio->flags & ATA_ITSDONE)
 			break;
 		siisata_intr_port(schp);
-		DELAY(1000);
+		DELAY(100);
 	}
 
 	siisata_enable_port_interrupt(chp);
@@ -1245,8 +1246,6 @@ siisata_bio_complete(struct ata_channel 
 			ata_bio->bcount = 0;
 	}
 	SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS);
-	if (ata_bio->flags & ATA_POLL)
-		return 1;
 	(*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer);
 	atastart(chp);
 	return 0;



  1   2   >