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