? 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_ */