Index: dev/pci/qle.c =================================================================== RCS file: /cvs/src/sys/dev/pci/qle.c,v retrieving revision 1.35 diff -u -p -r1.35 qle.c --- dev/pci/qle.c 14 Mar 2015 03:38:49 -0000 1.35 +++ dev/pci/qle.c 5 Jul 2015 01:02:56 -0000 @@ -72,7 +72,7 @@ int qledebug = QLE_D_PORT; #define QLE_MAX_TARGETS 2048 /* maximum number of segments allowed for in a single io */ -#define QLE_MAX_SEGS 16 +#define QLE_MAX_SEGS 32 enum qle_isp_gen { QLE_GEN_ISP24XX = 1, @@ -2572,11 +2572,6 @@ qle_put_cmd(struct qle_softc *sc, void * dmap->dm_segs[0].ds_len); } else { flags |= QLE_IOCB_CTRL_FLAG_EXT_SEG; - qle_sge(&req->req_data_seg, - QLE_DMA_DVA(sc->sc_segments) + - ccb->ccb_seg_offset, - (ccb->ccb_dmamap->dm_nsegs + 1) * - sizeof(struct qle_iocb_seg)); for (seg = 0; seg < dmap->dm_nsegs; seg++) { qle_sge(&ccb->ccb_segs[seg], @@ -2587,11 +2582,15 @@ qle_put_cmd(struct qle_softc *sc, void * bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_segments), ccb->ccb_seg_offset, - sizeof(*ccb->ccb_segs) * ccb->ccb_dmamap->dm_nsegs, + seg * sizeof(*ccb->ccb_segs), BUS_DMASYNC_PREWRITE); + + qle_sge(&req->req_data_seg, + QLE_DMA_DVA(sc->sc_segments) + ccb->ccb_seg_offset, + seg * sizeof(struct qle_iocb_seg)); } - htolem16(&req->req_data_seg_count, dmap->dm_nsegs); + htolem16(&req->req_data_seg_count, dmap->dm_nsegs); /* +1 ? */ htolem32(&req->req_data_len, xs->datalen); htolem16(&req->req_ctrl_flags, flags); } @@ -2887,7 +2886,7 @@ qle_alloc_ccbs(struct qle_softc *sc) ccb = &sc->sc_ccbs[i]; if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, - QLE_MAX_SEGS, MAXPHYS, 0, + QLE_MAX_SEGS - 1, MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap) != 0) { printf("%s: unable to create dma map\n", DEVNAME(sc)); Index: scsi/scsi_base.c =================================================================== RCS file: /cvs/src/sys/scsi/scsi_base.c,v retrieving revision 1.221 diff -u -p -r1.221 scsi_base.c --- scsi/scsi_base.c 7 Jun 2015 19:13:27 -0000 1.221 +++ scsi/scsi_base.c 5 Jul 2015 01:02:56 -0000 @@ -1299,15 +1299,44 @@ scsi_xs_exec(struct scsi_xfer *xs) void scsi_done(struct scsi_xfer *xs) { + struct scsi_link *link = xs->sc_link; + extern int ticks; + #ifdef SCSIDEBUG - if (xs->sc_link->flags & SDEV_DB1) { + if (xs->link->flags & SDEV_DB1) { if (xs->datalen && (xs->flags & SCSI_DATA_IN)) scsi_show_mem(xs->data, min(64, xs->datalen)); } #endif /* SCSIDEBUG */ - SET(xs->flags, ITSDONE); + + if (xs->error == XS_NOERROR) { + switch (xs->status) { + case SCSI_BUSY: + case SCSI_QUEUE_FULL: + xs->error = XS_BUSY; + break; + default: + break; + } + } + + /* XXX locking */ KERNEL_LOCK(); + if (xs->error == XS_BUSY) + link->adj_qfull++; + + if (ticks - link->adj_tick > hz / 4) { + if (link->adj_qfull > 8) { + if (link->openings > 1) + link->openings /= 2; + } else if (link->adj_qfull == 0) { + if (link->openings < link->hardopenings) + link->openings++; + } + link->adj_tick = ticks; + } + xs->done(xs); KERNEL_UNLOCK(); } Index: scsi/scsiconf.c =================================================================== RCS file: /cvs/src/sys/scsi/scsiconf.c,v retrieving revision 1.192 diff -u -p -r1.192 scsiconf.c --- scsi/scsiconf.c 7 Jun 2015 19:13:27 -0000 1.192 +++ scsi/scsiconf.c 5 Jul 2015 01:02:56 -0000 @@ -897,6 +897,8 @@ scsi_probedev(struct scsibus_softc *scsi SET(sc_link->flags, SDEV_OWN_IOPL); } + sc_link->hardopenings = sc_link->openings; + /* * Tell drivers that are paying attention to avoid sync/wide/tags until * INQUIRY data has been processed and the quirks information is Index: scsi/scsiconf.h =================================================================== RCS file: /cvs/src/sys/scsi/scsiconf.h,v retrieving revision 1.163 diff -u -p -r1.163 scsiconf.h --- scsi/scsiconf.h 7 Jun 2015 19:13:27 -0000 1.163 +++ scsi/scsiconf.h 5 Jul 2015 01:02:56 -0000 @@ -336,6 +336,10 @@ struct scsi_link { struct scsi_runq queue; u_int running; u_short pending; + u_short hardopenings; + + int adj_tick; + u_int adj_qfull; struct scsi_iopool *pool; }; Index: scsi/sd.c =================================================================== RCS file: /cvs/src/sys/scsi/sd.c,v retrieving revision 1.261 diff -u -p -r1.261 sd.c --- scsi/sd.c 7 Jun 2015 19:13:27 -0000 1.261 +++ scsi/sd.c 5 Jul 2015 01:02:56 -0000 @@ -736,11 +736,12 @@ sd_buf_done(struct scsi_xfer *xs) goto retry; case XS_BUSY: - if (xs->retries) { - if (scsi_delay(xs, 1) != ERESTART) - xs->retries = 0; - } - goto retry; + disk_unbusy(&sc->sc_dk, bp->b_bcount, + bp->b_flags & B_READ); + bufq_requeue(&sc->sc_bufq, bp); + scsi_xs_put(xs); + scsi_xsh_add(&sc->sc_xsh); + return; case XS_TIMEOUT: retry: