CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Oct 21 19:16:48 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: testing done (including PMP on siisata(4) and ATAPI cd(4) on ahcisata/siisata) To generate a diff of this commit: cvs rdiff -u -r1.4.2.16 -r1.4.2.17 src/sys/dev/ata/TODO.ncq 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.4.2.16 src/sys/dev/ata/TODO.ncq:1.4.2.17 --- src/sys/dev/ata/TODO.ncq:1.4.2.16 Wed Oct 17 18:03:26 2018 +++ src/sys/dev/ata/TODO.ncq Sun Oct 21 19:16:48 2018 @@ -1,7 +1,3 @@ -jdolecek-ncqfixes to finish: -- re-check READ LOG EXT handling under native -- recheck native working for ahcisata(4), siisata(4), mvsata(4) + PMP - Bugs test wd* at umass?, confirm the ata_channel kludge works @@ -29,7 +25,7 @@ add support for the NCQ TRIM if supporte implement DIOCGCACHE/DIOCCACHESYNC for ld@ataraid? just passthrough, like ccd -MSI/MSI-X support for AHCI and mvsata(4) +MSI/MSI-X support for ahcisata(4), siisata(4) and mvsata(4) mvsata - move pci-specific code to the pci attach code
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Oct 21 19:16:48 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: testing done (including PMP on siisata(4) and ATAPI cd(4) on ahcisata/siisata) To generate a diff of this commit: cvs rdiff -u -r1.4.2.16 -r1.4.2.17 src/sys/dev/ata/TODO.ncq Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Oct 21 18:13:14 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: siisata.c Log Message: decouple siisata_reset_channel() from siisata_reinit_port(); the former now needs channel lock, but we don't have it in siisata_init_port() during attach instead call siisata_reset_channel() when siisata_reinit_port() fails, and ignore the error during attach To generate a diff of this commit: cvs rdiff -u -r1.35.6.10 -r1.35.6.11 src/sys/dev/ic/siisata.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/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.35.6.10 src/sys/dev/ic/siisata.c:1.35.6.11 --- src/sys/dev/ic/siisata.c:1.35.6.10 Mon Oct 15 21:18:53 2018 +++ src/sys/dev/ic/siisata.c Sun Oct 21 18:13:14 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.35.6.10 2018/10/15 21:18:53 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.35.6.11 2018/10/21 18:13:14 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.10 2018/10/15 21:18:53 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.11 2018/10/21 18:13:14 jdolecek Exp $"); #include #include @@ -162,7 +162,7 @@ void siisata_bio_abort(struct ata_channe void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int); int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *); -static void siisata_reinit_port(struct ata_channel *, int); +static int siisata_reinit_port(struct ata_channel *, int); static void siisata_device_reset(struct ata_channel *); static void siisata_activate_prb(struct siisata_channel *, int); static void siisata_deactivate_prb(struct siisata_channel *, int); @@ -261,11 +261,12 @@ siisata_enable_port_interrupt(struct ata PR_PIS_CMDERRR | PR_PIS_CMDCMPL); } -static void +static int siisata_init_port(struct siisata_softc *sc, int port) { struct siisata_channel *schp; struct ata_channel *chp; + int error; schp = >sc_channels[port]; chp = (struct ata_channel *)schp; @@ -277,11 +278,13 @@ siisata_init_port(struct siisata_softc * PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET); /* initialize port */ - siisata_reinit_port(chp, -1); + error = siisata_reinit_port(chp, -1); /* enable CmdErrr+CmdCmpl interrupting */ siisata_enable_port_interrupt(chp); /* enable port interrupt */ GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); + + return error; } static void @@ -398,7 +401,7 @@ siisata_attach_port(struct siisata_softc return; } - siisata_init_port(sc, port); + (void)siisata_init_port(sc, port); ata_channel_attach(chp); @@ -450,15 +453,22 @@ siisata_detach(struct siisata_softc *sc, void siisata_resume(struct siisata_softc *sc) { - int i; - /* come out of reset state */ GRWRITE(sc, GR_GC, 0); - for (i = 0; i < sc->sc_atac.atac_nchannels; i++) { - siisata_init_port(sc, i); - } + for (int port = 0; port < sc->sc_atac.atac_nchannels; port++) { + int error; + + error = siisata_init_port(sc, port); + if (error) { + struct siisata_channel *schp = >sc_channels[port]; + struct ata_channel *chp = (struct ata_channel *)schp; + ata_channel_lock(chp); + siisata_reset_channel(chp, AT_POLL); + ata_channel_unlock(chp); + } + } } int @@ -625,7 +635,7 @@ siisata_channel_recover(struct ata_chann } KASSERT(drive >= 0); - siisata_reinit_port(chp, drive); + (void)siisata_reinit_port(chp, drive); ata_recovery_resume(chp, drive, tfd, flags); @@ -648,7 +658,8 @@ siisata_reset_drive(struct ata_drive_dat ata_channel_lock_owned(chp); - siisata_reinit_port(chp, drvp->drive); + if (siisata_reinit_port(chp, drvp->drive)) + siisata_reset_channel(chp, flags); /* get a slot for running the command on */ if (!ata_queue_alloc_slot(chp, _slot, ATA_MAX_OPENINGS)) { @@ -815,7 +826,8 @@ siisata_probe_drive(struct ata_channel * aprint_error_dev(sc->sc_atac.atac_dev, "timed out waiting for PORT_READY on port %d, " "reinitializing\n", chp->ch_channel); - siisata_reinit_port(chp, -1); + if (siisata_reinit_port(chp, -1)) +siisata_reset_channel(chp, AT_WAIT); } prb = schp->sch_prb[c_slot]; @@ -851,7 +863,8 @@ siisata_probe_drive(struct ata_channel * PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)), PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)), PRREAD(sc, PRX(chp->ch_channel, PRO_PIS))); - siisata_reinit_port(chp, -1); + if (siisata_reinit_port(chp, -1)) +siisata_reset_channel(chp, AT_WAIT); break; } @@ -1427,12 +1440,12 @@ siisata_deactivate_prb(struct siisata_ch SIISATA_PRB_SYNC(sc, schp, slot, BUS_DMASYNC_POSTWRITE); } -static void +static int siisata_reinit_port(struct ata_channel *chp, int drive) { struct siisata_softc *sc = (struct siisata_softc
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Oct 21 18:13:14 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: siisata.c Log Message: decouple siisata_reset_channel() from siisata_reinit_port(); the former now needs channel lock, but we don't have it in siisata_init_port() during attach instead call siisata_reset_channel() when siisata_reinit_port() fails, and ignore the error during attach To generate a diff of this commit: cvs rdiff -u -r1.35.6.10 -r1.35.6.11 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 20 21:08:23 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: satapmp_subr.c Log Message: hold lock during drive reset (new locking protocol) erase xfer before each reuse for read/write port commands To generate a diff of this commit: cvs rdiff -u -r1.14.2.1 -r1.14.2.2 src/sys/dev/ata/satapmp_subr.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/satapmp_subr.c diff -u src/sys/dev/ata/satapmp_subr.c:1.14.2.1 src/sys/dev/ata/satapmp_subr.c:1.14.2.2 --- src/sys/dev/ata/satapmp_subr.c:1.14.2.1 Sat Sep 22 09:22:59 2018 +++ src/sys/dev/ata/satapmp_subr.c Sat Oct 20 21:08:23 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: satapmp_subr.c,v 1.14.2.1 2018/09/22 09:22:59 jdolecek Exp $ */ +/* $NetBSD: satapmp_subr.c,v 1.14.2.2 2018/10/20 21:08:23 jdolecek Exp $ */ /* * Copyright (c) 2012 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.14.2.1 2018/09/22 09:22:59 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.14.2.2 2018/10/20 21:08:23 jdolecek Exp $"); #include #include @@ -62,6 +62,7 @@ satapmp_read_8(struct ata_channel *chp, KASSERT(drvp->drive == PMP_PORT_CTL); ata_channel_lock_owned(chp); + memset(xfer, 0, sizeof(*xfer)); xfer->c_ata_c.r_command = PMPC_READ_PORT; xfer->c_ata_c.r_features = reg; xfer->c_ata_c.r_device = port; @@ -133,6 +134,7 @@ satapmp_write_8(struct ata_channel *chp, KASSERT(drvp->drive == PMP_PORT_CTL); ata_channel_lock_owned(chp); + memset(xfer, 0, sizeof(*xfer)); xfer->c_ata_c.r_command = PMPC_WRITE_PORT; xfer->c_ata_c.r_features = reg; xfer->c_ata_c.r_device = port; @@ -261,10 +263,10 @@ satapmp_rescan(struct ata_channel *chp, device_xname(chp->atabus), i); continue; } - ata_channel_unlock(chp); + + ata_channel_lock_owned(chp); chp->ch_atac->atac_bustype_ata->ata_reset_drive( >ch_drive[i], AT_WAIT, ); - ata_channel_lock(chp); sata_interpret_sig(chp, i, sig); }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 20 21:08:23 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: satapmp_subr.c Log Message: hold lock during drive reset (new locking protocol) erase xfer before each reuse for read/write port commands To generate a diff of this commit: cvs rdiff -u -r1.14.2.1 -r1.14.2.2 src/sys/dev/ata/satapmp_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Oct 17 18:03:27 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: rechecked bad block handling under Parallels and it really doesn't set any error bits in any of the registers (neither IS nor SERR) for out-of-range block read nor write, while it works just fine under VMware, so not our bug To generate a diff of this commit: cvs rdiff -u -r1.4.2.15 -r1.4.2.16 src/sys/dev/ata/TODO.ncq Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Oct 17 18:03:27 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: rechecked bad block handling under Parallels and it really doesn't set any error bits in any of the registers (neither IS nor SERR) for out-of-range block read nor write, while it works just fine under VMware, so not our bug To generate a diff of this commit: cvs rdiff -u -r1.4.2.15 -r1.4.2.16 src/sys/dev/ata/TODO.ncq 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.4.2.15 src/sys/dev/ata/TODO.ncq:1.4.2.16 --- src/sys/dev/ata/TODO.ncq:1.4.2.15 Mon Oct 15 21:18:53 2018 +++ src/sys/dev/ata/TODO.ncq Wed Oct 17 18:03:26 2018 @@ -1,6 +1,6 @@ -jdolecek-ncqfixes goals: -- re-check READ LOG EXT handling under native and Parallels to make sure - the NOERROR under Parallels is their bug and not ours +jdolecek-ncqfixes to finish: +- re-check READ LOG EXT handling under native +- recheck native working for ahcisata(4), siisata(4), mvsata(4) + PMP Bugs
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Oct 15 21:18:53 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_recovery.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c src/sys/dev/usb [jdolecek-ncqfixes]: umass_isdata.c Log Message: change the SATA/NCQ recovery to run in the atabus thread To generate a diff of this commit: cvs rdiff -u -r1.4.2.14 -r1.4.2.15 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.17 -r1.141.6.18 src/sys/dev/ata/ata.c cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/dev/ata/ata_recovery.c cvs rdiff -u -r1.110.4.3 -r1.110.4.4 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.99.2.11 -r1.99.2.12 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.62.2.9 -r1.62.2.10 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.10 -r1.41.2.11 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.9 -r1.35.6.10 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.36.6.1 -r1.36.6.2 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.4.2.14 src/sys/dev/ata/TODO.ncq:1.4.2.15 --- src/sys/dev/ata/TODO.ncq:1.4.2.14 Sun Oct 14 14:50:54 2018 +++ src/sys/dev/ata/TODO.ncq Mon Oct 15 21:18:53 2018 @@ -1,9 +1,6 @@ jdolecek-ncqfixes goals: - re-check READ LOG EXT handling under native and Parallels to make sure the NOERROR under Parallels is their bug and not ours -- run recovery via atathread, move to new function and share ahci/siisata/mvsata -- maybe do device error handling in not-interrupt-context (maybe this should be - done on a mpata branch?) Bugs Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.17 src/sys/dev/ata/ata.c:1.141.6.18 --- src/sys/dev/ata/ata.c:1.141.6.17 Sun Oct 14 16:13:51 2018 +++ src/sys/dev/ata/ata.c Mon Oct 15 21:18:53 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.17 2018/10/14 16:13:51 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.18 2018/10/15 21:18:53 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.17 2018/10/14 16:13:51 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.18 2018/10/15 21:18:53 jdolecek Exp $"); #include "opt_ata.h" @@ -129,7 +129,6 @@ static bool atabus_suspend(device_t, con static void atabusconfig_thread(void *); static void ata_channel_idle(struct ata_channel *); -static void ata_channel_thaw_locked(struct ata_channel *); static void ata_activate_xfer_locked(struct ata_channel *, struct ata_xfer *); static void ata_channel_freeze_locked(struct ata_channel *); static void ata_thread_wake_locked(struct ata_channel *); @@ -463,7 +462,7 @@ atabus_thread(void *arg) ata_channel_lock(chp); for (;;) { if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_TH_DRIVE_RESET - | ATACH_SHUTDOWN)) == 0 && + | ATACH_TH_RECOVERY | ATACH_SHUTDOWN)) == 0 && (chq->queue_active == 0 || chq->queue_freeze == 0)) { chp->ch_flags &= ~ATACH_TH_RUN; cv_wait(>ch_thr_idle, >ch_lock); @@ -483,6 +482,7 @@ atabus_thread(void *arg) ata_thread_run(chp, AT_WAIT, ATACH_TH_RESET, ATACH_NODRIVE); } else if (chp->ch_flags & ATACH_TH_DRIVE_RESET) { + /* this will unfreeze the channel */ for (i = 0; i < chp->ch_ndrives; i++) { struct ata_drive_datas *drvp; @@ -494,6 +494,16 @@ atabus_thread(void *arg) } } chp->ch_flags &= ~ATACH_TH_DRIVE_RESET; + } else if (chp->ch_flags & ATACH_TH_RECOVERY) { + /* + * This will unfreeze the channel; drops locks during + * run, so must wrap in splbio()/splx() to avoid + * spurious interrupts. XXX MPSAFE + */ + int s = splbio(); + ata_thread_run(chp, AT_WAIT, ATACH_TH_RECOVERY, + chp->recovery_tfd); + splx(s); } else if (chq->queue_active > 0 && chq->queue_freeze == 1) { /* * Caller has bumped queue_freeze, decrease it. This @@ -522,10 +532,12 @@ atabus_thread(void *arg) } else if (chq->queue_freeze > 1) panic("%s: queue_freeze", __func__); - /* Try to run down the queue once after each event is handled */ - ata_channel_unlock(chp); - atastart(chp); - ata_channel_lock(chp); + /* Try to run down the queue once channel is unfrozen */ + if (chq->queue_freeze == 0) { + ata_channel_unlock(chp); + atastart(chp); + ata_channel_lock(chp); + } } chp->ch_thread = NULL; cv_signal(>ch_thr_idle); @@ -1499,7 +1511,7 @@ ata_channel_freeze(struct ata_channel *c ata_channel_unlock(chp); } -static void +void ata_channel_thaw_locked(struct ata_channel *chp) { KASSERT(mutex_owned(>ch_lock)); @@ -1511,21 +1523,13 @@ ata_channel_thaw_locked(struct ata_chann chp->ch_queue->queue_freeze), DEBUG_FUNCS | DEBUG_XFERS); } -void -ata_channel_thaw(struct ata_channel *chp) -{ - ata_channel_lock(chp); -
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Oct 15 21:18:53 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_recovery.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c src/sys/dev/usb [jdolecek-ncqfixes]: umass_isdata.c Log Message: change the SATA/NCQ recovery to run in the atabus thread To generate a diff of this commit: cvs rdiff -u -r1.4.2.14 -r1.4.2.15 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.17 -r1.141.6.18 src/sys/dev/ata/ata.c cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/dev/ata/ata_recovery.c cvs rdiff -u -r1.110.4.3 -r1.110.4.4 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.99.2.11 -r1.99.2.12 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.62.2.9 -r1.62.2.10 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.10 -r1.41.2.11 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.9 -r1.35.6.10 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.36.6.1 -r1.36.6.2 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.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Oct 14 16:13:51 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: add comment to kthread_create() call to explain why atabus_thread is actually running under KERNEL_LOCK() To generate a diff of this commit: cvs rdiff -u -r1.141.6.16 -r1.141.6.17 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Oct 14 16:13:51 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: add comment to kthread_create() call to explain why atabus_thread is actually running under KERNEL_LOCK() To generate a diff of this commit: cvs rdiff -u -r1.141.6.16 -r1.141.6.17 src/sys/dev/ata/ata.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.16 src/sys/dev/ata/ata.c:1.141.6.17 --- src/sys/dev/ata/ata.c:1.141.6.16 Thu Oct 11 20:57:51 2018 +++ src/sys/dev/ata/ata.c Sun Oct 14 16:13:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.16 2018/10/11 20:57:51 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.17 2018/10/14 16:13:51 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.16 2018/10/11 20:57:51 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.17 2018/10/14 16:13:51 jdolecek Exp $"); #include "opt_ata.h" @@ -593,6 +593,7 @@ atabus_attach(device_t parent, device_t mutex_exit(_qlock); config_pending_incr(sc->sc_dev); + /* XXX MPSAFE - no KTHREAD_MPSAFE, so protected by KERNEL_LOCK() */ if ((error = kthread_create(PRI_NONE, 0, NULL, atabus_thread, sc, >ch_thread, "%s", device_xname(self))) != 0) aprint_error_dev(self,
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Sun Oct 14 14:50:55 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: adjust mvsata_bio_intr() so it recognizes the 'tfd' parameter as passed by recovery and hence works; use it also for passing state from mvsata_edma_handle() To generate a diff of this commit: cvs rdiff -u -r1.4.2.13 -r1.4.2.14 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.41.2.9 -r1.41.2.10 src/sys/dev/ic/mvsata.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.4.2.13 src/sys/dev/ata/TODO.ncq:1.4.2.14 --- src/sys/dev/ata/TODO.ncq:1.4.2.13 Thu Oct 11 20:57:51 2018 +++ src/sys/dev/ata/TODO.ncq Sun Oct 14 14:50:54 2018 @@ -4,8 +4,6 @@ jdolecek-ncqfixes goals: - run recovery via atathread, move to new function and share ahci/siisata/mvsata - maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -- adjust mvsata() intr code to accept tfd (instead of irq 0/1) so that - ata_recovery_resume() works properly for it Bugs Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.41.2.9 src/sys/dev/ic/mvsata.c:1.41.2.10 --- src/sys/dev/ic/mvsata.c:1.41.2.9 Sat Oct 13 09:31:46 2018 +++ src/sys/dev/ic/mvsata.c Sun Oct 14 14:50:55 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.41.2.9 2018/10/13 09:31:46 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.41.2.10 2018/10/14 14:50:55 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.9 2018/10/13 09:31:46 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.10 2018/10/14 14:50:55 jdolecek Exp $"); #include "opt_mvsata.h" @@ -549,7 +549,7 @@ static void mvsata_channel_recover(struct mvsata_port *mvport) { struct ata_channel *chp = >port_ata_channel; - int drive, tfd = 1; + int drive, tfd = ATACH_ERR_ST(0, WDCS_ERR); ata_channel_lock(chp); KASSERT(!ISSET(chp->ch_flags, ATACH_RECOVERING)); @@ -571,16 +571,6 @@ mvsata_channel_recover(struct mvsata_por * as if nothing happened. */ -#if 0 - XXX recheck - mvsata used to have this to handle the successful - recovery via read_log_ext: - - xfer = ata_queue_hwslot_to_xfer(chp, eslot); - xfer->c_flags |= C_RECOVERED; - xfer->c_bio.error = ERROR; - xfer->c_bio.r_error = err; - xfer->ops->c_intr(chp, xfer, 1); -#endif ata_recovery_resume(chp, drive, tfd, AT_POLL); /* Drive unblocked, back to normal operation */ @@ -1244,6 +1234,11 @@ do_pio: } intr: + KASSERTMSG(((xfer->c_flags & C_DMA) != 0) + == (mvport->port_edmamode_curr != nodma), + "DMA mode mismatch: flags %x vs edmamode %d != %d", + xfer->c_flags, mvport->port_edmamode_curr, nodma); + /* Wait for IRQ (either real or polled) */ if ((ata_bio->flags & ATA_POLL) != 0) return ATASTART_POLL; @@ -1279,20 +1274,35 @@ mvsata_bio_poll(struct ata_channel *chp, } static int -mvsata_bio_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq) +mvsata_bio_intr(struct ata_channel *chp, struct ata_xfer *xfer, int intr_arg) { struct atac_softc *atac = chp->ch_atac; struct wdc_softc *wdc = CHAN_TO_WDC(chp); struct ata_bio *ata_bio = >c_bio; struct ata_drive_datas *drvp = >ch_drive[xfer->c_drive]; - int tfd; + int irq = ISSET(xfer->c_flags, (C_POLL|C_TIMEOU)) ? 0 : 1; + int tfd = 0; + + if (ISSET(xfer->c_flags, C_DMA|C_RECOVERED) && irq) { + /* Invoked via mvsata_edma_handle() or recovery */ + tfd = intr_arg; + + if (tfd > 0 && ata_bio->error == NOERROR) { + if (ATACH_ST(tfd) & WDCS_ERR) +ata_bio->error = ERROR; + if (ATACH_ST(tfd) & WDCS_BSY) +ata_bio->error = TIMEOUT; + ata_bio->r_error = ATACH_ERR(tfd); + } + } DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, ("%s:%d: %s: drive=%d\n", device_xname(atac->atac_dev), chp->ch_channel, __func__, xfer->c_drive)); - if (xfer->c_flags & C_TIMEOU && !irq) { - /* Cleanup EDMA if invoked from timeout handler */ + /* Cleanup EDMA if invoked from wdctimeout()/ata_timeout() */ + if (ISSET(xfer->c_flags, C_TIMEOU) && ISSET(xfer->c_flags, C_DMA) + && !ISSET(xfer->c_flags, C_POLL)) { mvsata_edma_rqq_remove((struct mvsata_port *)chp, xfer); } @@ -2814,17 +2824,14 @@ mvsata_edma_handle(struct mvsata_port *m ata_bio = >c_bio; ata_bio->error = NOERROR; - ata_bio->r_error = 0; - if (st & WDCS_ERR) - ata_bio->error = ERROR; - if (st & WDCS_BSY) - ata_bio->error = TIMEOUT; if (dmaerr != 0) ata_bio->error = ERR_DMA; mvsata_dma_bufunload(mvport, quetag, ata_bio->flags); - mvsata_bio_intr(chp, xfer, 1); + KASSERT(xfer->c_flags & C_DMA); + mvsata_bio_intr(chp, xfer, ATACH_ERR_ST(0, st)); + if (xfer1 == NULL) handled++; else if (xfer == xfer1) {
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Sun Oct 14 14:50:55 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: adjust mvsata_bio_intr() so it recognizes the 'tfd' parameter as passed by recovery and hence works; use it also for passing state from mvsata_edma_handle() To generate a diff of this commit: cvs rdiff -u -r1.4.2.13 -r1.4.2.14 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.41.2.9 -r1.41.2.10 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Oct 13 09:31:46 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: make compile again with MVSATA_WITHOUTDMA To generate a diff of this commit: cvs rdiff -u -r1.41.2.8 -r1.41.2.9 src/sys/dev/ic/mvsata.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/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.41.2.8 src/sys/dev/ic/mvsata.c:1.41.2.9 --- src/sys/dev/ic/mvsata.c:1.41.2.8 Sat Oct 13 07:23:34 2018 +++ src/sys/dev/ic/mvsata.c Sat Oct 13 09:31:46 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.41.2.8 2018/10/13 07:23:34 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.41.2.9 2018/10/13 09:31:46 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.8 2018/10/13 07:23:34 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.9 2018/10/13 09:31:46 jdolecek Exp $"); #include "opt_mvsata.h" @@ -107,9 +107,9 @@ int mvsata_debug = 0; static void mvsata_probe_drive(struct ata_channel *); -static void mvsata_reset_channel(struct ata_channel *, int); #ifndef MVSATA_WITHOUTDMA +static void mvsata_reset_channel(struct ata_channel *, int); static int mvsata_bio(struct ata_drive_datas *, struct ata_xfer *); static void mvsata_reset_drive(struct ata_drive_datas *, int, uint32_t *); static int mvsata_exec_command(struct ata_drive_datas *, struct ata_xfer *); @@ -651,7 +651,6 @@ mvsata_reset_drive(struct ata_drive_data mvsata_edma_enable(mvport); } } -#endif /* MVSATA_WITHOUTDMA */ static void mvsata_reset_channel(struct ata_channel *chp, int flags) @@ -689,14 +688,11 @@ mvsata_reset_channel(struct ata_channel ata_kill_active(chp, KILL_RESET, flags); -#ifndef MVSATA_WITHOUTDMA mvsata_edma_config(mvport, mvport->port_edmamode_curr); mvsata_edma_reset_qptr(mvport); mvsata_edma_enable(mvport); -#endif } -#ifndef MVSATA_WITHOUTDMA static int mvsata_addref(struct ata_drive_datas *drvp) { @@ -896,23 +892,19 @@ mvsata_atapi_kill_pending(struct scsipi_ static void mvsata_setup_channel(struct ata_channel *chp) { -#if !defined(MVSATA_WITHOUTDMA) || defined(MVSATA_DEBUG) +#ifndef MVSATA_WITHOUTDMA struct mvsata_port *mvport = (struct mvsata_port *)chp; -#endif struct ata_drive_datas *drvp; - uint32_t edma_mode; int drive, s; -#ifndef MVSATA_WITHOUTDMA + uint32_t edma_mode = nodma; int i; const int crqb_size = sizeof(union mvsata_crqb) * MVSATA_EDMAQ_LEN; const int crpb_size = sizeof(struct crpb) * MVSATA_EDMAQ_LEN; const int eprd_buf_size = MVSATA_EPRD_MAX_SIZE * MVSATA_EDMAQ_LEN; -#endif DPRINTF(DEBUG_FUNCS, ("%s:%d: mvsata_setup_channel: ", device_xname(MVSATA_DEV2(mvport)), chp->ch_channel)); - edma_mode = nodma; for (drive = 0; drive < chp->ch_ndrives; drive++) { drvp = >ch_drive[drive]; @@ -938,7 +930,6 @@ mvsata_setup_channel(struct ata_channel DPRINTF(DEBUG_FUNCS, ("EDMA %sactive mode\n", (edma_mode == nodma) ? "not " : "")); -#ifndef MVSATA_WITHOUTDMA if (edma_mode == nodma) { no_edma: if (mvport->port_crqb != NULL)
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Oct 13 09:31:46 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: make compile again with MVSATA_WITHOUTDMA To generate a diff of this commit: cvs rdiff -u -r1.41.2.8 -r1.41.2.9 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Oct 13 07:23:34 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: add C_TIMEOUT KASSERT() on fail path of mvsata_bio_poll() for clarity To generate a diff of this commit: cvs rdiff -u -r1.41.2.7 -r1.41.2.8 src/sys/dev/ic/mvsata.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/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.41.2.7 src/sys/dev/ic/mvsata.c:1.41.2.8 --- src/sys/dev/ic/mvsata.c:1.41.2.7 Thu Oct 11 20:57:51 2018 +++ src/sys/dev/ic/mvsata.c Sat Oct 13 07:23:34 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.41.2.7 2018/10/11 20:57:51 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.41.2.8 2018/10/13 07:23:34 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.7 2018/10/11 20:57:51 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.8 2018/10/13 07:23:34 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1281,8 +1281,10 @@ mvsata_bio_poll(struct ata_channel *chp, chp->ch_flags &= ~ATACH_DMA_WAIT; } - if ((xfer->c_bio.flags & ATA_ITSDONE) == 0) + if ((xfer->c_bio.flags & ATA_ITSDONE) == 0) { + KASSERT(xfer->c_flags & C_TIMEOU); mvsata_bio_intr(chp, xfer, 0); + } } static int
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Oct 13 07:23:34 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: add C_TIMEOUT KASSERT() on fail path of mvsata_bio_poll() for clarity To generate a diff of this commit: cvs rdiff -u -r1.41.2.7 -r1.41.2.8 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Thu Oct 11 20:57:51 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_subr.c atavar.h files.ata src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c ahcisatavar.h mvsata.c mvsatavar.h siisata.c siisatavar.h Added Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata_recovery.c Log Message: refactor shared parts of the SATA error recovery into new function ata_recovery_resume() and use for ahcisata/siisata/mvsata, also replace per-controller hold/unhold with generic version move the shared recovery code into separate file ata_recovery.c To generate a diff of this commit: cvs rdiff -u -r1.4.2.12 -r1.4.2.13 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.15 -r1.141.6.16 src/sys/dev/ata/ata.c cvs rdiff -u -r0 -r1.1.2.1 src/sys/dev/ata/ata_recovery.c cvs rdiff -u -r1.6.2.7 -r1.6.2.8 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.10 -r1.99.2.11 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.27 -r1.27.6.1 src/sys/dev/ata/files.ata cvs rdiff -u -r1.62.2.8 -r1.62.2.9 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.18 -r1.18.6.1 src/sys/dev/ic/ahcisatavar.h cvs rdiff -u -r1.41.2.6 -r1.41.2.7 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.4 -r1.4.2.1 src/sys/dev/ic/mvsatavar.h cvs rdiff -u -r1.35.6.8 -r1.35.6.9 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.7 -r1.7.6.1 src/sys/dev/ic/siisatavar.h 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.4.2.12 src/sys/dev/ata/TODO.ncq:1.4.2.13 --- src/sys/dev/ata/TODO.ncq:1.4.2.12 Sat Oct 6 20:27:28 2018 +++ src/sys/dev/ata/TODO.ncq Thu Oct 11 20:57:51 2018 @@ -4,7 +4,8 @@ jdolecek-ncqfixes goals: - run recovery via atathread, move to new function and share ahci/siisata/mvsata - maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -- remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c) +- adjust mvsata() intr code to accept tfd (instead of irq 0/1) so that + ata_recovery_resume() works properly for it Bugs Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.15 src/sys/dev/ata/ata.c:1.141.6.16 --- src/sys/dev/ata/ata.c:1.141.6.15 Sat Oct 6 21:19:55 2018 +++ src/sys/dev/ata/ata.c Thu Oct 11 20:57:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.15 2018/10/06 21:19:55 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.16 2018/10/11 20:57:51 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.15 2018/10/06 21:19:55 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.16 2018/10/11 20:57:51 jdolecek Exp $"); #include "opt_ata.h" @@ -933,98 +933,6 @@ out: return rv; } -int -ata_read_log_ext_ncq(struct ata_drive_datas *drvp, uint8_t flags, -uint8_t *slot, uint8_t *status, uint8_t *err) -{ - struct ata_xfer *xfer = >recovery_xfer; - int rv; - struct ata_channel *chp = drvp->chnl_softc; - struct atac_softc *atac = chp->ch_atac; - uint8_t *tb, cksum, page; - - ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS); - - /* Only NCQ ATA drives support/need this */ - if (drvp->drive_type != ATA_DRIVET_ATA || - (drvp->drive_flags & ATA_DRIVE_NCQ) == 0) - return EOPNOTSUPP; - - memset(xfer, 0, sizeof(*xfer)); - - tb = drvp->recovery_blk; - memset(tb, 0, sizeof(drvp->recovery_blk)); - - /* - * We could use READ LOG DMA EXT if drive supports it (i.e. - * when it supports Streaming feature) to avoid PIO command, - * and to make this a little faster. Realistically, it - * should not matter. - */ - xfer->c_flags |= C_SKIP_QUEUE; - xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT; - xfer->c_ata_c.r_lba = page = WDCC_LOG_PAGE_NCQ; - xfer->c_ata_c.r_st_bmask = WDCS_DRDY; - xfer->c_ata_c.r_st_pmask = WDCS_DRDY; - xfer->c_ata_c.r_count = 1; - xfer->c_ata_c.r_device = WDSD_LBA; - xfer->c_ata_c.flags = AT_READ | AT_LBA | AT_LBA48 | flags; - xfer->c_ata_c.timeout = 1000; /* 1s */ - xfer->c_ata_c.data = tb; - xfer->c_ata_c.bcount = sizeof(drvp->recovery_blk); - - if ((*atac->atac_bustype_ata->ata_exec_command)(drvp, - xfer) != ATACMD_COMPLETE) { - rv = EAGAIN; - goto out; - } - if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) { - rv = EINVAL; - goto out; - } - - cksum = 0; - for (int i = 0; i < sizeof(drvp->recovery_blk); i++) - cksum += tb[i]; - if (cksum != 0) { - device_printf(drvp->drv_softc, - "invalid checksum %x for READ LOG EXT page %x\n", - cksum, page); - rv = EINVAL; - goto out; - } - - if (tb[0] & WDCC_LOG_NQ) { - /* not queued command */ - rv = EOPNOTSUPP; - goto out; - } - - *slot = tb[0] & 0x1f; - *status = tb[2]; - *err = tb[3]; - - if ((*status & WDCS_ERR) == 0) { - /* - * We expect error here. Normal physical drives always - * do, it's
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Thu Oct 11 20:57:51 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_subr.c atavar.h files.ata src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c ahcisatavar.h mvsata.c mvsatavar.h siisata.c siisatavar.h Added Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata_recovery.c Log Message: refactor shared parts of the SATA error recovery into new function ata_recovery_resume() and use for ahcisata/siisata/mvsata, also replace per-controller hold/unhold with generic version move the shared recovery code into separate file ata_recovery.c To generate a diff of this commit: cvs rdiff -u -r1.4.2.12 -r1.4.2.13 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.15 -r1.141.6.16 src/sys/dev/ata/ata.c cvs rdiff -u -r0 -r1.1.2.1 src/sys/dev/ata/ata_recovery.c cvs rdiff -u -r1.6.2.7 -r1.6.2.8 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.10 -r1.99.2.11 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.27 -r1.27.6.1 src/sys/dev/ata/files.ata cvs rdiff -u -r1.62.2.8 -r1.62.2.9 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.18 -r1.18.6.1 src/sys/dev/ic/ahcisatavar.h cvs rdiff -u -r1.41.2.6 -r1.41.2.7 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.4 -r1.4.2.1 src/sys/dev/ic/mvsatavar.h cvs rdiff -u -r1.35.6.8 -r1.35.6.9 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.7 -r1.7.6.1 src/sys/dev/ic/siisatavar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Oct 7 15:44:48 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c Log Message: move atastart() call after xfer deactivation during ATA command completion, so that it's executed after the slot is freed To generate a diff of this commit: cvs rdiff -u -r1.62.2.7 -r1.62.2.8 src/sys/dev/ic/ahcisata_core.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/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.62.2.7 src/sys/dev/ic/ahcisata_core.c:1.62.2.8 --- src/sys/dev/ic/ahcisata_core.c:1.62.2.7 Thu Oct 4 17:59:35 2018 +++ src/sys/dev/ic/ahcisata_core.c Sun Oct 7 15:44:47 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.62.2.7 2018/10/04 17:59:35 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.62.2.8 2018/10/07 15:44:47 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.7 2018/10/04 17:59:35 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.8 2018/10/07 15:44:47 jdolecek Exp $"); #include #include @@ -1233,6 +1233,9 @@ ahci_cmd_complete(struct ata_channel *ch achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); ata_deactivate_xfer(chp, xfer); + if ((ata_c->flags & (AT_TIMEOU|AT_ERROR)) == 0) + atastart(chp); + return 0; } @@ -1243,7 +1246,6 @@ ahci_cmd_done(struct ata_channel *chp, s struct ahci_channel *achp = (struct ahci_channel *)chp; struct ata_command *ata_c = >c_ata_c; uint16_t *idwordbuf; - int flags = ata_c->flags; int i; AHCIDEBUG_PRINT(("ahci_cmd_done channel %d flags %#x/%#x\n", @@ -1273,9 +1275,6 @@ ahci_cmd_done(struct ata_channel *chp, s ata_c->flags |= AT_XFDONE; ahci_cmd_done_end(chp, xfer); - - if ((flags & (AT_TIMEOU|AT_ERROR)) == 0) - atastart(chp); } static void
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Oct 7 15:44:48 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c Log Message: move atastart() call after xfer deactivation during ATA command completion, so that it's executed after the slot is freed To generate a diff of this commit: cvs rdiff -u -r1.62.2.7 -r1.62.2.8 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Oct 7 15:42:47 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: siisata.c Log Message: call atastart() when ATA command completes without timeout or error, similar to AHCI To generate a diff of this commit: cvs rdiff -u -r1.35.6.7 -r1.35.6.8 src/sys/dev/ic/siisata.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/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.35.6.7 src/sys/dev/ic/siisata.c:1.35.6.8 --- src/sys/dev/ic/siisata.c:1.35.6.7 Thu Oct 4 17:59:35 2018 +++ src/sys/dev/ic/siisata.c Sun Oct 7 15:42:47 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.35.6.7 2018/10/04 17:59:35 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.35.6.8 2018/10/07 15:42:47 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.7 2018/10/04 17:59:35 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.8 2018/10/07 15:42:47 jdolecek Exp $"); #include #include @@ -1180,6 +1180,9 @@ siisata_cmd_complete(struct ata_channel siisata_deactivate_prb(schp, xfer->c_slot); ata_deactivate_xfer(chp, xfer); + if ((ata_c->flags & (AT_TIMEOU|AT_ERROR)) == 0) + atastart(chp); + return 0; }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Oct 7 15:42:47 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: siisata.c Log Message: call atastart() when ATA command completes without timeout or error, similar to AHCI To generate a diff of this commit: cvs rdiff -u -r1.35.6.7 -r1.35.6.8 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 21:19:55 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c atavar.h wd.c Log Message: actually, just make dump use the same queue skip as recovery, and remove the no longer necessary ata_queue_reset() call from wd(4) also for PR kern/47041 To generate a diff of this commit: cvs rdiff -u -r1.141.6.14 -r1.141.6.15 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.6 -r1.6.2.7 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.9 -r1.99.2.10 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.11 -r1.441.2.12 src/sys/dev/ata/wd.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.14 src/sys/dev/ata/ata.c:1.141.6.15 --- src/sys/dev/ata/ata.c:1.141.6.14 Sat Oct 6 20:27:36 2018 +++ src/sys/dev/ata/ata.c Sat Oct 6 21:19:55 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.15 2018/10/06 21:19:55 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.15 2018/10/06 21:19:55 jdolecek Exp $"); #include "opt_ata.h" @@ -961,7 +961,7 @@ ata_read_log_ext_ncq(struct ata_drive_da * and to make this a little faster. Realistically, it * should not matter. */ - xfer->c_flags |= C_RECOVERY; + xfer->c_flags |= C_SKIP_QUEUE; xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT; xfer->c_ata_c.r_lba = page = WDCC_LOG_PAGE_NCQ; xfer->c_ata_c.r_st_bmask = WDCS_DRDY; @@ -1087,7 +1087,7 @@ ata_exec_xfer(struct ata_channel *chp, s * Standard commands are added to the end of command list, but * recovery commands must be run immediatelly. */ - if ((xfer->c_flags & C_RECOVERY) == 0) + if ((xfer->c_flags & C_SKIP_QUEUE) == 0) SIMPLEQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer, c_xferchain); else @@ -1137,7 +1137,7 @@ atastart(struct ata_channel *chp) struct atac_softc *atac = chp->ch_atac; struct ata_queue *chq = chp->ch_queue; struct ata_xfer *xfer, *axfer; - bool recovery; + bool skipq; #ifdef ATA_DEBUG int spl1, spl2; @@ -1174,18 +1174,18 @@ again: goto out; } - recovery = ISSET(xfer->c_flags, C_RECOVERY); + skipq = ISSET(xfer->c_flags, C_SKIP_QUEUE); /* is the queue frozen? */ - if (__predict_false(!recovery && chq->queue_freeze > 0)) { + if (__predict_false(!skipq && chq->queue_freeze > 0)) { if (chq->queue_flags & QF_IDLE_WAIT) { chq->queue_flags &= ~QF_IDLE_WAIT; cv_signal(>ch_queue->queue_idle); } ATADEBUG_PRINT(("%s(chp=%p): channel %d drive %d " - "queue frozen: %d (recovery: %d)\n", + "queue frozen: %d\n", __func__, chp, chp->ch_channel, xfer->c_drive, - chq->queue_freeze, recovery), + chq->queue_freeze), DEBUG_XFERS); goto out; } @@ -1201,7 +1201,7 @@ again: * Need only check first xfer. * XXX FIS-based switching - revisit */ - if (!recovery && (axfer = TAILQ_FIRST(>ch_queue->active_xfers))) { + if (!skipq && (axfer = TAILQ_FIRST(>ch_queue->active_xfers))) { if (!ISSET(xfer->c_flags, C_NCQ) || !ISSET(axfer->c_flags, C_NCQ) || xfer->c_drive != axfer->c_drive) @@ -1211,17 +1211,17 @@ again: struct ata_drive_datas * const drvp = >ch_drive[xfer->c_drive]; /* - * Are we on limit of active xfers ? - * For recovery, we must leave one slot available at all times. + * Are we on limit of active xfers ? If the queue has more + * than 1 openings, we keep one slot reserved for recovery or dump. */ KASSERT(chq->queue_active <= chq->queue_openings); - const uint8_t chq_openings = (!recovery && chq->queue_openings > 1) + const uint8_t chq_openings = (!skipq && chq->queue_openings > 1) ? (chq->queue_openings - 1) : chq->queue_openings; const uint8_t drv_openings = ISSET(xfer->c_flags, C_NCQ) ? drvp->drv_openings : ATA_MAX_OPENINGS; if (chq->queue_active >= MIN(chq_openings, drv_openings)) { - if (recovery) { - panic("%s: channel %d busy, recovery not possible", + if (skipq) { + panic("%s: channel %d busy, xfer not possible", __func__, chp->ch_channel); } @@ -1272,8 +1272,8 @@ again: break; } - /* Queue more commands if possible, but not during recovery */ - if (!recovery && chq->queue_active < chq->queue_openings) + /* Queue more commands if possible, but not during recovery or dump */ + if (!skipq && chq->queue_active < chq->queue_openings) goto again; out: @@ -1321,17 +1321,9 @@ ata_activate_xfer_locked(struct ata_chan struct ata_queue * const chq = chp->ch_queue; KASSERT(mutex_owned(>ch_lock)); - - /* - * When openings is just 1, can't reserve anything for - * recovery. KASSERT() here is to catch code which naively - * relies on
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 21:19:55 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c atavar.h wd.c Log Message: actually, just make dump use the same queue skip as recovery, and remove the no longer necessary ata_queue_reset() call from wd(4) also for PR kern/47041 To generate a diff of this commit: cvs rdiff -u -r1.141.6.14 -r1.141.6.15 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.6 -r1.6.2.7 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.9 -r1.99.2.10 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.11 -r1.441.2.12 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:27:28 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: move the entry for error recovery on thread up, it will be done on ncqfixes branch To generate a diff of this commit: cvs rdiff -u -r1.4.2.11 -r1.4.2.12 src/sys/dev/ata/TODO.ncq 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.4.2.11 src/sys/dev/ata/TODO.ncq:1.4.2.12 --- src/sys/dev/ata/TODO.ncq:1.4.2.11 Thu Oct 4 19:42:01 2018 +++ src/sys/dev/ata/TODO.ncq Sat Oct 6 20:27:28 2018 @@ -2,6 +2,8 @@ jdolecek-ncqfixes goals: - re-check READ LOG EXT handling under native and Parallels to make sure the NOERROR under Parallels is their bug and not ours - run recovery via atathread, move to new function and share ahci/siisata/mvsata +- maybe do device error handling in not-interrupt-context (maybe this should be + done on a mpata branch?) - remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c) Bugs @@ -18,9 +20,6 @@ implement support for PM FIS-based switc for hw which supports it, adjust error handling in controller drivers to handle xfers for several different drives -maybe do device error handling in not-interrupt-context (maybe this should be -done on a mpata branch?) - dump to unopened disk fails (e.g. dump do wd1b when wd1a not mounted), due to the open path executing ata_get_params(), which eventually tsleeps() while waiting for the command to finish; specifically, if WDF_LOADED is not
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:27:28 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: move the entry for error recovery on thread up, it will be done on ncqfixes branch To generate a diff of this commit: cvs rdiff -u -r1.4.2.11 -r1.4.2.12 src/sys/dev/ata/TODO.ncq Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:27:36 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c atavar.h wd.c Log Message: remove AT_RST_EMERG, do the queue reset explicitly in wd(4) this should explicitly fix PR kern/47041 with sync during heavy disk activity, even thought it was actually already implicitly fixed by calling ata_thread_run() for drive reset in previous commit already, since the function already called ata_queue_reset() drop now unused ch_reset_flags and drive_reset_flags To generate a diff of this commit: cvs rdiff -u -r1.141.6.13 -r1.141.6.14 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.8 -r1.99.2.9 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.10 -r1.441.2.11 src/sys/dev/ata/wd.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.13 src/sys/dev/ata/ata.c:1.141.6.14 --- src/sys/dev/ata/ata.c:1.141.6.13 Sat Oct 6 20:13:12 2018 +++ src/sys/dev/ata/ata.c Sat Oct 6 20:27:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.13 2018/10/06 20:13:12 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.13 2018/10/06 20:13:12 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $"); #include "opt_ata.h" @@ -480,20 +480,17 @@ atabus_thread(void *arg) } if (chp->ch_flags & ATACH_TH_RESET) { /* this will unfreeze the channel */ - ata_thread_run(chp, AT_WAIT | chp->ch_reset_flags, + ata_thread_run(chp, AT_WAIT, ATACH_TH_RESET, ATACH_NODRIVE); } else if (chp->ch_flags & ATACH_TH_DRIVE_RESET) { for (i = 0; i < chp->ch_ndrives; i++) { struct ata_drive_datas *drvp; -int drv_reset_flags; drvp = >ch_drive[i]; -drv_reset_flags = drvp->drive_reset_flags; if (drvp->drive_flags & ATA_DRIVE_TH_RESET) { ata_thread_run(chp, - AT_WAIT | drv_reset_flags, - ATACH_TH_DRIVE_RESET, i); + AT_WAIT, ATACH_TH_DRIVE_RESET, i); } } chp->ch_flags &= ~ATACH_TH_DRIVE_RESET; @@ -1527,9 +1524,6 @@ ata_kill_active(struct ata_channel *chp, TAILQ_FOREACH_SAFE(xfer, >active_xfers, c_activechain, xfernext) { xfer->ops->c_kill_xfer(xfer->c_chp, xfer, reason); } - - if (flags & AT_RST_EMERG) - ata_queue_reset(chq); } /* @@ -1651,7 +1645,6 @@ ata_thread_run(struct ata_channel *chp, /* No need to schedule another reset */ return; } - chp->ch_reset_flags = flags & AT_RST_EMERG; break; case ATACH_TH_DRIVE_RESET: KASSERT(drive <= chp->ch_ndrives); @@ -1662,7 +1655,6 @@ ata_thread_run(struct ata_channel *chp, return; } drvp->drive_flags |= ATA_DRIVE_TH_RESET; - drvp->drive_reset_flags = flags; break; default: panic("%s: unknown type: %x", __func__, type); @@ -1726,11 +1718,6 @@ ata_thread_run(struct ata_channel *chp, /* Signal the thread in case there is an xfer to run */ cv_signal(>ch_thr_idle); - - if (flags & AT_RST_EMERG) { - /* make sure that we can use polled commands */ - ata_queue_reset(chp->ch_queue); - } } int Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.99.2.8 src/sys/dev/ata/atavar.h:1.99.2.9 --- src/sys/dev/ata/atavar.h:1.99.2.8 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ata/atavar.h Sat Oct 6 20:27:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.99.2.8 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.99.2.9 2018/10/06 20:27:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -275,7 +275,6 @@ struct ata_drive_datas { #define ATA_DRIVE_NCQ 0x0200 /* drive supports NCQ feature set */ #define ATA_DRIVE_NCQ_PRIO 0x0400 /* drive supports NCQ PRIO field */ #define ATA_DRIVE_TH_RESET 0x0800 /* drive waits for thread drive reset */ - int drive_reset_flags; /* flags for drive reset via thread */ uint8_t drive_type; #define ATA_DRIVET_NONE 0 @@ -365,9 +364,6 @@ struct ata_bustype { int (*ata_bio)(struct ata_drive_datas *, struct ata_xfer *); void (*ata_reset_drive)(struct ata_drive_datas *, int, uint32_t *); void (*ata_reset_channel)(struct ata_channel *, int); -/* extra flags for ata_reset_*(), in addition to AT_* */ -#define AT_RST_EMERG 0x1 /* emergency - e.g. for a dump */ - int (*ata_exec_command)(struct ata_drive_datas *, struct ata_xfer *); @@ -421,9 +417,6 @@ struct ata_channel { #define ATACH_NODRIVE 0xff /* no drive selected for reset */ - /* for the reset callback */ - int ch_reset_flags; - /* for the timeout callout */ struct callout c_timo_callout; /* timeout callout handle */ Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.10 src/sys/dev/ata/wd.c:1.441.2.11 ---
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:27:36 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c atavar.h wd.c Log Message: remove AT_RST_EMERG, do the queue reset explicitly in wd(4) this should explicitly fix PR kern/47041 with sync during heavy disk activity, even thought it was actually already implicitly fixed by calling ata_thread_run() for drive reset in previous commit already, since the function already called ata_queue_reset() drop now unused ch_reset_flags and drive_reset_flags To generate a diff of this commit: cvs rdiff -u -r1.141.6.13 -r1.141.6.14 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.8 -r1.99.2.9 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.10 -r1.441.2.11 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:13:12 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: remove extra newline To generate a diff of this commit: cvs rdiff -u -r1.141.6.12 -r1.141.6.13 src/sys/dev/ata/ata.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.12 src/sys/dev/ata/ata.c:1.141.6.13 --- src/sys/dev/ata/ata.c:1.141.6.12 Sat Oct 6 20:12:37 2018 +++ src/sys/dev/ata/ata.c Sat Oct 6 20:13:12 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.12 2018/10/06 20:12:37 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.13 2018/10/06 20:13:12 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.12 2018/10/06 20:12:37 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.13 2018/10/06 20:13:12 jdolecek Exp $"); #include "opt_ata.h" @@ -1676,7 +1676,6 @@ ata_thread_run(struct ata_channel *chp, ata_channel_freeze_locked(chp); chp->ch_flags |= type; - cv_signal(>ch_thr_idle); return; }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:13:12 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: remove extra newline To generate a diff of this commit: cvs rdiff -u -r1.141.6.12 -r1.141.6.13 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:12:37 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: fix ata_thread_run() for drive reset to set and check correct drive_flags To generate a diff of this commit: cvs rdiff -u -r1.141.6.11 -r1.141.6.12 src/sys/dev/ata/ata.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.11 src/sys/dev/ata/ata.c:1.141.6.12 --- src/sys/dev/ata/ata.c:1.141.6.11 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ata/ata.c Sat Oct 6 20:12:37 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.11 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.12 2018/10/06 20:12:37 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.11 2018/10/03 19:20:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.12 2018/10/06 20:12:37 jdolecek Exp $"); #include "opt_ata.h" @@ -490,7 +490,7 @@ atabus_thread(void *arg) drvp = >ch_drive[i]; drv_reset_flags = drvp->drive_reset_flags; -if (drvp->drive_flags & ATACH_TH_DRIVE_RESET) { +if (drvp->drive_flags & ATA_DRIVE_TH_RESET) { ata_thread_run(chp, AT_WAIT | drv_reset_flags, ATACH_TH_DRIVE_RESET, i); @@ -1645,26 +1645,23 @@ ata_thread_run(struct ata_channel *chp, ATADEBUG_PRINT(("%s flags 0x%x ch_flags 0x%x\n", __func__, flags, chp->ch_flags), DEBUG_FUNCS | DEBUG_XFERS); if ((flags & (AT_POLL | AT_WAIT)) == 0) { - if (chp->ch_flags & type) { - /* No need to schedule a reset more than one time. */ - return; - } - - /* - * Block execution of other commands while reset is scheduled - * to a thread. - */ - ata_channel_freeze_locked(chp); - chp->ch_flags |= type; - - switch (type) { case ATACH_TH_RESET: + if (chp->ch_flags & ATACH_TH_RESET) { +/* No need to schedule another reset */ +return; + } chp->ch_reset_flags = flags & AT_RST_EMERG; break; case ATACH_TH_DRIVE_RESET: + KASSERT(drive <= chp->ch_ndrives); drvp = >ch_drive[drive]; - drvp->drive_flags |= ATACH_TH_DRIVE_RESET; + + if (drvp->drive_flags & ATA_DRIVE_TH_RESET) { +/* No need to schedule another reset */ +return; + } + drvp->drive_flags |= ATA_DRIVE_TH_RESET; drvp->drive_reset_flags = flags; break; default: @@ -1672,6 +1669,14 @@ ata_thread_run(struct ata_channel *chp, /* NOTREACHED */ } + /* + * Block execution of other commands while reset is scheduled + * to a thread. + */ + ata_channel_freeze_locked(chp); + chp->ch_flags |= type; + + cv_signal(>ch_thr_idle); return; }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 20:12:37 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: fix ata_thread_run() for drive reset to set and check correct drive_flags To generate a diff of this commit: cvs rdiff -u -r1.141.6.11 -r1.141.6.12 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 19:25:43 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: wd.c Log Message: fix dump to also hold channel lock for the drive reset To generate a diff of this commit: cvs rdiff -u -r1.441.2.9 -r1.441.2.10 src/sys/dev/ata/wd.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/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.9 src/sys/dev/ata/wd.c:1.441.2.10 --- src/sys/dev/ata/wd.c:1.441.2.9 Thu Oct 4 19:42:01 2018 +++ src/sys/dev/ata/wd.c Sat Oct 6 19:25:43 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.9 2018/10/04 19:42:01 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.441.2.10 2018/10/06 19:25:43 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.9 2018/10/04 19:42:01 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.10 2018/10/06 19:25:43 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -1492,8 +1492,11 @@ wd_dumpblocks(device_t dev, void *va, da /* Recalibrate, if first dump transfer. */ if (wddumprecalibrated == 0) { wddumprecalibrated = 1; - (*wd->atabus->ata_reset_drive)(wd->drvp, - AT_POLL | AT_RST_EMERG, NULL); + ata_channel_lock(wd->drvp->chnl_softc); + /* This will directly execute the reset due to AT_POLL */ + ata_thread_run(wd->drvp->chnl_softc, AT_POLL | AT_RST_EMERG, + ATACH_TH_DRIVE_RESET, wd->drvp->drive); + ata_channel_unlock(wd->drvp->chnl_softc); wd->drvp->state = RESET; }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 6 19:25:43 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: wd.c Log Message: fix dump to also hold channel lock for the drive reset To generate a diff of this commit: cvs rdiff -u -r1.441.2.9 -r1.441.2.10 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Oct 4 19:42:01 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq wd.c Log Message: relax the NOERROR + C_CHAOS, just rerun the xfer instead of panic, to handle another variant of bad/missing AHCI error recovery, this time under Parallels To generate a diff of this commit: cvs rdiff -u -r1.4.2.10 -r1.4.2.11 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.441.2.8 -r1.441.2.9 src/sys/dev/ata/wd.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.4.2.10 src/sys/dev/ata/TODO.ncq:1.4.2.11 --- src/sys/dev/ata/TODO.ncq:1.4.2.10 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ata/TODO.ncq Thu Oct 4 19:42:01 2018 @@ -1,6 +1,7 @@ jdolecek-ncqfixes goals: -- fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY - ends up being handled as NOERROR, triggering KASSERT() in wd(4) +- re-check READ LOG EXT handling under native and Parallels to make sure + the NOERROR under Parallels is their bug and not ours +- run recovery via atathread, move to new function and share ahci/siisata/mvsata - remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c) Bugs Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.8 src/sys/dev/ata/wd.c:1.441.2.9 --- src/sys/dev/ata/wd.c:1.441.2.8 Thu Oct 4 17:53:23 2018 +++ src/sys/dev/ata/wd.c Thu Oct 4 19:42:01 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.8 2018/10/04 17:53:23 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.441.2.9 2018/10/04 19:42:01 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.8 2018/10/04 17:53:23 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.9 2018/10/04 19:42:01 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -914,13 +914,23 @@ out: bp->b_error = EIO; break; case NOERROR: +#ifdef WD_CHAOS_MONKEY + /* + * For example Parallels AHCI emulation doesn't actually + * return error for the invalid I/O, so just re-run + * the request and do not panic. + */ + if (__predict_false(xfer->c_flags & C_CHAOS)) { + xfer->c_bio.error = REQUEUE; + errmsg = "chaos noerror"; + goto retry2; + } +#endif + noerror: if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0) device_printf(dksc->sc_dev, "soft error (corrected) xfer %"PRIxPTR"\n", (intptr_t)xfer & PAGE_MASK); -#ifdef WD_CHAOS_MONKEY - KASSERT((xfer->c_flags & C_CHAOS) == 0); -#endif break; case ERR_NODEV: bp->b_error = EIO;
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Oct 4 19:42:01 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq wd.c Log Message: relax the NOERROR + C_CHAOS, just rerun the xfer instead of panic, to handle another variant of bad/missing AHCI error recovery, this time under Parallels To generate a diff of this commit: cvs rdiff -u -r1.4.2.10 -r1.4.2.11 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.441.2.8 -r1.441.2.9 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Thu Oct 4 17:59:35 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c Log Message: further channel locking pass for reset To generate a diff of this commit: cvs rdiff -u -r1.62.2.6 -r1.62.2.7 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.5 -r1.41.2.6 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.6 -r1.35.6.7 src/sys/dev/ic/siisata.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/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.62.2.6 src/sys/dev/ic/ahcisata_core.c:1.62.2.7 --- src/sys/dev/ic/ahcisata_core.c:1.62.2.6 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ic/ahcisata_core.c Thu Oct 4 17:59:35 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.62.2.6 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.62.2.7 2018/10/04 17:59:35 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.6 2018/10/03 19:20:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.7 2018/10/04 17:59:35 jdolecek Exp $"); #include #include @@ -885,7 +885,7 @@ ahci_reset_channel(struct ata_channel *c struct ahci_channel *achp = (struct ahci_channel *)chp; int i, tfd; - ata_channel_lock(chp); + ata_channel_lock_owned(chp); ahci_channel_stop(sc, chp, flags); if (sata_reset_interface(chp, sc->sc_ahcit, achp->ahcic_scontrol, @@ -915,8 +915,6 @@ ahci_reset_channel(struct ata_channel *c /* clear port interrupt register */ AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0x); - ata_channel_unlock(chp); - return; } @@ -1709,7 +1707,9 @@ ahci_channel_recover(struct ahci_softc * * transfers. */ reset: + ata_channel_lock(chp); ahci_reset_channel(chp, AT_POLL); + ata_channel_unlock(chp); goto out; /* NOTREACHED */ Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.41.2.5 src/sys/dev/ic/mvsata.c:1.41.2.6 --- src/sys/dev/ic/mvsata.c:1.41.2.5 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ic/mvsata.c Thu Oct 4 17:59:35 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.41.2.5 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.41.2.6 2018/10/04 17:59:35 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.5 2018/10/03 19:20:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.6 2018/10/04 17:59:35 jdolecek Exp $"); #include "opt_mvsata.h" @@ -635,7 +635,9 @@ mvsata_channel_recover(struct mvsata_por * reset the drive. This will also kill all still outstanding * transfers. */ + ata_channel_lock(chp); mvsata_reset_channel(chp, AT_POLL); + ata_channel_unlock(chp); goto out; /* NOTREACHED */ Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.35.6.6 src/sys/dev/ic/siisata.c:1.35.6.7 --- src/sys/dev/ic/siisata.c:1.35.6.6 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ic/siisata.c Thu Oct 4 17:59:35 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.35.6.6 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.35.6.7 2018/10/04 17:59:35 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.6 2018/10/03 19:20:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.7 2018/10/04 17:59:35 jdolecek Exp $"); #include #include @@ -686,7 +686,9 @@ siisata_channel_recover(struct ata_chann * transfers. */ reset: + ata_channel_lock(chp); siisata_device_reset(chp); + ata_channel_unlock(chp); goto out; /* NOTREACHED */ @@ -730,10 +732,10 @@ siisata_reset_drive(struct ata_drive_dat int i; bool timed_out; - siisata_reinit_port(chp, drvp->drive); - ata_channel_lock_owned(chp); + siisata_reinit_port(chp, drvp->drive); + /* get a slot for running the command on */ if (!ata_queue_alloc_slot(chp, _slot, ATA_MAX_OPENINGS)) { panic("%s: %s: failed to get xfer for reset, port %d\n", @@ -1556,7 +1558,9 @@ siisata_reinit_port(struct ata_channel * } if ((ps & PR_PS_PORT_READY) == 0) { printf("%s: timeout waiting for port to be ready\n", __func__); + ata_channel_lock(chp); siisata_reset_channel(chp, AT_POLL); + ata_channel_unlock(chp); } if (chp->ch_ndrives > 1)
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Thu Oct 4 17:59:35 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c Log Message: further channel locking pass for reset To generate a diff of this commit: cvs rdiff -u -r1.62.2.6 -r1.62.2.7 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.5 -r1.41.2.6 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.6 -r1.35.6.7 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Oct 4 17:53:23 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: wd.c Log Message: don't add +1 to retry on error To generate a diff of this commit: cvs rdiff -u -r1.441.2.7 -r1.441.2.8 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Oct 4 17:53:23 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: wd.c Log Message: don't add +1 to retry on error To generate a diff of this commit: cvs rdiff -u -r1.441.2.7 -r1.441.2.8 src/sys/dev/ata/wd.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/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.7 src/sys/dev/ata/wd.c:1.441.2.8 --- src/sys/dev/ata/wd.c:1.441.2.7 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ata/wd.c Thu Oct 4 17:53:23 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.7 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.441.2.8 2018/10/04 17:53:23 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.7 2018/10/03 19:20:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.8 2018/10/04 17:53:23 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -853,7 +853,7 @@ retry2: if (xfer->c_retries < WDIORETRIES) printf(", xfer %"PRIxPTR", retry %d", (intptr_t)xfer & PAGE_MASK, - xfer->c_retries + 1); + xfer->c_retries); printf("\n"); if (do_perror) wdperror(wd, xfer);
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Wed Oct 3 19:20:48 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c atavar.h wd.c src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c wdc.c Log Message: change channel reset and drive reset for all ATA controllers to always run via thread, and with channel lock held the whole time; the queue is frozen while reset is pending for this repurpose ata_reset_channel() into new ata_thread_run() also adjust some device printfs to not leak xfer pointer, and avoid aprint_* for non-autoconf messages To generate a diff of this commit: cvs rdiff -u -r1.4.2.9 -r1.4.2.10 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.10 -r1.141.6.11 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.7 -r1.99.2.8 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.6 -r1.441.2.7 src/sys/dev/ata/wd.c cvs rdiff -u -r1.62.2.5 -r1.62.2.6 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.4 -r1.41.2.5 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.5 -r1.35.6.6 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.288.6.2 -r1.288.6.3 src/sys/dev/ic/wdc.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.4.2.9 src/sys/dev/ata/TODO.ncq:1.4.2.10 --- src/sys/dev/ata/TODO.ncq:1.4.2.9 Mon Sep 24 19:48:02 2018 +++ src/sys/dev/ata/TODO.ncq Wed Oct 3 19:20:48 2018 @@ -2,8 +2,6 @@ jdolecek-ncqfixes goals: - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY ends up being handled as NOERROR, triggering KASSERT() in wd(4) - remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c) -- revert rev 1.431 of wd.c (AT_POOL removal) - ensure still works - for the reset-via-thread case Bugs Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.10 src/sys/dev/ata/ata.c:1.141.6.11 --- src/sys/dev/ata/ata.c:1.141.6.10 Mon Sep 24 19:48:02 2018 +++ src/sys/dev/ata/ata.c Wed Oct 3 19:20:48 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.10 2018/09/24 19:48:02 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.11 2018/10/03 19:20:48 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.10 2018/09/24 19:48:02 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.11 2018/10/03 19:20:48 jdolecek Exp $"); #include "opt_ata.h" @@ -440,7 +440,7 @@ atabus_thread(void *arg) struct ata_channel *chp = sc->sc_chan; struct ata_queue *chq = chp->ch_queue; struct ata_xfer *xfer; - int i, rv, s; + int i, rv; ata_channel_lock(chp); chp->ch_flags |= ATACH_TH_RUN; @@ -462,7 +462,8 @@ atabus_thread(void *arg) ata_channel_lock(chp); for (;;) { - if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 && + if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_TH_DRIVE_RESET + | ATACH_SHUTDOWN)) == 0 && (chq->queue_active == 0 || chq->queue_freeze == 0)) { chp->ch_flags &= ~ATACH_TH_RUN; cv_wait(>ch_thr_idle, >ch_lock); @@ -478,12 +479,24 @@ atabus_thread(void *arg) ata_channel_lock(chp); } if (chp->ch_flags & ATACH_TH_RESET) { - /* ata_reset_channel() will unfreeze the channel */ - ata_channel_unlock(chp); - s = splbio(); - ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags); - splx(s); - ata_channel_lock(chp); + /* this will unfreeze the channel */ + ata_thread_run(chp, AT_WAIT | chp->ch_reset_flags, + ATACH_TH_RESET, ATACH_NODRIVE); + } else if (chp->ch_flags & ATACH_TH_DRIVE_RESET) { + for (i = 0; i < chp->ch_ndrives; i++) { +struct ata_drive_datas *drvp; +int drv_reset_flags; + +drvp = >ch_drive[i]; +drv_reset_flags = drvp->drive_reset_flags; + +if (drvp->drive_flags & ATACH_TH_DRIVE_RESET) { + ata_thread_run(chp, + AT_WAIT | drv_reset_flags, + ATACH_TH_DRIVE_RESET, i); +} + } + chp->ch_flags &= ~ATACH_TH_DRIVE_RESET; } else if (chq->queue_active > 0 && chq->queue_freeze == 1) { /* * Caller has bumped queue_freeze, decrease it. This @@ -511,6 +524,11 @@ atabus_thread(void *arg) } } else if (chq->queue_freeze > 1) panic("%s: queue_freeze", __func__); + + /* Try to run down the queue once after each event is handled */ + ata_channel_unlock(chp); + atastart(chp); + ata_channel_lock(chp); } chp->ch_thread = NULL; cv_signal(>ch_thr_idle); @@ -1471,7 +1489,8 @@ ata_timo_xfer_check(struct ata_xfer *xfe ata_channel_unlock(chp); device_printf(drvp->drv_softc, - "xfer %p freed while invoking timeout\n", xfer); + "xfer %"PRIxPTR" freed while invoking timeout\n", + (intptr_t)xfer & PAGE_MASK); ata_free_xfer(chp, xfer); return true; @@ -1481,7 +1500,8 @@ ata_timo_xfer_check(struct ata_xfer *xfe ata_channel_unlock(chp);
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Wed Oct 3 19:20:48 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c atavar.h wd.c src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c wdc.c Log Message: change channel reset and drive reset for all ATA controllers to always run via thread, and with channel lock held the whole time; the queue is frozen while reset is pending for this repurpose ata_reset_channel() into new ata_thread_run() also adjust some device printfs to not leak xfer pointer, and avoid aprint_* for non-autoconf messages To generate a diff of this commit: cvs rdiff -u -r1.4.2.9 -r1.4.2.10 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.10 -r1.141.6.11 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.7 -r1.99.2.8 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.6 -r1.441.2.7 src/sys/dev/ata/wd.c cvs rdiff -u -r1.62.2.5 -r1.62.2.6 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.4 -r1.41.2.5 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.5 -r1.35.6.6 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.288.6.2 -r1.288.6.3 src/sys/dev/ic/wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Sep 24 21:19:50 UTC 2018 Modified Files: src/sys/dev/isa [jdolecek-ncqfixes]: files.isa src/sys/dev/isapnp [jdolecek-ncqfixes]: files.isapnp src/sys/dev/pci [jdolecek-ncqfixes]: files.pci src/sys/dev/pcmcia [jdolecek-ncqfixes]: files.pcmcia Log Message: partial HEAD sync - ISDN device removal To generate a diff of this commit: cvs rdiff -u -r1.169 -r1.169.6.1 src/sys/dev/isa/files.isa cvs rdiff -u -r1.38 -r1.38.166.1 src/sys/dev/isapnp/files.isapnp cvs rdiff -u -r1.400 -r1.400.2.1 src/sys/dev/pci/files.pci cvs rdiff -u -r1.58 -r1.58.42.1 src/sys/dev/pcmcia/files.pcmcia 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/isa/files.isa diff -u src/sys/dev/isa/files.isa:1.169 src/sys/dev/isa/files.isa:1.169.6.1 --- src/sys/dev/isa/files.isa:1.169 Tue Jan 2 00:25:35 2018 +++ src/sys/dev/isa/files.isa Mon Sep 24 21:19:50 2018 @@ -1,4 +1,4 @@ -# $NetBSD: files.isa,v 1.169 2018/01/02 00:25:35 christos Exp $ +# $NetBSD: files.isa,v 1.169.6.1 2018/09/24 21:19:50 jdolecek Exp $ # # Config file and device description for machine-independent ISA code. # Included by ports that need it. Requires that the SCSI files be @@ -484,22 +484,6 @@ device aps: sysmon_envsys attach aps at isa with aps file dev/isa/aps.c aps -# ISDN devices -attach isic at isa with isic_isa -file dev/isa/isic_isa.c isic_isa -#attach daic at isa with daic_isa -#file dev/isa/daic_isa.c daic_isa - -defflag opt_isicisa.h ISICISA_TEL_S0_8 ISICISA_TEL_S0_16 ISICISA_TEL_S0_16_3 - ISICISA_AVM_A1 ISICISA_USR_STI ISICISA_ITKIX1 - -file dev/isa/isic_isa_tel_s08.c isic_isa -file dev/isa/isic_isa_tel_s016.c isic_isa -file dev/isa/isic_isa_tel_s0163.c isic_isa -file dev/isa/isic_isa_avm_a1.c isic_isa -file dev/isa/isic_isa_usr_sti.c isic_isa -file dev/isa/isic_isa_itk_ix1.c isic_isa - # Game adapter (joystick) attach joy at isa with joy_isa file dev/isa/joy_isa.c joy_isa Index: src/sys/dev/isapnp/files.isapnp diff -u src/sys/dev/isapnp/files.isapnp:1.38 src/sys/dev/isapnp/files.isapnp:1.38.166.1 --- src/sys/dev/isapnp/files.isapnp:1.38 Sun Dec 11 12:22:16 2005 +++ src/sys/dev/isapnp/files.isapnp Mon Sep 24 21:19:50 2018 @@ -1,4 +1,4 @@ -# $NetBSD: files.isapnp,v 1.38 2005/12/11 12:22:16 christos Exp $ +# $NetBSD: files.isapnp,v 1.38.166.1 2018/09/24 21:19:50 jdolecek Exp $ # # Config file and device description for machine-independent ISAPnP code. # Included by ports that need it. @@ -91,24 +91,6 @@ file dev/isapnp/aha_isapnp.c aha_isapn attach aic at isapnp with aic_isapnp file dev/isapnp/aic_isapnp.c aic_isapnp -# ISDN devices -attach isic at isapnp with isic_isapnp -file dev/isapnp/isic_isapnp.c isic_isapnp - -defflag opt_isicpnp.h ISICPNP_TEL_S0_16_3_P ISICPNP_CRTX_S0_P ISICPNP_DRN_NGO - ISICPNP_ELSA_QS1ISA ISICPNP_ELSA_PCC16 - ISICPNP_SEDLBAUER ISICPNP_DYNALINK - ISICPNP_SIEMENS_ISURF2 ISICPNP_ITKIX - -file dev/isapnp/isic_isapnp_tel_s0P.c isic_isapnp -file dev/isapnp/isic_isapnp_ctx_s0P.c isic_isapnp -file dev/isapnp/isic_isapnp_drn_ngo.c isic_isapnp -file dev/isapnp/isic_isapnp_elsa_qs1i.c isic_isapnp -file dev/isapnp/isic_isapnp_sws.c isic_isapnp -file dev/isapnp/isic_isapnp_dynalink.c isic_isapnp -file dev/isapnp/isic_isapnp_siemens_isurf.c isic_isapnp -file dev/isapnp/isic_isapnp_itkix.c isic_isapnp - # Game adapter (joystick) attach joy at isapnp with joy_isapnp file dev/isapnp/joy_isapnp.c joy_isapnp Index: src/sys/dev/pci/files.pci diff -u src/sys/dev/pci/files.pci:1.400 src/sys/dev/pci/files.pci:1.400.2.1 --- src/sys/dev/pci/files.pci:1.400 Sat Aug 25 07:48:57 2018 +++ src/sys/dev/pci/files.pci Mon Sep 24 21:19:50 2018 @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.400 2018/08/25 07:48:57 maxv Exp $ +# $NetBSD: files.pci,v 1.400.2.1 2018/09/24 21:19:50 jdolecek Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -167,11 +167,6 @@ device de: ether, ifnet, arp attach de at pci file dev/pci/if_de.c de -# Efficient Networks, Inc. ATM interface -# device declaration in sys/conf/files -attach en at pci with en_pci -file dev/pci/if_en_pci.c en_pci - # 3Com 3c590 and 3c595 Ethernet controllers # device declaration in sys/conf/files attach ep at pci with ep_pci @@ -812,24 +807,6 @@ filedev/pci/if_malo_pci.c malo attach wi at pci with wi_pci file dev/pci/if_wi_pci.c wi_pci -# ISDN devices -attach isic at pci with isic_pci -file dev/pci/isic_pci.c isic_pci - -file dev/pci/isic_pci_elsa_qs1p.c isic_pci - -# AVM T1/B1 -attach iavc at pci with iavc_pci -file dev/pci/iavc_pci.c iavc_pci - -device ifpci: isdndev, passive_isdn, nisac -attach ifpci at pci -file dev/pci/ifpci.c ifpci - -device ifritz: isdndev, passive_isdn, nisacsx -attach ifritz at pci -file dev/pci/ifpci2.c ifritz - # Winbond
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Sep 24 21:19:50 UTC 2018 Modified Files: src/sys/dev/isa [jdolecek-ncqfixes]: files.isa src/sys/dev/isapnp [jdolecek-ncqfixes]: files.isapnp src/sys/dev/pci [jdolecek-ncqfixes]: files.pci src/sys/dev/pcmcia [jdolecek-ncqfixes]: files.pcmcia Log Message: partial HEAD sync - ISDN device removal To generate a diff of this commit: cvs rdiff -u -r1.169 -r1.169.6.1 src/sys/dev/isa/files.isa cvs rdiff -u -r1.38 -r1.38.166.1 src/sys/dev/isapnp/files.isapnp cvs rdiff -u -r1.400 -r1.400.2.1 src/sys/dev/pci/files.pci cvs rdiff -u -r1.58 -r1.58.42.1 src/sys/dev/pcmcia/files.pcmcia Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 24 19:48:02 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c Log Message: replace KASSERT() for READ LOG EXT returning without error indication with just log to avoid triggering panic under QEMU - it doesn't implement the command for AHCI emulation To generate a diff of this commit: cvs rdiff -u -r1.4.2.8 -r1.4.2.9 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.9 -r1.141.6.10 src/sys/dev/ata/ata.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.4.2.8 src/sys/dev/ata/TODO.ncq:1.4.2.9 --- src/sys/dev/ata/TODO.ncq:1.4.2.8 Sat Sep 22 17:52:24 2018 +++ src/sys/dev/ata/TODO.ncq Mon Sep 24 19:48:02 2018 @@ -1,9 +1,9 @@ jdolecek-ncqfixes goals: -- re-fix QEMU ahci(4) bug workaround (no READ LOG EXT support) - now it - triggers KASSERT() - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY ends up being handled as NOERROR, triggering KASSERT() in wd(4) - remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c) +- revert rev 1.431 of wd.c (AT_POOL removal) - ensure still works + for the reset-via-thread case Bugs Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.9 src/sys/dev/ata/ata.c:1.141.6.10 --- src/sys/dev/ata/ata.c:1.141.6.9 Sat Sep 22 16:14:25 2018 +++ src/sys/dev/ata/ata.c Mon Sep 24 19:48:02 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.9 2018/09/22 16:14:25 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.10 2018/09/24 19:48:02 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.9 2018/09/22 16:14:25 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.10 2018/09/24 19:48:02 jdolecek Exp $"); #include "opt_ata.h" @@ -972,7 +972,7 @@ ata_read_log_ext_ncq(struct ata_drive_da for (int i = 0; i < sizeof(drvp->recovery_blk); i++) cksum += tb[i]; if (cksum != 0) { - aprint_error_dev(drvp->drv_softc, + device_printf(drvp->drv_softc, "invalid checksum %x for READ LOG EXT page %x\n", cksum, page); rv = EINVAL; @@ -989,10 +989,20 @@ ata_read_log_ext_ncq(struct ata_drive_da *status = tb[2]; *err = tb[3]; - KASSERTMSG((*status & WDCS_ERR), - "%s: non-error command slot %d reported by READ LOG EXT page %x: " - "err %x status %x\n", - device_xname(drvp->drv_softc), *slot, page, *err, *status); + if ((*status & WDCS_ERR) == 0) { + /* + * We expect error here. Normal physical drives always + * do, it's part of ATA standard. However, QEMU AHCI emulation + * misehandles READ LOG EXT in a way that the command itself + * returns without error, but no data is transferred. + */ + device_printf(drvp->drv_softc, + "READ LOG EXT page %x failed to report error: " + "slot %d err %x status %x\n", + page, *slot, *err, *status); + rv = EOPNOTSUPP; + goto out; + } rv = 0; @@ -1460,7 +1470,7 @@ ata_timo_xfer_check(struct ata_xfer *xfe xfer->c_flags &= ~C_FREE; ata_channel_unlock(chp); - aprint_normal_dev(drvp->drv_softc, + device_printf(drvp->drv_softc, "xfer %p freed while invoking timeout\n", xfer); ata_free_xfer(chp, xfer); @@ -1470,7 +1480,7 @@ ata_timo_xfer_check(struct ata_xfer *xfe /* Race vs. callout_stop() in ata_deactivate_xfer() */ ata_channel_unlock(chp); - aprint_normal_dev(drvp->drv_softc, + device_printf(drvp->drv_softc, "xfer %p deactivated while invoking timeout\n", xfer); return true; }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 24 19:48:02 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c Log Message: replace KASSERT() for READ LOG EXT returning without error indication with just log to avoid triggering panic under QEMU - it doesn't implement the command for AHCI emulation To generate a diff of this commit: cvs rdiff -u -r1.4.2.8 -r1.4.2.9 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.9 -r1.141.6.10 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 17:52:24 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: one more To generate a diff of this commit: cvs rdiff -u -r1.4.2.7 -r1.4.2.8 src/sys/dev/ata/TODO.ncq 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.4.2.7 src/sys/dev/ata/TODO.ncq:1.4.2.8 --- src/sys/dev/ata/TODO.ncq:1.4.2.7 Sat Sep 22 17:50:09 2018 +++ src/sys/dev/ata/TODO.ncq Sat Sep 22 17:52:24 2018 @@ -3,6 +3,7 @@ jdolecek-ncqfixes goals: triggers KASSERT() - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY ends up being handled as NOERROR, triggering KASSERT() in wd(4) +- remove controller-specific slot bitmaps (ic/siisata.c, ic/ahcisata_core.c) Bugs
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 17:52:24 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: one more To generate a diff of this commit: cvs rdiff -u -r1.4.2.7 -r1.4.2.8 src/sys/dev/ata/TODO.ncq Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 17:50:09 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata_subr.c atavar.h wd.c wdvar.h Log Message: remove explicit ata_channel_start() calls, it's no longer necessary now that ata_xfer's are allocated via pool and not really limited; replace by just a callout to restart the processing for rare cases where system runs out of memory To generate a diff of this commit: cvs rdiff -u -r1.4.2.6 -r1.4.2.7 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.6.2.5 -r1.6.2.6 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.6 -r1.99.2.7 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.5 -r1.441.2.6 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46.6.3 -r1.46.6.4 src/sys/dev/ata/wdvar.h 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.4.2.6 src/sys/dev/ata/TODO.ncq:1.4.2.7 --- src/sys/dev/ata/TODO.ncq:1.4.2.6 Sat Sep 22 16:14:25 2018 +++ src/sys/dev/ata/TODO.ncq Sat Sep 22 17:50:09 2018 @@ -1,6 +1,4 @@ jdolecek-ncqfixes goals: -- add to wd(4) a callout to restart buf queue processing when ata_get_xfer() - call fails and remove ata_channel_start() - re-fix QEMU ahci(4) bug workaround (no READ LOG EXT support) - now it triggers KASSERT() - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY Index: src/sys/dev/ata/ata_subr.c diff -u src/sys/dev/ata/ata_subr.c:1.6.2.5 src/sys/dev/ata/ata_subr.c:1.6.2.6 --- src/sys/dev/ata/ata_subr.c:1.6.2.5 Sat Sep 22 09:22:59 2018 +++ src/sys/dev/ata/ata_subr.c Sat Sep 22 17:50:09 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_subr.c,v 1.6.2.5 2018/09/22 09:22:59 jdolecek Exp $ */ +/* $NetBSD: ata_subr.c,v 1.6.2.6 2018/09/22 17:50:09 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.5 2018/09/22 09:22:59 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.6 2018/09/22 17:50:09 jdolecek Exp $"); #include "opt_ata.h" @@ -257,54 +257,6 @@ ata_timeout(void *v) splx(s); } -/* - * Must be called without any locks, i.e. with both drive and channel locks - * released. - */ -void -ata_channel_start(struct ata_channel *chp, int drive, bool start_self) -{ - int i, s; - struct ata_drive_datas *drvp; - - s = splbio(); - - KASSERT(chp->ch_ndrives > 0); - -#define ATA_DRIVE_START(chp, drive) \ - do { \ - KASSERT(drive < chp->ch_ndrives); \ - drvp = >ch_drive[drive]; \ -\ - if (drvp->drive_type != ATA_DRIVET_ATA && \ - drvp->drive_type != ATA_DRIVET_ATAPI && \ - drvp->drive_type != ATA_DRIVET_OLD) \ - continue;\ -\ - if (drvp->drv_start != NULL) \ - (*drvp->drv_start)(drvp->drv_softc); \ - } while (0) - - /* - * Process drives in round robin fashion starting with next one after - * the one which finished transfer. Thus no single drive would - * completely starve other drives on same channel. - * This loop processes all but the current drive, so won't do anything - * if there is only one drive in channel. - */ - for (i = (drive + 1) % chp->ch_ndrives; i != drive; - i = (i + 1) % chp->ch_ndrives) { - ATA_DRIVE_START(chp, i); - } - - /* Now try to kick off xfers on the current drive */ - if (start_self) - ATA_DRIVE_START(chp, drive); - - splx(s); -#undef ATA_DRIVE_START -} - void ata_channel_lock(struct ata_channel *chp) { Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.99.2.6 src/sys/dev/ata/atavar.h:1.99.2.7 --- src/sys/dev/ata/atavar.h:1.99.2.6 Sat Sep 22 16:14:25 2018 +++ src/sys/dev/ata/atavar.h Sat Sep 22 17:50:09 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.99.2.6 2018/09/22 16:14:25 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.99.2.7 2018/09/22 17:50:09 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -327,7 +327,6 @@ struct ata_drive_datas { /* Callbacks into the drive's driver. */ void (*drv_done)(device_t, struct ata_xfer *); /* xfer is done */ - void (*drv_start)(device_t); /* start queue */ device_t drv_softc; /* ATA drives softc, if any */ struct ata_channel *chnl_softc; /* channel softc */ @@ -547,7 +546,6 @@ void ata_kill_active(struct ata_channel void ata_reset_channel(struct ata_channel *, int); void ata_channel_freeze(struct ata_channel *); void ata_channel_thaw(struct ata_channel *); -void ata_channel_start(struct ata_channel *, int, bool); void ata_channel_lock(struct ata_channel *); void ata_channel_unlock(struct ata_channel *); void ata_channel_lock_owned(struct ata_channel *); Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.5 src/sys/dev/ata/wd.c:1.441.2.6 --- src/sys/dev/ata/wd.c:1.441.2.5 Sat Sep 22 16:14:25 2018 +++ src/sys/dev/ata/wd.c Sat Sep 22 17:50:09 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.5 2018/09/22
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 17:50:09 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata_subr.c atavar.h wd.c wdvar.h Log Message: remove explicit ata_channel_start() calls, it's no longer necessary now that ata_xfer's are allocated via pool and not really limited; replace by just a callout to restart the processing for rare cases where system runs out of memory To generate a diff of this commit: cvs rdiff -u -r1.4.2.6 -r1.4.2.7 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.6.2.5 -r1.6.2.6 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.6 -r1.99.2.7 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.5 -r1.441.2.6 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46.6.3 -r1.46.6.4 src/sys/dev/ata/wdvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 16:14:25 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c atavar.h wd.c wdvar.h Log Message: fix use-after-free in wd(4) dump, detected by switch to the pool change code in wd_dumpblocks() to use it's own non-pool ata_xfer, which skips the deallocation step and thus keeps the contents when the I/O is finished To generate a diff of this commit: cvs rdiff -u -r1.4.2.5 -r1.4.2.6 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.8 -r1.141.6.9 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.5 -r1.99.2.6 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.4 -r1.441.2.5 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46.6.2 -r1.46.6.3 src/sys/dev/ata/wdvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 16:14:25 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c atavar.h wd.c wdvar.h Log Message: fix use-after-free in wd(4) dump, detected by switch to the pool change code in wd_dumpblocks() to use it's own non-pool ata_xfer, which skips the deallocation step and thus keeps the contents when the I/O is finished To generate a diff of this commit: cvs rdiff -u -r1.4.2.5 -r1.4.2.6 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.8 -r1.141.6.9 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.5 -r1.99.2.6 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.4 -r1.441.2.5 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46.6.2 -r1.46.6.3 src/sys/dev/ata/wdvar.h 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.4.2.5 src/sys/dev/ata/TODO.ncq:1.4.2.6 --- src/sys/dev/ata/TODO.ncq:1.4.2.5 Sat Sep 22 09:26:48 2018 +++ src/sys/dev/ata/TODO.ncq Sat Sep 22 16:14:25 2018 @@ -1,8 +1,6 @@ jdolecek-ncqfixes goals: - add to wd(4) a callout to restart buf queue processing when ata_get_xfer() call fails and remove ata_channel_start() -- change wd(4) dump code to use preallocated or on-stack ata_xfer to not rely - on pool having memory - re-fix QEMU ahci(4) bug workaround (no READ LOG EXT support) - now it triggers KASSERT() - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.8 src/sys/dev/ata/ata.c:1.141.6.9 --- src/sys/dev/ata/ata.c:1.141.6.8 Sat Sep 22 12:20:31 2018 +++ src/sys/dev/ata/ata.c Sat Sep 22 16:14:25 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.8 2018/09/22 12:20:31 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.9 2018/09/22 16:14:25 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.8 2018/09/22 12:20:31 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.9 2018/09/22 16:14:25 jdolecek Exp $"); #include "opt_ata.h" @@ -1350,7 +1350,7 @@ ata_free_xfer(struct ata_channel *chp, s ata_channel_lock(chp); - if (xfer->c_flags & (C_WAITACT|C_WAITTIMO)) { + if (__predict_false(xfer->c_flags & (C_WAITACT|C_WAITTIMO))) { /* Someone is waiting for this xfer, so we can't free now */ xfer->c_flags |= C_FREE; cv_broadcast(>c_active); @@ -1360,7 +1360,7 @@ ata_free_xfer(struct ata_channel *chp, s /* XXX move PIOBM and free_gw to deactivate? */ #if NATA_PIOBM /* XXX wdc dependent code */ - if (xfer->c_flags & C_PIOBM) { + if (__predict_false(xfer->c_flags & C_PIOBM)) { struct wdc_softc *wdc = CHAN_TO_WDC(chp); /* finish the busmastering PIO */ @@ -1375,7 +1375,8 @@ ata_free_xfer(struct ata_channel *chp, s ata_channel_unlock(chp); - pool_put(_xfer_pool, xfer); + if (__predict_true(!ISSET(xfer->c_flags, C_PRIVATE_ALLOC))) + pool_put(_xfer_pool, xfer); } void Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.99.2.5 src/sys/dev/ata/atavar.h:1.99.2.6 --- src/sys/dev/ata/atavar.h:1.99.2.5 Sat Sep 22 09:22:59 2018 +++ src/sys/dev/ata/atavar.h Sat Sep 22 16:14:25 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.99.2.5 2018/09/22 09:22:59 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.99.2.6 2018/09/22 16:14:25 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -198,6 +198,7 @@ struct ata_xfer_ops { #define C_WAITTIMO 0x0400 /* race vs. timeout */ #define C_CHAOS 0x0800 /* forced error xfer */ #define C_RECOVERED 0x1000 /* error recovered, no need for reset */ +#define C_PRIVATE_ALLOC 0x2000 /* private alloc, skip pool_put() */ /* reasons for c_kill_xfer() */ #define KILL_GONE 1 /* device is gone while xfer was active */ Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.4 src/sys/dev/ata/wd.c:1.441.2.5 --- src/sys/dev/ata/wd.c:1.441.2.4 Sat Sep 22 09:22:59 2018 +++ src/sys/dev/ata/wd.c Sat Sep 22 16:14:25 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.4 2018/09/22 09:22:59 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.441.2.5 2018/09/22 16:14:25 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.4 2018/09/22 09:22:59 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.5 2018/09/22 16:14:25 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -1458,7 +1458,7 @@ wd_dumpblocks(device_t dev, void *va, da struct wd_softc *wd = device_private(dev); struct dk_softc *dksc = >sc_dksc; struct disk_geom *dg = >sc_dkdev.dk_geom; - struct ata_xfer *xfer; + struct ata_xfer *xfer = >dump_xfer; int err; /* Recalibrate, if first dump transfer. */ @@ -1469,11 +1469,8 @@ wd_dumpblocks(device_t dev, void *va, da
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 12:20:32 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: revert atabus_alloc_drives() to use KM_NOSLEEP again - it's called with ch_lock held hence cannot actually sleep, fixing is out of scope of the branch To generate a diff of this commit: cvs rdiff -u -r1.141.6.7 -r1.141.6.8 src/sys/dev/ata/ata.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.7 src/sys/dev/ata/ata.c:1.141.6.8 --- src/sys/dev/ata/ata.c:1.141.6.7 Sat Sep 22 09:26:48 2018 +++ src/sys/dev/ata/ata.c Sat Sep 22 12:20:31 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.7 2018/09/22 09:26:48 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.8 2018/09/22 12:20:31 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.7 2018/09/22 09:26:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.8 2018/09/22 12:20:31 jdolecek Exp $"); #include "opt_ata.h" @@ -719,7 +719,7 @@ atabus_alloc_drives(struct ata_channel * atabus_free_drives(chp); if (chp->ch_drive == NULL) { chp->ch_drive = kmem_zalloc( - sizeof(struct ata_drive_datas) * ndrives, KM_SLEEP); + sizeof(struct ata_drive_datas) * ndrives, KM_NOSLEEP); } if (chp->ch_drive == NULL) { aprint_error_dev(chp->ch_atac->atac_dev,
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 12:20:32 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c Log Message: revert atabus_alloc_drives() to use KM_NOSLEEP again - it's called with ch_lock held hence cannot actually sleep, fixing is out of scope of the branch To generate a diff of this commit: cvs rdiff -u -r1.141.6.7 -r1.141.6.8 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 09:26:49 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c Log Message: use KM_SLEEP in atabus_alloc_drives() to avoid spurious failures; this is not called from interrupt context To generate a diff of this commit: cvs rdiff -u -r1.4.2.4 -r1.4.2.5 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.6 -r1.141.6.7 src/sys/dev/ata/ata.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.4.2.4 src/sys/dev/ata/TODO.ncq:1.4.2.5 --- src/sys/dev/ata/TODO.ncq:1.4.2.4 Sat Sep 22 09:22:59 2018 +++ src/sys/dev/ata/TODO.ncq Sat Sep 22 09:26:48 2018 @@ -7,7 +7,6 @@ jdolecek-ncqfixes goals: triggers KASSERT() - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY ends up being handled as NOERROR, triggering KASSERT() in wd(4) -- weed out remaining KM_NOSLEEP Bugs Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.6 src/sys/dev/ata/ata.c:1.141.6.7 --- src/sys/dev/ata/ata.c:1.141.6.6 Sat Sep 22 09:22:59 2018 +++ src/sys/dev/ata/ata.c Sat Sep 22 09:26:48 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.6 2018/09/22 09:22:59 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.7 2018/09/22 09:26:48 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.6 2018/09/22 09:22:59 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.7 2018/09/22 09:26:48 jdolecek Exp $"); #include "opt_ata.h" @@ -719,7 +719,7 @@ atabus_alloc_drives(struct ata_channel * atabus_free_drives(chp); if (chp->ch_drive == NULL) { chp->ch_drive = kmem_zalloc( - sizeof(struct ata_drive_datas) * ndrives, KM_NOSLEEP); + sizeof(struct ata_drive_datas) * ndrives, KM_SLEEP); } if (chp->ch_drive == NULL) { aprint_error_dev(chp->ch_atac->atac_dev,
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 22 09:26:49 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c Log Message: use KM_SLEEP in atabus_alloc_drives() to avoid spurious failures; this is not called from interrupt context To generate a diff of this commit: cvs rdiff -u -r1.4.2.4 -r1.4.2.5 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.6 -r1.141.6.7 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Sat Sep 22 09:23:00 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_subr.c atavar.h satapmp_subr.c wd.c wdvar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c src/sys/dev/usb [jdolecek-ncqfixes]: umass_isdata.c Log Message: separate ata_xfer slot allocation and the memory allocation, so that there can be more queued xfers than number of supported slots by controller, and use a pool instead of custom pre-allocation primarily to help PR kern/52614 remove no longer needed custom wd(4) logic for flush cache switch also wd(4) trim/suspend/setcache/wdioctlstrategy to sleep waiting for the memory, they are all called from process context and this avoids spurious failures To generate a diff of this commit: cvs rdiff -u -r1.4.2.3 -r1.4.2.4 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.5 -r1.141.6.6 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.4 -r1.6.2.5 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.4 -r1.99.2.5 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.14 -r1.14.2.1 src/sys/dev/ata/satapmp_subr.c cvs rdiff -u -r1.441.2.3 -r1.441.2.4 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46.6.1 -r1.46.6.2 src/sys/dev/ata/wdvar.h cvs rdiff -u -r1.62.2.4 -r1.62.2.5 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.3 -r1.41.2.4 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.4 -r1.35.6.5 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.129.6.3 -r1.129.6.4 src/sys/dev/scsipi/atapi_wdc.c cvs rdiff -u -r1.36 -r1.36.6.1 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.4.2.3 src/sys/dev/ata/TODO.ncq:1.4.2.4 --- src/sys/dev/ata/TODO.ncq:1.4.2.3 Mon Sep 17 20:54:41 2018 +++ src/sys/dev/ata/TODO.ncq Sat Sep 22 09:22:59 2018 @@ -1,16 +1,13 @@ jdolecek-ncqfixes goals: -- make ata_xfer dynamically allocated using a pool - - will fix: queue is allocated regardless if there are any drives, fix? - - malloc() -> kmem_zalloc() in ata_queue_alloc() once this is done -- remove limit of queued ata_xfers, allow any number of pending xfers; - this should fix kern/52614 AKA wdc-attached ATAPI cd(4) -- remove the wd(4) flush condition, just allocate a dynamic ata_xfer -- change wd(4) dump code to use on-stack ata_xfer to not rely on pool having - memory +- add to wd(4) a callout to restart buf queue processing when ata_get_xfer() + call fails and remove ata_channel_start() +- change wd(4) dump code to use preallocated or on-stack ata_xfer to not rely + on pool having memory - re-fix QEMU ahci(4) bug workaround (no READ LOG EXT support) - now it triggers KASSERT() - fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY ends up being handled as NOERROR, triggering KASSERT() in wd(4) +- weed out remaining KM_NOSLEEP Bugs Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.5 src/sys/dev/ata/ata.c:1.141.6.6 --- src/sys/dev/ata/ata.c:1.141.6.5 Mon Sep 17 20:54:41 2018 +++ src/sys/dev/ata/ata.c Sat Sep 22 09:22:59 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.5 2018/09/17 20:54:41 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.6 2018/09/22 09:22:59 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.5 2018/09/17 20:54:41 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.6 2018/09/22 09:22:59 jdolecek Exp $"); #include "opt_ata.h" @@ -84,6 +84,7 @@ int atadebug_mask = ATADEBUG_MASK; #endif static ONCE_DECL(ata_init_ctrl); +static struct pool ata_xfer_pool; /* * A queue of atabus instances, used to ensure the same bus probe order @@ -142,6 +143,8 @@ static int atabus_init(void) { + pool_init(_xfer_pool, sizeof(struct ata_xfer), 0, 0, 0, + "ataspl", NULL, IPL_BIO); TAILQ_INIT(_initq_head); mutex_init(_qlock, MUTEX_DEFAULT, IPL_NONE); cv_init(_qcv, "atainitq"); @@ -779,7 +782,7 @@ ata_get_params(struct ata_drive_datas *d ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS); - xfer = ata_get_xfer(chp); + xfer = ata_get_xfer(chp, false); if (xfer == NULL) { ATADEBUG_PRINT(("%s: no xfer\n", __func__), DEBUG_FUNCS|DEBUG_PROBE); @@ -884,7 +887,7 @@ ata_set_mode(struct ata_drive_datas *drv ATADEBUG_PRINT(("ata_set_mode=0x%x\n", mode), DEBUG_FUNCS); - xfer = ata_get_xfer(chp); + xfer = ata_get_xfer(chp, false); if (xfer == NULL) { ATADEBUG_PRINT(("%s: no xfer\n", __func__), DEBUG_FUNCS|DEBUG_PROBE); @@ -919,7 +922,7 @@ int ata_read_log_ext_ncq(struct ata_drive_datas *drvp, uint8_t flags, uint8_t *slot, uint8_t *status, uint8_t *err) { - struct ata_xfer *xfer; + struct ata_xfer *xfer = >recovery_xfer; int rv; struct
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Sat Sep 22 09:23:00 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_subr.c atavar.h satapmp_subr.c wd.c wdvar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c src/sys/dev/usb [jdolecek-ncqfixes]: umass_isdata.c Log Message: separate ata_xfer slot allocation and the memory allocation, so that there can be more queued xfers than number of supported slots by controller, and use a pool instead of custom pre-allocation primarily to help PR kern/52614 remove no longer needed custom wd(4) logic for flush cache switch also wd(4) trim/suspend/setcache/wdioctlstrategy to sleep waiting for the memory, they are all called from process context and this avoids spurious failures To generate a diff of this commit: cvs rdiff -u -r1.4.2.3 -r1.4.2.4 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.5 -r1.141.6.6 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.4 -r1.6.2.5 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.4 -r1.99.2.5 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.14 -r1.14.2.1 src/sys/dev/ata/satapmp_subr.c cvs rdiff -u -r1.441.2.3 -r1.441.2.4 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46.6.1 -r1.46.6.2 src/sys/dev/ata/wdvar.h cvs rdiff -u -r1.62.2.4 -r1.62.2.5 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.3 -r1.41.2.4 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.4 -r1.35.6.5 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.129.6.3 -r1.129.6.4 src/sys/dev/scsipi/atapi_wdc.c cvs rdiff -u -r1.36 -r1.36.6.1 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.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 17 20:54:41 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_raid.c ata_raid_adaptec.c ata_raid_intel.c ata_raid_jmicron.c ata_raid_nvidia.c ata_raid_promise.c ata_raid_via.c ata_subr.c ata_wdc.c ld_ataraid.c wd.c Log Message: convert from malloc()/free() to kmem_zalloc()/kmem_free() To generate a diff of this commit: cvs rdiff -u -r1.4.2.2 -r1.4.2.3 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.4 -r1.141.6.5 src/sys/dev/ata/ata.c cvs rdiff -u -r1.40 -r1.40.4.1 src/sys/dev/ata/ata_raid.c cvs rdiff -u -r1.10 -r1.10.6.1 src/sys/dev/ata/ata_raid_adaptec.c cvs rdiff -u -r1.8 -r1.8.6.1 src/sys/dev/ata/ata_raid_intel.c \ src/sys/dev/ata/ata_raid_via.c cvs rdiff -u -r1.6 -r1.6.6.1 src/sys/dev/ata/ata_raid_jmicron.c cvs rdiff -u -r1.3 -r1.3.6.1 src/sys/dev/ata/ata_raid_nvidia.c cvs rdiff -u -r1.12 -r1.12.6.1 src/sys/dev/ata/ata_raid_promise.c cvs rdiff -u -r1.6.2.3 -r1.6.2.4 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.110.4.2 -r1.110.4.3 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.45 -r1.45.4.1 src/sys/dev/ata/ld_ataraid.c cvs rdiff -u -r1.441.2.2 -r1.441.2.3 src/sys/dev/ata/wd.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.4.2.2 src/sys/dev/ata/TODO.ncq:1.4.2.3 --- src/sys/dev/ata/TODO.ncq:1.4.2.2 Fri Aug 31 19:23:54 2018 +++ src/sys/dev/ata/TODO.ncq Mon Sep 17 20:54:41 2018 @@ -1,6 +1,7 @@ jdolecek-ncqfixes goals: - make ata_xfer dynamically allocated using a pool - - fixes: queue is allocated regardless if there are any drives, fix? + - will fix: queue is allocated regardless if there are any drives, fix? + - malloc() -> kmem_zalloc() in ata_queue_alloc() once this is done - remove limit of queued ata_xfers, allow any number of pending xfers; this should fix kern/52614 AKA wdc-attached ATAPI cd(4) - remove the wd(4) flush condition, just allocate a dynamic ata_xfer Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.4 src/sys/dev/ata/ata.c:1.141.6.5 --- src/sys/dev/ata/ata.c:1.141.6.4 Mon Sep 17 19:00:43 2018 +++ src/sys/dev/ata/ata.c Mon Sep 17 20:54:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.4 2018/09/17 19:00:43 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.5 2018/09/17 20:54:41 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,14 +25,13 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.4 2018/09/17 19:00:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.5 2018/09/17 20:54:41 jdolecek Exp $"); #include "opt_ata.h" #include #include #include -#include #include #include #include @@ -292,7 +291,7 @@ atabusconfig(struct atabus_softc *atabus cv_broadcast(_qcv); mutex_exit(_qlock); - free(atabus_initq, M_DEVBUF); + kmem_free(atabus_initq, sizeof(*atabus_initq)); ata_delref(chp); @@ -418,7 +417,7 @@ atabusconfig_thread(void *arg) cv_broadcast(_qcv); mutex_exit(_qlock); - free(atabus_initq, M_DEVBUF); + kmem_free(atabus_initq, sizeof(*atabus_initq)); ata_delref(chp); @@ -569,7 +568,7 @@ atabus_attach(device_t parent, device_t RUN_ONCE(_init_ctrl, atabus_init); - initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); + initq = kmem_zalloc(sizeof(*initq), KM_SLEEP); initq->atabus_sc = sc; mutex_enter(_qlock); TAILQ_INSERT_TAIL(_initq_head, initq, atabus_initq); @@ -716,9 +715,8 @@ atabus_alloc_drives(struct ata_channel * if (chp->ch_ndrives != ndrives) atabus_free_drives(chp); if (chp->ch_drive == NULL) { - chp->ch_drive = malloc( - sizeof(struct ata_drive_datas) * ndrives, - M_DEVBUF, M_NOWAIT | M_ZERO); + chp->ch_drive = kmem_zalloc( + sizeof(struct ata_drive_datas) * ndrives, KM_NOSLEEP); } if (chp->ch_drive == NULL) { aprint_error_dev(chp->ch_atac->atac_dev, @@ -761,8 +759,9 @@ atabus_free_drives(struct ata_channel *c if (chp->ch_drive == NULL) return; + kmem_free(chp->ch_drive, + sizeof(struct ata_drive_datas) * chp->ch_ndrives); chp->ch_ndrives = 0; - free(chp->ch_drive, M_DEVBUF); chp->ch_drive = NULL; } @@ -2218,7 +2217,7 @@ atabus_rescan(device_t self, const char } } - initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); + initq = kmem_zalloc(sizeof(*initq), KM_SLEEP); initq->atabus_sc = sc; mutex_enter(_qlock); TAILQ_INSERT_TAIL(_initq_head, initq, atabus_initq); Index: src/sys/dev/ata/ata_raid.c diff -u src/sys/dev/ata/ata_raid.c:1.40 src/sys/dev/ata/ata_raid.c:1.40.4.1 --- src/sys/dev/ata/ata_raid.c:1.40 Fri Jun 22 09:06:04 2018 +++ src/sys/dev/ata/ata_raid.c Mon Sep 17 20:54:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_raid.c,v 1.40 2018/06/22 09:06:04 pgoyette Exp $ */ +/* $NetBSD: ata_raid.c,v 1.40.4.1 2018/09/17 20:54:41 jdolecek Exp $ */ /* * Copyright (c) 2003 Wasabi
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 17 20:54:41 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq ata.c ata_raid.c ata_raid_adaptec.c ata_raid_intel.c ata_raid_jmicron.c ata_raid_nvidia.c ata_raid_promise.c ata_raid_via.c ata_subr.c ata_wdc.c ld_ataraid.c wd.c Log Message: convert from malloc()/free() to kmem_zalloc()/kmem_free() To generate a diff of this commit: cvs rdiff -u -r1.4.2.2 -r1.4.2.3 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.141.6.4 -r1.141.6.5 src/sys/dev/ata/ata.c cvs rdiff -u -r1.40 -r1.40.4.1 src/sys/dev/ata/ata_raid.c cvs rdiff -u -r1.10 -r1.10.6.1 src/sys/dev/ata/ata_raid_adaptec.c cvs rdiff -u -r1.8 -r1.8.6.1 src/sys/dev/ata/ata_raid_intel.c \ src/sys/dev/ata/ata_raid_via.c cvs rdiff -u -r1.6 -r1.6.6.1 src/sys/dev/ata/ata_raid_jmicron.c cvs rdiff -u -r1.3 -r1.3.6.1 src/sys/dev/ata/ata_raid_nvidia.c cvs rdiff -u -r1.12 -r1.12.6.1 src/sys/dev/ata/ata_raid_promise.c cvs rdiff -u -r1.6.2.3 -r1.6.2.4 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.110.4.2 -r1.110.4.3 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.45 -r1.45.4.1 src/sys/dev/ata/ld_ataraid.c cvs rdiff -u -r1.441.2.2 -r1.441.2.3 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Sep 17 19:30:26 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: atavar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c Log Message: move ATAPI-only members of ata_xfer to an union struct to further save space To generate a diff of this commit: cvs rdiff -u -r1.99.2.3 -r1.99.2.4 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.62.2.3 -r1.62.2.4 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.2 -r1.41.2.3 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.3 -r1.35.6.4 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.129.6.2 -r1.129.6.3 src/sys/dev/scsipi/atapi_wdc.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/atavar.h diff -u src/sys/dev/ata/atavar.h:1.99.2.3 src/sys/dev/ata/atavar.h:1.99.2.4 --- src/sys/dev/ata/atavar.h:1.99.2.3 Mon Sep 17 19:00:43 2018 +++ src/sys/dev/ata/atavar.h Mon Sep 17 19:30:25 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.99.2.3 2018/09/17 19:00:43 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.99.2.4 2018/09/17 19:30:25 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -144,8 +144,6 @@ struct ata_xfer { void *c_databuf; /* pointer to data buffer */ int c_bcount; /* byte count left */ int c_skip; /* bytes already transferred */ - int c_dscpoll; /* counter for dsc polling (ATAPI) */ - int c_lenoff; /* offset to c_bcount (ATAPI) */ #define ATACH_ERR_ST(error, status) ((error) << 8 | (status)) #define ATACH_ERR(val) (((val) >> 8) & 0xff) #define ATACH_ST(val) (((val) >> 0) & 0xff) @@ -153,11 +151,16 @@ struct ata_xfer { union { struct ata_bio c_bio; /* ATA transfer */ struct ata_command c_ata_c; /* ATA command */ - struct scsipi_xfer *c_scsipi; /* SCSI transfer */ + struct { + struct scsipi_xfer *c_scsipi; /* SCSI transfer */ + int c_dscpoll; /* counter for dsc polling (ATAPI) */ + int c_lenoff; /* offset to c_bcount (ATAPI) */ + } atapi; } u; #define c_bio u.c_bio #define c_ata_c u.c_ata_c -#define c_scsipi u.c_scsipi +#define c_atapi u.atapi +#define c_scsipi c_atapi.c_scsipi /* Link on the command queue. */ SIMPLEQ_ENTRY(ata_xfer) c_xferchain; Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.62.2.3 src/sys/dev/ic/ahcisata_core.c:1.62.2.4 --- src/sys/dev/ic/ahcisata_core.c:1.62.2.3 Mon Sep 17 18:36:13 2018 +++ src/sys/dev/ic/ahcisata_core.c Mon Sep 17 19:30:25 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.62.2.3 2018/09/17 18:36:13 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.62.2.4 2018/09/17 19:30:25 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.3 2018/09/17 18:36:13 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.4 2018/09/17 19:30:25 jdolecek Exp $"); #include #include @@ -1877,11 +1877,11 @@ ahci_atapi_scsipi_request(struct scsipi_ xfer->c_flags |= C_POLL; xfer->c_drive = drive; xfer->c_flags |= C_ATAPI; - xfer->c_scsipi = sc_xfer; xfer->c_databuf = sc_xfer->data; xfer->c_bcount = sc_xfer->datalen; xfer->ops = _atapi_xfer_ops; - xfer->c_dscpoll = 0; + xfer->c_scsipi = sc_xfer; + xfer->c_atapi.c_dscpoll = 0; s = splbio(); ata_exec_xfer(atac->atac_channels[channel], xfer); #ifdef DIAGNOSTIC Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.41.2.2 src/sys/dev/ic/mvsata.c:1.41.2.3 --- src/sys/dev/ic/mvsata.c:1.41.2.2 Mon Sep 17 18:36:14 2018 +++ src/sys/dev/ic/mvsata.c Mon Sep 17 19:30:25 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.41.2.2 2018/09/17 18:36:14 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.41.2.3 2018/09/17 19:30:25 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.2 2018/09/17 18:36:14 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.3 2018/09/17 19:30:25 jdolecek Exp $"); #include "opt_mvsata.h" @@ -2092,11 +2092,11 @@ mvsata_atapi_scsipi_request(struct scsip xfer->c_flags |= C_POLL; xfer->c_drive = drive; xfer->c_flags |= C_ATAPI; - xfer->c_scsipi = sc_xfer; xfer->c_databuf = sc_xfer->data; xfer->c_bcount = sc_xfer->datalen; xfer->ops = _atapi_xfer_ops; - xfer->c_dscpoll = 0; + xfer->c_scsipi = sc_xfer; + xfer->c_atapi.c_dscpoll = 0; s = splbio(); ata_exec_xfer(chp, xfer); #ifdef DIAGNOSTIC @@ -2444,7 +2444,7 @@ again: mvsata_atapi_reset(chp, xfer); return 1; } - xfer->c_lenoff = len - xfer->c_bcount; + xfer->c_atapi.c_lenoff = len - xfer->c_bcount; if (xfer->c_bcount < len) { aprint_error_dev(atac->atac_dev, "channel %d drive %d:" " warning: write only %d of %d requested bytes\n", @@ -2456,7 +2456,7 @@
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Sep 17 19:30:26 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: atavar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c Log Message: move ATAPI-only members of ata_xfer to an union struct to further save space To generate a diff of this commit: cvs rdiff -u -r1.99.2.3 -r1.99.2.4 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.62.2.3 -r1.62.2.4 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.2 -r1.41.2.3 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.3 -r1.35.6.4 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.129.6.2 -r1.129.6.3 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 17 19:00:43 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c atavar.h Log Message: switch from TAILQ to SIMPLEQ for ata_xfer pending queue to save space, don't need doubly linked queue To generate a diff of this commit: cvs rdiff -u -r1.141.6.3 -r1.141.6.4 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.2 -r1.6.2.3 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.2 -r1.99.2.3 src/sys/dev/ata/atavar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 17 19:00:43 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c atavar.h Log Message: switch from TAILQ to SIMPLEQ for ata_xfer pending queue to save space, don't need doubly linked queue To generate a diff of this commit: cvs rdiff -u -r1.141.6.3 -r1.141.6.4 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.2 -r1.6.2.3 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.99.2.2 -r1.99.2.3 src/sys/dev/ata/atavar.h 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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.3 src/sys/dev/ata/ata.c:1.141.6.4 --- src/sys/dev/ata/ata.c:1.141.6.3 Mon Sep 17 18:36:13 2018 +++ src/sys/dev/ata/ata.c Mon Sep 17 19:00:43 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.3 2018/09/17 18:36:13 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.4 2018/09/17 19:00:43 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.3 2018/09/17 18:36:13 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.4 2018/09/17 19:00:43 jdolecek Exp $"); #include "opt_ata.h" @@ -1062,10 +1062,10 @@ ata_exec_xfer(struct ata_channel *chp, s * recovery commands must be run immediatelly. */ if ((xfer->c_flags & C_RECOVERY) == 0) - TAILQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer, + SIMPLEQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer, c_xferchain); else - TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer, + SIMPLEQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer, c_xferchain); /* @@ -1073,7 +1073,7 @@ ata_exec_xfer(struct ata_channel *chp, s */ if ((xfer->c_flags & (C_POLL | C_WAIT)) == (C_POLL | C_WAIT)) { while (chp->ch_queue->queue_active > 0 || - TAILQ_FIRST(>ch_queue->queue_xfer) != xfer) { + SIMPLEQ_FIRST(>ch_queue->queue_xfer) != xfer) { xfer->c_flags |= C_WAITACT; cv_wait(>ch_queue->c_active, >ch_lock); xfer->c_flags &= ~C_WAITACT; @@ -1137,7 +1137,7 @@ again: } /* is there a xfer ? */ - if ((xfer = TAILQ_FIRST(>ch_queue->queue_xfer)) == NULL) { + if ((xfer = SIMPLEQ_FIRST(>ch_queue->queue_xfer)) == NULL) { ATADEBUG_PRINT(("%s(chp=%p): channel %d queue_xfer is empty\n", __func__, chp, chp->ch_channel), DEBUG_XFERS); goto out; @@ -1207,6 +1207,8 @@ again: else CLR(chp->ch_flags, ATACH_NCQ); + SIMPLEQ_REMOVE_HEAD(>queue_xfer, c_xferchain); + ata_activate_xfer_locked(chp, xfer); if (atac->atac_cap & ATAC_CAP_NOIRQ) @@ -1275,7 +1277,6 @@ ata_activate_xfer_locked(struct ata_chan KASSERT(chq->queue_active < chq->queue_openings); KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0); - TAILQ_REMOVE(>queue_xfer, xfer, c_xferchain); if ((xfer->c_flags & C_RECOVERY) == 0) TAILQ_INSERT_TAIL(>active_xfers, xfer, c_activechain); else { @@ -1419,18 +1420,18 @@ ata_kill_pending(struct ata_drive_datas { struct ata_channel * const chp = drvp->chnl_softc; struct ata_queue * const chq = chp->ch_queue; - struct ata_xfer *xfer, *xfernext; + struct ata_xfer *xfer; ata_channel_lock(chp); /* Kill all pending transfers */ - TAILQ_FOREACH_SAFE(xfer, >queue_xfer, c_xferchain, xfernext) { + while ((xfer = SIMPLEQ_FIRST(>queue_xfer))) { KASSERT(xfer->c_chp == chp); if (xfer->c_drive != drvp->drive) continue; - TAILQ_REMOVE(>ch_queue->queue_xfer, xfer, c_xferchain); + SIMPLEQ_REMOVE_HEAD(>ch_queue->queue_xfer, c_xferchain); /* * Keep the lock, so that we get deadlock (and 'locking against Index: src/sys/dev/ata/ata_subr.c diff -u src/sys/dev/ata/ata_subr.c:1.6.2.2 src/sys/dev/ata/ata_subr.c:1.6.2.3 --- src/sys/dev/ata/ata_subr.c:1.6.2.2 Mon Sep 17 18:36:13 2018 +++ src/sys/dev/ata/ata_subr.c Mon Sep 17 19:00:43 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_subr.c,v 1.6.2.2 2018/09/17 18:36:13 jdolecek Exp $ */ +/* $NetBSD: ata_subr.c,v 1.6.2.3 2018/09/17 19:00:43 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.2 2018/09/17 18:36:13 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.3 2018/09/17 19:00:43 jdolecek Exp $"); #include "opt_ata.h" @@ -70,7 +70,7 @@ void ata_queue_reset(struct ata_queue *chq) { /* make sure that we can use polled commands */ - TAILQ_INIT(>queue_xfer); + SIMPLEQ_INIT(>queue_xfer); TAILQ_INIT(>active_xfers); chq->queue_freeze = 0; chq->queue_active = 0; Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.99.2.2 src/sys/dev/ata/atavar.h:1.99.2.3 --- src/sys/dev/ata/atavar.h:1.99.2.2 Mon Sep 17 18:36:13 2018 +++ src/sys/dev/ata/atavar.h Mon Sep 17 19:00:43 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.99.2.2 2018/09/17 18:36:13 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.99.2.3 2018/09/17 19:00:43
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Sep 17 18:36:14 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c wdc.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c Log Message: move low-level protocol handlers hooks from ata_xfer to separate struct, initialized statically primarily to reduce ata_xfer struct size, but also improves readibility, and enforces consistency To generate a diff of this commit: cvs rdiff -u -r1.141.6.2 -r1.141.6.3 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.1 -r1.6.2.2 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.110.4.1 -r1.110.4.2 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.99.2.1 -r1.99.2.2 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.62.2.2 -r1.62.2.3 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.1 -r1.41.2.2 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.2 -r1.35.6.3 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.288.6.1 -r1.288.6.2 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.129.6.1 -r1.129.6.2 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Mon Sep 17 18:36:14 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c wdc.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c Log Message: move low-level protocol handlers hooks from ata_xfer to separate struct, initialized statically primarily to reduce ata_xfer struct size, but also improves readibility, and enforces consistency To generate a diff of this commit: cvs rdiff -u -r1.141.6.2 -r1.141.6.3 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6.2.1 -r1.6.2.2 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.110.4.1 -r1.110.4.2 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.99.2.1 -r1.99.2.2 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.62.2.2 -r1.62.2.3 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41.2.1 -r1.41.2.2 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35.6.2 -r1.35.6.3 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.288.6.1 -r1.288.6.2 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.129.6.1 -r1.129.6.2 src/sys/dev/scsipi/atapi_wdc.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.2 src/sys/dev/ata/ata.c:1.141.6.3 --- src/sys/dev/ata/ata.c:1.141.6.2 Sat Sep 1 09:48:32 2018 +++ src/sys/dev/ata/ata.c Mon Sep 17 18:36:13 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.2 2018/09/01 09:48:32 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.3 2018/09/17 18:36:13 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.2 2018/09/01 09:48:32 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.3 2018/09/17 18:36:13 jdolecek Exp $"); #include "opt_ata.h" @@ -1238,7 +1238,7 @@ ata_xfer_start(struct ata_xfer *xfer) KASSERT(mutex_owned(>ch_lock)); - rv = xfer->c_start(chp, xfer); + rv = xfer->ops->c_start(chp, xfer); switch (rv) { case ATASTART_STARTED: /* nothing to do */ @@ -1250,14 +1250,14 @@ ata_xfer_start(struct ata_xfer *xfer) case ATASTART_POLL: /* can happen even in thread context for some ATAPI devices */ ata_channel_unlock(chp); - KASSERT(xfer->c_poll != NULL); - xfer->c_poll(chp, xfer); + KASSERT(xfer->ops != NULL && xfer->ops->c_poll != NULL); + xfer->ops->c_poll(chp, xfer); ata_channel_lock(chp); break; case ATASTART_ABORT: ata_channel_unlock(chp); - KASSERT(xfer->c_abort != NULL); - xfer->c_abort(chp, xfer); + KASSERT(xfer->ops != NULL && xfer->ops->c_abort != NULL); + xfer->ops->c_abort(chp, xfer); ata_channel_lock(chp); break; } @@ -1337,7 +1337,7 @@ ata_waitdrain_xfer_check(struct ata_chan if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { ata_channel_unlock(chp); - (*xfer->c_kill_xfer)(chp, xfer, KILL_GONE); + xfer->ops->c_kill_xfer(chp, xfer, KILL_GONE); ata_channel_lock(chp); chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; @@ -1404,7 +1404,7 @@ ata_kill_active(struct ata_channel *chp, KASSERT(mutex_owned(>ch_lock)); TAILQ_FOREACH_SAFE(xfer, >active_xfers, c_activechain, xfernext) { - (*xfer->c_kill_xfer)(xfer->c_chp, xfer, reason); + xfer->ops->c_kill_xfer(xfer->c_chp, xfer, reason); } if (flags & AT_RST_EMERG) @@ -1438,7 +1438,7 @@ ata_kill_pending(struct ata_drive_datas * data corruption, if the hook tries to call back into * middle layer for inactive xfer. */ - (*xfer->c_kill_xfer)(chp, xfer, KILL_GONE_INACTIVE); + xfer->ops->c_kill_xfer(chp, xfer, KILL_GONE_INACTIVE); } /* Wait until all active transfers on the drive finish */ Index: src/sys/dev/ata/ata_subr.c diff -u src/sys/dev/ata/ata_subr.c:1.6.2.1 src/sys/dev/ata/ata_subr.c:1.6.2.2 --- src/sys/dev/ata/ata_subr.c:1.6.2.1 Fri Aug 31 19:08:03 2018 +++ src/sys/dev/ata/ata_subr.c Mon Sep 17 18:36:13 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_subr.c,v 1.6.2.1 2018/08/31 19:08:03 jdolecek Exp $ */ +/* $NetBSD: ata_subr.c,v 1.6.2.2 2018/09/17 18:36:13 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.1 2018/08/31 19:08:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.2 2018/09/17 18:36:13 jdolecek Exp $"); #include "opt_ata.h" @@ -326,6 +326,7 @@ ata_free_xfer(struct ata_channel *chp, s goto out; } + /* XXX move PIOBM and free_gw to deactivate? */ #if NATA_PIOBM /* XXX wdc dependent code */ if (xfer->c_flags & C_PIOBM) { struct wdc_softc *wdc = CHAN_TO_WDC(chp); @@ -386,7 +387,7 @@ ata_timeout(void *v) /* Mark as timed out. Do not print anything, wd(4) will. */ xfer->c_flags |= C_TIMEOU; - xfer->c_intr(xfer->c_chp, xfer, 0); + xfer->ops->c_intr(xfer->c_chp, xfer, 0); } splx(s);
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Sep 1 10:13:41 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c siisata.c Log Message: only call ata_deactivate_xfer() once completely done with the active xfer in controller code (i.e. after bus_dmamap_sync() et.al.), so that the command slot is safe to be reused immediatelly after deactivate To generate a diff of this commit: cvs rdiff -u -r1.62.2.1 -r1.62.2.2 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.35.6.1 -r1.35.6.2 src/sys/dev/ic/siisata.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/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.62.2.1 src/sys/dev/ic/ahcisata_core.c:1.62.2.2 --- src/sys/dev/ic/ahcisata_core.c:1.62.2.1 Fri Aug 31 19:08:03 2018 +++ src/sys/dev/ic/ahcisata_core.c Sat Sep 1 10:13:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.62.2.1 2018/08/31 19:08:03 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.62.2.2 2018/09/01 10:13:41 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.1 2018/08/31 19:08:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.62.2.2 2018/09/01 10:13:41 jdolecek Exp $"); #include #include @@ -1206,9 +1206,6 @@ ahci_cmd_complete(struct ata_channel *ch if (ata_waitdrain_xfer_check(chp, xfer)) return 0; - KASSERT((achp->ahcic_cmds_active & (1U << xfer->c_slot)) != 0); - achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); - if (xfer->c_flags & C_TIMEOU) { ata_c->flags |= AT_TIMEOU; } @@ -1225,6 +1222,8 @@ ahci_cmd_complete(struct ata_channel *ch ahci_cmd_done(chp, xfer); + KASSERT((achp->ahcic_cmds_active & (1U << xfer->c_slot)) != 0); + achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); ata_deactivate_xfer(chp, xfer); return 0; @@ -1453,10 +1452,6 @@ ahci_bio_complete(struct ata_channel *ch if (ata_waitdrain_xfer_check(chp, xfer)) return 0; - KASSERT((achp->ahcic_cmds_active & (1U << xfer->c_slot)) != 0); - achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); - ata_deactivate_xfer(chp, xfer); - if (xfer->c_flags & C_TIMEOU) { ata_bio->error = TIMEOUT; } @@ -1497,6 +1492,11 @@ ahci_bio_complete(struct ata_channel *ch le32toh(achp->ahcic_cmdh[xfer->c_slot].cmdh_prdbc); } AHCIDEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); + + KASSERT((achp->ahcic_cmds_active & (1U << xfer->c_slot)) != 0); + achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); + ata_deactivate_xfer(chp, xfer); + (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); if ((AHCI_TFD_ST(tfd) & WDCS_ERR) == 0) atastart(chp); @@ -1997,10 +1997,6 @@ ahci_atapi_complete(struct ata_channel * if (ata_waitdrain_xfer_check(chp, xfer)) return 0; - KASSERT((achp->ahcic_cmds_active & (1U << xfer->c_slot)) != 0); - achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); - ata_deactivate_xfer(chp, xfer); - if (xfer->c_flags & C_TIMEOU) { sc_xfer->error = XS_TIMEOUT; } @@ -2030,7 +2026,12 @@ ahci_atapi_complete(struct ata_channel * sc_xfer->error = XS_BUSY; sc_xfer->status = SCSI_CHECK; } - } + } + + KASSERT((achp->ahcic_cmds_active & (1U << xfer->c_slot)) != 0); + achp->ahcic_cmds_active &= ~(1U << xfer->c_slot); + ata_deactivate_xfer(chp, xfer); + ata_free_xfer(chp, xfer); scsipi_done(sc_xfer); if ((AHCI_TFD_ST(tfd) & WDCS_ERR) == 0) Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.35.6.1 src/sys/dev/ic/siisata.c:1.35.6.2 --- src/sys/dev/ic/siisata.c:1.35.6.1 Fri Aug 31 19:08:03 2018 +++ src/sys/dev/ic/siisata.c Sat Sep 1 10:13:41 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.35.6.1 2018/08/31 19:08:03 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.35.6.2 2018/09/01 10:13:41 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.1 2018/08/31 19:08:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.35.6.2 2018/09/01 10:13:41 jdolecek Exp $"); #include #include @@ -1154,8 +1154,6 @@ siisata_cmd_complete(struct ata_channel if (ata_waitdrain_xfer_check(chp, xfer)) return 0; - siisata_deactivate_prb(schp, xfer->c_slot); - if (xfer->c_flags & C_TIMEOU) ata_c->flags |= AT_TIMEOU; @@ -1168,6 +1166,7 @@ siisata_cmd_complete(struct ata_channel siisata_cmd_done(chp, xfer, tfd); + siisata_deactivate_prb(schp, xfer->c_slot); ata_deactivate_xfer(chp, xfer); return 0; @@ -1382,9 +1381,6 @@ siisata_bio_complete(struct ata_channel if (ata_waitdrain_xfer_check(chp, xfer)) return 0; - siisata_deactivate_prb(schp, xfer->c_slot); - ata_deactivate_xfer(chp, xfer); - if (xfer->c_flags & C_TIMEOU) { ata_bio->error = TIMEOUT; } @@ -1414,6 +1410,10 @@ siisata_bio_complete(struct ata_channel ata_bio->bcount = 0; }
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Sep 1 10:13:41 UTC 2018 Modified Files: src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c siisata.c Log Message: only call ata_deactivate_xfer() once completely done with the active xfer in controller code (i.e. after bus_dmamap_sync() et.al.), so that the command slot is safe to be reused immediatelly after deactivate To generate a diff of this commit: cvs rdiff -u -r1.62.2.1 -r1.62.2.2 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.35.6.1 -r1.35.6.2 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 1 09:48:32 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c wd.c Log Message: stop assuming c_slot is immutable, use the xfer pointer rather than c_slot in printfs() To generate a diff of this commit: cvs rdiff -u -r1.141.6.1 -r1.141.6.2 src/sys/dev/ata/ata.c cvs rdiff -u -r1.441.2.1 -r1.441.2.2 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 1 09:48:32 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c wd.c Log Message: stop assuming c_slot is immutable, use the xfer pointer rather than c_slot in printfs() To generate a diff of this commit: cvs rdiff -u -r1.141.6.1 -r1.141.6.2 src/sys/dev/ata/ata.c cvs rdiff -u -r1.441.2.1 -r1.441.2.2 src/sys/dev/ata/wd.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.1 src/sys/dev/ata/ata.c:1.141.6.2 --- src/sys/dev/ata/ata.c:1.141.6.1 Fri Aug 31 19:08:03 2018 +++ src/sys/dev/ata/ata.c Sat Sep 1 09:48:32 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.1 2018/08/31 19:08:03 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.2 2018/09/01 09:48:32 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.1 2018/08/31 19:08:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.2 2018/09/01 09:48:32 jdolecek Exp $"); #include "opt_ata.h" @@ -1370,8 +1370,7 @@ ata_timo_xfer_check(struct ata_xfer *xfe ata_channel_unlock(chp); aprint_normal_dev(drvp->drv_softc, - "xfer %d freed while invoking timeout\n", - xfer->c_slot); + "xfer %p freed while invoking timeout\n", xfer); ata_free_xfer(chp, xfer); return true; @@ -1381,8 +1380,7 @@ ata_timo_xfer_check(struct ata_xfer *xfe ata_channel_unlock(chp); aprint_normal_dev(drvp->drv_softc, - "xfer %d deactivated while invoking timeout\n", - xfer->c_slot); + "xfer %p deactivated while invoking timeout\n", xfer); return true; } Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.1 src/sys/dev/ata/wd.c:1.441.2.2 --- src/sys/dev/ata/wd.c:1.441.2.1 Fri Aug 31 19:08:03 2018 +++ src/sys/dev/ata/wd.c Sat Sep 1 09:48:32 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.1 2018/08/31 19:08:03 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.441.2.2 2018/09/01 09:48:32 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.1 2018/08/31 19:08:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.2 2018/09/01 09:48:32 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -660,8 +660,8 @@ wdstart1(struct wd_softc *wd, struct buf */ if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wd->drv_chaos_freq > 0 && (++wd->drv_chaos_cnt % wd->drv_chaos_freq) == 0) { - aprint_normal_dev(dksc->sc_dev, "%s: chaos xfer %d\n", - __func__, xfer->c_slot); + aprint_normal_dev(dksc->sc_dev, "%s: chaos xfer %p\n", + __func__, xfer); xfer->c_bio.blkno = 777 + wd->sc_capacity; xfer->c_flags |= C_CHAOS; } @@ -852,7 +852,7 @@ retry2: diskerr(bp, "wd", errmsg, LOG_PRINTF, xfer->c_bio.blkdone, dksc->sc_dkdev.dk_label); if (xfer->c_retries < WDIORETRIES) - printf(", slot %d, retry %d", xfer->c_slot, + printf(", xfer %p, retry %d", xfer, xfer->c_retries + 1); printf("\n"); if (do_perror) @@ -916,7 +916,7 @@ out: case NOERROR: noerror: if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0) aprint_error_dev(dksc->sc_dev, - "soft error (corrected) slot %d\n", xfer->c_slot); + "soft error (corrected) xfer %p\n", xfer); #ifdef WD_CHAOS_MONKEY KASSERT((xfer->c_flags & C_CHAOS) == 0); #endif
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Aug 31 19:23:54 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: fix comment - dynamically allocated yes, per-drive not To generate a diff of this commit: cvs rdiff -u -r1.4.2.1 -r1.4.2.2 src/sys/dev/ata/TODO.ncq 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.4.2.1 src/sys/dev/ata/TODO.ncq:1.4.2.2 --- src/sys/dev/ata/TODO.ncq:1.4.2.1 Fri Aug 31 19:15:04 2018 +++ src/sys/dev/ata/TODO.ncq Fri Aug 31 19:23:54 2018 @@ -1,5 +1,5 @@ jdolecek-ncqfixes goals: -- make ata_xfer dynamically allocated per-drive using a pool +- make ata_xfer dynamically allocated using a pool - fixes: queue is allocated regardless if there are any drives, fix? - remove limit of queued ata_xfers, allow any number of pending xfers; this should fix kern/52614 AKA wdc-attached ATAPI cd(4)
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Aug 31 19:23:54 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: fix comment - dynamically allocated yes, per-drive not To generate a diff of this commit: cvs rdiff -u -r1.4.2.1 -r1.4.2.2 src/sys/dev/ata/TODO.ncq Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Aug 31 19:15:04 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: list goals for the jdolecek-ncqfixes branch To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.4.2.1 src/sys/dev/ata/TODO.ncq 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.4 src/sys/dev/ata/TODO.ncq:1.4.2.1 --- src/sys/dev/ata/TODO.ncq:1.4 Fri Aug 31 18:44:04 2018 +++ src/sys/dev/ata/TODO.ncq Fri Aug 31 19:15:04 2018 @@ -1,3 +1,16 @@ +jdolecek-ncqfixes goals: +- make ata_xfer dynamically allocated per-drive using a pool + - fixes: queue is allocated regardless if there are any drives, fix? +- remove limit of queued ata_xfers, allow any number of pending xfers; + this should fix kern/52614 AKA wdc-attached ATAPI cd(4) +- remove the wd(4) flush condition, just allocate a dynamic ata_xfer +- change wd(4) dump code to use on-stack ata_xfer to not rely on pool having + memory +- re-fix QEMU ahci(4) bug workaround (no READ LOG EXT support) - now it + triggers KASSERT() +- fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY + ends up being handled as NOERROR, triggering KASSERT() in wd(4) + Bugs test wd* at umass?, confirm the ata_channel kludge works @@ -15,8 +28,6 @@ xfers for several different drives maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -queue is allocated regardless if there are any drives, fix? - dump to unopened disk fails (e.g. dump do wd1b when wd1a not mounted), due to the open path executing ata_get_params(), which eventually tsleeps() while waiting for the command to finish; specifically, if WDF_LOADED is not
CVS commit: [jdolecek-ncqfixes] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Aug 31 19:15:04 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq Log Message: list goals for the jdolecek-ncqfixes branch To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.4.2.1 src/sys/dev/ata/TODO.ncq Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Fri Aug 31 19:08:03 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c ata_wdc.c atavar.h wd.c wdvar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c wdc.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c Log Message: refactor ata_xfer to be just dumb structure; move all callouts/condvars out retry callout to wd(4); reset callout and the active/cmd finish condvars to channel queue; change code using the condvars so it works if there are multiple waiters simplify the async wait code for cmds, replace ata_wait_xfer()/ata_wake_xfer() with ata_wait_cmd() fix the callout_invoking/ack race handling code for timeouts to actually have chance to work; change mvsata(4) to use generic timeout func towards resolution of kern/52614 To generate a diff of this commit: cvs rdiff -u -r1.141 -r1.141.6.1 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.110 -r1.110.4.1 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.99 -r1.99.2.1 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441 -r1.441.2.1 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46 -r1.46.6.1 src/sys/dev/ata/wdvar.h cvs rdiff -u -r1.62 -r1.62.2.1 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41 -r1.41.2.1 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35 -r1.35.6.1 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.288 -r1.288.6.1 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.129 -r1.129.6.1 src/sys/dev/scsipi/atapi_wdc.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/ata.c diff -u src/sys/dev/ata/ata.c:1.141 src/sys/dev/ata/ata.c:1.141.6.1 --- src/sys/dev/ata/ata.c:1.141 Sat Oct 28 04:53:54 2017 +++ src/sys/dev/ata/ata.c Fri Aug 31 19:08:03 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141 2017/10/28 04:53:54 riastradh Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.1 2018/08/31 19:08:03 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141 2017/10/28 04:53:54 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.1 2018/08/31 19:08:03 jdolecek Exp $"); #include "opt_ata.h" @@ -1075,19 +1075,19 @@ ata_exec_xfer(struct ata_channel *chp, s while (chp->ch_queue->queue_active > 0 || TAILQ_FIRST(>ch_queue->queue_xfer) != xfer) { xfer->c_flags |= C_WAITACT; - cv_wait(>c_active, >ch_lock); + cv_wait(>ch_queue->c_active, >ch_lock); xfer->c_flags &= ~C_WAITACT; + } - /* - * Free xfer now if it there was attempt to free it - * while we were waiting. - */ - if ((xfer->c_flags & (C_FREE|C_WAITTIMO)) == C_FREE) { -ata_channel_unlock(chp); + /* + * Free xfer now if it there was attempt to free it + * while we were waiting. + */ + if ((xfer->c_flags & (C_FREE|C_WAITTIMO)) == C_FREE) { + ata_channel_unlock(chp); -ata_free_xfer(chp, xfer); -return; - } + ata_free_xfer(chp, xfer); + return; } } @@ -1187,7 +1187,7 @@ again: ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d " "wait active\n", xfer, chp->ch_channel, xfer->c_drive), DEBUG_XFERS); - cv_signal(>c_active); + cv_broadcast(>ch_queue->c_active); goto out; } @@ -1300,15 +1300,20 @@ ata_deactivate_xfer(struct ata_channel * KASSERT(chq->queue_active > 0); KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) != 0); - callout_stop(>c_timo_callout); + /* Stop only when this is last active xfer */ + if (chq->queue_active == 1) + callout_stop(>c_timo_callout); - if (callout_invoking(>c_timo_callout)) + if (callout_invoking(>c_timo_callout)) xfer->c_flags |= C_WAITTIMO; TAILQ_REMOVE(>active_xfers, xfer, c_activechain); chq->active_xfers_used &= ~__BIT(xfer->c_slot); chq->queue_active--; + if (xfer->c_flags & C_WAIT) + cv_broadcast(>c_cmd_finish); + ata_channel_unlock(chp); } @@ -1356,8 +1361,6 @@ ata_timo_xfer_check(struct ata_xfer *xfe ata_channel_lock(chp); - callout_ack(>c_timo_callout); - if (xfer->c_flags & C_WAITTIMO) { xfer->c_flags &= ~C_WAITTIMO; @@ -1389,30 +1392,6 @@ ata_timo_xfer_check(struct ata_xfer *xfe return false; } -void -ata_timeout(void *v) -{ - struct ata_xfer *xfer = v; - int s; - - ATADEBUG_PRINT(("%s: slot %d\n", __func__, xfer->c_slot), - DEBUG_FUNCS|DEBUG_XFERS); - - s = splbio();/* XXX MPSAFE */ - - if (ata_timo_xfer_check(xfer)) { - /* Already logged */ - goto out; - } - - /* Mark as timed out. Do not print anything, wd(4) will. */ - xfer->c_flags |= C_TIMEOU; - xfer->c_intr(xfer->c_chp, xfer, 0); - -out: - splx(s); -} - /* * Kill off all active xfers for a ata_channel. * @@ -2304,17 +2283,17 @@ atacmd_toncq(struct ata_xfer *xfer, uint } void -ata_wait_xfer(struct ata_channel *chp, struct ata_xfer *xfer) +ata_wait_cmd(struct ata_channel *chp,
CVS commit: [jdolecek-ncqfixes] src/sys/dev
Module Name:src Committed By: jdolecek Date: Fri Aug 31 19:08:03 UTC 2018 Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c ata_wdc.c atavar.h wd.c wdvar.h src/sys/dev/ic [jdolecek-ncqfixes]: ahcisata_core.c mvsata.c siisata.c wdc.c src/sys/dev/scsipi [jdolecek-ncqfixes]: atapi_wdc.c Log Message: refactor ata_xfer to be just dumb structure; move all callouts/condvars out retry callout to wd(4); reset callout and the active/cmd finish condvars to channel queue; change code using the condvars so it works if there are multiple waiters simplify the async wait code for cmds, replace ata_wait_xfer()/ata_wake_xfer() with ata_wait_cmd() fix the callout_invoking/ack race handling code for timeouts to actually have chance to work; change mvsata(4) to use generic timeout func towards resolution of kern/52614 To generate a diff of this commit: cvs rdiff -u -r1.141 -r1.141.6.1 src/sys/dev/ata/ata.c cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/dev/ata/ata_subr.c cvs rdiff -u -r1.110 -r1.110.4.1 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.99 -r1.99.2.1 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441 -r1.441.2.1 src/sys/dev/ata/wd.c cvs rdiff -u -r1.46 -r1.46.6.1 src/sys/dev/ata/wdvar.h cvs rdiff -u -r1.62 -r1.62.2.1 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.41 -r1.41.2.1 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.35 -r1.35.6.1 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.288 -r1.288.6.1 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.129 -r1.129.6.1 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.