On Thu, Jun 10, 2021 at 12:02:19PM +0200, Michael van Elst wrote:

> If you don't like the fake errno, the function needs to return
> two values, the error value and a boolean to finish the
> unqueued request. Cleaner, but more changes.

E.g. (not even compile-tested):

Index: st.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st.c,v
retrieving revision 1.240
diff -p -u -r1.240 st.c
--- st.c        27 Dec 2019 09:41:51 -0000      1.240
+++ st.c        10 Jun 2021 10:11:47 -0000
@@ -343,7 +343,7 @@ static int  st_mount_tape(dev_t, int);
 static void    st_unmount(struct st_softc *, boolean);
 static int     st_decide_mode(struct st_softc *, boolean);
 static void    ststart(struct scsipi_periph *);
-static int     ststart1(struct scsipi_periph *, struct buf *);
+static int     ststart1(struct scsipi_periph *, struct buf *, int *);
 static void    strestart(void *);
 static void    stdone(struct scsipi_xfer *, int);
 static int     st_read(struct st_softc *, char *, int, int);
@@ -1183,13 +1183,13 @@ abort:
  * ststart() is called with channel lock held
  */
 static int
-ststart1(struct scsipi_periph *periph, struct buf *bp)
+ststart1(struct scsipi_periph *periph, struct buf *bp, int *errnop)
 {
        struct st_softc *st = device_private(periph->periph_dev);
         struct scsipi_channel *chan = periph->periph_channel;
        struct scsi_rw_tape cmd;
        struct scsipi_xfer *xs;
-       int flags, error;
+       int flags, error, complete = 1;
 
        SC_DEBUG(periph, SCSIPI_DB2, ("ststart1 "));
 
@@ -1299,11 +1299,14 @@ ststart1(struct scsipi_periph *periph, s
        error = scsipi_execute_xs(xs);
        /* with a scsipi_xfer preallocated, scsipi_command can't fail */
        KASSERT(error == 0);
+       if (error == 0)
+               complete = 0;
 
 out:
        mutex_exit(chan_mtx(chan));
 
-       return error;
+       *errnop = error;
+       return complete;
 }
 
 static void
@@ -1312,7 +1315,7 @@ ststart(struct scsipi_periph *periph)
        struct st_softc *st = device_private(periph->periph_dev);
         struct scsipi_channel *chan = periph->periph_channel;
        struct buf *bp;
-       int error;
+       int error, complete;
 
        SC_DEBUG(periph, SCSIPI_DB2, ("ststart "));
 
@@ -1325,19 +1328,20 @@ ststart(struct scsipi_periph *periph)
                iostat_busy(st->stats);
                mutex_exit(&st->sc_iolock);
 
-               error = ststart1(periph, bp);
+               complete = ststart1(periph, bp, &error);
 
                mutex_enter(&st->sc_iolock);
-               if (error != 0)
+               if (complete) {
                        iostat_unbusy(st->stats, 0,
                                      ((bp->b_flags & B_READ) == B_READ));
-               if (error == EAGAIN) {
-                       bufq_put(st->buf_defer, bp);
-                       break;
+                       if (error == EAGAIN) {
+                               bufq_put(st->buf_defer, bp);
+                               break;
+                       }
                }
                mutex_exit(&st->sc_iolock);
 
-               if (error != 0) {
+               if (complete) {
                        bp->b_error = error;
                        bp->b_resid = bp->b_bcount;
                        biodone(bp);


-- 
                                Michael van Elst
Internet: mlel...@serpens.de
                                "A potential Snark may lurk in every tree."

Reply via email to