Module Name:    src
Committed By:   rin
Date:           Tue Oct  5 08:01:05 UTC 2021

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

Log Message:
PR kern/56403

Fix kernel freeze for wdc(4) variants with ATAC_CAP_NOIRQ:

(1) Change ata_xfer_ops:c_poll from void to int function. When it returns
    ATAPOLL_AGAIN, let ata_xfer_start() iterate itself again.

(2) Let wdc_ata_bio_poll() return ATAPOLL_AGAIN until ATA_ITSDONE is
    achieved.

A similar change has been made for mvsata(4) (see mvsata_bio_poll()),
and no functional changes for other devices.

This is how the drivers worked before jdolecek-ncq branch was merged.

Note that this changes are less likely to cause infinite recursion:

(1) wdc_ata_bio_intr() called from wdc_ata_bio_poll() asserts ATA_ITSDONE
    in its error handling paths via wdc_ata_bio_done().

(2) Return value from c_start (= wdc_ata_bio_start()) is checked in
    ata_xfer_start().

Therefore, errors encountered in ata_xfer_ops:c_poll and c_start routines
terminate the recursion for wdc(4). The situation is similar for mvsata(4).

Still, there is a possibility where ata_xfer_start() takes long time to
finish a normal operation. This can result in a delayed response for lower
priority interrupts. But, I've never observed such a situation, even when
heavy thrashing takes place for swap partition in wd(4).

"Go ahead" by jdolecek@.


To generate a diff of this commit:
cvs rdiff -u -r1.163 -r1.164 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.119 -r1.120 src/sys/dev/ata/ata_wdc.c
cvs rdiff -u -r1.108 -r1.109 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.101 -r1.102 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.60 -r1.61 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.48 -r1.49 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.307 -r1.308 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.140 -r1.141 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.163 src/sys/dev/ata/ata.c:1.164
--- src/sys/dev/ata/ata.c:1.163	Sun Aug 29 23:49:32 2021
+++ src/sys/dev/ata/ata.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.163 2021/08/29 23:49:32 rin Exp $	*/
+/*	$NetBSD: ata.c,v 1.164 2021/10/05 08:01:05 rin 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.163 2021/08/29 23:49:32 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.164 2021/10/05 08:01:05 rin Exp $");
 
 #include "opt_ata.h"
 
@@ -1231,10 +1231,11 @@ int
 ata_xfer_start(struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = xfer->c_chp;
-	int rv;
+	int rv, status;
 
 	KASSERT(mutex_owned(&chp->ch_lock));
 
+again:
 	rv = xfer->ops->c_start(chp, xfer);
 	switch (rv) {
 	case ATASTART_STARTED:
@@ -1248,8 +1249,10 @@ ata_xfer_start(struct ata_xfer *xfer)
 		/* can happen even in thread context for some ATAPI devices */
 		ata_channel_unlock(chp);
 		KASSERT(xfer->ops != NULL && xfer->ops->c_poll != NULL);
-		xfer->ops->c_poll(chp, xfer);
+		status = xfer->ops->c_poll(chp, xfer);
 		ata_channel_lock(chp);
+		if (status == ATAPOLL_AGAIN)
+			goto again;
 		break;
 	case ATASTART_ABORT:
 		ata_channel_unlock(chp);

Index: src/sys/dev/ata/ata_wdc.c
diff -u src/sys/dev/ata/ata_wdc.c:1.119 src/sys/dev/ata/ata_wdc.c:1.120
--- src/sys/dev/ata/ata_wdc.c:1.119	Fri Dec 25 08:55:40 2020
+++ src/sys/dev/ata/ata_wdc.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_wdc.c,v 1.119 2020/12/25 08:55:40 skrll Exp $	*/
+/*	$NetBSD: ata_wdc.c,v 1.120 2021/10/05 08:01:05 rin Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.119 2020/12/25 08:55:40 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.120 2021/10/05 08:01:05 rin Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -105,7 +105,7 @@ extern int wdcdebug_wd_mask; /* inited i
 static void	wdc_ata_bio(struct ata_drive_datas*, struct ata_xfer *);
 static int	wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *);
 static int	_wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *);
-static void	wdc_ata_bio_poll(struct ata_channel *,struct ata_xfer *);
+static int	wdc_ata_bio_poll(struct ata_channel *,struct ata_xfer *);
 static int	wdc_ata_bio_intr(struct ata_channel *, struct ata_xfer *,
 				 int);
 static void	wdc_ata_bio_kill_xfer(struct ata_channel *,
@@ -609,7 +609,7 @@ timeout:
 	return ATASTART_ABORT;
 }
 
-static void
+static int
 wdc_ata_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	/* Wait for at last 400ns for status bit to be valid */
@@ -621,6 +621,7 @@ wdc_ata_bio_poll(struct ata_channel *chp
 	}
 #endif
 	wdc_ata_bio_intr(chp, xfer, 0);
+	return (xfer->c_bio.flags & ATA_ITSDONE) ? ATAPOLL_DONE : ATAPOLL_AGAIN;
 }
 
 static int
@@ -773,7 +774,10 @@ end:
 			callout_stop(&chp->c_timo_callout);
 			ata_xfer_start(xfer);
 		} else {
-			/* Let _wdc_ata_bio_start do the loop */
+			/*
+			 * Let ata_xfer_start() do the loop;
+			 * see wdc_ata_bio_poll().
+			 */
 		}
 		ata_channel_unlock(chp);
 		return 1;

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.108 src/sys/dev/ata/atavar.h:1.109
--- src/sys/dev/ata/atavar.h:1.108	Mon May 25 18:29:25 2020
+++ src/sys/dev/ata/atavar.h	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.108 2020/05/25 18:29:25 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.109 2021/10/05 08:01:05 rin Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -178,7 +178,9 @@ struct ata_xfer_ops {
 #define ATASTART_TH		1	/* xfer needs to be run in thread */
 #define ATASTART_POLL		2	/* xfer needs to be polled */
 #define ATASTART_ABORT		3	/* error occurred, abort xfer */
-	void	(*c_poll)(struct ata_channel *, struct ata_xfer *);
+	int	(*c_poll)(struct ata_channel *, struct ata_xfer *);
+#define	ATAPOLL_DONE		0
+#define	ATAPOLL_AGAIN		1
 	void	(*c_abort)(struct ata_channel *, struct ata_xfer *);
 	int	(*c_intr)(struct ata_channel *, struct ata_xfer *, int);
 	void	(*c_kill_xfer)(struct ata_channel *, struct ata_xfer *, int);

Index: src/sys/dev/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.101 src/sys/dev/ic/ahcisata_core.c:1.102
--- src/sys/dev/ic/ahcisata_core.c:1.101	Fri Sep  3 01:23:33 2021
+++ src/sys/dev/ic/ahcisata_core.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.101 2021/09/03 01:23:33 mrg Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.102 2021/10/05 08:01:05 rin Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.101 2021/09/03 01:23:33 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.102 2021/10/05 08:01:05 rin Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -69,13 +69,13 @@ static void ahci_killpending(struct ata_
 
 static int  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_poll(struct ata_channel *, struct ata_xfer *);
+static int  ahci_cmd_poll(struct ata_channel *, struct ata_xfer *);
 static void ahci_cmd_abort(struct ata_channel *, struct ata_xfer *);
 static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *);
 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 int  ahci_bio_start(struct ata_channel *, struct ata_xfer *);
-static void ahci_bio_poll(struct ata_channel *, struct ata_xfer *);
+static int  ahci_bio_poll(struct ata_channel *, struct ata_xfer *);
 static void ahci_bio_abort(struct ata_channel *, struct ata_xfer *);
 static int  ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int);
 static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ;
@@ -93,7 +93,7 @@ static void ahci_atapi_minphys(struct bu
 static void ahci_atapi_scsipi_request(struct scsipi_channel *,
     scsipi_adapter_req_t, void *);
 static int  ahci_atapi_start(struct ata_channel *, struct ata_xfer *);
-static void ahci_atapi_poll(struct ata_channel *, struct ata_xfer *);
+static int  ahci_atapi_poll(struct ata_channel *, struct ata_xfer *);
 static void ahci_atapi_abort(struct ata_channel *, struct ata_xfer *);
 static int  ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int);
 static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
@@ -1208,7 +1208,7 @@ ahci_cmd_start(struct ata_channel *chp, 
 		return ATASTART_POLL;
 }
 
-static void
+static int
 ahci_cmd_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct ahci_softc *sc = AHCI_CH2SC(chp);
@@ -1245,6 +1245,8 @@ ahci_cmd_poll(struct ata_channel *chp, s
 	}
 	/* reenable interrupts */
 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
+
+	return ATAPOLL_DONE;
 }
 
 static void
@@ -1456,7 +1458,7 @@ ahci_bio_start(struct ata_channel *chp, 
 		return ATASTART_POLL;
 }
 
-static void
+static int
 ahci_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
@@ -1486,6 +1488,7 @@ ahci_bio_poll(struct ata_channel *chp, s
 	}
 	/* reenable interrupts */
 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
+	return ATAPOLL_DONE;
 }
 
 static void
@@ -1953,7 +1956,7 @@ ahci_atapi_start(struct ata_channel *chp
 		return ATASTART_POLL;
 }
 
-static void
+static int
 ahci_atapi_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
@@ -1983,6 +1986,7 @@ ahci_atapi_poll(struct ata_channel *chp,
 	}
 	/* reenable interrupts */
 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
+	return ATAPOLL_DONE;
 }
 
 static void

Index: src/sys/dev/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.60 src/sys/dev/ic/mvsata.c:1.61
--- src/sys/dev/ic/mvsata.c:1.60	Sat Aug  7 16:19:12 2021
+++ src/sys/dev/ic/mvsata.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.60 2021/08/07 16:19:12 thorpej Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.61 2021/10/05 08:01:05 rin 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.60 2021/08/07 16:19:12 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.61 2021/10/05 08:01:05 rin Exp $");
 
 #include "opt_mvsata.h"
 
@@ -143,14 +143,14 @@ static void mvsata_setup_channel(struct 
 #ifndef MVSATA_WITHOUTDMA
 static int mvsata_bio_start(struct ata_channel *, struct ata_xfer *);
 static int mvsata_bio_intr(struct ata_channel *, struct ata_xfer *, int);
-static void mvsata_bio_poll(struct ata_channel *, struct ata_xfer *);
+static int mvsata_bio_poll(struct ata_channel *, struct ata_xfer *);
 static void mvsata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 static void mvsata_bio_done(struct ata_channel *, struct ata_xfer *);
 static int mvsata_bio_ready(struct mvsata_port *, struct ata_bio *, int,
 			    int);
 static int mvsata_wdc_cmd_start(struct ata_channel *, struct ata_xfer *);
 static int mvsata_wdc_cmd_intr(struct ata_channel *, struct ata_xfer *, int);
-static void mvsata_wdc_cmd_poll(struct ata_channel *, struct ata_xfer *);
+static int mvsata_wdc_cmd_poll(struct ata_channel *, struct ata_xfer *);
 static void mvsata_wdc_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *,
 				     int);
 static void mvsata_wdc_cmd_done(struct ata_channel *, struct ata_xfer *);
@@ -158,7 +158,7 @@ static void mvsata_wdc_cmd_done_end(stru
 #if NATAPIBUS > 0
 static int mvsata_atapi_start(struct ata_channel *, struct ata_xfer *);
 static int mvsata_atapi_intr(struct ata_channel *, struct ata_xfer *, int);
-static void mvsata_atapi_poll(struct ata_channel *, struct ata_xfer *);
+static int mvsata_atapi_poll(struct ata_channel *, struct ata_xfer *);
 static void mvsata_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *,
 				   int);
 static void mvsata_atapi_reset(struct ata_channel *, struct ata_xfer *);
@@ -1245,7 +1245,7 @@ timeout:
 	return ATASTART_ABORT;
 }
 
-static void
+static int
 mvsata_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
@@ -1259,10 +1259,9 @@ mvsata_bio_poll(struct ata_channel *chp,
 		chp->ch_flags &= ~ATACH_DMA_WAIT;
 	}
 
-	if ((xfer->c_bio.flags & ATA_ITSDONE) == 0) {
-		KASSERT(xfer->c_flags & C_TIMEOU);
-		mvsata_bio_intr(chp, xfer, 0);
-	}
+	mvsata_bio_intr(chp, xfer, 0);
+
+	return (xfer->c_bio.flags & ATA_ITSDONE) ? ATAPOLL_DONE : ATAPOLL_AGAIN;
 }
 
 static int
@@ -1385,7 +1384,10 @@ end:
 			/* Start the next operation */
 			ata_xfer_start(xfer);
 		} else {
-			/* Let mvsata_bio_start do the loop */
+			/*
+			 * Let ata_xfer_start() do the loop;
+			 * see mvsata_bio_poll().
+			 */
 		}
 		ata_channel_unlock(chp);
 	} else { /* Done with this transfer */
@@ -1680,7 +1682,7 @@ mvsata_wdc_cmd_start(struct ata_channel 
 	return ATASTART_POLL;
 }
 
-static void
+static int
 mvsata_wdc_cmd_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	/*
@@ -1689,6 +1691,7 @@ mvsata_wdc_cmd_poll(struct ata_channel *
 	 */
 	delay(10);	/* 400ns delay */
 	mvsata_wdc_cmd_intr(chp, xfer, 0);
+	return ATAPOLL_DONE;
 }
 
 static int
@@ -2165,7 +2168,7 @@ error:
 	return ATASTART_ABORT;
 }
 
-static void
+static int
 mvsata_atapi_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	/*
@@ -2180,7 +2183,7 @@ mvsata_atapi_poll(struct ata_channel *ch
 	mvsata_atapi_intr(chp, xfer, 0);
 
 	if (!poll)
-		return;
+		return ATAPOLL_DONE;
 
 	if (chp->ch_flags & ATACH_DMA_WAIT) {
 		wdc_dmawait(chp, xfer, xfer->c_scsipi->timeout);
@@ -2192,6 +2195,8 @@ mvsata_atapi_poll(struct ata_channel *ch
 		DELAY(1);
 		mvsata_atapi_intr(chp, xfer, 0);
 	}
+
+	return ATAPOLL_DONE;
 }
 
 static int

Index: src/sys/dev/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.48 src/sys/dev/ic/siisata.c:1.49
--- src/sys/dev/ic/siisata.c:1.48	Sat Aug  7 16:19:12 2021
+++ src/sys/dev/ic/siisata.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.48 2021/08/07 16:19:12 thorpej Exp $ */
+/* $NetBSD: siisata.c,v 1.49 2021/10/05 08:01:05 rin Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.48 2021/08/07 16:19:12 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.49 2021/10/05 08:01:05 rin Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -149,7 +149,7 @@ void siisata_killpending(struct ata_driv
 
 int siisata_cmd_start(struct ata_channel *, struct ata_xfer *);
 int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
-void siisata_cmd_poll(struct ata_channel *, struct ata_xfer *);
+int siisata_cmd_poll(struct ata_channel *, struct ata_xfer *);
 void siisata_cmd_abort(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 *);
@@ -157,7 +157,7 @@ void siisata_cmd_kill_xfer(struct ata_ch
 
 int siisata_bio_start(struct ata_channel *, struct ata_xfer *);
 int siisata_bio_complete(struct ata_channel *, struct ata_xfer *, int);
-void siisata_bio_poll(struct ata_channel *, struct ata_xfer *);
+int siisata_bio_poll(struct ata_channel *, struct ata_xfer *);
 void siisata_bio_abort(struct ata_channel *, struct ata_xfer *);
 void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 void siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
@@ -175,7 +175,7 @@ void siisata_atapi_probe_device(struct a
 void siisata_atapi_minphys(struct buf *);
 int siisata_atapi_start(struct ata_channel *,struct ata_xfer *);
 int siisata_atapi_complete(struct ata_channel *, struct ata_xfer *, int);
-void siisata_atapi_poll(struct ata_channel *, struct ata_xfer *);
+int siisata_atapi_poll(struct ata_channel *, struct ata_xfer *);
 void siisata_atapi_abort(struct ata_channel *, struct ata_xfer *);
 void siisata_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
 void siisata_atapi_scsipi_request(struct scsipi_channel *,
@@ -1006,7 +1006,7 @@ siisata_cmd_start(struct ata_channel *ch
 		return ATASTART_POLL;
 }
 
-void
+int
 siisata_cmd_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
@@ -1031,6 +1031,8 @@ siisata_cmd_poll(struct ata_channel *chp
 	SIISATA_DEBUG_PRINT(("%s: %s: done\n",
 	    SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__),
 	    DEBUG_FUNCS);
+
+	return ATAPOLL_DONE;
 }
 
 void
@@ -1233,7 +1235,7 @@ siisata_bio_start(struct ata_channel *ch
 		return ATASTART_POLL;
 }
 
-void
+int
 siisata_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
@@ -1257,6 +1259,8 @@ siisata_bio_poll(struct ata_channel *chp
 	SIISATA_DEBUG_PRINT(("%s: %s: done\n",
 	    SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__),
 	    DEBUG_FUNCS);
+
+	return ATAPOLL_DONE;
 }
 
 void
@@ -1835,7 +1839,7 @@ siisata_atapi_start(struct ata_channel *
 		return ATASTART_POLL;
 }
 
-void
+int
 siisata_atapi_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
@@ -1858,6 +1862,8 @@ siisata_atapi_poll(struct ata_channel *c
 	SIISATA_DEBUG_PRINT(("%s: %s: done\n",
 	    SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__),
             DEBUG_FUNCS);
+
+	return ATAPOLL_DONE;
 }
 
 void

Index: src/sys/dev/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.307 src/sys/dev/ic/wdc.c:1.308
--- src/sys/dev/ic/wdc.c:1.307	Fri Sep 17 10:15:35 2021
+++ src/sys/dev/ic/wdc.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.307 2021/09/17 10:15:35 rin Exp $ */
+/*	$NetBSD: wdc.c,v 1.308 2021/10/05 08:01:05 rin 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.307 2021/09/17 10:15:35 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.308 2021/10/05 08:01:05 rin Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -149,7 +149,7 @@ static int	wdcreset(struct ata_channel *
 static void	__wdcerror(struct ata_channel *, const char *);
 static int	__wdcwait_reset(struct ata_channel *, int, int);
 static void	__wdccommand_done(struct ata_channel *, struct ata_xfer *);
-static void	__wdccommand_poll(struct ata_channel *, struct ata_xfer *);
+static int	__wdccommand_poll(struct ata_channel *, struct ata_xfer *);
 static void	__wdccommand_done_end(struct ata_channel *, struct ata_xfer *);
 static void	__wdccommand_kill_xfer(struct ata_channel *,
 			               struct ata_xfer *, int);
@@ -1487,10 +1487,11 @@ __wdccommand_start(struct ata_channel *c
 	return ATASTART_POLL;
 }
 
-static void
+static int
 __wdccommand_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	__wdccommand_intr(chp, xfer, 0);
+	return ATAPOLL_DONE;
 }
 
 static int

Index: src/sys/dev/scsipi/atapi_wdc.c
diff -u src/sys/dev/scsipi/atapi_wdc.c:1.140 src/sys/dev/scsipi/atapi_wdc.c:1.141
--- src/sys/dev/scsipi/atapi_wdc.c:1.140	Sat Aug  7 16:19:16 2021
+++ src/sys/dev/scsipi/atapi_wdc.c	Tue Oct  5 08:01:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: atapi_wdc.c,v 1.140 2021/08/07 16:19:16 thorpej Exp $	*/
+/*	$NetBSD: atapi_wdc.c,v 1.141 2021/10/05 08:01:05 rin Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.140 2021/08/07 16:19:16 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.141 2021/10/05 08:01:05 rin Exp $");
 
 #ifndef ATADEBUG
 #define ATADEBUG
@@ -90,7 +90,7 @@ static int	wdc_atapi_intr(struct ata_cha
 static void	wdc_atapi_kill_xfer(struct ata_channel *,
 				    struct ata_xfer *, int);
 static void	wdc_atapi_phase_complete(struct ata_xfer *, int);
-static void	wdc_atapi_poll(struct ata_channel *, struct ata_xfer *);
+static int	wdc_atapi_poll(struct ata_channel *, struct ata_xfer *);
 static void	wdc_atapi_done(struct ata_channel *, struct ata_xfer *);
 static void	wdc_atapi_reset(struct ata_channel *, struct ata_xfer *);
 static void	wdc_atapi_scsipi_request(struct scsipi_channel *,
@@ -696,7 +696,7 @@ error:
 	return ATASTART_ABORT;
 }
 
-static void
+static int
 wdc_atapi_poll(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	/*
@@ -711,7 +711,7 @@ wdc_atapi_poll(struct ata_channel *chp, 
 	wdc_atapi_intr(chp, xfer, 0);
 
 	if (!poll)
-		return;
+		return ATAPOLL_DONE;
 
 #if NATA_DMA
 	if (chp->ch_flags & ATACH_DMA_WAIT) {
@@ -724,6 +724,8 @@ wdc_atapi_poll(struct ata_channel *chp, 
 		DELAY(1);
 		wdc_atapi_intr(chp, xfer, 0);
 	}
+
+	return ATAPOLL_DONE;
 }
 
 static int

Reply via email to