NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/58452 (NCR5380 SCSI fixes for aborting transfers. BlueSCSI(v2))
Attached is the patch mentioned in the report.
diff -r 30e85f50c073 sys/dev/ic/ncr5380sbc.c
--- a/sys/dev/ic/ncr5380sbc.c Mon Apr 22 21:02:18 2024 +0000
+++ b/sys/dev/ic/ncr5380sbc.c Sat Apr 27 02:19:31 2024 +1000
@@ -393,6 +393,7 @@
static void
ncr5380_reset_scsibus(struct ncr5380_softc *sc)
{
+ struct sci_req *sr;
NCR_TRACE("reset_scsibus, cur=0x%x\n",
(long) sc->sc_current);
@@ -409,6 +410,9 @@
delay(100000);
/* XXX - Need to cancel disconnected requests. */
+ sr = sc->sc_current;
+ if (sr)
+ ncr5380_abort(sc);
}
@@ -617,9 +621,11 @@
/* Terminate any current command. */
sr = sc->sc_current;
if (sr) {
+#ifdef NCR5380_DEBUG
printf("%s: polled request aborting %d/%d\n",
device_xname(sc->sc_dev),
sr->sr_target, sr->sr_lun);
+#endif
ncr5380_abort(sc);
}
if (sc->sc_state != NCR_IDLE) {
@@ -802,7 +808,7 @@
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. */
diff -r 30e85f50c073 sys/dev/scsipi/scsipi_base.c
--- a/sys/dev/scsipi/scsipi_base.c Mon Apr 22 21:02:18 2024 +0000
+++ b/sys/dev/scsipi/scsipi_base.c Sat Apr 27 02:19:31 2024 +1000
@@ -96,6 +96,8 @@
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);
@@ -1056,6 +1058,13 @@
case SKEY_VOLUME_OVERFLOW:
error = ENOSPC;
break;
+ case SKEY_MEDIUM_ERROR:
+ if (xs->xs_retries != 0) {
+ xs->xs_retries--;
+ error = ERESTART;
+ } else
+ error = EIO;
+ break;
default:
error = EIO;
break;
@@ -1584,6 +1593,28 @@
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;
@@ -1672,7 +1703,7 @@
*/
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));
@@ -1684,7 +1715,7 @@
* 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;
@@ -1699,11 +1730,7 @@
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;
}
/*
diff -r 30e85f50c073 sys/dev/scsipi/scsipiconf.h
--- a/sys/dev/scsipi/scsipiconf.h Mon Apr 22 21:02:18 2024 +0000
+++ b/sys/dev/scsipi/scsipiconf.h Sat Apr 27 02:19:31 2024 +1000
@@ -700,6 +700,7 @@
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 *);
Home |
Main Index |
Thread Index |
Old Index