Module Name: src Committed By: nat Date: Mon Oct 28 14:36:43 UTC 2024
Modified Files: src/sys/dev/ic: ncr5380sbc.c src/sys/dev/scsipi: scsipi_base.c scsipiconf.h Log Message: Introduce scsipi_done_once. This allows for transfers to be sucessfully aborted on the ncr5380sbc(4). This may be usefull in future for other scsi controllers. Callers of scsipi_done are not affected by this change. Part of kern/58452. As posted to tech-kern: https://mail-index.netbsd.org/tech-kern/2024/08/02/msg029652.html Ok thorpej@. To generate a diff of this commit: cvs rdiff -u -r1.71 -r1.72 src/sys/dev/ic/ncr5380sbc.c cvs rdiff -u -r1.190 -r1.191 src/sys/dev/scsipi/scsipi_base.c cvs rdiff -u -r1.131 -r1.132 src/sys/dev/scsipi/scsipiconf.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/ncr5380sbc.c diff -u src/sys/dev/ic/ncr5380sbc.c:1.71 src/sys/dev/ic/ncr5380sbc.c:1.72 --- src/sys/dev/ic/ncr5380sbc.c:1.71 Mon Oct 28 14:32:04 2024 +++ src/sys/dev/ic/ncr5380sbc.c Mon Oct 28 14:36:43 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ncr5380sbc.c,v 1.71 2024/10/28 14:32:04 nat Exp $ */ +/* $NetBSD: ncr5380sbc.c,v 1.72 2024/10/28 14:36:43 nat Exp $ */ /* * Copyright (c) 1995 David Jones, Gordon W. Ross @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ncr5380sbc.c,v 1.71 2024/10/28 14:32:04 nat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ncr5380sbc.c,v 1.72 2024/10/28 14:36:43 nat Exp $"); #include "opt_ddb.h" @@ -808,10 +808,13 @@ finish: sc->sc_ncmds--; /* Tell common SCSI code it is done. */ - scsipi_done(xs); + scsipi_done_once(xs); sc->sc_state = NCR_IDLE; /* Now ncr5380_sched() may be called again. */ + + /* Check the queue. */ + scsipi_channel_thaw(&sc->sc_channel, 0); } Index: src/sys/dev/scsipi/scsipi_base.c diff -u src/sys/dev/scsipi/scsipi_base.c:1.190 src/sys/dev/scsipi/scsipi_base.c:1.191 --- src/sys/dev/scsipi/scsipi_base.c:1.190 Fri Jun 14 18:44:18 2024 +++ src/sys/dev/scsipi/scsipi_base.c Mon Oct 28 14:36:43 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: scsipi_base.c,v 1.190 2024/06/14 18:44:18 kardel Exp $ */ +/* $NetBSD: scsipi_base.c,v 1.191 2024/10/28 14:36:43 nat Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.190 2024/06/14 18:44:18 kardel Exp $"); +__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.191 2024/10/28 14:36:43 nat Exp $"); #ifdef _KERNEL_OPT #include "opt_scsi.h" @@ -96,6 +96,8 @@ SDT_PROBE_DEFINE1(scsi, base, xfer, rest SDT_PROBE_DEFINE1(scsi, base, xfer, free, "struct scsipi_xfer *"/*xs*/); static int scsipi_complete(struct scsipi_xfer *); +static struct scsipi_channel* + scsipi_done_internal(struct scsipi_xfer *, bool); static void scsipi_request_sense(struct scsipi_xfer *); static int scsipi_enqueue(struct scsipi_xfer *); static void scsipi_run_queue(struct scsipi_channel *chan); @@ -1597,6 +1599,28 @@ scsipi_free_opcodeinfo(struct scsipi_per void scsipi_done(struct scsipi_xfer *xs) { + struct scsipi_channel *chan; + /* + * If there are more xfers on the channel's queue, attempt to + * run them. + */ + if ((chan = scsipi_done_internal(xs, true)) != NULL) + scsipi_run_queue(chan); +} + +/* + * Just like scsipi_done(), but no recursion. Useful if aborting the current + * transfer. + */ +void +scsipi_done_once(struct scsipi_xfer *xs) +{ + (void)scsipi_done_internal(xs, false); +} + +static struct scsipi_channel* +scsipi_done_internal(struct scsipi_xfer *xs, bool more) +{ struct scsipi_periph *periph = xs->xs_periph; struct scsipi_channel *chan = periph->periph_channel; int freezecnt; @@ -1685,7 +1709,7 @@ scsipi_done(struct scsipi_xfer *xs) */ if (xs->xs_control & XS_CTL_POLL) { mutex_exit(chan_mtx(chan)); - return; + return NULL; } cv_broadcast(xs_cv(xs)); mutex_exit(chan_mtx(chan)); @@ -1697,7 +1721,7 @@ scsipi_done(struct scsipi_xfer *xs) * without error; no use in taking a context switch * if we can handle it in interrupt context. */ - if (xs->error == XS_NOERROR) { + if (xs->error == XS_NOERROR && more == true) { mutex_exit(chan_mtx(chan)); (void) scsipi_complete(xs); goto out; @@ -1712,11 +1736,7 @@ scsipi_done(struct scsipi_xfer *xs) mutex_exit(chan_mtx(chan)); out: - /* - * If there are more xfers on the channel's queue, attempt to - * run them. - */ - scsipi_run_queue(chan); + return chan; } /* Index: src/sys/dev/scsipi/scsipiconf.h diff -u src/sys/dev/scsipi/scsipiconf.h:1.131 src/sys/dev/scsipi/scsipiconf.h:1.132 --- src/sys/dev/scsipi/scsipiconf.h:1.131 Sat Jun 22 10:07:46 2024 +++ src/sys/dev/scsipi/scsipiconf.h Mon Oct 28 14:36:43 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: scsipiconf.h,v 1.131 2024/06/22 10:07:46 palle Exp $ */ +/* $NetBSD: scsipiconf.h,v 1.132 2024/10/28 14:36:43 nat Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2004 The NetBSD Foundation, Inc. @@ -702,6 +702,7 @@ int scsipi_mode_sense_big(struct scsipi_ struct scsi_mode_parameter_header_10 *, int, int, int, int); int scsipi_start(struct scsipi_periph *, int, int); void scsipi_done(struct scsipi_xfer *); +void scsipi_done_once(struct scsipi_xfer *); void scsipi_user_done(struct scsipi_xfer *); int scsipi_interpret_sense(struct scsipi_xfer *); void scsipi_wait_drain(struct scsipi_periph *);