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