? ChangeLog
Index: wd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/wd.c,v
retrieving revision 1.443
diff -p -u -r1.443 wd.c
--- wd.c        24 Oct 2018 19:46:44 -0000      1.443
+++ wd.c        10 Mar 2019 17:42:01 -0000
@@ -321,6 +321,7 @@ wdattach(device_t parent, device_t self,
       SLIST_INIT(&wd->sc_bslist);
#endif
       wd->atabus = adev->adev_bustype;
+       wd->inflight = 0;
       wd->drvp = adev->adev_drv_data;

       wd->drvp->drv_openings = 1;
@@ -724,6 +730,7 @@ wdstart1(struct wd_softc *wd, struct buf
               xfer->c_bio.flags |= ATA_FUA;
       }

+       wd->inflight++;
       switch (wd->atabus->ata_bio(wd->drvp, xfer)) {
       case ATACMD_TRY_AGAIN:
               panic("wdstart1: try again");
@@ -744,10 +751,25 @@ wd_diskstart(device_t dev, struct buf *b
       struct dk_softc *dksc = &wd->sc_dksc;
#endif
       struct ata_xfer *xfer;
+       struct ata_channel *chp;
+       unsigned openings;

       mutex_enter(&wd->sc_lock);

-       xfer = ata_get_xfer(wd->drvp->chnl_softc, false);
+       chp = wd->drvp->chnl_softc;
+
+       ata_channel_lock(chp);
+       openings = ata_queue_openings(chp);
+       ata_channel_unlock(chp);
+
+       openings = uimin(openings, wd->drvp->drv_openings);
+
+       if (wd->inflight >= openings) {
+               mutex_exit(&wd->sc_lock);
+               return EAGAIN;
+       }
+
+       xfer = ata_get_xfer(chp, false);
       if (xfer == NULL) {
               ATADEBUG_PRINT(("wd_diskstart %s no xfer\n",
                   dksc->sc_xname), DEBUG_XFERS);
@@ -947,7 +969,9 @@ noerror:    if ((xfer->c_bio.flags & ATA_CO

       ata_free_xfer(wd->drvp->chnl_softc, xfer);

+       wd->inflight--;
       dk_done(dksc, bp);
+       dk_start(dksc, NULL);
}

static void
Index: wdvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/wdvar.h,v
retrieving revision 1.47
diff -p -u -r1.47 wdvar.h
--- wdvar.h     22 Oct 2018 20:13:47 -0000      1.47
+++ wdvar.h     10 Mar 2019 17:42:01 -0000
@@ -86,6 +86,8 @@ struct wd_softc {
       int drv_chaos_freq;             /* frequency of simulated bio errors */
       int drv_chaos_cnt;              /* count of processed bio read xfers */
#endif
+       unsigned inflight;
};

#endif /* _DEV_ATA_WDVAR_H_ */