Module Name:    src
Committed By:   jdolecek
Date:           Wed Oct  3 19:20:48 UTC 2018

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

Log Message:
change channel reset and drive reset for all ATA controllers to always
run via thread, and with channel lock held the whole time; the queue is
frozen while reset is pending

for this repurpose ata_reset_channel() into new ata_thread_run()

also adjust some device printfs to not leak xfer pointer, and avoid
aprint_* for non-autoconf messages


To generate a diff of this commit:
cvs rdiff -u -r1.4.2.9 -r1.4.2.10 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.141.6.10 -r1.141.6.11 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.99.2.7 -r1.99.2.8 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.441.2.6 -r1.441.2.7 src/sys/dev/ata/wd.c
cvs rdiff -u -r1.62.2.5 -r1.62.2.6 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.41.2.4 -r1.41.2.5 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.35.6.5 -r1.35.6.6 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.288.6.2 -r1.288.6.3 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.4.2.9 src/sys/dev/ata/TODO.ncq:1.4.2.10
--- src/sys/dev/ata/TODO.ncq:1.4.2.9	Mon Sep 24 19:48:02 2018
+++ src/sys/dev/ata/TODO.ncq	Wed Oct  3 19:20:48 2018
@@ -2,8 +2,6 @@ jdolecek-ncqfixes goals:
 - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY
   ends up being handled as NOERROR, triggering KASSERT() in wd(4)
 - remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c)
-- revert rev 1.431 of wd.c (AT_POOL removal) - ensure still works
-  for the reset-via-thread case
 
 Bugs
 ----

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.141.6.10 src/sys/dev/ata/ata.c:1.141.6.11
--- src/sys/dev/ata/ata.c:1.141.6.10	Mon Sep 24 19:48:02 2018
+++ src/sys/dev/ata/ata.c	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.141.6.10 2018/09/24 19:48:02 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.141.6.11 2018/10/03 19:20:48 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.10 2018/09/24 19:48:02 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.11 2018/10/03 19:20:48 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -440,7 +440,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, rv, s;
+	int i, rv;
 
 	ata_channel_lock(chp);
 	chp->ch_flags |= ATACH_TH_RUN;
@@ -462,7 +462,8 @@ atabus_thread(void *arg)
 
 	ata_channel_lock(chp);
 	for (;;) {
-		if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 &&
+		if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_TH_DRIVE_RESET
+		    | ATACH_SHUTDOWN)) == 0 &&
 		    (chq->queue_active == 0 || chq->queue_freeze == 0)) {
 			chp->ch_flags &= ~ATACH_TH_RUN;
 			cv_wait(&chp->ch_thr_idle, &chp->ch_lock);
@@ -478,12 +479,24 @@ atabus_thread(void *arg)
 			ata_channel_lock(chp);
 		}
 		if (chp->ch_flags & ATACH_TH_RESET) {
-			/* ata_reset_channel() will unfreeze the channel */
-			ata_channel_unlock(chp);
-			s = splbio();
-			ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags);
-			splx(s);
-			ata_channel_lock(chp);
+			/* this will unfreeze the channel */
+			ata_thread_run(chp, AT_WAIT | chp->ch_reset_flags,
+			    ATACH_TH_RESET, ATACH_NODRIVE);
+		} else if (chp->ch_flags & ATACH_TH_DRIVE_RESET) {
+			for (i = 0; i < chp->ch_ndrives; i++) {
+				struct ata_drive_datas *drvp;
+				int drv_reset_flags;
+
+				drvp = &chp->ch_drive[i];
+				drv_reset_flags = drvp->drive_reset_flags;
+
+				if (drvp->drive_flags & ATACH_TH_DRIVE_RESET) {
+					ata_thread_run(chp,
+					    AT_WAIT | drv_reset_flags,
+					    ATACH_TH_DRIVE_RESET, i);
+				}
+			}
+			chp->ch_flags &= ~ATACH_TH_DRIVE_RESET;
 		} else if (chq->queue_active > 0 && chq->queue_freeze == 1) {
 			/*
 			 * Caller has bumped queue_freeze, decrease it. This
@@ -511,6 +524,11 @@ atabus_thread(void *arg)
 			}
 		} else if (chq->queue_freeze > 1)
 			panic("%s: queue_freeze", __func__);
+
+		/* Try to run down the queue once after each event is handled */
+		ata_channel_unlock(chp);
+		atastart(chp);
+		ata_channel_lock(chp);
 	}
 	chp->ch_thread = NULL;
 	cv_signal(&chp->ch_thr_idle);
@@ -1471,7 +1489,8 @@ ata_timo_xfer_check(struct ata_xfer *xfe
 			ata_channel_unlock(chp);
 
 	    		device_printf(drvp->drv_softc,
-			    "xfer %p freed while invoking timeout\n", xfer); 
+			    "xfer %"PRIxPTR" freed while invoking timeout\n",
+			    (intptr_t)xfer & PAGE_MASK); 
 
 			ata_free_xfer(chp, xfer);
 			return true;
@@ -1481,7 +1500,8 @@ ata_timo_xfer_check(struct ata_xfer *xfe
 		ata_channel_unlock(chp);
 
 	    	device_printf(drvp->drv_softc,
-		    "xfer %p deactivated while invoking timeout\n", xfer); 
+		    "xfer %"PRIxPTR" deactivated while invoking timeout\n",
+		    (intptr_t)xfer & PAGE_MASK); 
 		return true;
 	}
 
@@ -1605,44 +1625,28 @@ ata_channel_thaw(struct ata_channel *chp
 }
 
 /*
- * ata_reset_channel:
+ * ata_thread_run:
  *
- *	Reset and ATA channel.
- *
- *	MUST BE CALLED AT splbio()!
+ *	Reset and ATA channel. Channel lock must be held.
  */
 void
-ata_reset_channel(struct ata_channel *chp, int flags)
+ata_thread_run(struct ata_channel *chp, int flags, int type, int drive)
 {
 	struct atac_softc *atac = chp->ch_atac;
-	int drive;
 	bool threset = false;
+	struct ata_drive_datas *drvp;
 
-#ifdef ATA_DEBUG
-	int spl1, spl2;
-
-	spl1 = splbio();
-	spl2 = splbio();
-	if (spl2 != spl1) {
-		printf("ata_reset_channel: not at splbio()\n");
-		panic("ata_reset_channel");
-	}
-	splx(spl2);
-	splx(spl1);
-#endif /* ATA_DEBUG */
-
-	ata_channel_lock(chp);
+	ata_channel_lock_owned(chp);
 
 	/*
 	 * If we can poll or wait it's OK, otherwise wake up the
 	 * kernel thread to do it for us.
 	 */
-	ATADEBUG_PRINT(("ata_reset_channel flags 0x%x ch_flags 0x%x\n",
-	    flags, chp->ch_flags), DEBUG_FUNCS | DEBUG_XFERS);
+	ATADEBUG_PRINT(("%s flags 0x%x ch_flags 0x%x\n",
+	    __func__, flags, chp->ch_flags), DEBUG_FUNCS | DEBUG_XFERS);
 	if ((flags & (AT_POLL | AT_WAIT)) == 0) {
-		if (chp->ch_flags & ATACH_TH_RESET) {
+		if (chp->ch_flags & type) {
 			/* No need to schedule a reset more than one time. */
-			ata_channel_unlock(chp);
 			return;
 		}
 
@@ -1651,10 +1655,24 @@ ata_reset_channel(struct ata_channel *ch
 		 * to a thread.
 		 */
 		ata_channel_freeze_locked(chp);
-		chp->ch_flags |= ATACH_TH_RESET;
-		chp->ch_reset_flags = flags & AT_RST_EMERG;
+		chp->ch_flags |= type;
+
+
+		switch (type) {
+		case ATACH_TH_RESET:
+			chp->ch_reset_flags = flags & AT_RST_EMERG;
+			break;
+		case ATACH_TH_DRIVE_RESET:
+			drvp = &chp->ch_drive[drive];
+			drvp->drive_flags |= ATACH_TH_DRIVE_RESET;
+			drvp->drive_reset_flags = flags;
+			break;
+		default:
+			panic("%s: unknown type: %x", __func__, type);
+			/* NOTREACHED */
+		}
+
 		cv_signal(&chp->ch_thr_idle);
-		ata_channel_unlock(chp);
 		return;
 	}
 
@@ -1666,19 +1684,31 @@ ata_reset_channel(struct ata_channel *ch
 	 * the flag now so that the thread won't try to execute it if
 	 * we happen to sleep, and thaw one more time after the reset.
 	 */
-	if (chp->ch_flags & ATACH_TH_RESET) {
-		chp->ch_flags &= ~ATACH_TH_RESET;
+	if (chp->ch_flags & type) {
+		chp->ch_flags &= ~type;
 		threset = true;
 	}
 
-	ata_channel_unlock(chp);
+	switch (type) {
+	case ATACH_TH_RESET:
+		(*atac->atac_bustype_ata->ata_reset_channel)(chp, flags);
 
-	(*atac->atac_bustype_ata->ata_reset_channel)(chp, flags);
+		KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL);
+		for (drive = 0; drive < chp->ch_ndrives; drive++)
+			chp->ch_drive[drive].state = 0;
+		break;
 
-	ata_channel_lock(chp);
-	KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL);
-	for (drive = 0; drive < chp->ch_ndrives; drive++)
-		chp->ch_drive[drive].state = 0;
+	case ATACH_TH_DRIVE_RESET:
+		KASSERT(drive <= chp->ch_ndrives);
+		drvp = &chp->ch_drive[drive];
+		(*atac->atac_bustype_ata->ata_reset_drive)(drvp, flags, NULL);
+		drvp->state = 0;
+		break;
+
+	default:
+		panic("%s: unknown type: %x", __func__, type);
+		/* NOTREACHED */
+	}
 
 	/*
 	 * Thaw one extra time to clear the freeze done when the reset has
@@ -1693,13 +1723,9 @@ ata_reset_channel(struct ata_channel *ch
 	/* Signal the thread in case there is an xfer to run */
 	cv_signal(&chp->ch_thr_idle);
 
-	ata_channel_unlock(chp);
-
 	if (flags & AT_RST_EMERG) {
 		/* make sure that we can use polled commands */
 		ata_queue_reset(chp->ch_queue);
-	} else {
-		atastart(chp);
 	}
 }
 
@@ -1846,7 +1872,7 @@ ata_downgrade_mode(struct ata_drive_data
 	(*atac->atac_set_modes)(chp);
 	ata_print_modes(chp);
 	/* reset the channel, which will schedule all drives for setup */
-	ata_reset_channel(chp, flags);
+	ata_thread_run(chp, flags, ATACH_TH_RESET, ATACH_NODRIVE);
 	return 1;
 }
 #endif	/* NATA_DMA */
@@ -2186,7 +2212,6 @@ atabusioctl(dev_t dev, u_long cmd, void 
 	struct ata_channel *chp = sc->sc_chan;
 	int min_drive, max_drive, drive;
 	int error;
-	int s;
 
 	/*
 	 * Enforce write permission for ioctls that change the
@@ -2203,9 +2228,10 @@ atabusioctl(dev_t dev, u_long cmd, void 
 
 	switch (cmd) {
 	case ATABUSIORESET:
-		s = splbio();
-		ata_reset_channel(sc->sc_chan, AT_WAIT | AT_POLL);
-		splx(s);
+		ata_channel_lock(chp);
+		ata_thread_run(sc->sc_chan, AT_WAIT | AT_POLL,
+		    ATACH_TH_RESET, ATACH_NODRIVE);
+		ata_channel_unlock(chp);
 		return 0;
 	case ATABUSIOSCAN:
 	{
@@ -2283,11 +2309,11 @@ atabus_resume(device_t dv, const pmf_qua
 	/* unfreeze the queue and reset drives */
 	ata_channel_thaw_locked(chp);
 
-	ata_channel_unlock(chp);
-
 	/* reset channel only if there are drives attached */
 	if (chp->ch_ndrives > 0)
-		ata_reset_channel(chp, AT_WAIT);
+		ata_thread_run(chp, AT_WAIT, ATACH_TH_RESET, ATACH_NODRIVE);
+
+	ata_channel_unlock(chp);
 
 out:
 	return true;
@@ -2336,6 +2362,7 @@ atabus_rescan(device_t self, const char 
 void
 ata_delay(struct ata_channel *chp, int ms, const char *msg, int flags)
 {
+	KASSERT(mutex_owned(&chp->ch_lock));
 
 	if ((flags & (AT_WAIT | AT_POLL)) == AT_POLL) {
 		/*
@@ -2346,7 +2373,6 @@ ata_delay(struct ata_channel *chp, int m
 	} else {
 		int pause = mstohz(ms);
 
-		KASSERT(mutex_owned(&chp->ch_lock));
 		kpause(msg, false, pause > 0 ? pause : 1, &chp->ch_lock);
 	}
 }

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.99.2.7 src/sys/dev/ata/atavar.h:1.99.2.8
--- src/sys/dev/ata/atavar.h:1.99.2.7	Sat Sep 22 17:50:09 2018
+++ src/sys/dev/ata/atavar.h	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.99.2.7 2018/09/22 17:50:09 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.99.2.8 2018/10/03 19:20:48 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -274,6 +274,8 @@ struct ata_drive_datas {
 #define ATA_DRIVE_WFUA		0x0100	/* drive supports WRITE DMA FUA EXT */
 #define ATA_DRIVE_NCQ		0x0200	/* drive supports NCQ feature set */
 #define ATA_DRIVE_NCQ_PRIO	0x0400	/* drive supports NCQ PRIO field */
+#define ATA_DRIVE_TH_RESET	0x0800	/* drive waits for thread drive reset */
+	int drive_reset_flags;	/* flags for drive reset via thread */
 
 	uint8_t drive_type;
 #define	ATA_DRIVET_NONE		0
@@ -415,6 +417,9 @@ struct ata_channel {
 #define ATACH_TH_RESCAN 0x400	/* rescan requested */
 #define ATACH_NCQ	0x800	/* channel executing NCQ commands */
 #define ATACH_DMA_BEFORE_CMD	0x1000	/* start DMA first */
+#define ATACH_TH_DRIVE_RESET	0x2000	/* thread asked for drive(s) reset */
+
+#define ATACH_NODRIVE	0xff	/* no drive selected for reset */
 
 	/* for the reset callback */
 	int ch_reset_flags;
@@ -543,7 +548,7 @@ void	ata_timeout(void *);
 bool	ata_timo_xfer_check(struct ata_xfer *);
 void	ata_kill_pending(struct ata_drive_datas *);
 void	ata_kill_active(struct ata_channel *, int, int);
-void	ata_reset_channel(struct ata_channel *, int);
+void	ata_thread_run(struct ata_channel *, int, int, int);
 void	ata_channel_freeze(struct ata_channel *);
 void	ata_channel_thaw(struct ata_channel *);
 void	ata_channel_lock(struct ata_channel *);

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.441.2.6 src/sys/dev/ata/wd.c:1.441.2.7
--- src/sys/dev/ata/wd.c:1.441.2.6	Sat Sep 22 17:50:09 2018
+++ src/sys/dev/ata/wd.c	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.441.2.6 2018/09/22 17:50:09 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.441.2.7 2018/10/03 19:20:48 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.6 2018/09/22 17:50:09 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.7 2018/10/03 19:20:48 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -661,8 +661,8 @@ wdstart1(struct wd_softc *wd, struct buf
 	 */
 	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(dksc->sc_dev, "%s: chaos xfer %p\n",
-		    __func__, xfer);
+		device_printf(dksc->sc_dev, "%s: chaos xfer %"PRIxPTR"\n",
+		    __func__, (intptr_t)xfer & PAGE_MASK);
 		xfer->c_bio.blkno = 7777777 + wd->sc_capacity;
 		xfer->c_flags |= C_CHAOS;
 	}
@@ -840,7 +840,10 @@ wddone(device_t self, struct ata_xfer *x
 retry:		/* Just reset and retry. Can we do more ? */
 		if ((xfer->c_flags & C_RECOVERED) == 0) {
 			int wflags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
-			(*wd->atabus->ata_reset_drive)(wd->drvp, wflags, NULL);
+			ata_channel_lock(wd->drvp->chnl_softc);
+			ata_thread_run(wd->drvp->chnl_softc, wflags,
+			    ATACH_TH_DRIVE_RESET, wd->drvp->drive);
+			ata_channel_unlock(wd->drvp->chnl_softc);
 		}
 retry2:
 		mutex_enter(&wd->sc_lock);
@@ -848,7 +851,8 @@ retry2:
 		diskerr(bp, "wd", errmsg, LOG_PRINTF,
 		    xfer->c_bio.blkdone, dksc->sc_dkdev.dk_label);
 		if (xfer->c_retries < WDIORETRIES)
-			printf(", xfer %p, retry %d", xfer,
+			printf(", xfer %"PRIxPTR", retry %d",
+			    (intptr_t)xfer & PAGE_MASK,
 			    xfer->c_retries + 1);
 		printf("\n");
 		if (do_perror)
@@ -911,8 +915,9 @@ out:
 		break;
 	case NOERROR:
 noerror:	if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0)
-			aprint_error_dev(dksc->sc_dev,
-			    "soft error (corrected) xfer %p\n", xfer);
+			device_printf(dksc->sc_dev,
+			    "soft error (corrected) xfer %"PRIxPTR"\n",
+			    (intptr_t)xfer & PAGE_MASK);
 #ifdef WD_CHAOS_MONKEY
 		KASSERT((xfer->c_flags & C_CHAOS) == 0);
 #endif

Index: src/sys/dev/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.62.2.5 src/sys/dev/ic/ahcisata_core.c:1.62.2.6
--- src/sys/dev/ic/ahcisata_core.c:1.62.2.5	Sat Sep 22 09:22:59 2018
+++ src/sys/dev/ic/ahcisata_core.c	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.62.2.5 2018/09/22 09:22:59 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.62.2.6 2018/10/03 19:20:48 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.5 2018/09/22 09:22:59 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.6 2018/10/03 19:20:48 jdolecek Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -683,7 +683,7 @@ ahci_reset_drive(struct ata_drive_datas 
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	uint8_t c_slot;
 
-	ata_channel_lock(chp);
+	ata_channel_lock_owned(chp);
 
 	/* get a slot for running the command on */
 	if (!ata_queue_alloc_slot(chp, &c_slot, ATA_MAX_OPENINGS)) {
@@ -696,13 +696,10 @@ ahci_reset_drive(struct ata_drive_datas 
 	AHCI_WRITE(sc, AHCI_GHC,
 	    AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
 	ahci_channel_stop(sc, chp, flags);
-	if (ahci_do_reset_drive(chp, drvp->drive, flags, sigp, c_slot) != 0)
-		ata_reset_channel(chp, flags);
+	ahci_do_reset_drive(chp, drvp->drive, flags, sigp, c_slot);
 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
 
 	ata_queue_free_slot(chp, c_slot);
-
-	ata_channel_unlock(chp);
 }
 
 /* return error code from ata_bio */

Index: src/sys/dev/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.41.2.4 src/sys/dev/ic/mvsata.c:1.41.2.5
--- src/sys/dev/ic/mvsata.c:1.41.2.4	Sat Sep 22 09:22:59 2018
+++ src/sys/dev/ic/mvsata.c	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.41.2.4 2018/09/22 09:22:59 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.41.2.5 2018/10/03 19:20:48 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.4 2018/09/22 09:22:59 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.5 2018/10/03 19:20:48 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -703,7 +703,7 @@ mvsata_reset_drive(struct ata_drive_data
 	uint32_t edma_c;
 	uint32_t sig;
 
-	ata_channel_lock(chp);
+	ata_channel_lock_owned(chp);
 
 	edma_c = MVSATA_EDMA_READ_4(mvport, EDMA_CMD);
 
@@ -726,10 +726,6 @@ mvsata_reset_drive(struct ata_drive_data
 		mvsata_edma_reset_qptr(mvport);
 		mvsata_edma_enable(mvport);
 	}
-
-	ata_channel_unlock(chp);
-
-	return;
 }
 #endif /* MVSATA_WITHOUTDMA */
 
@@ -743,7 +739,7 @@ mvsata_reset_channel(struct ata_channel 
 	DPRINTF(DEBUG_FUNCS, ("%s: mvsata_reset_channel: channel=%d\n",
 	    device_xname(MVSATA_DEV2(mvport)), chp->ch_channel));
 
-	ata_channel_lock(chp);
+	ata_channel_lock_owned(chp);
 
 	mvsata_hreset_port(mvport);
 	sstat = sata_reset_interface(chp, mvport->port_iot,
@@ -774,10 +770,6 @@ mvsata_reset_channel(struct ata_channel 
 	mvsata_edma_reset_qptr(mvport);
 	mvsata_edma_enable(mvport);
 #endif
-
-	ata_channel_unlock(chp);
-
-	return;
 }
 
 #ifndef MVSATA_WITHOUTDMA
@@ -3563,6 +3555,8 @@ mvsata_edma_disable(struct mvsata_port *
 	uint32_t idlestatus = EDMA_S_EDMAIDLE | EDMA_S_ECACHEEMPTY;
 	int t;
 
+	ata_channel_lock_owned(chp);
+
 	if (MVSATA_EDMA_READ_4(mvport, EDMA_CMD) & EDMA_CMD_EENEDMA) {
 
 		timeout = mstohz(timeout + hztoms(1) - 1);

Index: src/sys/dev/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.35.6.5 src/sys/dev/ic/siisata.c:1.35.6.6
--- src/sys/dev/ic/siisata.c:1.35.6.5	Sat Sep 22 09:22:59 2018
+++ src/sys/dev/ic/siisata.c	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.35.6.5 2018/09/22 09:22:59 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.35.6.6 2018/10/03 19:20:48 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.5 2018/09/22 09:22:59 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.6 2018/10/03 19:20:48 jdolecek Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -732,7 +732,7 @@ siisata_reset_drive(struct ata_drive_dat
 
 	siisata_reinit_port(chp, drvp->drive);
 
-	ata_channel_lock(chp);
+	ata_channel_lock_owned(chp);
 
 	/* get a slot for running the command on */
 	if (!ata_queue_alloc_slot(chp, &c_slot, ATA_MAX_OPENINGS)) {
@@ -783,8 +783,6 @@ siisata_reset_drive(struct ata_drive_dat
 
 	siisata_enable_port_interrupt(chp);
 
-	ata_channel_unlock(chp);
-
 	if (timed_out) {
 		/* timeout */
 		siisata_device_reset(chp);	/* XXX is this right? */
@@ -801,11 +799,7 @@ siisata_reset_drive(struct ata_drive_dat
 		}
 	}
 
-	ata_channel_lock(chp);
 	ata_queue_free_slot(chp, c_slot);
-	ata_channel_unlock(chp);
-
-	return;
 }
 
 void
@@ -817,6 +811,8 @@ siisata_reset_channel(struct ata_channel
 	SIISATA_DEBUG_PRINT(("%s: %s channel %d\n", SIISATANAME(sc), __func__,
 	    chp->ch_channel), DEBUG_FUNCS);
 
+	ata_channel_lock_owned(chp);
+
 	if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol,
 	    schp->sch_sstatus, flags) != SStatus_DET_DEV) {
 		aprint_error("%s port %d: reset failed\n",
@@ -1573,6 +1569,8 @@ siisata_device_reset(struct ata_channel 
 	struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 	int ps;
 
+	ata_channel_lock_owned(chp);
+
 	/*
 	 * This is always called after siisata_reinit_port(), so don't
 	 * need to deal with RESUME and clearing device error state.

Index: src/sys/dev/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.288.6.2 src/sys/dev/ic/wdc.c:1.288.6.3
--- src/sys/dev/ic/wdc.c:1.288.6.2	Mon Sep 17 18:36:14 2018
+++ src/sys/dev/ic/wdc.c	Wed Oct  3 19:20:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.288.6.2 2018/09/17 18:36:14 jdolecek Exp $ */
+/*	$NetBSD: wdc.c,v 1.288.6.3 2018/10/03 19:20:48 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.288.6.2 2018/09/17 18:36:14 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.288.6.3 2018/10/03 19:20:48 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -932,19 +932,24 @@ wdc_reset_drive(struct ata_drive_datas *
 {
 	struct ata_channel *chp = drvp->chnl_softc;
 
+	ata_channel_lock_owned(chp);
+
 	KASSERT(sigp == NULL);
 
 	ATADEBUG_PRINT(("wdc_reset_drive %s:%d for drive %d\n",
 	    device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
 	    drvp->drive), DEBUG_FUNCS);
 
-	ata_reset_channel(chp, flags);
+	ata_thread_run(chp, flags, ATACH_TH_RESET, ATACH_NODRIVE);
 }
 
 void
 wdc_reset_channel(struct ata_channel *chp, int flags)
 {
 	struct ata_xfer *xfer;
+
+	ata_channel_lock_owned(chp);
+
 #if NATA_DMA || NATA_PIOBM
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 #endif
@@ -955,9 +960,7 @@ wdc_reset_channel(struct ata_channel *ch
 	 * if the current command is on an ATAPI device, issue a
 	 * ATAPI_SOFT_RESET
 	 */
-	xfer = ata_queue_get_active_xfer(chp);
-
-	ata_channel_lock(chp);
+	xfer = ata_queue_get_active_xfer_locked(chp);
 
 	if (xfer && xfer->c_chp == chp && (xfer->c_flags & C_ATAPI)) {
 		wdccommandshort(chp, xfer->c_drive, ATAPI_SOFT_RESET);
@@ -984,9 +987,8 @@ wdc_reset_channel(struct ata_channel *ch
 	 */
 	if (xfer) {
 		if (xfer->c_chp != chp) {
-			ata_channel_unlock(chp);
-			ata_reset_channel(xfer->c_chp, flags);
-			ata_channel_lock(chp);
+			ata_thread_run(xfer->c_chp, flags, ATACH_TH_RESET,
+			    ATACH_NODRIVE);
 		} else {
 #if NATA_DMA || NATA_PIOBM
 			/*
@@ -1004,8 +1006,6 @@ wdc_reset_channel(struct ata_channel *ch
 	}
 
 	ata_kill_active(chp, KILL_RESET, flags);
-
-	ata_channel_unlock(chp);
 }
 
 static int

Reply via email to