Module Name: src Committed By: jdolecek Date: Tue Jun 20 20:58:23 UTC 2017
Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h satapmp_subr.c wd.c src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c wdc.c src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c src/sys/dev/usb [jdolecek-ncq]: umass_isdata.c Log Message: remove ata queue downsizing - every device, attached to the same channel, uses slots according to it's own limits wdc code changed to expect maximum one active xfer, and not check number of openings in the channel; this is to facilitate using wdc functions for e.g. handling of atapi commands for drivers which support both ATAPI and NCQ To generate a diff of this commit: cvs rdiff -u -r1.1.2.18 -r1.1.2.19 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.11 -r1.132.8.12 src/sys/dev/ata/ata.c cvs rdiff -u -r1.105.6.4 -r1.105.6.5 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.10 -r1.92.8.11 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.12.24.3 -r1.12.24.4 src/sys/dev/ata/satapmp_subr.c cvs rdiff -u -r1.428.2.18 -r1.428.2.19 src/sys/dev/ata/wd.c cvs rdiff -u -r1.57.6.14 -r1.57.6.15 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.35.6.12 -r1.35.6.13 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.283.2.6 -r1.283.2.7 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.123.4.6 -r1.123.4.7 src/sys/dev/scsipi/atapi_wdc.c cvs rdiff -u -r1.33.4.3 -r1.33.4.4 src/sys/dev/usb/umass_isdata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.18 src/sys/dev/ata/TODO.ncq:1.1.2.19 --- src/sys/dev/ata/TODO.ncq:1.1.2.18 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ata/TODO.ncq Tue Jun 20 20:58:22 2017 @@ -22,14 +22,6 @@ do proper NCQ error recovery (currently maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -atabus(4) queue depth can only shrink, causing NCQ to not be available if NCQ -drive rescaned after detach of non-NCQ drive -- careful with PMP, must be minimum of openings supported by drives - attached to the same channel -- the downsize can leak transfers with PMP if other device happens - to have active or pending transfers (e.g. when non-NCQ device is attached - while there is already NCQ device present) - add mechanics to re-check queue when xfer is finished - needed on PMP and for IDE disks, when one drive uses up all available xfers nothing ever restarts queue for the other drives Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.11 src/sys/dev/ata/ata.c:1.132.8.12 --- src/sys/dev/ata/ata.c:1.132.8.11 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ata/ata.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.11 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.12 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.11 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.12 2017/06/20 20:58:22 jdolecek Exp $"); #include "opt_ata.h" @@ -131,6 +131,7 @@ static void atabusconfig_thread(void *); static void ata_xfer_init(struct ata_xfer *, bool); static void ata_xfer_destroy(struct ata_xfer *); +static void ata_channel_idle(struct ata_channel *); /* * atabus_init: @@ -214,13 +215,14 @@ ata_queue_hwslot_to_xfer(struct ata_queu /* * This interface is supposed only to be used when there is exactly - * one outstanding command, and there is no information about the slot, + * one outstanding command, when there is no information about the slot, * which triggered the command. ata_queue_hwslot_to_xfer() interface - * is preferred in all standard cases. + * is preferred in all NCQ cases. */ struct ata_xfer * -ata_queue_active_xfer_peek(struct ata_queue *chq) +ata_queue_get_active_xfer(struct ata_queue *chq) { + KASSERT(chq->queue_active <= 1); return TAILQ_FIRST(&chq->active_xfers); } @@ -246,13 +248,8 @@ ata_queue_alloc(uint8_t openings) if (openings == 0) openings = 1; - /* - * While hw supports up to 32 tags, in practice we must never - * allow 32 active commands, since that would signal same as - * channel error. So just limit this to 31. - */ - if (openings > 31) - openings = 31; + if (openings > ATA_MAX_OPENINGS) + openings = ATA_MAX_OPENINGS; struct ata_queue *chq = malloc(offsetof(struct ata_queue, queue_xfers[openings]), M_DEVBUF, M_WAITOK | M_ZERO); @@ -268,17 +265,6 @@ ata_queue_alloc(uint8_t openings) return chq; } -static void -ata_queue_downsize(struct ata_queue *chq, uint8_t openings) -{ - KASSERT(chq->queue_active == 0); - KASSERT(TAILQ_FIRST(&chq->queue_xfer) == NULL); - KASSERT(openings < chq->queue_openings); - - chq->queue_openings = openings; - ata_queue_reset(chq); -} - void ata_queue_free(struct ata_queue *chq) { @@ -588,13 +574,13 @@ atabus_thread(void *arg) * ata_reset_channel() will freeze 2 times, so * unfreeze one time. Not a problem as we're at splbio */ - chq->queue_freeze--; + ata_channel_thaw(chp); ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags); } else if (chq->queue_active > 0 && chq->queue_freeze == 1) { /* * Caller has bumped queue_freeze, decrease it. */ - chq->queue_freeze--; + ata_channel_thaw(chp); u_int active __diagused = 0; TAILQ_FOREACH(xfer, &chq->active_xfers, c_activechain) { (*xfer->c_start)(xfer->c_chp, xfer); @@ -1020,14 +1006,14 @@ ata_dmaerr(struct ata_drive_datas *drvp, * freeze the queue and wait for the controller to be idle. Caller has to * unfreeze/restart the queue */ -void -ata_queue_idle(struct ata_queue *queue) +static void +ata_channel_idle(struct ata_channel *chp) { int s = splbio(); - queue->queue_freeze++; - while (queue->queue_active > 0) { - queue->queue_flags |= QF_IDLE_WAIT; - tsleep(&queue->queue_flags, PRIBIO, "qidl", 0); + ata_channel_freeze(chp); + while (chp->ch_queue->queue_active > 0) { + chp->ch_queue->queue_flags |= QF_IDLE_WAIT; + tsleep(&chp->ch_queue->queue_flags, PRIBIO, "qidl", 0); } splx(s); } @@ -1160,18 +1146,28 @@ atastart(struct ata_channel *chp) xfer->c_start(chp, xfer); } +/* + * Does it's own locking, does not require splbio(). + * wait - whether to block waiting for free xfer + * openings - limit of openings supported by device, <= 0 means tag not + * relevant, and any available xfer can be returned + */ struct ata_xfer * -ata_get_xfer(struct ata_channel *chp, bool wait) +ata_get_xfer_ext(struct ata_channel *chp, bool wait, int8_t openings) { struct ata_queue *chq = chp->ch_queue; struct ata_xfer *xfer = NULL; - uint32_t avail, slot; + uint32_t avail, slot, mask; int error; mutex_enter(&chp->ch_lock); retry: - avail = ffs32(chq->queue_xfers_avail); + mask = (openings > 0) + ? (__BIT(MIN(ATA_MAX_OPENINGS, openings)) - 1) + : chq->queue_xfers_avail; + + avail = ffs32(chq->queue_xfers_avail & mask); if (avail == 0) { if (wait) { chq->queue_flags |= QF_NEED_XFER; @@ -1356,6 +1352,18 @@ ata_kill_pending(struct ata_drive_datas splx(s); } +void +ata_channel_freeze(struct ata_channel *chp) +{ + chp->ch_queue->queue_freeze++; /* XXX MPSAFE */ +} + +void +ata_channel_thaw(struct ata_channel *chp) +{ + chp->ch_queue->queue_freeze--; /* XXX MPSAFE */ +} + /* * ata_reset_channel: * @@ -1382,7 +1390,7 @@ ata_reset_channel(struct ata_channel *ch splx(spl1); #endif /* ATA_DEBUG */ - chp->ch_queue->queue_freeze++; + ata_channel_freeze(chp); /* * If we can poll or wait it's OK, otherwise wake up the @@ -1393,7 +1401,7 @@ ata_reset_channel(struct ata_channel *ch if ((flags & (AT_POLL | AT_WAIT)) == 0) { if (chp->ch_flags & ATACH_TH_RESET) { /* No need to schedule a reset more than one time. */ - chp->ch_queue->queue_freeze--; + ata_channel_thaw(chp); return; } chp->ch_flags |= ATACH_TH_RESET; @@ -1410,7 +1418,7 @@ ata_reset_channel(struct ata_channel *ch chp->ch_flags &= ~ATACH_TH_RESET; if ((flags & AT_RST_EMERG) == 0) { - chp->ch_queue->queue_freeze--; + ata_channel_thaw(chp); atastart(chp); } else { /* make sure that we can use polled commands */ @@ -1831,8 +1839,6 @@ ata_probe_caps(struct ata_drive_datas *d aprint_verbose(" w/PRIO"); } } - if (drvp->drv_openings < chp->ch_queue->queue_openings) - ata_queue_downsize(chp->ch_queue, drvp->drv_openings); splx(s); if (printed) @@ -1976,7 +1982,7 @@ atabus_suspend(device_t dv, const pmf_qu struct atabus_softc *sc = device_private(dv); struct ata_channel *chp = sc->sc_chan; - ata_queue_idle(chp->ch_queue); + ata_channel_idle(chp); return true; } @@ -1999,7 +2005,7 @@ atabus_resume(device_t dv, const pmf_qua } KASSERT(chp->ch_queue->queue_freeze > 0); /* unfreeze the queue and reset drives */ - chp->ch_queue->queue_freeze--; + ata_channel_thaw(chp); /* reset channel only if there are drives attached */ if (chp->ch_ndrives > 0) Index: src/sys/dev/ata/ata_wdc.c diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.4 src/sys/dev/ata/ata_wdc.c:1.105.6.5 --- src/sys/dev/ata/ata_wdc.c:1.105.6.4 Fri Jun 16 20:40:49 2017 +++ src/sys/dev/ata/ata_wdc.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.105.6.4 2017/06/16 20:40:49 jdolecek Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.105.6.5 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.4 2017/06/16 20:40:49 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.5 2017/06/20 20:58:22 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -199,7 +199,7 @@ wdc_ata_bio_start(struct ata_channel *ch /* If it's not a polled command, we need the kernel thread */ if ((xfer->c_flags & C_POLL) == 0 && (chp->ch_flags & ATACH_TH_RUN) == 0) { - chp->ch_queue->queue_freeze++; + ata_channel_freeze(chp); wakeup(&chp->ch_thread); return; } Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.10 src/sys/dev/ata/atavar.h:1.92.8.11 --- src/sys/dev/ata/atavar.h:1.92.8.10 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ata/atavar.h Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.10 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.11 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -183,16 +183,23 @@ struct ata_xfer { #define KILL_GONE 1 /* device is gone */ #define KILL_RESET 2 /* xfer was reset */ +/* + * While hw supports up to 32 tags, in practice we must never + * allow 32 active commands, since that would signal same as + * channel error. So just limit this to 31. + */ +#define ATA_MAX_OPENINGS 31 + /* Per-channel queue of ata_xfers */ struct ata_queue { - TAILQ_HEAD(, ata_xfer) queue_xfer; /* queue of pending commands */ - int queue_freeze; /* freeze count for the queue */ int8_t queue_flags; /* flags for this queue */ #define QF_IDLE_WAIT 0x01 /* someone wants the controller idle */ #define QF_NEED_XFER 0x02 /* someone wants xfer */ int8_t queue_active; /* number of active transfers */ - int8_t queue_openings; /* max number of active transfers */ #ifdef ATABUS_PRIVATE + int8_t queue_openings; /* max number of active xfers */ + TAILQ_HEAD(, ata_xfer) queue_xfer; /* queue of pending commands */ + int queue_freeze; /* freeze count for the queue */ kcondvar_t queue_busy; /* c: waiting of xfer */ TAILQ_HEAD(, ata_xfer) active_xfers; /* active commands */ uint32_t active_xfers_used; /* mask of active commands */ @@ -477,10 +484,9 @@ int ata_set_mode(struct ata_drive_datas #define CMD_ERR 1 #define CMD_AGAIN 2 -struct ata_xfer *ata_get_xfer(struct ata_channel *, bool); +struct ata_xfer *ata_get_xfer_ext(struct ata_channel *, bool, int8_t); +#define ata_get_xfer(chp) ata_get_xfer_ext((chp), true, 0); void ata_free_xfer(struct ata_channel *, struct ata_xfer *); -#define ATAXF_CANSLEEP 0x00 -#define ATAXF_NOSLEEP 0x01 void ata_activate_xfer(struct ata_channel *, struct ata_xfer *); void ata_deactivate_xfer(struct ata_channel *, struct ata_xfer *); @@ -489,6 +495,8 @@ void ata_exec_xfer(struct ata_channel *, void ata_kill_pending(struct ata_drive_datas *); void ata_kill_active(struct ata_channel *, int, int); void ata_reset_channel(struct ata_channel *, int); +void ata_channel_freeze(struct ata_channel *); +void ata_channel_thaw(struct ata_channel *); int ata_addref(struct ata_channel *); void ata_delref(struct ata_channel *); @@ -502,14 +510,13 @@ void ata_probe_caps(struct ata_drive_dat #if NATA_DMA void ata_dmaerr(struct ata_drive_datas *, int); #endif -void ata_queue_idle(struct ata_queue *); struct ata_queue * ata_queue_alloc(uint8_t openings); void ata_queue_free(struct ata_queue *); struct ata_xfer * ata_queue_hwslot_to_xfer(struct ata_queue *, int); struct ata_xfer * - ata_queue_active_xfer_peek(struct ata_queue *); + ata_queue_get_active_xfer(struct ata_queue *); void ata_delay(int, const char *, int); Index: src/sys/dev/ata/satapmp_subr.c diff -u src/sys/dev/ata/satapmp_subr.c:1.12.24.3 src/sys/dev/ata/satapmp_subr.c:1.12.24.4 --- src/sys/dev/ata/satapmp_subr.c:1.12.24.3 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ata/satapmp_subr.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: satapmp_subr.c,v 1.12.24.3 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: satapmp_subr.c,v 1.12.24.4 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 2012 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.3 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.4 2017/06/20 20:58:22 jdolecek Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -61,7 +61,7 @@ satapmp_read_8(struct ata_channel *chp, drvp = &chp->ch_drive[PMP_PORT_CTL]; KASSERT(drvp->drive == PMP_PORT_CTL); - xfer = ata_get_xfer(chp, true); + xfer = ata_get_xfer(chp); if (xfer == NULL) return EINTR; @@ -133,7 +133,7 @@ satapmp_write_8(struct ata_channel *chp, drvp = &chp->ch_drive[PMP_PORT_CTL]; KASSERT(drvp->drive == PMP_PORT_CTL); - xfer = ata_get_xfer(chp, true); + xfer = ata_get_xfer(chp); if (xfer == NULL) return EINTR; Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.428.2.18 src/sys/dev/ata/wd.c:1.428.2.19 --- src/sys/dev/ata/wd.c:1.428.2.18 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ata/wd.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.18 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.19 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.18 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.19 2017/06/20 20:58:22 jdolecek Exp $"); #include "opt_ata.h" @@ -309,6 +309,7 @@ wdattach(device_t parent, device_t self, wd->atabus = adev->adev_bustype; wd->drvp = adev->adev_drv_data; + wd->drvp->drv_openings = 1; wd->drvp->drv_done = wddone; wd->drvp->drv_softc = wd->sc_dev; /* done in atabusconfig_thread() but too late */ @@ -646,7 +647,8 @@ wdstart(struct wd_softc *wd) while (bufq_peek(wd->sc_q) != NULL) { /* First try to get command */ - xfer = ata_get_xfer(wd->drvp->chnl_softc, false); + xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, + wd->drvp->drv_openings); if (xfer == NULL) break; @@ -1637,7 +1639,7 @@ wddump(dev_t dev, daddr_t blkno, void *v wd->drvp->state = RESET; } - xfer = ata_get_xfer(wd->drvp->chnl_softc, false); + xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, 0); if (xfer == NULL) return EAGAIN; @@ -1827,7 +1829,7 @@ wd_setcache(struct wd_softc *wd, int bit (bits & DKCACHE_SAVE) != 0) return EOPNOTSUPP; - xfer = ata_get_xfer(wd->drvp->chnl_softc, true); + xfer = ata_get_xfer(wd->drvp->chnl_softc); if (xfer == NULL) return EINTR; @@ -1868,7 +1870,7 @@ wd_standby(struct wd_softc *wd, int flag struct ata_xfer *xfer; int error; - xfer = ata_get_xfer(wd->drvp->chnl_softc, true); + xfer = ata_get_xfer(wd->drvp->chnl_softc); if (xfer == NULL) return EINTR; @@ -1919,7 +1921,7 @@ wd_flushcache(struct wd_softc *wd, int f wd->sc_params.atap_cmd_set2 == 0xffff)) return ENODEV; - xfer = ata_get_xfer(wd->drvp->chnl_softc, true); + xfer = ata_get_xfer(wd->drvp->chnl_softc); if (xfer == NULL) return EINTR; @@ -1971,7 +1973,7 @@ wd_trim(struct wd_softc *wd, int part, d if (part != RAW_PART) bno += wd->sc_dk.dk_label->d_partitions[part].p_offset;; - xfer = ata_get_xfer(wd->drvp->chnl_softc, true); + xfer = ata_get_xfer(wd->drvp->chnl_softc); if (xfer == NULL) return EINTR; @@ -2137,7 +2139,7 @@ wdioctlstrategy(struct buf *bp) goto out2; } - xfer = ata_get_xfer(wi->wi_softc->drvp->chnl_softc, true); + xfer = ata_get_xfer(wi->wi_softc->drvp->chnl_softc); if (xfer == NULL) { error = EINTR; goto out2; Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.14 src/sys/dev/ic/ahcisata_core.c:1.57.6.15 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.14 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ic/ahcisata_core.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.14 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.15 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.14 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.15 2017/06/20 20:58:22 jdolecek Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -1569,7 +1569,7 @@ ahci_atapi_scsipi_request(struct scsipi_ scsipi_done(sc_xfer); return; } - xfer = ata_get_xfer(atac->atac_channels[channel], false); + xfer = ata_get_xfer_ext(atac->atac_channels[channel], false, 0); if (xfer == NULL) { sc_xfer->error = XS_RESOURCE_SHORTAGE; scsipi_done(sc_xfer); Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.12 src/sys/dev/ic/mvsata.c:1.35.6.13 --- src/sys/dev/ic/mvsata.c:1.35.6.12 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ic/mvsata.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.12 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.13 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.12 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.13 2017/06/20 20:58:22 jdolecek Exp $"); #include "opt_mvsata.h" @@ -791,7 +791,7 @@ mvsata_atapi_scsipi_request(struct scsip scsipi_done(sc_xfer); return; } - xfer = ata_get_xfer(chp, false); + xfer = ata_get_xfer_ext(chp, false, 0); if (xfer == NULL) { sc_xfer->error = XS_RESOURCE_SHORTAGE; scsipi_done(sc_xfer); @@ -1219,7 +1219,7 @@ do_pio: * thread */ if ((xfer->c_flags & C_POLL) == 0 && cpu_intr_p()) { - chp->ch_queue->queue_freeze++; + ata_channel_freeze(chp); wakeup(&chp->ch_thread); return; } @@ -1897,7 +1897,7 @@ mvsata_atapi_start(struct ata_channel *c if (__predict_false(drvp->state < READY)) { /* If it's not a polled command, we need the kernel thread */ if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 && cpu_intr_p()) { - chp->ch_queue->queue_freeze++; + ata_channel_freeze(chp); wakeup(&chp->ch_thread); return; } Index: src/sys/dev/ic/wdc.c diff -u src/sys/dev/ic/wdc.c:1.283.2.6 src/sys/dev/ic/wdc.c:1.283.2.7 --- src/sys/dev/ic/wdc.c:1.283.2.6 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/ic/wdc.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.283.2.6 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: wdc.c,v 1.283.2.7 2017/06/20 20:58:22 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.6 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.7 2017/06/20 20:58:22 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -873,11 +873,10 @@ wdcintr(void *arg) } ATADEBUG_PRINT(("wdcintr\n"), DEBUG_INTR); - KASSERT(chp->ch_queue->queue_openings == 1); - xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0); + KASSERT(chp->ch_queue->queue_active == 1); + xfer = ata_queue_get_active_xfer(chp->ch_queue); + KASSERT(xfer != NULL); #ifdef DIAGNOSTIC - if (xfer == NULL) - panic("wdcintr: no xfer"); if (xfer->c_chp != chp) { printf("channel %d expected %d\n", xfer->c_chp->ch_channel, chp->ch_channel); @@ -933,8 +932,7 @@ wdc_reset_channel(struct ata_channel *ch * if the current command is on an ATAPI device, issue a * ATAPI_SOFT_RESET */ - KASSERT(chp->ch_queue->queue_openings == 1); - xfer = ata_queue_active_xfer_peek(chp->ch_queue); + xfer = ata_queue_get_active_xfer(chp->ch_queue); if (xfer && xfer->c_chp == chp && (xfer->c_flags & C_ATAPI)) { wdccommandshort(chp, xfer->c_drive, ATAPI_SOFT_RESET); if (flags & AT_WAIT) @@ -1205,7 +1203,9 @@ __wdcwait(struct ata_channel *chp, int m #ifdef WDCNDELAY_DEBUG /* After autoconfig, there should be no long delays. */ if (!cold && xtime > WDCNDELAY_DEBUG) { - struct ata_xfer *xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0); + struct ata_xfer *xfer; + + xfer = ata_queue_get_active_xfer(chp->ch_queue); if (xfer == NULL) printf("%s channel %d: warning: busy-wait took %dus\n", device_xname(chp->ch_atac->atac_dev), @@ -1254,11 +1254,7 @@ wdcwait(struct ata_channel *chp, int mas * we're probably in interrupt context, * ask the thread to come back here */ -#ifdef DIAGNOSTIC - if (chp->ch_queue->queue_freeze > 0) - panic("wdcwait: queue_freeze"); -#endif - chp->ch_queue->queue_freeze++; + ata_channel_freeze(chp); wakeup(&chp->ch_thread); return(WDCWAIT_THR); } @@ -1817,7 +1813,7 @@ static void __wdcerror(struct ata_channel *chp, const char *msg) { struct atac_softc *atac = chp->ch_atac; - struct ata_xfer *xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0); + struct ata_xfer *xfer = ata_queue_get_active_xfer(chp->ch_queue); if (xfer == NULL) aprint_error("%s:%d: %s\n", device_xname(atac->atac_dev), Index: src/sys/dev/scsipi/atapi_wdc.c diff -u src/sys/dev/scsipi/atapi_wdc.c:1.123.4.6 src/sys/dev/scsipi/atapi_wdc.c:1.123.4.7 --- src/sys/dev/scsipi/atapi_wdc.c:1.123.4.6 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/scsipi/atapi_wdc.c Tue Jun 20 20:58:23 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atapi_wdc.c,v 1.123.4.6 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: atapi_wdc.c,v 1.123.4.7 2017/06/20 20:58:23 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.6 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.7 2017/06/20 20:58:23 jdolecek Exp $"); #ifndef ATADEBUG #define ATADEBUG @@ -201,7 +201,7 @@ wdc_atapi_get_params(struct scsipi_chann struct ata_xfer *xfer; int rv; - xfer = ata_get_xfer(chp, true); + xfer = ata_get_xfer(chp); if (xfer == NULL) { printf("wdc_atapi_get_params: no xfer\n"); return EBUSY; @@ -376,7 +376,7 @@ wdc_atapi_scsipi_request(struct scsipi_c return; } - xfer = ata_get_xfer(atac->atac_channels[channel], false); + xfer = ata_get_xfer_ext(atac->atac_channels[channel], false, 0); if (xfer == NULL) { sc_xfer->error = XS_RESOURCE_SHORTAGE; scsipi_done(sc_xfer); @@ -485,7 +485,7 @@ wdc_atapi_start(struct ata_channel *chp, /* If it's not a polled command, we need the kernel thread */ if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 && (chp->ch_flags & ATACH_TH_RUN) == 0) { - chp->ch_queue->queue_freeze++; + ata_channel_freeze(chp); wakeup(&chp->ch_thread); return; } Index: src/sys/dev/usb/umass_isdata.c diff -u src/sys/dev/usb/umass_isdata.c:1.33.4.3 src/sys/dev/usb/umass_isdata.c:1.33.4.4 --- src/sys/dev/usb/umass_isdata.c:1.33.4.3 Mon Jun 19 21:00:00 2017 +++ src/sys/dev/usb/umass_isdata.c Tue Jun 20 20:58:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.c,v 1.33.4.3 2017/06/19 21:00:00 jdolecek Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.33.4.4 2017/06/20 20:58:22 jdolecek Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.3 2017/06/19 21:00:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.4 2017/06/20 20:58:22 jdolecek Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -502,7 +502,7 @@ uisdata_kill_pending(struct ata_drive_da struct ata_channel *chp = drv->chnl_softc; struct umass_softc *sc = CH2SELF(chp); struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus; - struct ata_xfer *xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0); + struct ata_xfer *xfer = ata_queue_get_active_xfer(chp->ch_queue); struct ata_bio *ata_bio = &xfer->c_bio; DPRINTFN(-1,("%s\n", __func__)); @@ -534,7 +534,7 @@ uisdata_get_params(struct ata_drive_data memset(tb, 0, DEV_BSIZE); memset(prms, 0, sizeof(struct ataparams)); - xfer = ata_get_xfer(drvp->chnl_softc, true); + xfer = ata_get_xfer(drvp->chnl_softc); if (!xfer) { rv = CMD_AGAIN; goto out;