CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 7 15:24:36 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c wdvar.h Log Message: make usage of NCQ 'high' priority for BPRIO_TIMECRITICAL xfers settable via sysctl, too To generate a diff of this commit: cvs rdiff -u -r1.428.2.35 -r1.428.2.36 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.9 -r1.43.4.10 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Oct 7 15:24:36 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c wdvar.h Log Message: make usage of NCQ 'high' priority for BPRIO_TIMECRITICAL xfers settable via sysctl, too To generate a diff of this commit: cvs rdiff -u -r1.428.2.35 -r1.428.2.36 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.9 -r1.43.4.10 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/wd.c diff -u src/sys/dev/ata/wd.c:1.428.2.35 src/sys/dev/ata/wd.c:1.428.2.36 --- src/sys/dev/ata/wd.c:1.428.2.35 Thu Sep 28 20:34:23 2017 +++ src/sys/dev/ata/wd.c Sat Oct 7 15:24:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.36 2017/10/07 15:24:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.36 2017/10/07 15:24:36 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -751,7 +751,7 @@ wdstart1(struct wd_softc *wd, struct buf xfer->c_bio.flags |= ATA_LBA48; xfer->c_flags |= C_NCQ; - if ((wd->drvp->drive_flags & ATA_DRIVE_NCQ_PRIO) && + if (WD_USE_NCQ_PRIO(wd) && BIO_GETPRIO(bp) == BPRIO_TIMECRITICAL) xfer->c_bio.flags |= ATA_PRIO_HIGH; } @@ -2360,6 +2360,19 @@ wd_sysctl_attach(struct wd_softc *wd) return; } + wd->drv_ncq_prio = true; + if ((error = sysctl_createv(>nodelog, 0, NULL, NULL, +CTLFLAG_READWRITE, CTLTYPE_BOOL, "use_ncq_prio", +SYSCTL_DESCR("use NCQ PRIORITY if supported"), +NULL, 0, >drv_ncq_prio, 0, +CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL)) +!= 0) { + aprint_error_dev(wd->sc_dev, + "could not create %s.%s.use_ncq_prio sysctl - error %d\n", + "hw", device_xname(wd->sc_dev), error); + return; + } + #ifdef WD_CHAOS_MONKEY wd->drv_chaos_freq = 0; if ((error = sysctl_createv(>nodelog, 0, NULL, NULL, Index: src/sys/dev/ata/wdvar.h diff -u src/sys/dev/ata/wdvar.h:1.43.4.9 src/sys/dev/ata/wdvar.h:1.43.4.10 --- src/sys/dev/ata/wdvar.h:1.43.4.9 Thu Sep 28 20:34:23 2017 +++ src/sys/dev/ata/wdvar.h Sat Oct 7 15:24:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdvar.h,v 1.43.4.9 2017/09/28 20:34:23 jdolecek Exp $ */ +/* $NetBSD: wdvar.h,v 1.43.4.10 2017/10/07 15:24:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -78,6 +78,9 @@ struct wd_softc { bool drv_ncq; #define WD_USE_NCQ(wd) \ ((wd)->drv_ncq && ((wd)->drvp->drive_flags & ATA_DRIVE_NCQ)) + bool drv_ncq_prio; +#define WD_USE_NCQ_PRIO(wd) \ + ((wd)->drv_ncq_prio && ((wd)->drvp->drive_flags & ATA_DRIVE_NCQ_PRIO)) #ifdef WD_CHAOS_MONKEY int drv_chaos_freq; /* frequency of simulated bio errors */ int drv_chaos_cnt; /* count of processed bio read xfers */
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Sep 29 20:05:07 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c atavar.h Log Message: introduce ATA_BSIZE and use it instead of DEV_BSIZE for get params and recovery, where they are by spec 512 bytes and not negotiable To generate a diff of this commit: cvs rdiff -u -r1.1.2.46 -r1.1.2.47 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.38 -r1.132.8.39 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.28 -r1.92.8.29 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/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.46 src/sys/dev/ata/TODO.ncq:1.1.2.47 --- src/sys/dev/ata/TODO.ncq:1.1.2.46 Thu Sep 28 20:34:23 2017 +++ src/sys/dev/ata/TODO.ncq Fri Sep 29 20:05:07 2017 @@ -2,10 +2,6 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works -stop using DEV_BSIZE when really meaning ATA sector size and revert - inclusion in: -cvs rdiff -u -r1.2.30.1 -r1.2.30.2 src/sys/arch/amiga/dev/wdc_xsurf.c - Other random notes (do outside the NCQ branch): - do biodone() in wddone() starting the dump to not leak bufs when dumping from Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.38 src/sys/dev/ata/ata.c:1.132.8.39 --- src/sys/dev/ata/ata.c:1.132.8.38 Wed Sep 27 19:05:57 2017 +++ src/sys/dev/ata/ata.c Fri Sep 29 20:05:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.39 2017/09/29 20:05:07 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.39 2017/09/29 20:05:07 jdolecek Exp $"); #include "opt_ata.h" @@ -961,7 +961,7 @@ ata_get_params(struct ata_drive_datas *d return CMD_AGAIN; } - tb = kmem_zalloc(DEV_BSIZE, KM_SLEEP); + tb = kmem_zalloc(ATA_BSIZE, KM_SLEEP); memset(prms, 0, sizeof(struct ataparams)); if (drvp->drive_type == ATA_DRIVET_ATA) { @@ -982,7 +982,7 @@ ata_get_params(struct ata_drive_datas *d } xfer->c_ata_c.flags = AT_READ | flags; xfer->c_ata_c.data = tb; - xfer->c_ata_c.bcount = DEV_BSIZE; + xfer->c_ata_c.bcount = ATA_BSIZE; if ((*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer) != ATACMD_COMPLETE) { ATADEBUG_PRINT(("ata_get_parms: wdc_exec_command failed\n"), @@ -1044,7 +1044,7 @@ ata_get_params(struct ata_drive_datas *d rv = CMD_OK; out: - kmem_free(tb, DEV_BSIZE); + kmem_free(tb, ATA_BSIZE); ata_free_xfer(chp, xfer); return rv; } @@ -1110,7 +1110,7 @@ ata_read_log_ext_ncq(struct ata_drive_da xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0); tb = drvp->recovery_blk; - memset(tb, 0, DEV_BSIZE); + memset(tb, 0, sizeof(drvp->recovery_blk)); /* * We could use READ LOG DMA EXT if drive supports it (i.e. @@ -1128,7 +1128,7 @@ ata_read_log_ext_ncq(struct ata_drive_da 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 = DEV_BSIZE; + xfer->c_ata_c.bcount = sizeof(drvp->recovery_blk); if ((*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer) != ATACMD_COMPLETE) { @@ -1141,7 +1141,7 @@ ata_read_log_ext_ncq(struct ata_drive_da } cksum = 0; - for (int i = 0; i < DEV_BSIZE; i++) + for (int i = 0; i < sizeof(drvp->recovery_blk); i++) cksum += tb[i]; if (cksum != 0) { aprint_error_dev(drvp->drv_softc, Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.28 src/sys/dev/ata/atavar.h:1.92.8.29 --- src/sys/dev/ata/atavar.h:1.92.8.28 Wed Sep 27 19:05:57 2017 +++ src/sys/dev/ata/atavar.h Fri Sep 29 20:05:07 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.28 2017/09/27 19:05:57 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.29 2017/09/29 20:05:07 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -207,6 +207,8 @@ struct ata_xfer { #define ATA_MAX_OPENINGS 32 #define ATA_REAL_OPENINGS(op) ((op) > 1 ? (op) - 1 : 1) +#define ATA_BSIZE 512 /* Standard ATA block size (bytes) */ + /* Per-channel queue of ata_xfers */ #ifndef ATABUS_PRIVATE struct ata_queue; @@ -329,7 +331,7 @@ struct ata_drive_datas { daddr_t badsect[127]; /* 126 plus trailing -1 marker */ /* Recovery buffer */ - uint8_t recovery_blk[DEV_BSIZE]; + uint8_t recovery_blk[ATA_BSIZE]; }; /* User config flags that force (or disable) the use of a mode */
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Sep 29 20:05:07 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c atavar.h Log Message: introduce ATA_BSIZE and use it instead of DEV_BSIZE for get params and recovery, where they are by spec 512 bytes and not negotiable To generate a diff of this commit: cvs rdiff -u -r1.1.2.46 -r1.1.2.47 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.38 -r1.132.8.39 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.28 -r1.92.8.29 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 28 20:34:23 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq wd.c wdvar.h Log Message: add sysctls to control if NCQ is being used, and how many max tags; I have a drive which is significantly slower with NCQ than non-NCQ, and it's generally useful to have this easily overridable while here, also move the frequency settings for WD_CHAOS_MONKEY to a sysctl and make it per-drive To generate a diff of this commit: cvs rdiff -u -r1.1.2.45 -r1.1.2.46 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.428.2.34 -r1.428.2.35 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.8 -r1.43.4.9 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 28 20:34:23 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq wd.c wdvar.h Log Message: add sysctls to control if NCQ is being used, and how many max tags; I have a drive which is significantly slower with NCQ than non-NCQ, and it's generally useful to have this easily overridable while here, also move the frequency settings for WD_CHAOS_MONKEY to a sysctl and make it per-drive To generate a diff of this commit: cvs rdiff -u -r1.1.2.45 -r1.1.2.46 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.428.2.34 -r1.428.2.35 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.8 -r1.43.4.9 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.1.2.45 src/sys/dev/ata/TODO.ncq:1.1.2.46 --- src/sys/dev/ata/TODO.ncq:1.1.2.45 Thu Sep 28 20:25:45 2017 +++ src/sys/dev/ata/TODO.ncq Thu Sep 28 20:34:23 2017 @@ -32,8 +32,6 @@ set is too much for emergency crash dump code path - old bug - kern/16789 -add nibble to control number of tags (1==disable NCQ)? - add support for the NCQ TRIM if supported by device? implement DIOCGCACHE/DIOCCACHESYNC for ld@ataraid? just passthrough, like ccd Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.428.2.34 src/sys/dev/ata/wd.c:1.428.2.35 --- src/sys/dev/ata/wd.c:1.428.2.34 Sun Aug 13 15:12:04 2017 +++ src/sys/dev/ata/wd.c Thu Sep 28 20:34:23 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34: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.428.2.34 2017/08/13 15:12:04 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -116,11 +116,6 @@ int wdcdebug_wd_mask = 0x0; #define ATADEBUG_PRINT(args, level) #endif -#ifdef WD_CHAOS_MONKEY -int wdcdebug_wd_cnt = 0; -int wdcdebug_wd_chaos = 0; -#endif - int wdprobe(device_t, cfdata_t, void *); void wdattach(device_t, device_t, void *); int wddetach(device_t, int); @@ -211,6 +206,9 @@ bool wd_shutdown(device_t, int); int wd_getcache(struct wd_softc *, int *); int wd_setcache(struct wd_softc *, int); +static void wd_sysctl_attach(struct wd_softc *); +static void wd_sysctl_detach(struct wd_softc *); + struct dkdriver wddkdriver = { .d_strategy = wdstrategy, .d_minphys = wdminphys @@ -450,6 +448,8 @@ out: if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown)) aprint_error_dev(self, "couldn't establish power handler\n"); + + wd_sysctl_attach(wd); } static bool @@ -520,6 +520,8 @@ wddetach(device_t self, int flags) pmf_device_deregister(self); + wd_sysctl_detach(sc); + /* Unhook the entropy source. */ rnd_detach_source(>rnd_source); @@ -663,8 +665,7 @@ wdstart(device_t self) while (bufq_peek(wd->sc_q) != NULL) { /* First try to get xfer. Limit to drive openings iff NCQ. */ xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0, - ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ) - ? wd->drvp->drv_openings : 0); + WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0); if (xfer == NULL) break; @@ -708,8 +709,8 @@ wdstart1(struct wd_softc *wd, struct buf * the command be clipped, or otherwise misinterpreted, by the * driver or controller. */ - if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wdcdebug_wd_cnt > 0 && - (++wdcdebug_wd_chaos % wdcdebug_wd_cnt) == 0) { + 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(wd->sc_dev, "%s: chaos xfer %d\n", __func__, xfer->c_slot); xfer->c_bio.blkno = 777 + wd->sc_capacity; @@ -745,8 +746,7 @@ wdstart1(struct wd_softc *wd, struct buf * the semantics - FUA would not be honored. In that case, continue * retrying with NCQ. */ - if (wd->drvp->drive_flags & ATA_DRIVE_NCQ && - (xfer->c_retries < WDIORETRIES_SINGLE || + if (WD_USE_NCQ(wd) && (xfer->c_retries < WDIORETRIES_SINGLE || (bp->b_flags & B_MEDIA_FUA) != 0)) { xfer->c_bio.flags |= ATA_LBA48; xfer->c_flags |= C_NCQ; @@ -1856,7 +1856,7 @@ wd_getcache(struct wd_softc *wd, int *bi if (params.atap_cmd1_en & WDC_CMD1_CACHE) *bitsp |= DKCACHE_WRITE; - if (wd->drvp->drive_flags & (ATA_DRIVE_NCQ|ATA_DRIVE_WFUA)) + if (WD_USE_NCQ(wd) || (wd->drvp->drive_flags & ATA_DRIVE_WFUA)) *bitsp |= DKCACHE_FUA; return 0; @@ -2315,3 +2315,84 @@ out2: bp->b_resid = bp->b_bcount; biodone(bp); } + +static void +wd_sysctl_attach(struct wd_softc *wd) +{ + const struct sysctlnode *node; + int error; + + /* sysctl set-up */ + if (sysctl_createv(>nodelog, 0, NULL, , +0, CTLTYPE_NODE,
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 28 20:25:45 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: add note about DEV_BSIZE use To generate a diff of this commit: cvs rdiff -u -r1.1.2.44 -r1.1.2.45 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.1.2.44 src/sys/dev/ata/TODO.ncq:1.1.2.45 --- src/sys/dev/ata/TODO.ncq:1.1.2.44 Thu Sep 21 17:15:18 2017 +++ src/sys/dev/ata/TODO.ncq Thu Sep 28 20:25:45 2017 @@ -2,6 +2,10 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works +stop using DEV_BSIZE when really meaning ATA sector size and revert + inclusion in: +cvs rdiff -u -r1.2.30.1 -r1.2.30.2 src/sys/arch/amiga/dev/wdc_xsurf.c + Other random notes (do outside the NCQ branch): - do biodone() in wddone() starting the dump to not leak bufs when dumping from
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 28 20:25:45 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: add note about DEV_BSIZE use To generate a diff of this commit: cvs rdiff -u -r1.1.2.44 -r1.1.2.45 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 27 19:05:57 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: restore the atac_claim_hw and atac_free_hw hooks, they are used on atari To generate a diff of this commit: cvs rdiff -u -r1.132.8.37 -r1.132.8.38 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.27 -r1.92.8.28 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 27 19:05:57 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: restore the atac_claim_hw and atac_free_hw hooks, they are used on atari To generate a diff of this commit: cvs rdiff -u -r1.132.8.37 -r1.132.8.38 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.27 -r1.92.8.28 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.132.8.37 src/sys/dev/ata/ata.c:1.132.8.38 --- src/sys/dev/ata/ata.c:1.132.8.37 Mon Sep 25 22:43:46 2017 +++ src/sys/dev/ata/ata.c Wed Sep 27 19:05:57 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.38 2017/09/27 19:05:57 jdolecek Exp $"); #include "opt_ata.h" @@ -1355,6 +1355,10 @@ again: goto out; } + if (atac->atac_claim_hw) + if (!atac->atac_claim_hw(chp, 0)) + goto out; + ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d\n", xfer, chp->ch_channel, xfer->c_drive), DEBUG_XFERS); if (drvp->drive_flags & ATA_DRIVE_RESET) { @@ -1529,6 +1533,9 @@ ata_free_xfer(struct ata_channel *chp, s } #endif + if (chp->ch_atac->atac_free_hw) + chp->ch_atac->atac_free_hw(chp); + KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0); KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0); chq->queue_xfers_avail |= __BIT(xfer->c_slot); Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.27 src/sys/dev/ata/atavar.h:1.92.8.28 --- src/sys/dev/ata/atavar.h:1.92.8.27 Tue Sep 26 20:15:36 2017 +++ src/sys/dev/ata/atavar.h Wed Sep 27 19:05:57 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.27 2017/09/26 20:15:36 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.28 2017/09/27 19:05:57 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -483,6 +483,13 @@ struct atac_softc { void (*atac_probe)(struct ata_channel *); /* + * Optional callbacks to lock/unlock hardware. + * Called with channel mutex held. + */ + int (*atac_claim_hw)(struct ata_channel *, int); + void (*atac_free_hw)(struct ata_channel *); + + /* * Optional callbacks to set drive mode. Required for anything * but basic PIO operation. */
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Sep 26 20:15:36 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c atavar.h Log Message: make compile without NATA_DMA To generate a diff of this commit: cvs rdiff -u -r1.105.6.10 -r1.105.6.11 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.26 -r1.92.8.27 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_wdc.c diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.10 src/sys/dev/ata/ata_wdc.c:1.105.6.11 --- src/sys/dev/ata/ata_wdc.c:1.105.6.10 Thu Sep 21 18:47:21 2017 +++ src/sys/dev/ata/ata_wdc.c Tue Sep 26 20:15:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -340,9 +340,9 @@ _wdc_ata_bio_start(struct ata_channel *c int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; uint16_t cyl; uint8_t head, sect, cmd = 0; - int nblks; + int nblks, tfd; #if NATA_DMA || NATA_PIOBM - int error, dma_flags = 0, tfd; + int error, dma_flags = 0; #endif ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n", Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.26 src/sys/dev/ata/atavar.h:1.92.8.27 --- src/sys/dev/ata/atavar.h:1.92.8.26 Tue Sep 19 21:06:25 2017 +++ src/sys/dev/ata/atavar.h Tue Sep 26 20:15:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.26 2017/09/19 21:06:25 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.27 2017/09/26 20:15:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -304,9 +304,9 @@ struct ata_drive_datas { #define RESET 0 #define READY 1 -#if NATA_DMA uint8_t drv_openings; /* # of command tags */ +#if NATA_DMA /* numbers of xfers and DMA errs. Used by ata_dmaerr() */ uint8_t n_dmaerrs; uint32_t n_xfers;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Sep 26 20:15:36 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c atavar.h Log Message: make compile without NATA_DMA To generate a diff of this commit: cvs rdiff -u -r1.105.6.10 -r1.105.6.11 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.26 -r1.92.8.27 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 25 22:43:46 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: put recovery command on head of active xfers queue, so that drivers using ata_queue_get_active_xfer() like mvsata(4) will find it and not random other NCQ xfer never return NCQ xfer from ata_queue_get_active_xfer(), if the first xfer is NCQ simply return NULL adjust ata_timo_xfer_check() to not check the expiring flag in C_WAITTIMO branch, if we get there we ought to get the timeout handler aborted To generate a diff of this commit: cvs rdiff -u -r1.132.8.36 -r1.132.8.37 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.132.8.36 src/sys/dev/ata/ata.c:1.132.8.37 --- src/sys/dev/ata/ata.c:1.132.8.36 Sat Sep 23 14:53:26 2017 +++ src/sys/dev/ata/ata.c Mon Sep 25 22:43:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.37 2017/09/25 22:43:46 jdolecek Exp $"); #include "opt_ata.h" @@ -208,7 +208,8 @@ ata_queue_hwslot_to_xfer(struct ata_chan KASSERTMSG(hwslot < chq->queue_openings, "hwslot %d > openings %d", hwslot, chq->queue_openings); - KASSERT((chq->active_xfers_used & __BIT(hwslot)) != 0); + KASSERTMSG((chq->active_xfers_used & __BIT(hwslot)) != 0, + "hwslot %d not active", hwslot); /* Usually the first entry will be the one */ TAILQ_FOREACH(xfer, >active_xfers, c_activechain) { @@ -228,8 +229,17 @@ ata_queue_hwslot_to_xfer(struct ata_chan static struct ata_xfer * ata_queue_get_active_xfer_locked(struct ata_channel *chp) { + struct ata_xfer *xfer; + KASSERT(mutex_owned(>ch_lock)); - return TAILQ_FIRST(>ch_queue->active_xfers); + xfer = TAILQ_FIRST(>ch_queue->active_xfers); + + if (xfer && ISSET(xfer->c_flags, C_NCQ)) { + /* Spurious call, never return NCQ xfer from this interface */ + xfer = NULL; + } + + return xfer; } /* @@ -1543,7 +1553,16 @@ ata_activate_xfer_locked(struct ata_chan KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0); TAILQ_REMOVE(>queue_xfer, xfer, c_xferchain); - TAILQ_INSERT_TAIL(>active_xfers, xfer, c_activechain); + if ((xfer->c_flags & C_RECOVERY) == 0) + TAILQ_INSERT_TAIL(>active_xfers, xfer, c_activechain); + else { + /* + * Must go to head, so that ata_queue_get_active_xfer() + * returns the recovery command, and not some other + * random active transfer. + */ + TAILQ_INSERT_HEAD(>active_xfers, xfer, c_activechain); + } chq->active_xfers_used |= __BIT(xfer->c_slot); chq->queue_active++; } @@ -1632,15 +1651,13 @@ ata_timo_xfer_check(struct ata_xfer *xfe return true; } - /* Handle race vs. callout_stop() in ata_deactivate_xfer() */ - if (!callout_expired(>c_timo_callout)) { - ata_channel_unlock(chp); + /* Race vs. callout_stop() in ata_deactivate_xfer() */ + ata_channel_unlock(chp); - aprint_normal_dev(drvp->drv_softc, - "xfer %d deactivated while invoking timeout\n", - xfer->c_slot); - return true; - } + aprint_normal_dev(drvp->drv_softc, + "xfer %d deactivated while invoking timeout\n", + xfer->c_slot); + return true; } ata_channel_unlock(chp);
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 25 22:43:46 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: put recovery command on head of active xfers queue, so that drivers using ata_queue_get_active_xfer() like mvsata(4) will find it and not random other NCQ xfer never return NCQ xfer from ata_queue_get_active_xfer(), if the first xfer is NCQ simply return NULL adjust ata_timo_xfer_check() to not check the expiring flag in C_WAITTIMO branch, if we get there we ought to get the timeout handler aborted To generate a diff of this commit: cvs rdiff -u -r1.132.8.36 -r1.132.8.37 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 23 14:53:26 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: note to previous: the KASSERT() insisted actually there is at most one active xfer, which is false during NCQ error recovery To generate a diff of this commit: cvs rdiff -u -r1.132.8.35 -r1.132.8.36 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.132.8.35 src/sys/dev/ata/ata.c:1.132.8.36 --- src/sys/dev/ata/ata.c:1.132.8.35 Sat Sep 23 13:13:19 2017 +++ src/sys/dev/ata/ata.c Sat Sep 23 14:53:26 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.36 2017/09/23 14:53:26 jdolecek Exp $"); #include "opt_ata.h"
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 23 14:53:26 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: note to previous: the KASSERT() insisted actually there is at most one active xfer, which is false during NCQ error recovery To generate a diff of this commit: cvs rdiff -u -r1.132.8.35 -r1.132.8.36 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 23 13:13:19 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: remove ata_queue_get_active_xfer() KASSERT() about having at least one active xfer; it can happen we get interrupt while no longer having the cmd active e.g. during recovery, and all callers handle getting NULL as result fixes panic in mvsata(4) during error recovery To generate a diff of this commit: cvs rdiff -u -r1.132.8.34 -r1.132.8.35 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.132.8.34 src/sys/dev/ata/ata.c:1.132.8.35 --- src/sys/dev/ata/ata.c:1.132.8.34 Wed Sep 20 19:39:36 2017 +++ src/sys/dev/ata/ata.c Sat Sep 23 13:13:19 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.35 2017/09/23 13:13:19 jdolecek Exp $"); #include "opt_ata.h" @@ -244,10 +244,7 @@ ata_queue_get_active_xfer(struct ata_cha struct ata_xfer *xfer = NULL; ata_channel_lock(chp); - - KASSERT(chp->ch_queue->queue_active <= 1); xfer = ata_queue_get_active_xfer_locked(chp); - ata_channel_unlock(chp); return xfer;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 23 13:13:19 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: remove ata_queue_get_active_xfer() KASSERT() about having at least one active xfer; it can happen we get interrupt while no longer having the cmd active e.g. during recovery, and all callers handle getting NULL as result fixes panic in mvsata(4) during error recovery To generate a diff of this commit: cvs rdiff -u -r1.132.8.34 -r1.132.8.35 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 21 18:47:21 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c Log Message: add missing ata_channel_unlock() in bailout path of wdc_ata_bio_intr() To generate a diff of this commit: cvs rdiff -u -r1.105.6.9 -r1.105.6.10 src/sys/dev/ata/ata_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_wdc.c diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.9 src/sys/dev/ata/ata_wdc.c:1.105.6.10 --- src/sys/dev/ata/ata_wdc.c:1.105.6.9 Sun Sep 10 19:31:15 2017 +++ src/sys/dev/ata/ata_wdc.c Thu Sep 21 18:47:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.105.6.9 2017/09/10 19:31:15 jdolecek Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.9 2017/09/10 19:31:15 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.10 2017/09/21 18:47:21 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -662,8 +662,10 @@ wdc_ata_bio_intr(struct ata_channel *chp /* Ack interrupt done by wdc_wait_for_unbusy */ if (wdc_wait_for_unbusy(chp, poll ? ATA_DELAY : 0, AT_POLL, ) < 0) { - if (!poll && (xfer->c_flags & C_TIMEOU) == 0) + if (!poll && (xfer->c_flags & C_TIMEOU) == 0) { + ata_channel_unlock(chp); return 0; /* IRQ was not for us */ + } printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n", device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, xfer->c_bcount, xfer->c_skip);
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 21 18:47:21 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c Log Message: add missing ata_channel_unlock() in bailout path of wdc_ata_bio_intr() To generate a diff of this commit: cvs rdiff -u -r1.105.6.9 -r1.105.6.10 src/sys/dev/ata/ata_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Thu Sep 21 17:15:18 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: wddone() doesn't need more locking To generate a diff of this commit: cvs rdiff -u -r1.1.2.43 -r1.1.2.44 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.1.2.43 src/sys/dev/ata/TODO.ncq:1.1.2.44 --- src/sys/dev/ata/TODO.ncq:1.1.2.43 Wed Sep 20 19:45:37 2017 +++ src/sys/dev/ata/TODO.ncq Thu Sep 21 17:15:18 2017 @@ -32,8 +32,6 @@ add nibble to control number of tags (1= add support for the NCQ TRIM if supported by device? -protect more of wddone() with mutex? - implement DIOCGCACHE/DIOCCACHESYNC for ld@ataraid? just passthrough, like ccd MSI/MSI-X support for AHCI and mvsata(4)
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 20 19:45:37 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: MVSATA_WITHOUTDMA seems to work fine To generate a diff of this commit: cvs rdiff -u -r1.1.2.42 -r1.1.2.43 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 20 19:45:37 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: MVSATA_WITHOUTDMA seems to work fine To generate a diff of this commit: cvs rdiff -u -r1.1.2.42 -r1.1.2.43 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.1.2.42 src/sys/dev/ata/TODO.ncq:1.1.2.43 --- src/sys/dev/ata/TODO.ncq:1.1.2.42 Tue Sep 19 21:06:25 2017 +++ src/sys/dev/ata/TODO.ncq Wed Sep 20 19:45:37 2017 @@ -2,8 +2,6 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works -mvsata - resest MVSATA_WITHOUTDMA - Other random notes (do outside the NCQ branch): - do biodone() in wddone() starting the dump to not leak bufs when dumping from
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 20 19:39:36 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: add forgotten destroy of queue_idle cv in ata_queue_free() To generate a diff of this commit: cvs rdiff -u -r1.132.8.33 -r1.132.8.34 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.132.8.33 src/sys/dev/ata/ata.c:1.132.8.34 --- src/sys/dev/ata/ata.c:1.132.8.33 Tue Sep 19 21:06:25 2017 +++ src/sys/dev/ata/ata.c Wed Sep 20 19:39:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06:25 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39: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.132.8.33 2017/09/19 21:06:25 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.34 2017/09/20 19:39:36 jdolecek Exp $"); #include "opt_ata.h" @@ -328,6 +328,7 @@ ata_queue_free(struct ata_queue *chq) cv_destroy(>queue_busy); cv_destroy(>queue_drain); + cv_destroy(>queue_idle); free(chq, M_DEVBUF); }
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 20 19:39:36 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: add forgotten destroy of queue_idle cv in ata_queue_free() To generate a diff of this commit: cvs rdiff -u -r1.132.8.33 -r1.132.8.34 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 13 19:55:12 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: two more - mvsata MVSATA_WITHOUTDMA seems to be broken, and latest channel lock changes introduced panic in mi_switch() on code paths which kpause/tsleep To generate a diff of this commit: cvs rdiff -u -r1.1.2.40 -r1.1.2.41 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.1.2.40 src/sys/dev/ata/TODO.ncq:1.1.2.41 --- src/sys/dev/ata/TODO.ncq:1.1.2.40 Mon Sep 11 22:31:42 2017 +++ src/sys/dev/ata/TODO.ncq Wed Sep 13 19:55:12 2017 @@ -2,6 +2,12 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works +mvsata - resest MVSATA_WITHOUTDMA + +the changes to lock channel lock cause now mi_switch() with spinlock held +when invoking ata_delay() (which calls kpause()) or on tsleep, need +to refactor + Other random notes (do outside the NCQ branch): - do biodone() in wddone() starting the dump to not leak bufs when dumping from
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Sep 13 19:55:12 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: two more - mvsata MVSATA_WITHOUTDMA seems to be broken, and latest channel lock changes introduced panic in mi_switch() on code paths which kpause/tsleep To generate a diff of this commit: cvs rdiff -u -r1.1.2.40 -r1.1.2.41 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:31:42 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: doesn't seem the freeze/thaw in error recovery can cause the thread to panic, all commands within are executed as polled and hence thread is not invoked To generate a diff of this commit: cvs rdiff -u -r1.1.2.39 -r1.1.2.40 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:31:42 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: doesn't seem the freeze/thaw in error recovery can cause the thread to panic, all commands within are executed as polled and hence thread is not invoked To generate a diff of this commit: cvs rdiff -u -r1.1.2.39 -r1.1.2.40 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.1.2.39 src/sys/dev/ata/TODO.ncq:1.1.2.40 --- src/sys/dev/ata/TODO.ncq:1.1.2.39 Mon Sep 11 22:30:05 2017 +++ src/sys/dev/ata/TODO.ncq Mon Sep 11 22:31:42 2017 @@ -2,8 +2,6 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works -reconsider freeze/thaw in error recovery - can it screw up with thread? - Other random notes (do outside the NCQ branch): - do biodone() in wddone() starting the dump to not leak bufs when dumping from
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:30:05 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: atastart() rechecked - it's okay to call it even in error path in those several cases we do, it's just optimization to skip the call; I'm not even very convinced it's useful to have this conditional, but keeping for now until proven harmful To generate a diff of this commit: cvs rdiff -u -r1.1.2.38 -r1.1.2.39 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.1.2.38 src/sys/dev/ata/TODO.ncq:1.1.2.39 --- src/sys/dev/ata/TODO.ncq:1.1.2.38 Sun Sep 10 19:31:15 2017 +++ src/sys/dev/ata/TODO.ncq Mon Sep 11 22:30:05 2017 @@ -2,11 +2,6 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works -revise calls to atastart() - now called alsoafter ATASTART_ABORT(), call -only from intr routine -- wdc.c never calls atastart() (start always false) -- ata_wdc.c calls atastart() regardless if error - reconsider freeze/thaw in error recovery - can it screw up with thread? Other random notes (do outside the NCQ branch):
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:30:05 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: atastart() rechecked - it's okay to call it even in error path in those several cases we do, it's just optimization to skip the call; I'm not even very convinced it's useful to have this conditional, but keeping for now until proven harmful To generate a diff of this commit: cvs rdiff -u -r1.1.2.38 -r1.1.2.39 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:16:18 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: move debug printf where it belongs To generate a diff of this commit: cvs rdiff -u -r1.132.8.31 -r1.132.8.32 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:16:18 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: move debug printf where it belongs To generate a diff of this commit: cvs rdiff -u -r1.132.8.31 -r1.132.8.32 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.132.8.31 src/sys/dev/ata/ata.c:1.132.8.32 --- src/sys/dev/ata/ata.c:1.132.8.31 Sun Sep 10 19:31:15 2017 +++ src/sys/dev/ata/ata.c Mon Sep 11 22:16:18 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $"); #include "opt_ata.h" @@ -1230,8 +1230,6 @@ ata_exec_xfer(struct ata_channel *chp, s else TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer, c_xferchain); - ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n", - chp->ch_flags), DEBUG_XFERS); /* * if polling and can sleep, wait for the xfer to be at head of queue @@ -1256,6 +1254,8 @@ ata_exec_xfer(struct ata_channel *chp, s ata_channel_unlock(chp); + ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n", + chp->ch_flags), DEBUG_XFERS); atastart(chp); }
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Sep 10 19:22:57 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: fix regression in atabus_thread() when it was converted from spl to mutex - the reset and c_start() routines expect to run on splbio; wrap the calls insite splbio/splx() again for now, since we can't hold the mutex while calling them fixes problem experienced by Jonathan, where drive setup triggered an spurious interrupt and panic due to state < READY To generate a diff of this commit: cvs rdiff -u -r1.132.8.29 -r1.132.8.30 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.132.8.29 src/sys/dev/ata/ata.c:1.132.8.30 --- src/sys/dev/ata/ata.c:1.132.8.29 Tue Aug 15 11:21:32 2017 +++ src/sys/dev/ata/ata.c Sun Sep 10 19:22:56 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $"); #include "opt_ata.h" @@ -586,7 +586,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; + int i, s; mutex_enter(>ch_lock); chp->ch_flags |= ATACH_TH_RUN; @@ -630,7 +630,9 @@ atabus_thread(void *arg) */ mutex_exit(>ch_lock); ata_channel_thaw(chp); + s = splbio(); ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags); + splx(s); mutex_enter(>ch_lock); } else if (chq->queue_active > 0 && chq->queue_freeze == 1) { /* @@ -644,7 +646,9 @@ atabus_thread(void *arg) ata_channel_thaw(chp); xfer = ata_queue_get_active_xfer(chp); KASSERT(xfer != NULL); + s = splbio(); (*xfer->c_start)(xfer->c_chp, xfer); + splx(s); mutex_enter(>ch_lock); } else if (chq->queue_freeze > 1) panic("%s: queue_freeze", __func__);
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Sep 10 19:22:57 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: fix regression in atabus_thread() when it was converted from spl to mutex - the reset and c_start() routines expect to run on splbio; wrap the calls insite splbio/splx() again for now, since we can't hold the mutex while calling them fixes problem experienced by Jonathan, where drive setup triggered an spurious interrupt and panic due to state < READY To generate a diff of this commit: cvs rdiff -u -r1.132.8.29 -r1.132.8.30 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 2 12:01:25 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wdvar.h Log Message: include opt_wd.h instead of opt_wd_softbadsect.h, the option doesn't have private file any more To generate a diff of this commit: cvs rdiff -u -r1.43.4.7 -r1.43.4.8 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/wdvar.h diff -u src/sys/dev/ata/wdvar.h:1.43.4.7 src/sys/dev/ata/wdvar.h:1.43.4.8 --- src/sys/dev/ata/wdvar.h:1.43.4.7 Wed Jul 19 19:39:28 2017 +++ src/sys/dev/ata/wdvar.h Sat Sep 2 12:01:25 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdvar.h,v 1.43.4.7 2017/07/19 19:39:28 jdolecek Exp $ */ +/* $NetBSD: wdvar.h,v 1.43.4.8 2017/09/02 12:01:25 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -28,7 +28,7 @@ #define _DEV_ATA_WDVAR_H_ #ifdef _KERNEL_OPT -#include "opt_wd_softbadsect.h" +#include "opt_wd.h" #endif #include
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Sep 2 12:01:25 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wdvar.h Log Message: include opt_wd.h instead of opt_wd_softbadsect.h, the option doesn't have private file any more To generate a diff of this commit: cvs rdiff -u -r1.43.4.7 -r1.43.4.8 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 29 13:38:38 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: some notes around c_start/atastart() To generate a diff of this commit: cvs rdiff -u -r1.1.2.36 -r1.1.2.37 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.1.2.36 src/sys/dev/ata/TODO.ncq:1.1.2.37 --- src/sys/dev/ata/TODO.ncq:1.1.2.36 Sun Aug 13 11:46:32 2017 +++ src/sys/dev/ata/TODO.ncq Tue Aug 29 13:38:38 2017 @@ -2,6 +2,11 @@ Bugs test wd* at umass?, confirm the ata_channel kludge works +c_start() needs to be called on splbio to avoid spurious irq during reset, +is not e.g. in ata thread and may not in atastart() neither +- wdc.c never calls atastart() (start always false) +- ata_wdc.c calls atastart() regardless if error + Other random notes (do outside the NCQ branch): - do biodone() in wddone() starting the dump to not leak bufs when dumping from
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 29 13:38:38 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: some notes around c_start/atastart() To generate a diff of this commit: cvs rdiff -u -r1.1.2.36 -r1.1.2.37 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 15 11:21:32 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: explicitly do not try to activate any further commands when running recovery xfer; it was kind of implied since the code would not queue another non-NCQ command when non-NCQ command is active, but this is better for readibility To generate a diff of this commit: cvs rdiff -u -r1.132.8.28 -r1.132.8.29 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 15 11:21:32 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: explicitly do not try to activate any further commands when running recovery xfer; it was kind of implied since the code would not queue another non-NCQ command when non-NCQ command is active, but this is better for readibility To generate a diff of this commit: cvs rdiff -u -r1.132.8.28 -r1.132.8.29 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.132.8.28 src/sys/dev/ata/ata.c:1.132.8.29 --- src/sys/dev/ata/ata.c:1.132.8.28 Sat Aug 12 22:31:50 2017 +++ src/sys/dev/ata/ata.c Tue Aug 15 11:21:32 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21: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.132.8.28 2017/08/12 22:31:50 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.29 2017/08/15 11:21:32 jdolecek Exp $"); #include "opt_ata.h" @@ -1249,7 +1249,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 immediate; + bool recovery; #ifdef ATA_DEBUG int spl1, spl2; @@ -1276,10 +1276,10 @@ again: if ((xfer = TAILQ_FIRST(>ch_queue->queue_xfer)) == NULL) goto out; - immediate = ISSET(xfer->c_flags, C_RECOVERY); + recovery = ISSET(xfer->c_flags, C_RECOVERY); /* is the queue frozen? */ - if (__predict_false(!immediate && chq->queue_freeze > 0)) { + if (__predict_false(!recovery && chq->queue_freeze > 0)) { if (chq->queue_flags & QF_IDLE_WAIT) { chq->queue_flags &= ~QF_IDLE_WAIT; wakeup(>queue_flags); @@ -1298,7 +1298,7 @@ again: * Need only check first xfer. * XXX FIS-based switching - revisit */ - if (!immediate && (axfer = TAILQ_FIRST(>ch_queue->active_xfers))) { + if (!recovery && (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) @@ -1344,8 +1344,8 @@ again: */ xfer->c_start(chp, xfer); - /* Queue more commands if possible */ - if (chq->queue_active < chq->queue_openings) + /* Queue more commands if possible, but not during recovery */ + if (!recovery && chq->queue_active < chq->queue_openings) goto again; return;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Aug 13 15:12:04 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: by default make the chaos monkey do nothing, so it's easier to have this compiled in all the time for testing; the vars can be set via DDB when needed To generate a diff of this commit: cvs rdiff -u -r1.428.2.33 -r1.428.2.34 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Aug 13 15:12:04 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: by default make the chaos monkey do nothing, so it's easier to have this compiled in all the time for testing; the vars can be set via DDB when needed To generate a diff of this commit: cvs rdiff -u -r1.428.2.33 -r1.428.2.34 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.428.2.33 src/sys/dev/ata/wd.c:1.428.2.34 --- src/sys/dev/ata/wd.c:1.428.2.33 Sun Aug 13 11:40:25 2017 +++ src/sys/dev/ata/wd.c Sun Aug 13 15:12:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -117,7 +117,7 @@ int wdcdebug_wd_mask = 0x0; #endif #ifdef WD_CHAOS_MONKEY -int wdcdebug_wd_cnt = 200; +int wdcdebug_wd_cnt = 0; int wdcdebug_wd_chaos = 0; #endif
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Aug 13 11:46:32 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: move the dump note to post-merge, it's not new siisata seems to be fine, no longer holds the merge remove the kill active transfers after software drive reset - not relevant now only the wd* at umass? stays as new item, but I won't hold the merge for this, as I don't have the hardware and it is contained enough to be resolved on HEAD To generate a diff of this commit: cvs rdiff -u -r1.1.2.35 -r1.1.2.36 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.1.2.35 src/sys/dev/ata/TODO.ncq:1.1.2.36 --- src/sys/dev/ata/TODO.ncq:1.1.2.35 Sat Aug 12 22:43:22 2017 +++ src/sys/dev/ata/TODO.ncq Sun Aug 13 11:46:32 2017 @@ -1,19 +1,13 @@ Bugs - -siisata - fix all new XXX and unmergable bits - test wd* at umass?, confirm the ata_channel kludge works +Other random notes (do outside the NCQ branch): +- do biodone() in wddone() starting the dump to not leak bufs when dumping from active system? make sure to not trigger atastart() - call ata_kill_active() + ata_kill_pending() when dumping -kill active transfers after software drive reset - race timeout vs. -error recovery - -Other random notes (do outside the NCQ branch): -- implement support for PM FIS-based switching, remove restriction in atastart() for hw which supports it, adjust error handling in controller drivers to handle xfers for several different drives
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Aug 13 11:46:32 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: move the dump note to post-merge, it's not new siisata seems to be fine, no longer holds the merge remove the kill active transfers after software drive reset - not relevant now only the wd* at umass? stays as new item, but I won't hold the merge for this, as I don't have the hardware and it is contained enough to be resolved on HEAD To generate a diff of this commit: cvs rdiff -u -r1.1.2.35 -r1.1.2.36 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Aug 13 11:40:25 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: restore the fallback to non-NCQ on retries, do this after WDIORETRIES_SINGLE retries, but only for non-FUA I/O; also only do the ATA_SINGLE fallback when non-FUA this makes sure that bio with ATA_SINGLE is not attempted as NCQ - the ATA_SINGLE I/O is usually done using PIO by drivers which actually support it, and thus are not compatible with DMA-only NCQ To generate a diff of this commit: cvs rdiff -u -r1.428.2.32 -r1.428.2.33 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.428.2.32 src/sys/dev/ata/wd.c:1.428.2.33 --- src/sys/dev/ata/wd.c:1.428.2.32 Sat Aug 12 22:12:04 2017 +++ src/sys/dev/ata/wd.c Sun Aug 13 11:40:25 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40: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.428.2.32 2017/08/12 22:12:04 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -720,9 +720,12 @@ wdstart1(struct wd_softc *wd, struct buf /* * If we're retrying, retry in single-sector mode. This will give us * the sector number of the problem, and will eventually allow the - * transfer to succeed. + * transfer to succeed. If FUA is requested, we can't actually + * do this, as ATA_SINGLE is usually executed as PIO transfer by drivers + * which support it, and that isn't compatible with NCQ/FUA. */ - if (xfer->c_retries >= WDIORETRIES_SINGLE) + if (xfer->c_retries >= WDIORETRIES_SINGLE && + (bp->b_flags & B_MEDIA_FUA) == 0) xfer->c_bio.flags = ATA_SINGLE; else xfer->c_bio.flags = 0; @@ -734,10 +737,17 @@ wdstart1(struct wd_softc *wd, struct buf xfer->c_bio.flags |= ATA_LBA48; /* - * If NCQ was negotiated, always use it. Some drives return random - * errors when switching between NCQ and non-NCQ I/O too often. + * If NCQ was negotiated, always use it for the first several attempts. + * Since device cancels all outstanding requests on error, downgrade + * to non-NCQ on retry, so that the retried transfer would not cause + * cascade failure for the other transfers if it fails again. + * If FUA was requested, we can't downgrade, as that would violate + * the semantics - FUA would not be honored. In that case, continue + * retrying with NCQ. */ - if (wd->drvp->drive_flags & ATA_DRIVE_NCQ) { + if (wd->drvp->drive_flags & ATA_DRIVE_NCQ && + (xfer->c_retries < WDIORETRIES_SINGLE || + (bp->b_flags & B_MEDIA_FUA) != 0)) { xfer->c_bio.flags |= ATA_LBA48; xfer->c_flags |= C_NCQ;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Aug 13 11:40:25 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: restore the fallback to non-NCQ on retries, do this after WDIORETRIES_SINGLE retries, but only for non-FUA I/O; also only do the ATA_SINGLE fallback when non-FUA this makes sure that bio with ATA_SINGLE is not attempted as NCQ - the ATA_SINGLE I/O is usually done using PIO by drivers which actually support it, and thus are not compatible with DMA-only NCQ To generate a diff of this commit: cvs rdiff -u -r1.428.2.32 -r1.428.2.33 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Aug 12 22:31:50 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: use AT_LBA48 flag for the READ LOG EXT - it's required so that e.g. mvsata() executes the command using wdccommandext(), it fails when executed using wdccommand() To generate a diff of this commit: cvs rdiff -u -r1.132.8.27 -r1.132.8.28 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Aug 12 22:31:50 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: use AT_LBA48 flag for the READ LOG EXT - it's required so that e.g. mvsata() executes the command using wdccommandext(), it fails when executed using wdccommand() To generate a diff of this commit: cvs rdiff -u -r1.132.8.27 -r1.132.8.28 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.132.8.27 src/sys/dev/ata/ata.c:1.132.8.28 --- src/sys/dev/ata/ata.c:1.132.8.27 Sat Aug 12 15:08:38 2017 +++ src/sys/dev/ata/ata.c Sat Aug 12 22:31:50 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.28 2017/08/12 22:31:50 jdolecek Exp $"); #include "opt_ata.h" @@ -1091,7 +1091,7 @@ ata_read_log_ext_ncq(struct ata_drive_da 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 | flags; + 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 = DEV_BSIZE;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Aug 12 15:08:38 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: take atabus_qlock while inserting into atabus_initq_head to avoid race in attach and rescan; just cleanup, noticed this while doing the thread locking, don't think there is realistic way to trigger this To generate a diff of this commit: cvs rdiff -u -r1.132.8.26 -r1.132.8.27 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Aug 12 15:08:38 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: take atabus_qlock while inserting into atabus_initq_head to avoid race in attach and rescan; just cleanup, noticed this while doing the thread locking, don't think there is realistic way to trigger this To generate a diff of this commit: cvs rdiff -u -r1.132.8.26 -r1.132.8.27 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.132.8.26 src/sys/dev/ata/ata.c:1.132.8.27 --- src/sys/dev/ata/ata.c:1.132.8.26 Sat Aug 12 14:41:54 2017 +++ src/sys/dev/ata/ata.c Sat Aug 12 15:08:38 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.27 2017/08/12 15:08:38 jdolecek Exp $"); #include "opt_ata.h" @@ -711,7 +711,9 @@ atabus_attach(device_t parent, device_t initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); initq->atabus_sc = sc; + mutex_enter(_qlock); TAILQ_INSERT_TAIL(_initq_head, initq, atabus_initq); + mutex_exit(_qlock); config_pending_incr(sc->sc_dev); if ((error = kthread_create(PRI_NONE, 0, NULL, atabus_thread, sc, @@ -2390,7 +2392,9 @@ atabus_rescan(device_t self, const char initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); initq->atabus_sc = sc; + mutex_enter(_qlock); TAILQ_INSERT_TAIL(_initq_head, initq, atabus_initq); + mutex_exit(_qlock); config_pending_incr(sc->sc_dev); mutex_enter(>ch_lock);
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 1 22:04:48 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: another one down To generate a diff of this commit: cvs rdiff -u -r1.1.2.31 -r1.1.2.32 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 1 22:04:48 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: another one down To generate a diff of this commit: cvs rdiff -u -r1.1.2.31 -r1.1.2.32 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.1.2.31 src/sys/dev/ata/TODO.ncq:1.1.2.32 --- src/sys/dev/ata/TODO.ncq:1.1.2.31 Mon Jul 31 20:11:17 2017 +++ src/sys/dev/ata/TODO.ncq Tue Aug 1 22:04:48 2017 @@ -18,12 +18,6 @@ active system? make sure to not trigger kill active transfers after software drive reset - race timeout vs. error recovery -multi-pmp disk open+i/o on siisata fails - track down and fix -#!/bin/sh -for disk in $disks; do -(echo $disk; for i in `seq 0 3`; do dd if=/dev/r${disk}d bs=16m of=/dev/null count=1; done)& -done; - Other random notes (do outside the NCQ branch): - implement support for PM FIS-based switching, remove restriction in atastart()
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 1 21:41:26 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: make atastart() schedule as many commands as possible, instead of always only one; makes it able to pick up pace again after processing non-NCQ command To generate a diff of this commit: cvs rdiff -u -r1.132.8.23 -r1.132.8.24 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.132.8.23 src/sys/dev/ata/ata.c:1.132.8.24 --- src/sys/dev/ata/ata.c:1.132.8.23 Tue Aug 1 21:39:51 2017 +++ src/sys/dev/ata/ata.c Tue Aug 1 21:41:25 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39:51 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41: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.132.8.23 2017/08/01 21:39:51 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41:25 jdolecek Exp $"); #include "opt_ata.h" @@ -1240,6 +1240,7 @@ atastart(struct ata_channel *chp) splx(spl1); #endif /* ATA_DEBUG */ +again: mutex_enter(>ch_lock); KASSERT(chq->queue_active <= chq->queue_openings); @@ -1318,6 +1319,11 @@ atastart(struct ata_channel *chp) * routine for polled commands. */ xfer->c_start(chp, xfer); + + /* Queue more commands if possible */ + if (chq->queue_active < chq->queue_openings) + goto again; + return; out:
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 1 21:41:26 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: make atastart() schedule as many commands as possible, instead of always only one; makes it able to pick up pace again after processing non-NCQ command To generate a diff of this commit: cvs rdiff -u -r1.132.8.23 -r1.132.8.24 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 1 21:39:51 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: move the drive recovery block to drive struct, it's inherently per-drive To generate a diff of this commit: cvs rdiff -u -r1.132.8.22 -r1.132.8.23 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.20 -r1.92.8.21 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.132.8.22 src/sys/dev/ata/ata.c:1.132.8.23 --- src/sys/dev/ata/ata.c:1.132.8.22 Sat Jul 29 12:58:29 2017 +++ src/sys/dev/ata/ata.c Tue Aug 1 21:39:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39: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.132.8.22 2017/07/29 12:58:29 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.23 2017/08/01 21:39:51 jdolecek Exp $"); #include "opt_ata.h" @@ -1051,7 +1051,7 @@ ata_read_log_ext_ncq(struct ata_drive_da xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0); - tb = chp->ch_recovery; + tb = drvp->recovery_blk; memset(tb, 0, DEV_BSIZE); /* Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.20 src/sys/dev/ata/atavar.h:1.92.8.21 --- src/sys/dev/ata/atavar.h:1.92.8.20 Sat Jul 29 12:58:29 2017 +++ src/sys/dev/ata/atavar.h Tue Aug 1 21:39:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.20 2017/07/29 12:58:29 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.21 2017/08/01 21:39:51 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -321,6 +321,9 @@ struct ata_drive_datas { struct disklabel *lp; /* pointer to drive's label info */ uint8_t multi; /* # of blocks to transfer in multi-mode */ daddr_t badsect[127]; /* 126 plus trailing -1 marker */ + + /* Recovery buffer */ + uint8_t recovery_blk[DEV_BSIZE]; }; /* User config flags that force (or disable) the use of a mode */ @@ -425,9 +428,6 @@ struct ata_channel { /* Number of sata PMP ports, if any */ int ch_satapmp_nports; - - /* Recovery buffer */ - uint8_t ch_recovery[DEV_BSIZE]; }; /*
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Aug 1 21:39:51 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: move the drive recovery block to drive struct, it's inherently per-drive To generate a diff of this commit: cvs rdiff -u -r1.132.8.22 -r1.132.8.23 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.20 -r1.92.8.21 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 31 20:11:17 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: some more notes To generate a diff of this commit: cvs rdiff -u -r1.1.2.30 -r1.1.2.31 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.1.2.30 src/sys/dev/ata/TODO.ncq:1.1.2.31 --- src/sys/dev/ata/TODO.ncq:1.1.2.30 Wed Jul 19 20:26:52 2017 +++ src/sys/dev/ata/TODO.ncq Mon Jul 31 20:11:17 2017 @@ -11,8 +11,18 @@ do proper NCQ error recovery ch_status/ch_error/ATACH_IRQ_WAIT - retest ATAPI -ahcisata - use dynamic xfer in ahci_do_reset_drive() instead of hardcoding -0, which can clash on drive reset after command failure +do biodone() in wddone() starting the dump to not leak bufs when dumping from +active system? make sure to not trigger atastart() +- call ata_kill_active() + ata_kill_pending() when dumping + +kill active transfers after software drive reset - race timeout vs. +error recovery + +multi-pmp disk open+i/o on siisata fails - track down and fix +#!/bin/sh +for disk in $disks; do +(echo $disk; for i in `seq 0 3`; do dd if=/dev/r${disk}d bs=16m of=/dev/null count=1; done)& +done; Other random notes (do outside the NCQ branch): -
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 31 20:11:17 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: some more notes To generate a diff of this commit: cvs rdiff -u -r1.1.2.30 -r1.1.2.31 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Jul 30 20:16:29 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: actually change the retry to also use NCQ - with one drive I see very frequent fatal errors on siisata when switching often between NCQ and non-NCQ I/O commands with chaos monkey (basically, always the next NCQ command on a slot which had non-NCQ I/O throws fatal error); they completely vanish when just using NCQ all the time To generate a diff of this commit: cvs rdiff -u -r1.428.2.30 -r1.428.2.31 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.428.2.30 src/sys/dev/ata/wd.c:1.428.2.31 --- src/sys/dev/ata/wd.c:1.428.2.30 Sat Jul 29 12:51:22 2017 +++ src/sys/dev/ata/wd.c Sun Jul 30 20:16:29 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -734,16 +734,10 @@ wdstart1(struct wd_softc *wd, struct buf xfer->c_bio.flags |= ATA_LBA48; /* - * If NCQ was negotiated, always use it for the first attempt. - * Since device cancels all outstanding requests on error, downgrade - * to non-NCQ on retry, so that the retried transfer would not cause - * cascade failure for the other transfers if it fails again. - * If FUA was requested, we can't downgrade, as that would violate - * the semantics - FUA would not be honored. In that case, continue - * retrying with NCQ. + * If NCQ was negotiated, always use it. Some drives return random + * errors when switching between NCQ and non-NCQ I/O too often. */ - if (wd->drvp->drive_flags & ATA_DRIVE_NCQ && - (xfer->c_retries == 0 || (bp->b_flags & B_MEDIA_FUA))) { + if (wd->drvp->drive_flags & ATA_DRIVE_NCQ) { xfer->c_bio.flags |= ATA_LBA48; xfer->c_flags |= C_NCQ;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Jul 30 20:16:29 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: actually change the retry to also use NCQ - with one drive I see very frequent fatal errors on siisata when switching often between NCQ and non-NCQ I/O commands with chaos monkey (basically, always the next NCQ command on a slot which had non-NCQ I/O throws fatal error); they completely vanish when just using NCQ all the time To generate a diff of this commit: cvs rdiff -u -r1.428.2.30 -r1.428.2.31 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jul 29 12:58:30 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: reserve the highest slot for error recovery, and also have ata_channel include space for the READ LOG EXT sector, so that it's not necessary to allocate memory on the error handling path; now ata_read_log_ext_ncq() will never fail due to resource shortage To generate a diff of this commit: cvs rdiff -u -r1.132.8.21 -r1.132.8.22 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.19 -r1.92.8.20 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.132.8.21 src/sys/dev/ata/ata.c:1.132.8.22 --- src/sys/dev/ata/ata.c:1.132.8.21 Sat Jul 22 22:02:21 2017 +++ src/sys/dev/ata/ata.c Sat Jul 29 12:58:29 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.22 2017/07/29 12:58:29 jdolecek Exp $"); #include "opt_ata.h" @@ -191,7 +191,7 @@ ata_queue_reset(struct ata_queue *chq) chq->queue_freeze = 0; chq->queue_active = 0; chq->active_xfers_used = 0; - chq->queue_xfers_avail = (1 << chq->queue_openings) - 1; + chq->queue_xfers_avail = __BIT(chq->queue_openings) - 1; } struct ata_xfer * @@ -202,7 +202,8 @@ ata_queue_hwslot_to_xfer(struct ata_chan mutex_enter(>ch_lock); - KASSERT(hwslot < chq->queue_openings); + KASSERTMSG(hwslot < chq->queue_openings, "hwslot %d > openings %d", + hwslot, chq->queue_openings); KASSERT((chq->active_xfers_used & __BIT(hwslot)) != 0); /* Usually the first entry will be the one */ @@ -1048,20 +1049,9 @@ ata_read_log_ext_ncq(struct ata_drive_da (drvp->drive_flags & ATA_DRIVE_NCQ) == 0) return EOPNOTSUPP; - xfer = ata_get_xfer_ext(chp, false, 0); - if (xfer == NULL) { - ATADEBUG_PRINT(("%s: no xfer\n", __func__), - DEBUG_FUNCS|DEBUG_XFERS); - return EAGAIN; - } + xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0); - tb = malloc(DEV_BSIZE, M_DEVBUF, M_NOWAIT); - if (tb == NULL) { - ATADEBUG_PRINT(("%s: memory allocation failed\n", __func__), - DEBUG_FUNCS|DEBUG_XFERS); - rv = EAGAIN; - goto out; - } + tb = chp->ch_recovery; memset(tb, 0, DEV_BSIZE); /* @@ -1070,14 +1060,14 @@ 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_IMMEDIATE; + xfer->c_flags |= C_RECOVERY; 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.flags = AT_READ | AT_LBA | flags; xfer->c_ata_c.timeout = 1000; /* 1s */ xfer->c_ata_c.data = tb; xfer->c_ata_c.bcount = DEV_BSIZE; @@ -1085,11 +1075,11 @@ ata_read_log_ext_ncq(struct ata_drive_da if ((*atac->atac_bustype_ata->ata_exec_command)(drvp, xfer) != ATACMD_COMPLETE) { rv = EAGAIN; - goto out2; + goto out; } if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) { rv = EINVAL; - goto out2; + goto out; } cksum = 0; @@ -1100,23 +1090,26 @@ ata_read_log_ext_ncq(struct ata_drive_da "invalid checksum %x for READ LOG EXT page %x\n", cksum, page); rv = EINVAL; - goto out2; + goto out; } if (tb[0] & WDCC_LOG_NQ) { /* not queued command */ rv = EOPNOTSUPP; - goto out2; + goto out; } *slot = tb[0] & 0x1f; *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); + rv = 0; -out2: - free(tb, DEV_BSIZE); out: ata_free_xfer(chp, xfer); return rv; @@ -1180,12 +1173,15 @@ ata_exec_xfer(struct ata_channel *chp, s mutex_enter(>ch_lock); - /* insert at the end of command list unless specially requested */ - if (xfer->c_flags & C_IMMEDIATE) - TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer, + /* + * Standard commands are added to the end of command list, but + * recovery commands must be run immediatelly. + */ + if ((xfer->c_flags & C_RECOVERY) == 0) + TAILQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer, c_xferchain); else - TAILQ_INSERT_TAIL(>ch_queue->queue_xfer, xfer, + TAILQ_INSERT_HEAD(>ch_queue->queue_xfer, xfer, c_xferchain); ATADEBUG_PRINT(("atastart from ata_exec_xfer, flags 0x%x\n", chp->ch_flags),
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jul 29 12:58:30 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: reserve the highest slot for error recovery, and also have ata_channel include space for the READ LOG EXT sector, so that it's not necessary to allocate memory on the error handling path; now ata_read_log_ext_ncq() will never fail due to resource shortage To generate a diff of this commit: cvs rdiff -u -r1.132.8.21 -r1.132.8.22 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.19 -r1.92.8.20 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jul 29 12:51:22 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: actually count the REQUEUE as retry also, so that it will be retried as non-NCQ, will not be subject to chaos monkey, and reported as fixed once finished, too To generate a diff of this commit: cvs rdiff -u -r1.428.2.29 -r1.428.2.30 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.428.2.29 src/sys/dev/ata/wd.c:1.428.2.30 --- src/sys/dev/ata/wd.c:1.428.2.29 Sun Jul 23 13:50:43 2017 +++ src/sys/dev/ata/wd.c Sat Jul 29 12:51:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.30 2017/07/29 12:51:22 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -662,7 +662,7 @@ wdstart(device_t self) while (bufq_peek(wd->sc_q) != NULL) { /* First try to get xfer. Limit to drive openings iff NCQ. */ - xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, + xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0, ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ) ? wd->drvp->drv_openings : 0); if (xfer == NULL) @@ -839,17 +839,11 @@ retry2: wdperror(wd, xfer); if (xfer->c_retries < WDIORETRIES) { - int timo; + xfer->c_retries++; - if (xfer->c_bio.error == REQUEUE) { -/* rerun ASAP, and do not count as retry */ -timo = 1; - } else { -xfer->c_retries++; -timo = RECOVERYTIME; - } - - callout_reset(>c_retry_callout, timo, + /* Rerun ASAP if just requeued */ + callout_reset(>c_retry_callout, + (xfer->c_bio.error == REQUEUE) ? 1 : RECOVERYTIME, wdbiorestart, xfer); mutex_exit(>sc_lock); @@ -894,7 +888,7 @@ out: case NOERROR: noerror: if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0) aprint_error_dev(wd->sc_dev, - "soft error (corrected)\n"); + "soft error (corrected) slot %d\n", xfer->c_slot); #ifdef WD_CHAOS_MONKEY KASSERT((xfer->c_flags & C_CHAOS) == 0); #endif @@ -1692,7 +1686,7 @@ wddump(dev_t dev, daddr_t blkno, void *v wd->drvp->state = RESET; } - xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, 0); + xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0, 0); if (xfer == NULL) { printf("%s: no xfer\n", __func__); return EAGAIN;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jul 29 12:51:22 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: actually count the REQUEUE as retry also, so that it will be retried as non-NCQ, will not be subject to chaos monkey, and reported as fixed once finished, too To generate a diff of this commit: cvs rdiff -u -r1.428.2.29 -r1.428.2.30 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 26 18:12:12 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: satapmp_subr.c Log Message: write the device and channel for port multiplier attach (not just the atabus), so it's easier to check To generate a diff of this commit: cvs rdiff -u -r1.12.24.4 -r1.12.24.5 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.12.24.4 src/sys/dev/ata/satapmp_subr.c:1.12.24.5 --- src/sys/dev/ata/satapmp_subr.c:1.12.24.4 Tue Jun 20 20:58:22 2017 +++ src/sys/dev/ata/satapmp_subr.c Wed Jul 26 18:12:12 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: satapmp_subr.c,v 1.12.24.4 2017/06/20 20:58:22 jdolecek Exp $ */ +/* $NetBSD: satapmp_subr.c,v 1.12.24.5 2017/07/26 18:12:12 jdolecek Exp $ */ /* * Copyright (c) 2012 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.4 2017/06/20 20:58:22 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.5 2017/07/26 18:12:12 jdolecek Exp $"); #include #include @@ -274,8 +274,10 @@ satapmp_attach(struct ata_channel *chp) return; } - aprint_normal_dev(chp->atabus, - "SATA port multiplier, %d ports\n", PMP_INF_NPORTS(inf)); + aprint_normal("%s at %s channel %d: SATA port multiplier, %d ports\n", + device_xname(chp->atabus), + device_xname(chp->ch_atac->atac_dev), chp->ch_channel, + PMP_INF_NPORTS(inf)); aprint_verbose_dev(chp->atabus, "vendor 0x%04x, product 0x%04x", PMP_ID_VEND(id), PMP_ID_DEV(id));
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 26 18:12:12 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: satapmp_subr.c Log Message: write the device and channel for port multiplier attach (not just the atabus), so it's easier to check To generate a diff of this commit: cvs rdiff -u -r1.12.24.4 -r1.12.24.5 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Jul 23 13:50:43 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: for wd, only call disk_busy() on the first try, do not call it on retries, as unbusy is called just once when the xfer is finished also noticed in PR kern/43169 by Matthias Pfaller, but contrary to suggested fix done in way to keep the disk marked busy during the timeouts, as I think it's more correct To generate a diff of this commit: cvs rdiff -u -r1.428.2.28 -r1.428.2.29 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.428.2.28 src/sys/dev/ata/wd.c:1.428.2.29 --- src/sys/dev/ata/wd.c:1.428.2.28 Fri Jul 21 17:32:27 2017 +++ src/sys/dev/ata/wd.c Sun Jul 23 13:50:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50: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.428.2.28 2017/07/21 17:32:27 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.29 2017/07/23 13:50:43 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -766,7 +766,8 @@ wdstart1(struct wd_softc *wd, struct buf } /* Instrumentation. */ - disk_busy(>sc_dk); + if (xfer->c_retries == 0) + disk_busy(>sc_dk); switch (wd->atabus->ata_bio(wd->drvp, xfer)) { case ATACMD_TRY_AGAIN: panic("wdstart1: try again");
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sun Jul 23 13:50:43 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: for wd, only call disk_busy() on the first try, do not call it on retries, as unbusy is called just once when the xfer is finished also noticed in PR kern/43169 by Matthias Pfaller, but contrary to suggested fix done in way to keep the disk marked busy during the timeouts, as I think it's more correct To generate a diff of this commit: cvs rdiff -u -r1.428.2.28 -r1.428.2.29 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jul 22 22:02:21 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: provide channel flag when executing NCQ commands, so that e.g. intr handler can use this for handling decisions without checking xfer To generate a diff of this commit: cvs rdiff -u -r1.132.8.20 -r1.132.8.21 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.18 -r1.92.8.19 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.132.8.20 src/sys/dev/ata/ata.c:1.132.8.21 --- src/sys/dev/ata/ata.c:1.132.8.20 Fri Jul 21 18:12:37 2017 +++ src/sys/dev/ata/ata.c Sat Jul 22 22:02:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.21 2017/07/22 22:02:21 jdolecek Exp $"); #include "opt_ata.h" @@ -1305,6 +1305,11 @@ atastart(struct ata_channel *chp) drvp->state = 0; } + if (ISSET(xfer->c_flags, C_NCQ)) + SET(chp->ch_flags, ATACH_NCQ); + else + CLR(chp->ch_flags, ATACH_NCQ); + ata_activate_xfer_locked(chp, xfer); if (atac->atac_cap & ATAC_CAP_NOIRQ) Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.18 src/sys/dev/ata/atavar.h:1.92.8.19 --- src/sys/dev/ata/atavar.h:1.92.8.18 Fri Jul 21 17:32:27 2017 +++ src/sys/dev/ata/atavar.h Sat Jul 22 22:02:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.18 2017/07/21 17:32:27 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.19 2017/07/22 22:02:21 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -394,6 +394,7 @@ struct ata_channel { #define ATACH_TH_RUN 0x100 /* the kernel thread is working */ #define ATACH_TH_RESET 0x200 /* someone ask the thread to reset */ #define ATACH_TH_RESCAN 0x400 /* rescan requested */ +#define ATACH_NCQ 0x800 /* channel executing NCQ commands */ #if 1 /* for now */ uint8_t ch_status; /* copy of status register */ uint8_t ch_error; /* copy of error register */
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jul 22 22:02:21 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h Log Message: provide channel flag when executing NCQ commands, so that e.g. intr handler can use this for handling decisions without checking xfer To generate a diff of this commit: cvs rdiff -u -r1.132.8.20 -r1.132.8.21 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.18 -r1.92.8.19 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jul 21 18:12:37 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: add checksum verification for data returned by READ LOG EXT; this is mostly just paranoia for eventual driver/hw DMA bugs this doesn't make difference for QEMU, as there the command actually always just fails (it's not implemented) To generate a diff of this commit: cvs rdiff -u -r1.132.8.19 -r1.132.8.20 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jul 21 18:12:37 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: add checksum verification for data returned by READ LOG EXT; this is mostly just paranoia for eventual driver/hw DMA bugs this doesn't make difference for QEMU, as there the command actually always just fails (it's not implemented) To generate a diff of this commit: cvs rdiff -u -r1.132.8.19 -r1.132.8.20 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.132.8.19 src/sys/dev/ata/ata.c:1.132.8.20 --- src/sys/dev/ata/ata.c:1.132.8.19 Wed Jul 19 19:39:28 2017 +++ src/sys/dev/ata/ata.c Fri Jul 21 18:12:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.20 2017/07/21 18: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.132.8.19 2017/07/19 19:39:28 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $"); #include "opt_ata.h" @@ -1039,7 +1039,7 @@ ata_read_log_ext_ncq(struct ata_drive_da int rv; struct ata_channel *chp = drvp->chnl_softc; struct atac_softc *atac = chp->ch_atac; - uint8_t *tb; + uint8_t *tb, cksum, page; ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS); @@ -1072,12 +1072,12 @@ ata_read_log_ext_ncq(struct ata_drive_da */ xfer->c_flags |= C_IMMEDIATE; xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT; - xfer->c_ata_c.r_lba = WDCC_LOG_PAGE_NCQ; + 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 | flags; + 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 = DEV_BSIZE; @@ -1092,10 +1092,19 @@ ata_read_log_ext_ncq(struct ata_drive_da goto out2; } - /* XXX verify checksum and refuse if not correct (QEMU) */ + cksum = 0; + for (int i = 0; i < DEV_BSIZE; i++) + cksum += tb[i]; + if (cksum != 0) { + aprint_error_dev(drvp->drv_softc, + "invalid checksum %x for READ LOG EXT page %x\n", + cksum, page); + rv = EINVAL; + goto out2; + } if (tb[0] & WDCC_LOG_NQ) { - /* not a NCQ command */ + /* not queued command */ rv = EOPNOTSUPP; goto out2; }
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jul 21 17:32:27 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: atavar.h wd.c Log Message: KASSERT() that chaosed xfer actually ends up with error; might end up being returned as successful due to bugs in error recovery code To generate a diff of this commit: cvs rdiff -u -r1.92.8.17 -r1.92.8.18 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.428.2.27 -r1.428.2.28 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/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.17 src/sys/dev/ata/atavar.h:1.92.8.18 --- src/sys/dev/ata/atavar.h:1.92.8.17 Wed Jul 19 19:39:28 2017 +++ src/sys/dev/ata/atavar.h Fri Jul 21 17:32:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.17 2017/07/19 19:39:28 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.18 2017/07/21 17:32:27 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -186,6 +186,7 @@ struct ata_xfer { #define C_NCQ 0x0100 /* command is queued */ #define C_IMMEDIATE 0x0200 /* execute command without queuing */ #define C_WAITTIMO 0x0400 /* race vs. timeout */ +#define C_CHAOS 0x0800 /* forced error xfer */ /* 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.428.2.27 src/sys/dev/ata/wd.c:1.428.2.28 --- src/sys/dev/ata/wd.c:1.428.2.27 Wed Jul 19 19:46:52 2017 +++ src/sys/dev/ata/wd.c Fri Jul 21 17:32:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.28 2017/07/21 17:32:27 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -713,6 +713,7 @@ wdstart1(struct wd_softc *wd, struct buf aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n", __func__, xfer->c_slot); xfer->c_bio.blkno = 777 + wd->sc_capacity; + xfer->c_flags |= C_CHAOS; } #endif @@ -893,6 +894,9 @@ out: noerror: if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0) aprint_error_dev(wd->sc_dev, "soft error (corrected)\n"); +#ifdef WD_CHAOS_MONKEY + KASSERT((xfer->c_flags & C_CHAOS) == 0); +#endif break; case ERR_NODEV: bp->b_error = EIO;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jul 21 17:32:27 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: atavar.h wd.c Log Message: KASSERT() that chaosed xfer actually ends up with error; might end up being returned as successful due to bugs in error recovery code To generate a diff of this commit: cvs rdiff -u -r1.92.8.17 -r1.92.8.18 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.428.2.27 -r1.428.2.28 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 19 20:26:52 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: update to note remaining work move some stuff to 'after-merge' To generate a diff of this commit: cvs rdiff -u -r1.1.2.29 -r1.1.2.30 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 19 20:26:52 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: update to note remaining work move some stuff to 'after-merge' To generate a diff of this commit: cvs rdiff -u -r1.1.2.29 -r1.1.2.30 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.1.2.29 src/sys/dev/ata/TODO.ncq:1.1.2.30 --- src/sys/dev/ata/TODO.ncq:1.1.2.29 Mon Jul 3 18:17:01 2017 +++ src/sys/dev/ata/TODO.ncq Wed Jul 19 20:26:52 2017 @@ -5,26 +5,24 @@ siisata - fix all new XXX and unmergable test wd* at umass?, confirm the ata_channel kludge works -test non-NCQ device error handling -- test retry code paths, locking -- channel reset on fatal errors - -do proper NCQ error recovery (currently not even really attempted) -- if fatal error, do channel reset -- if tranfer error (both TFD.STS.BSY and DRQ is 0), need READ LOG EXT log - page 10h to read tag which caused the error, and reset the device to idle -- need to cancel and restart the other active transfers in a way to not - increase retry count, and not trigger drive reset +do proper NCQ error recovery +- update mvsata to do same as ahcisata/siisata (read log ext, timeouts, et.al) +- update also ic/wdc.c, scsipi/atapi_wdc.c, ata/ata_wdc.c to not use + ch_status/ch_error/ATACH_IRQ_WAIT +- retest ATAPI -maybe do device error handling in not-interrupt-context (maybe this should be -done on a mpata branch?) - -in atastart(), restrict NCQ commands to commands for the same drive? it's -fine for fis-based switching to have outstanding for several drives, but -not non-FIS +ahcisata - use dynamic xfer in ahci_do_reset_drive() instead of hardcoding +0, which can clash on drive reset after command failure Other random notes (do outside the NCQ branch): - +implement support for PM FIS-based switching, remove restriction in atastart() +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?) + queue is allocated regardless if there are any drives, fix? change wd(4) to use dksubr
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 19 19:46:52 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: files.ata wd.c Log Message: defflag WD_CHAOS_MONKEY into opt_wd.h together with WD_SOFTBADSECT to set/unset this more easily To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.24.28.1 src/sys/dev/ata/files.ata cvs rdiff -u -r1.428.2.26 -r1.428.2.27 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/files.ata diff -u src/sys/dev/ata/files.ata:1.24 src/sys/dev/ata/files.ata:1.24.28.1 --- src/sys/dev/ata/files.ata:1.24 Tue Jul 31 15:50:34 2012 +++ src/sys/dev/ata/files.ata Wed Jul 19 19:46:52 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.ata,v 1.24 2012/07/31 15:50:34 bouyer Exp $ +# $NetBSD: files.ata,v 1.24.28.1 2017/07/19 19:46:52 jdolecek Exp $ # # Config file and device description for machine-independent devices # which attach to ATA busses. Included by ports that need it. Ports @@ -11,7 +11,8 @@ attach wd at ata_hl file dev/ata/wd.c wd needs-flag file dev/ata/ata_wdc.c wd & atabus & wdc_common -defflag WD_SOFTBADSECT +defflag opt_wd.h WD_SOFTBADSECT +defflag opt_wd.h WD_CHAOS_MONKEY file dev/ata/ata.c (ata_hl | atapi) & atabus Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.428.2.26 src/sys/dev/ata/wd.c:1.428.2.27 --- src/sys/dev/ata/wd.c:1.428.2.26 Wed Jul 19 19:39:28 2017 +++ src/sys/dev/ata/wd.c Wed Jul 19 19:46:52 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.26 2017/07/19 19:39:28 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,9 +54,10 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.26 2017/07/19 19:39:28 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.27 2017/07/19 19:46:52 jdolecek Exp $"); #include "opt_ata.h" +#include "opt_wd.h" #include #include
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 19 19:46:52 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: files.ata wd.c Log Message: defflag WD_CHAOS_MONKEY into opt_wd.h together with WD_SOFTBADSECT to set/unset this more easily To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.24.28.1 src/sys/dev/ata/files.ata cvs rdiff -u -r1.428.2.26 -r1.428.2.27 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 19 19:39:28 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atareg.h atavar.h satafis_subr.c satafisvar.h wd.c wdvar.h Log Message: tighen and expand error handling, mostly for NCQ use cases: - make retry timeout callout per xfer, i.e. retry separately - zero whole bio struct on retry to avoid more stale state - add a REQUEUE option, which doesn't bump retry count - add ata_read_log_ext_ncq() for NCQ recovery - adjust logic for activating xfers - allow next command only when it's for same drive, several concurrent are only supported when HBA and driver support FIS-based switching - add new ata_timeout() which handles race between callout_stop() and the invokation, add appropriate handling on deactivate/free paths - stop using ch_status/ch_error in non-wdc code; later it will be dropped completely To generate a diff of this commit: cvs rdiff -u -r1.132.8.18 -r1.132.8.19 src/sys/dev/ata/ata.c cvs rdiff -u -r1.43.18.2 -r1.43.18.3 src/sys/dev/ata/atareg.h cvs rdiff -u -r1.92.8.16 -r1.92.8.17 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.7.28.2 -r1.7.28.3 src/sys/dev/ata/satafis_subr.c cvs rdiff -u -r1.3 -r1.3.50.1 src/sys/dev/ata/satafisvar.h cvs rdiff -u -r1.428.2.25 -r1.428.2.26 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.6 -r1.43.4.7 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/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.18 src/sys/dev/ata/ata.c:1.132.8.19 --- src/sys/dev/ata/ata.c:1.132.8.18 Tue Jun 27 18:36:03 2017 +++ src/sys/dev/ata/ata.c Wed Jul 19 19:39:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $"); #include "opt_ata.h" @@ -241,14 +241,34 @@ ata_queue_get_active_xfer(struct ata_cha return xfer; } +struct ata_xfer * +ata_queue_drive_active_xfer(struct ata_channel *chp, int drive) +{ + struct ata_xfer *xfer = NULL; + + mutex_enter(>ch_lock); + + TAILQ_FOREACH(xfer, >ch_queue->active_xfers, c_activechain) { + if (xfer->c_drive == drive) + break; + } + KASSERT(xfer != NULL); + + mutex_exit(>ch_lock); + + return xfer; +} + static void -ata_xfer_init(struct ata_xfer *xfer, bool zero) +ata_xfer_init(struct ata_xfer *xfer, uint8_t slot) { - if (zero) - memset(xfer, 0, sizeof(*xfer)); + memset(xfer, 0, sizeof(*xfer)); + + xfer->c_slot = slot; cv_init(>c_active, "ataact"); callout_init(>c_timo_callout, 0); /* XXX MPSAFE */ + callout_init(>c_retry_callout, 0); /* XXX MPSAFE */ } static void @@ -256,6 +276,8 @@ ata_xfer_destroy(struct ata_xfer *xfer) { callout_halt(>c_timo_callout, NULL); /* XXX MPSAFE */ callout_destroy(>c_timo_callout); + callout_halt(>c_retry_callout, NULL); /* XXX MPSAFE */ + callout_destroy(>c_retry_callout); cv_destroy(>c_active); } @@ -278,7 +300,7 @@ ata_queue_alloc(uint8_t openings) cv_init(>queue_drain, "atdrn"); for (uint8_t i = 0; i < openings; i++) - ata_xfer_init(>queue_xfers[i], false); + ata_xfer_init(>queue_xfers[i], i); return chq; } @@ -1009,6 +1031,88 @@ 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; + int rv; + struct ata_channel *chp = drvp->chnl_softc; + struct atac_softc *atac = chp->ch_atac; + uint8_t *tb; + + 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; + + xfer = ata_get_xfer_ext(chp, false, 0); + if (xfer == NULL) { + ATADEBUG_PRINT(("%s: no xfer\n", __func__), + DEBUG_FUNCS|DEBUG_XFERS); + return EAGAIN; + } + + tb = malloc(DEV_BSIZE, M_DEVBUF, M_NOWAIT); + if (tb == NULL) { + ATADEBUG_PRINT(("%s: memory allocation failed\n", __func__), + DEBUG_FUNCS|DEBUG_XFERS); + rv = EAGAIN; + goto out; + } + memset(tb, 0, DEV_BSIZE); + + /* + * 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_IMMEDIATE; + xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT; + xfer->c_ata_c.r_lba = 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 | flags; + xfer->c_ata_c.timeout = 1000; /* 1s
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jul 19 19:39:28 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c atareg.h atavar.h satafis_subr.c satafisvar.h wd.c wdvar.h Log Message: tighen and expand error handling, mostly for NCQ use cases: - make retry timeout callout per xfer, i.e. retry separately - zero whole bio struct on retry to avoid more stale state - add a REQUEUE option, which doesn't bump retry count - add ata_read_log_ext_ncq() for NCQ recovery - adjust logic for activating xfers - allow next command only when it's for same drive, several concurrent are only supported when HBA and driver support FIS-based switching - add new ata_timeout() which handles race between callout_stop() and the invokation, add appropriate handling on deactivate/free paths - stop using ch_status/ch_error in non-wdc code; later it will be dropped completely To generate a diff of this commit: cvs rdiff -u -r1.132.8.18 -r1.132.8.19 src/sys/dev/ata/ata.c cvs rdiff -u -r1.43.18.2 -r1.43.18.3 src/sys/dev/ata/atareg.h cvs rdiff -u -r1.92.8.16 -r1.92.8.17 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.7.28.2 -r1.7.28.3 src/sys/dev/ata/satafis_subr.c cvs rdiff -u -r1.3 -r1.3.50.1 src/sys/dev/ata/satafisvar.h cvs rdiff -u -r1.428.2.25 -r1.428.2.26 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.6 -r1.43.4.7 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 3 19:54:44 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: reset xfer c_flags before retry, to clear flags like C_TIMEOU, or C_NCQ, so that retry, and no-NCQ downgrade logic actually works - drivers typically doesn't reset this field print number of retries to make it easier to spot the same xfer being retried several times in wddone(), hold the wd lock only when reading/changing wd softc structures, and not e.g. when calling malloc(), rnd_add_uint32() or ata_free_xfer(), which have their own locks; initially done to fix diagnostic assertion about held spin lock in kpause() within ata_reset_drive hook, but need to run that hook with AT_POLL anyway, since wddone() is typically invoked from interrupt context fix another interrupt context bug for WD_SOFTBADSECT - the malloc() needs to be called with M_NOWAIT To generate a diff of this commit: cvs rdiff -u -r1.428.2.24 -r1.428.2.25 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 3 19:54:44 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: reset xfer c_flags before retry, to clear flags like C_TIMEOU, or C_NCQ, so that retry, and no-NCQ downgrade logic actually works - drivers typically doesn't reset this field print number of retries to make it easier to spot the same xfer being retried several times in wddone(), hold the wd lock only when reading/changing wd softc structures, and not e.g. when calling malloc(), rnd_add_uint32() or ata_free_xfer(), which have their own locks; initially done to fix diagnostic assertion about held spin lock in kpause() within ata_reset_drive hook, but need to run that hook with AT_POLL anyway, since wddone() is typically invoked from interrupt context fix another interrupt context bug for WD_SOFTBADSECT - the malloc() needs to be called with M_NOWAIT To generate a diff of this commit: cvs rdiff -u -r1.428.2.24 -r1.428.2.25 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.428.2.24 src/sys/dev/ata/wd.c:1.428.2.25 --- src/sys/dev/ata/wd.c:1.428.2.24 Mon Jul 3 19:31:16 2017 +++ src/sys/dev/ata/wd.c Mon Jul 3 19:54:44 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.25 2017/07/03 19:54:44 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.25 2017/07/03 19:54:44 jdolecek Exp $"); #include "opt_ata.h" @@ -695,6 +695,10 @@ wdstart1(struct wd_softc *wd, struct buf KASSERT(bp == xfer->c_bio.bp || xfer->c_bio.bp == NULL); xfer->c_bio.bp = bp; + /* Reset state flags, so that retries don't use stale info */ + KASSERT((xfer->c_flags & (C_WAITACT|C_FREE)) == 0); + xfer->c_flags = 0; + #ifdef WD_CHAOS_MONKEY /* * Override blkno to be over device capacity to trigger error, @@ -787,8 +791,6 @@ wddone(device_t self, struct ata_xfer *x return; } - mutex_enter(>sc_lock); - bp = xfer->c_bio.bp; KASSERT(bp != NULL); @@ -814,12 +816,14 @@ wddone(device_t self, struct ata_xfer *x errmsg = "error"; do_perror = 1; retry: /* Just reset and retry. Can we do more ? */ - (*wd->atabus->ata_reset_drive)(wd->drvp, 0, NULL); + (*wd->atabus->ata_reset_drive)(wd->drvp, AT_POLL, NULL); retry2: + mutex_enter(>sc_lock); + diskerr(bp, "wd", errmsg, LOG_PRINTF, xfer->c_bio.blkdone, wd->sc_dk.dk_label); if (xfer->c_bio.retries < WDIORETRIES) - printf(", retrying"); + printf(", retrying %d", xfer->c_bio.retries + 1); printf("\n"); if (do_perror) wdperror(wd, xfer); @@ -841,6 +845,8 @@ retry2: return; } + mutex_exit(>sc_lock); + #ifdef WD_SOFTBADSECT /* * Not all errors indicate a failed block but those that do, @@ -853,14 +859,24 @@ retry2: (wd->drvp->ata_vers < 4 && xfer->c_bio.r_error & 192))) { struct disk_badsectors *dbs; - dbs = malloc(sizeof *dbs, M_TEMP, M_WAITOK); + dbs = malloc(sizeof *dbs, M_TEMP, M_NOWAIT); + if (dbs == NULL) { +aprint_error_dev(wd->sc_dev, +"failed to add bad block to list\n"); +goto out; + } + dbs->dbs_min = bp->b_rawblkno; dbs->dbs_max = dbs->dbs_min + (bp->b_bcount /wd->sc_blksize) - 1; microtime(>dbs_failedat); + + mutex_enter(>sc_lock); SLIST_INSERT_HEAD(>sc_bslist, dbs, dbs_next); wd->sc_bscount++; + mutex_exit(>sc_lock); } +out: #endif bp->b_error = EIO; break; @@ -885,7 +901,6 @@ noerror: if ((xfer->c_bio.flags & ATA_CO (bp->b_flags & B_READ)); rnd_add_uint32(>rnd_source, bp->b_blkno); ata_free_xfer(wd->drvp->chnl_softc, xfer); - mutex_exit(>sc_lock); biodone(bp); ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive); }
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 3 19:31:16 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: introduce some code to test retry paths To generate a diff of this commit: cvs rdiff -u -r1.428.2.23 -r1.428.2.24 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.428.2.23 src/sys/dev/ata/wd.c:1.428.2.24 --- src/sys/dev/ata/wd.c:1.428.2.23 Sat Jun 24 00:00:10 2017 +++ src/sys/dev/ata/wd.c Mon Jul 3 19:31:16 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.24 2017/07/03 19:31:16 jdolecek Exp $"); #include "opt_ata.h" @@ -115,6 +115,10 @@ int wdcdebug_wd_mask = 0x0; #define ATADEBUG_PRINT(args, level) #endif +#ifdef WD_CHAOS_MONKEY +int wdcdebug_wd_chaos = 0; +#endif + int wdprobe(device_t, cfdata_t, void *); void wdattach(device_t, device_t, void *); int wddetach(device_t, int); @@ -691,6 +695,20 @@ wdstart1(struct wd_softc *wd, struct buf KASSERT(bp == xfer->c_bio.bp || xfer->c_bio.bp == NULL); xfer->c_bio.bp = bp; +#ifdef WD_CHAOS_MONKEY + /* + * Override blkno to be over device capacity to trigger error, + * but only if it's read, to avoid trashing disk contents should + * the command be clipped, or otherwise misinterpreted, by the + * driver or controller. + */ + if (BUF_ISREAD(bp) && (++wdcdebug_wd_chaos % WD_CHAOS_MONKEY) == 0) { + aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n", + __func__, xfer->c_slot); + xfer->c_bio.blkno = 777 + wd->sc_capacity; + } +#endif + /* * If we're retrying, retry in single-sector mode. This will give us * the sector number of the problem, and will eventually allow the
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 3 19:31:16 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: introduce some code to test retry paths To generate a diff of this commit: cvs rdiff -u -r1.428.2.23 -r1.428.2.24 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 3 18:17:01 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: expand what needs to be done with error handling To generate a diff of this commit: cvs rdiff -u -r1.1.2.28 -r1.1.2.29 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.1.2.28 src/sys/dev/ata/TODO.ncq:1.1.2.29 --- src/sys/dev/ata/TODO.ncq:1.1.2.28 Wed Jun 28 19:54:38 2017 +++ src/sys/dev/ata/TODO.ncq Mon Jul 3 18:17:01 2017 @@ -5,9 +5,16 @@ siisata - fix all new XXX and unmergable test wd* at umass?, confirm the ata_channel kludge works -test device error handling (currently appears to not work well, at least in NCQ case) +test non-NCQ device error handling +- test retry code paths, locking +- channel reset on fatal errors do proper NCQ error recovery (currently not even really attempted) +- if fatal error, do channel reset +- if tranfer error (both TFD.STS.BSY and DRQ is 0), need READ LOG EXT log + page 10h to read tag which caused the error, and reset the device to idle +- need to cancel and restart the other active transfers in a way to not + increase retry count, and not trigger drive reset maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?)
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Mon Jul 3 18:17:01 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: expand what needs to be done with error handling To generate a diff of this commit: cvs rdiff -u -r1.1.2.28 -r1.1.2.29 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jun 28 19:54:38 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: ATAPI on siisata(4), ahcisata(4) tested To generate a diff of this commit: cvs rdiff -u -r1.1.2.27 -r1.1.2.28 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Wed Jun 28 19:54:38 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: ATAPI on siisata(4), ahcisata(4) tested To generate a diff of this commit: cvs rdiff -u -r1.1.2.27 -r1.1.2.28 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.1.2.27 src/sys/dev/ata/TODO.ncq:1.1.2.28 --- src/sys/dev/ata/TODO.ncq:1.1.2.27 Tue Jun 27 18:16:50 2017 +++ src/sys/dev/ata/TODO.ncq Wed Jun 28 19:54:38 2017 @@ -3,8 +3,6 @@ Bugs siisata - fix all new XXX and unmergable bits -test ATAPI on siisata, ahcisata - test wd* at umass?, confirm the ata_channel kludge works test device error handling (currently appears to not work well, at least in NCQ case)
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Jun 27 18:16:50 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: note ATAPI on siisata, ahcisata needs to be tested To generate a diff of this commit: cvs rdiff -u -r1.1.2.26 -r1.1.2.27 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.1.2.26 src/sys/dev/ata/TODO.ncq:1.1.2.27 --- src/sys/dev/ata/TODO.ncq:1.1.2.26 Sat Jun 24 14:33:06 2017 +++ src/sys/dev/ata/TODO.ncq Tue Jun 27 18:16:50 2017 @@ -3,6 +3,8 @@ Bugs siisata - fix all new XXX and unmergable bits +test ATAPI on siisata, ahcisata + test wd* at umass?, confirm the ata_channel kludge works test device error handling (currently appears to not work well, at least in NCQ case)
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Tue Jun 27 18:16:50 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq Log Message: note ATAPI on siisata, ahcisata needs to be tested To generate a diff of this commit: cvs rdiff -u -r1.1.2.26 -r1.1.2.27 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jun 24 14:57:17 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: change ata_delay() to tsleep for 1 hz rather than indefinitely if provided ms is lower than 1 hz To generate a diff of this commit: cvs rdiff -u -r1.132.8.16 -r1.132.8.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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jun 24 14:57:17 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: change ata_delay() to tsleep for 1 hz rather than indefinitely if provided ms is lower than 1 hz To generate a diff of this commit: cvs rdiff -u -r1.132.8.16 -r1.132.8.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.132.8.16 src/sys/dev/ata/ata.c:1.132.8.17 --- src/sys/dev/ata/ata.c:1.132.8.16 Fri Jun 23 20:40:51 2017 +++ src/sys/dev/ata/ata.c Sat Jun 24 14:57:17 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.16 2017/06/23 20:40:51 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.16 2017/06/23 20:40:51 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $"); #include "opt_ata.h" @@ -2110,7 +2110,8 @@ ata_delay(int ms, const char *msg, int f */ delay(ms * 1000); } else { - kpause(msg, false, mstohz(ms), NULL); + int pause = mstohz(ms); + kpause(msg, false, pause > 0 ? pause : 1, NULL); } }
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jun 24 00:00:10 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq wd.c Log Message: only limit the openings for I/O xfer if the drive actually supports NCQ; if it's non-NCQ drive, the tag is not going to be used, so we can use any xfer To generate a diff of this commit: cvs rdiff -u -r1.1.2.23 -r1.1.2.24 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.428.2.22 -r1.428.2.23 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Sat Jun 24 00:00:10 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq wd.c Log Message: only limit the openings for I/O xfer if the drive actually supports NCQ; if it's non-NCQ drive, the tag is not going to be used, so we can use any xfer To generate a diff of this commit: cvs rdiff -u -r1.1.2.23 -r1.1.2.24 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.428.2.22 -r1.428.2.23 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.1.2.23 src/sys/dev/ata/TODO.ncq:1.1.2.24 --- src/sys/dev/ata/TODO.ncq:1.1.2.23 Fri Jun 23 23:49:20 2017 +++ src/sys/dev/ata/TODO.ncq Sat Jun 24 00:00:10 2017 @@ -16,9 +16,6 @@ do proper NCQ error recovery (currently maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -do not limit openings for xfers for non-NCQ drives in wdstart(), the tag -will not be used so can use any xfer - in atastart(), restrict NCQ commands to commands for the same drive? it's fine for fis-based switching to have outstanding for several drives, but not non-FIS Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.428.2.22 src/sys/dev/ata/wd.c:1.428.2.23 --- src/sys/dev/ata/wd.c:1.428.2.22 Fri Jun 23 23:45:09 2017 +++ src/sys/dev/ata/wd.c Sat Jun 24 00:00:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.22 2017/06/23 23:45:09 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.22 2017/06/23 23:45:09 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.23 2017/06/24 00:00:10 jdolecek Exp $"); #include "opt_ata.h" @@ -659,9 +659,10 @@ wdstart(device_t self) goto out; while (bufq_peek(wd->sc_q) != NULL) { - /* First try to get command */ + /* First try to get xfer. Limit to drive openings iff NCQ. */ xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, - wd->drvp->drv_openings); + ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ) + ? wd->drvp->drv_openings : 0); if (xfer == NULL) break;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jun 23 23:45:09 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: add debug printf if we fail to obtain xfer in wddump() To generate a diff of this commit: cvs rdiff -u -r1.428.2.21 -r1.428.2.22 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.428.2.21 src/sys/dev/ata/wd.c:1.428.2.22 --- src/sys/dev/ata/wd.c:1.428.2.21 Fri Jun 23 22:11:13 2017 +++ src/sys/dev/ata/wd.c Fri Jun 23 23:45:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.21 2017/06/23 22:11:13 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.22 2017/06/23 23:45:09 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.21 2017/06/23 22:11:13 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.22 2017/06/23 23:45:09 jdolecek Exp $"); #include "opt_ata.h" @@ -1654,8 +1654,10 @@ wddump(dev_t dev, daddr_t blkno, void *v } xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, false, 0); - if (xfer == NULL) + if (xfer == NULL) { + printf("%s: no xfer\n", __func__); return EAGAIN; + } xfer->c_bio.blkno = blkno; xfer->c_bio.flags = ATA_POLL;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jun 23 23:45:09 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: add debug printf if we fail to obtain xfer in wddump() To generate a diff of this commit: cvs rdiff -u -r1.428.2.21 -r1.428.2.22 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jun 23 22:11:13 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: change wd_standby() to remove the ata_channel_start() call - the purpose of that particular command is to make the drive idle fix locking bug in wddetach() exposed by calling ata_channel_start() in wd_standby() - move wd_standby() call out of the section protected by drive mutex, to avoid lock against itself should it need to get the lock change wd_flushcache() to only call ata_channel_start() when called from the ioctl; particularly, don't call it when suspending, closing, or on shutdown To generate a diff of this commit: cvs rdiff -u -r1.428.2.20 -r1.428.2.21 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.428.2.20 src/sys/dev/ata/wd.c:1.428.2.21 --- src/sys/dev/ata/wd.c:1.428.2.20 Fri Jun 23 20:40:51 2017 +++ src/sys/dev/ata/wd.c Fri Jun 23 22:11:13 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.20 2017/06/23 20:40:51 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.21 2017/06/23 22:11:13 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.20 2017/06/23 20:40:51 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.21 2017/06/23 22:11:13 jdolecek Exp $"); #include "opt_ata.h" @@ -198,7 +198,7 @@ void wdrestart(void *); void wddone(device_t, struct ata_xfer *); static void wd_params_to_properties(struct wd_softc *); int wd_get_params(struct wd_softc *, uint8_t, struct ataparams *); -int wd_flushcache(struct wd_softc *, int); +int wd_flushcache(struct wd_softc *, int, bool); int wd_trim(struct wd_softc *, int, daddr_t, long); bool wd_shutdown(device_t, int); @@ -458,7 +458,7 @@ wd_suspend(device_t dv, const pmf_qual_t if (sc->atabus->ata_addref(sc->drvp)) return true; /* no need to complain */ - wd_flushcache(sc, AT_WAIT); + wd_flushcache(sc, AT_WAIT, false); wd_standby(sc, AT_WAIT); sc->atabus->ata_delref(sc->drvp); @@ -494,10 +494,11 @@ wddetach(device_t self, int flags) bufq_drain(sc->sc_q); sc->atabus->ata_killpending(sc->drvp); + mutex_exit(>sc_lock); + if (flags & DETACH_POWEROFF) wd_standby(sc, AT_POLL); - mutex_exit(>sc_lock); bufq_free(sc->sc_q); /* Detach disk. */ @@ -1035,7 +1036,7 @@ wdlastclose(device_t self) { struct wd_softc *wd = device_private(self); - wd_flushcache(wd, AT_WAIT); + wd_flushcache(wd, AT_WAIT, false); if (! (wd->sc_flags & WDF_KLABEL)) wd->sc_flags &= ~WDF_LOADED; @@ -1416,7 +1417,7 @@ wdioctl(dev_t dev, u_long xfer, void *ad return wd_setcache(wd, *(int *)addr); case DIOCCACHESYNC: - return wd_flushcache(wd, AT_WAIT); + return wd_flushcache(wd, AT_WAIT, true); case ATAIOCCOMMAND: /* @@ -1917,12 +1918,12 @@ wd_standby(struct wd_softc *wd, int flag out: ata_free_xfer(wd->drvp->chnl_softc, xfer); - ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive); + /* drive is supposed to go idle, do not call ata_channel_start() */ return error; } int -wd_flushcache(struct wd_softc *wd, int flags) +wd_flushcache(struct wd_softc *wd, int flags, bool start) { struct ata_xfer *xfer; int error; @@ -1989,7 +1990,8 @@ out_xfer: out: /* kick queue processing blocked while waiting for flush xfer */ - ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive); + if (start) + ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive); return error; } @@ -2067,7 +2069,7 @@ wd_shutdown(device_t dev, int how) if (wd->atabus->ata_addref(wd->drvp)) return true; /* no need to complain */ - wd_flushcache(wd, AT_POLL); + wd_flushcache(wd, AT_POLL, false); if ((how & RB_POWERDOWN) == RB_POWERDOWN) wd_standby(wd, AT_POLL); return true;
CVS commit: [jdolecek-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jun 23 22:11:13 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: change wd_standby() to remove the ata_channel_start() call - the purpose of that particular command is to make the drive idle fix locking bug in wddetach() exposed by calling ata_channel_start() in wd_standby() - move wd_standby() call out of the section protected by drive mutex, to avoid lock against itself should it need to get the lock change wd_flushcache() to only call ata_channel_start() when called from the ioctl; particularly, don't call it when suspending, closing, or on shutdown To generate a diff of this commit: cvs rdiff -u -r1.428.2.20 -r1.428.2.21 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-ncq] src/sys/dev/ata
Module Name:src Committed By: jdolecek Date: Fri Jun 23 20:40:51 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c atavar.h wd.c wdvar.h Log Message: restart I/O processing after freeing xfer, i.e. now even after commands like cache flush or standby; the command handling no longer use on-stack xfer, hence use queue slot and compete with normal I/O for the xfers the restart give change to all drives attached to the same channel in round-robin fashion, for fair usage and to recover from situation when disk is idle due to all xfers being consumed by other drives make special concession for flush cache - ignore any new I/O requests on the particular disk while the flush cache is waiting for xfer, so that I/O queue won't starve the flush cache and the flush cache would be done ASAP tested on piixide(4), ahci(4), siisata(4) To generate a diff of this commit: cvs rdiff -u -r1.1.2.21 -r1.1.2.22 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.15 -r1.132.8.16 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.14 -r1.92.8.15 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.428.2.19 -r1.428.2.20 src/sys/dev/ata/wd.c cvs rdiff -u -r1.43.4.5 -r1.43.4.6 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.1.2.21 src/sys/dev/ata/TODO.ncq:1.1.2.22 --- src/sys/dev/ata/TODO.ncq:1.1.2.21 Wed Jun 21 22:40:43 2017 +++ src/sys/dev/ata/TODO.ncq Fri Jun 23 20:40:51 2017 @@ -2,12 +2,15 @@ Bugs fix crashdump for mvsata - request times out (maybe same as HEAD?) +- HEAD crash due to KASSERT(chp->ch_queue->active_xfer != NULL) -siisata - fix all new XXX and unmergable bits, fix PMP +siisata - fix all new XXX and unmergable bits test crashdump with siisata - fails with recursive panic via pmap_kremove_local() regardless if - drive connected via PMP or direct + drive connected via PMP or direct (failed KASSERT(panicstr != NULL)) +- HEAD crashes same as branch +- see kern/49610 for potential fix test wd* at umass?, confirm the ata_channel kludge works + add detach code (channel detach, free queue) @@ -19,13 +22,16 @@ do proper NCQ error recovery (currently maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -add mechanics to re-check queue when xfer is finished - needed on PMP -and for IDE disks, when one drive uses up all available xfers nothing -ever restarts queue for the other drives +do not limit openings for xfers for non-NCQ drives in wdstart(), the tag +will not be used so can use any xfer + +in atastart(), restrict NCQ commands to commands for the same drive? it's +fine for fis-based switching to have outstanding for several drives, but +not non-FIS Other random notes (do outside the NCQ branch): - -change wd(4) to use dk_open() +change wd(4) to use dksubr 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() Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.15 src/sys/dev/ata/ata.c:1.132.8.16 --- src/sys/dev/ata/ata.c:1.132.8.15 Wed Jun 21 22:40:43 2017 +++ src/sys/dev/ata/ata.c Fri Jun 23 20:40:51 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.15 2017/06/21 22:40:43 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.16 2017/06/23 20:40: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.132.8.15 2017/06/21 22:40:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.16 2017/06/23 20:40:51 jdolecek Exp $"); #include "opt_ata.h" @@ -2143,3 +2143,47 @@ atacmd_toncq(struct ata_xfer *xfer, uint if (xfer->c_bio.flags & ATA_FUA) *device |= WDSD_FUA; } + +/* + * 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) +{ + int i; + struct ata_drive_datas *drvp; + + 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;