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
Module Name:src Committed By: jdolecek Date: Sat Sep 30 21:32:32 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata_wdc.c src/sys/dev/ic [jdolecek-ncq]: mvsata.c src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c Log Message: must drop channel lock before calling ata_dmaerr() to avoid 'locking against myself' in case of consecutive errors from ata_reset_channel() called via ata_downgrade_mode() To generate a diff of this commit: cvs rdiff -u -r1.105.6.11 -r1.105.6.12 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.35.6.31 -r1.35.6.32 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.123.4.13 -r1.123.4.14 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/ata_wdc.c diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.11 src/sys/dev/ata/ata_wdc.c:1.105.6.12 --- src/sys/dev/ata/ata_wdc.c:1.105.6.11 Tue Sep 26 20:15:36 2017 +++ src/sys/dev/ata/ata_wdc.c Sat Sep 30 21:32:31 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.105.6.11 2017/09/26 20:15:36 jdolecek Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.105.6.12 2017/09/30 21:32:31 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.11 2017/09/26 20:15:36 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.105.6.12 2017/09/30 21:32:31 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -718,14 +718,18 @@ wdc_ata_bio_intr(struct ata_channel *chp } if (drv_err != WDC_ATA_ERR) goto end; - if (ata_bio->r_error & WDCE_CRC || ata_bio->error == ERR_DMA) + if (ata_bio->r_error & WDCE_CRC || ata_bio->error == ERR_DMA) { + ata_channel_unlock(chp); ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); + goto err; + } } #endif /* NATA_DMA */ /* if we had an error, end */ if (drv_err == WDC_ATA_ERR) { ata_channel_unlock(chp); +err: wdc_ata_bio_done(chp, xfer); return 1; } Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.31 src/sys/dev/ic/mvsata.c:1.35.6.32 --- src/sys/dev/ic/mvsata.c:1.35.6.31 Wed Sep 27 07:19:34 2017 +++ src/sys/dev/ic/mvsata.c Sat Sep 30 21:32:31 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.31 2017/09/27 07:19:34 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.32 2017/09/30 21:32:31 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.31 2017/09/27 07:19:34 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.32 2017/09/30 21:32:31 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1426,14 +1426,18 @@ mvsata_bio_intr(struct ata_channel *chp, if (xfer->c_flags & C_DMA) { if (ata_bio->error == NOERROR) goto end; - if (ata_bio->error == ERR_DMA) + if (ata_bio->error == ERR_DMA) { + ata_channel_unlock(chp); ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); + goto err; + } } /* if we had an error, end */ if (ata_bio->error != NOERROR) { ata_channel_unlock(chp); +err: mvsata_bio_done(chp, xfer); return 1; } @@ -2349,10 +2353,10 @@ mvsata_atapi_intr(struct ata_channel *ch aprint_error_dev(atac->atac_dev, "channel %d: device timeout, c_bcount=%d, c_skip=%d\n", chp->ch_channel, xfer->c_bcount, xfer->c_skip); + ata_channel_unlock(chp); if (xfer->c_flags & C_DMA) ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); - ata_channel_unlock(chp); sc_xfer->error = XS_TIMEOUT; mvsata_atapi_reset(chp, xfer); return 1; @@ -2363,8 +2367,8 @@ mvsata_atapi_intr(struct ata_channel *ch * and reset device. */ if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) { - ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); ata_channel_unlock(chp); + ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); sc_xfer->error = XS_RESET; mvsata_atapi_reset(chp, xfer); return (1); @@ -2425,10 +2429,10 @@ again: aprint_error_dev(atac->atac_dev, "channel %d drive %d: bad data phase DATAOUT\n", chp->ch_channel, xfer->c_drive); + ata_channel_unlock(chp); if (xfer->c_flags & C_DMA) ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); - ata_channel_unlock(chp); sc_xfer->error = XS_TIMEOUT; mvsata_atapi_reset(chp, xfer); return 1; @@ -2461,10 +2465,10 @@ again: aprint_error_dev(atac->atac_dev, "channel %d drive %d: bad data phase DATAIN\n", chp->ch_channel, xfer->c_drive); + ata_channel_unlock(chp); if (xfer->c_flags & C_DMA) ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); - ata_channel_unlock(chp); sc_xfer->error = XS_TIMEOUT; mvsata_atapi_reset(chp, xfer); return 1; @@ -2515,10 +2519,10 @@ again: sc_xfer->error = XS_SHORTSENSE; sc_xfer->sense.atapi_sense =
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: 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: 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/ic
Module Name:src Committed By: jdolecek Date: Tue Sep 26 17:05:37 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: make compile without MVSATA_DEBUG To generate a diff of this commit: cvs rdiff -u -r1.35.6.29 -r1.35.6.30 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.29 src/sys/dev/ic/mvsata.c:1.35.6.30 --- src/sys/dev/ic/mvsata.c:1.35.6.29 Mon Sep 25 22:50:20 2017 +++ src/sys/dev/ic/mvsata.c Tue Sep 26 17:05:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.30 2017/09/26 17:05:37 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.30 2017/09/26 17:05:37 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1673,7 +1673,6 @@ static int mvsata_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer) { struct ata_channel *chp = drvp->chnl_softc; - struct mvsata_port *mvport = (struct mvsata_port *)chp; struct ata_command *ata_c = >c_ata_c; int rv, s; @@ -1681,7 +1680,8 @@ mvsata_exec_command(struct ata_drive_dat ("%s:%d: mvsata_exec_command: drive=%d, bcount=%d," " r_lba=0x%012"PRIx64", r_count=0x%04x, r_features=0x%04x," " r_device=0x%02x, r_command=0x%02x\n", - device_xname(MVSATA_DEV2(mvport)), chp->ch_channel, + device_xname(MVSATA_DEV2((struct mvsata_port *)chp)), + chp->ch_channel, drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count, ata_c->r_features, ata_c->r_device, ata_c->r_command));
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Mon Sep 25 22:50:20 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: move mvsata_quetag_get() to the start routines, so that it always matches the active list of ata queue; important during error recovery, fixes panics when calling in mvsata_edma_handle() ignore events for non-active xfers fix some missing ata_channel_unlock() on error path in mvsata_bio_intr() and mvsata_atapi_intr(), fixes 'locking against myself' with LOCKDEBUG with this, mvsata(4) finally survives full fio run with wdcdebug_wd_cnt == 200 To generate a diff of this commit: cvs rdiff -u -r1.35.6.28 -r1.35.6.29 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.28 src/sys/dev/ic/mvsata.c:1.35.6.29 --- src/sys/dev/ic/mvsata.c:1.35.6.28 Fri Sep 22 20:19:08 2017 +++ src/sys/dev/ic/mvsata.c Mon Sep 25 22:50:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.29 2017/09/25 22:50:20 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1086,7 +1086,6 @@ static int mvsata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer) { struct ata_channel *chp = drvp->chnl_softc; - struct mvsata_port *mvport = (struct mvsata_port *)chp; struct atac_softc *atac = chp->ch_atac; struct ata_bio *ata_bio = >c_bio; @@ -1095,8 +1094,6 @@ mvsata_bio(struct ata_drive_datas *drvp, ", bcount=%ld\n", device_xname(atac->atac_dev), chp->ch_channel, drvp->drive, ata_bio->blkno, ata_bio->bcount)); - mvsata_quetag_get(mvport, xfer->c_slot); - if (atac->atac_cap & ATAC_CAP_NOIRQ) ata_bio->flags |= ATA_POLL; if (ata_bio->flags & ATA_POLL) @@ -1135,6 +1132,8 @@ mvsata_bio_start(struct ata_channel *chp ata_channel_lock_owned(chp); + mvsata_quetag_get(mvport, xfer->c_slot); + if (xfer->c_flags & C_DMA) if (drvp->n_xfers <= NXFER) drvp->n_xfers++; @@ -1410,8 +1409,10 @@ mvsata_bio_intr(struct ata_channel *chp, if (!(xfer->c_flags & C_DMA) && (wdc_wait_for_unbusy(chp, (irq == 0) ? ATA_DELAY : 0, AT_POLL, ) == WDCWAIT_TOUT)) { - if (irq && (xfer->c_flags & C_TIMEOU) == 0) + if (irq && (xfer->c_flags & C_TIMEOU) == 0) { + ata_channel_unlock(chp); return 0; /* IRQ was not for us */ + } aprint_error_dev(atac->atac_dev, "channel %d: drive %d timeout, c_bcount=%d, c_skip%d\n", chp->ch_channel, xfer->c_drive, xfer->c_bcount, @@ -1570,6 +1571,8 @@ mvsata_bio_ready(struct mvsata_port *mvp flags |= AT_POLL; /* XXX */ + ata_channel_lock_owned(chp); + /* * disable interrupts, all commands here should be quick * enough to be able to poll, and we don't go here that often @@ -1682,8 +1685,6 @@ mvsata_exec_command(struct ata_drive_dat drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count, ata_c->r_features, ata_c->r_device, ata_c->r_command)); - mvsata_quetag_get(mvport, xfer->c_slot); - if (ata_c->flags & AT_POLL) xfer->c_flags |= C_POLL; if (ata_c->flags & AT_WAIT) @@ -1736,6 +1737,8 @@ mvsata_wdc_cmd_start(struct ata_channel ata_channel_lock_owned(chp); + mvsata_quetag_get(mvport, xfer->c_slot); + /* First, EDMA disable, if enabled this channel. */ KASSERT((chp->ch_flags & ATACH_NCQ) == 0); if (mvport->port_edmamode_curr != nodma) @@ -2050,7 +2053,6 @@ mvsata_atapi_scsipi_request(struct scsip struct atac_softc *atac = >sc_wdcdev.sc_atac; struct ata_channel *chp = atac->atac_channels[chan->chan_channel]; struct ata_xfer *xfer; - struct mvsata_port *mvport = (struct mvsata_port *)chp; int drive, s; switch (req) { @@ -2071,8 +2073,6 @@ mvsata_atapi_scsipi_request(struct scsip return; } - mvsata_quetag_get(mvport, xfer->c_slot); - if (sc_xfer->xs_control & XS_CTL_POLL) xfer->c_flags |= C_POLL; xfer->c_drive = drive; @@ -2122,6 +2122,8 @@ mvsata_atapi_start(struct ata_channel *c ata_channel_lock_owned(chp); + mvsata_quetag_get(mvport, xfer->c_slot); + KASSERT((chp->ch_flags & ATACH_NCQ) == 0); if (mvport->port_edmamode_curr != nodma) mvsata_edma_disable(mvport, 10 /* ms */, wait_flags); @@ -2426,6 +2428,7 @@ again: if (xfer->c_flags & C_DMA) ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0); + ata_channel_unlock(chp); sc_xfer->error = XS_TIMEOUT; mvsata_atapi_reset(chp, xfer); return 1; @@ -2883,8 +2886,15 @@ mvsata_edma_handle(struct mvsata_port *m mvsata_print_crpb(mvport, erpqop); #endif crpb = mvport->port_crpb + erpqop; +
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: 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 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/ic
Module Name:src Committed By: jdolecek Date: Fri Sep 22 20:19:08 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: fix inverted logic for calling atastart() To generate a diff of this commit: cvs rdiff -u -r1.35.6.27 -r1.35.6.28 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.27 src/sys/dev/ic/mvsata.c:1.35.6.28 --- src/sys/dev/ic/mvsata.c:1.35.6.27 Wed Sep 20 18:35:37 2017 +++ src/sys/dev/ic/mvsata.c Fri Sep 22 20:19:08 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.28 2017/09/22 20:19:08 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1529,7 +1529,7 @@ mvsata_bio_done(struct ata_channel *chp, struct mvsata_port *mvport = (struct mvsata_port *)chp; struct ata_bio *ata_bio = >c_bio; int drive = xfer->c_drive; - bool iserror = (ata_bio->error == NOERROR); + bool iserror = (ata_bio->error != NOERROR); DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, ("%s:%d: mvsata_bio_done: drive=%d, flags=0x%x\n", @@ -2689,7 +2689,7 @@ mvsata_atapi_done(struct ata_channel *ch { struct mvsata_port *mvport = (struct mvsata_port *)chp; struct scsipi_xfer *sc_xfer = xfer->c_scsipi; - bool iserror = (sc_xfer->error == XS_NOERROR); + bool iserror = (sc_xfer->error != XS_NOERROR); DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, ("%s:%d:%d: mvsata_atapi_done: flags 0x%x\n",
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 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/isa
Module Name:src Committed By: jdolecek Date: Wed Sep 20 19:59:22 UTC 2017 Modified Files: src/sys/dev/isa [jdolecek-ncq]: wdc_isa.c Log Message: deallocate the channel structures properly in wdc_isa_probe() also when already the initial bus_space_map() fails To generate a diff of this commit: cvs rdiff -u -r1.59.28.2 -r1.59.28.3 src/sys/dev/isa/wdc_isa.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/isa/wdc_isa.c diff -u src/sys/dev/isa/wdc_isa.c:1.59.28.2 src/sys/dev/isa/wdc_isa.c:1.59.28.3 --- src/sys/dev/isa/wdc_isa.c:1.59.28.2 Wed Sep 20 19:44:38 2017 +++ src/sys/dev/isa/wdc_isa.c Wed Sep 20 19:59:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $ */ +/* $NetBSD: wdc_isa.c,v 1.59.28.3 2017/09/20 19:59:22 jdolecek Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.3 2017/09/20 19:59:22 jdolecek Exp $"); #include #include @@ -143,9 +143,9 @@ wdc_isa_probe(device_t parent, cfdata_t bus_space_unmap(wdr.ctl_iot, wdr.ctl_ioh, WDC_ISA_AUXREG_NPORTS); outunmap: bus_space_unmap(wdr.cmd_iot, wdr.cmd_baseioh, WDC_ISA_REG_NPORTS); +out: ata_queue_free(ch.ch_queue); ata_channel_destroy(); -out: return (result); }
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/isa
Module Name:src Committed By: jdolecek Date: Wed Sep 20 19:44:39 UTC 2017 Modified Files: src/sys/dev/isa [jdolecek-ncq]: wdc_isa.c Log Message: initialize properly ata_channel during probe To generate a diff of this commit: cvs rdiff -u -r1.59.28.1 -r1.59.28.2 src/sys/dev/isa/wdc_isa.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/isa/wdc_isa.c diff -u src/sys/dev/isa/wdc_isa.c:1.59.28.1 src/sys/dev/isa/wdc_isa.c:1.59.28.2 --- src/sys/dev/isa/wdc_isa.c:1.59.28.1 Wed Jun 21 19:21:25 2017 +++ src/sys/dev/isa/wdc_isa.c Wed Sep 20 19:44:38 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_isa.c,v 1.59.28.1 2017/06/21 19:21:25 jdolecek Exp $ */ +/* $NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.1 2017/06/21 19:21:25 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59.28.2 2017/09/20 19:44:38 jdolecek Exp $"); #include #include @@ -107,7 +107,9 @@ wdc_isa_probe(device_t parent, cfdata_t memset(, 0, sizeof(wdc)); memset(, 0, sizeof(ch)); + ata_channel_init(); ch.ch_atac = _atac; + ch.ch_queue = ata_queue_alloc(1); wdc.regs = wdr.cmd_iot = ia->ia_iot; @@ -141,6 +143,8 @@ wdc_isa_probe(device_t parent, cfdata_t bus_space_unmap(wdr.ctl_iot, wdr.ctl_ioh, WDC_ISA_AUXREG_NPORTS); outunmap: bus_space_unmap(wdr.cmd_iot, wdr.cmd_baseioh, WDC_ISA_REG_NPORTS); + ata_queue_free(ch.ch_queue); + ata_channel_destroy(); out: return (result); }
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/ic
Module Name:src Committed By: jdolecek Date: Wed Sep 20 18:35:37 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: make compile again with MVSATA_WITHOUTDMA To generate a diff of this commit: cvs rdiff -u -r1.35.6.26 -r1.35.6.27 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.26 src/sys/dev/ic/mvsata.c:1.35.6.27 --- src/sys/dev/ic/mvsata.c:1.35.6.26 Tue Sep 19 21:06:25 2017 +++ src/sys/dev/ic/mvsata.c Wed Sep 20 18:35:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.26 2017/09/19 21:06:25 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.26 2017/09/19 21:06:25 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.27 2017/09/20 18:35:37 jdolecek Exp $"); #include "opt_mvsata.h" @@ -107,10 +107,11 @@ int mvsata_debug = 0; static void mvsata_probe_drive(struct ata_channel *); +static void mvsata_reset_channel(struct ata_channel *, int); + #ifndef MVSATA_WITHOUTDMA static int mvsata_bio(struct ata_drive_datas *, struct ata_xfer *); static void mvsata_reset_drive(struct ata_drive_datas *, int, uint32_t *); -static void mvsata_reset_channel(struct ata_channel *, int); static int mvsata_exec_command(struct ata_drive_datas *, struct ata_xfer *); static int mvsata_addref(struct ata_drive_datas *); static void mvsata_delref(struct ata_drive_datas *); @@ -731,6 +732,7 @@ mvsata_reset_drive(struct ata_drive_data return; } +#endif /* MVSATA_WITHOUTDMA */ static void mvsata_reset_channel(struct ata_channel *chp, int flags) @@ -768,16 +770,18 @@ mvsata_reset_channel(struct ata_channel ata_kill_active(chp, KILL_RESET, flags); +#ifndef MVSATA_WITHOUTDMA mvsata_edma_config(mvport, mvport->port_edmamode_curr); mvsata_edma_reset_qptr(mvport); mvsata_edma_enable(mvport); +#endif ata_channel_unlock(chp); return; } - +#ifndef MVSATA_WITHOUTDMA static int mvsata_addref(struct ata_drive_datas *drvp) {
CVS commit: [jdolecek-ncq] src/sys/dev
Module Name:src Committed By: jdolecek Date: Tue Sep 19 21:06:25 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c atavar.h sata_subr.c satapmp_subr.c satapmpvar.h src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c Log Message: replace all remaining tsleep()/wakeup() calls with condition variables, or calls to ata_delay(), as appropriate; change ata_delay() to require the channel lock on entry, and pass the lock to kpause() for unlocking while sleeping To generate a diff of this commit: cvs rdiff -u -r1.1.2.41 -r1.1.2.42 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.32 -r1.132.8.33 src/sys/dev/ata/ata.c cvs rdiff -u -r1.92.8.25 -r1.92.8.26 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.21 -r1.21.24.1 src/sys/dev/ata/sata_subr.c cvs rdiff -u -r1.12.24.5 -r1.12.24.6 src/sys/dev/ata/satapmp_subr.c cvs rdiff -u -r1.3 -r1.3.30.1 src/sys/dev/ata/satapmpvar.h cvs rdiff -u -r1.57.6.28 -r1.57.6.29 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.35.6.25 -r1.35.6.26 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.30.4.37 -r1.30.4.38 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.283.2.15 -r1.283.2.16 src/sys/dev/ic/wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.41 src/sys/dev/ata/TODO.ncq:1.1.2.42 --- src/sys/dev/ata/TODO.ncq:1.1.2.41 Wed Sep 13 19:55:12 2017 +++ src/sys/dev/ata/TODO.ncq Tue Sep 19 21:06:25 2017 @@ -4,10 +4,6 @@ test wd* at umass?, confirm the ata_chan 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 Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.32 src/sys/dev/ata/ata.c:1.132.8.33 --- src/sys/dev/ata/ata.c:1.132.8.32 Mon Sep 11 22:16:18 2017 +++ src/sys/dev/ata/ata.c Tue Sep 19 21:06:25 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.32 2017/09/11 22:16:18 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06: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.32 2017/09/11 22:16:18 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.33 2017/09/19 21:06:25 jdolecek Exp $"); #include "opt_ata.h" @@ -279,6 +279,7 @@ ata_xfer_init(struct ata_xfer *xfer, uin xfer->c_slot = slot; cv_init(>c_active, "ataact"); + cv_init(>c_finish, "atafin"); callout_init(>c_timo_callout, 0); /* XXX MPSAFE */ callout_init(>c_retry_callout, 0); /* XXX MPSAFE */ } @@ -291,6 +292,7 @@ ata_xfer_destroy(struct ata_xfer *xfer) callout_halt(>c_retry_callout, NULL); /* XXX MPSAFE */ callout_destroy(>c_retry_callout); cv_destroy(>c_active); + cv_destroy(>c_finish); } struct ata_queue * @@ -310,6 +312,7 @@ ata_queue_alloc(uint8_t openings) cv_init(>queue_busy, "ataqbusy"); cv_init(>queue_drain, "atdrn"); + cv_init(>queue_idle, "qidl"); for (uint8_t i = 0; i < openings; i++) ata_xfer_init(>queue_xfers[i], i); @@ -1194,13 +1197,13 @@ ata_dmaerr(struct ata_drive_datas *drvp, static void ata_channel_idle(struct ata_channel *chp) { - int s = splbio(); - ata_channel_freeze(chp); + ata_channel_lock(chp); + ata_channel_freeze_locked(chp); while (chp->ch_queue->queue_active > 0) { chp->ch_queue->queue_flags |= QF_IDLE_WAIT; - tsleep(>ch_queue->queue_flags, PRIBIO, "qidl", 0); + cv_timedwait(>ch_queue->queue_idle, >ch_lock, 1); } - splx(s); + ata_channel_unlock(chp); } /* @@ -1246,6 +1249,8 @@ ata_exec_xfer(struct ata_channel *chp, s * while we were waiting. */ if ((xfer->c_flags & (C_FREE|C_WAITTIMO)) == C_FREE) { +ata_channel_unlock(chp); + ata_free_xfer(chp, xfer); return; } @@ -1305,7 +1310,7 @@ again: if (__predict_false(!recovery && chq->queue_freeze > 0)) { if (chq->queue_flags & QF_IDLE_WAIT) { chq->queue_flags &= ~QF_IDLE_WAIT; - wakeup(>queue_flags); + cv_signal(>ch_queue->queue_idle); } goto out; /* queue frozen */ } @@ -1673,7 +1678,7 @@ out: /* * Kill off all active xfers for a ata_channel. * - * Must be called at splbio(). + * Must be called with channel lock held. */ void ata_kill_active(struct ata_channel *chp, int reason, int flags) @@ -1681,6 +1686,8 @@ ata_kill_active(struct ata_channel *chp, struct ata_queue * const chq = chp->ch_queue; struct ata_xfer *xfer, *xfernext; + KASSERT(mutex_owned(>ch_lock)); + TAILQ_FOREACH_SAFE(xfer, >active_xfers, c_activechain, xfernext) { (*xfer->c_kill_xfer)(xfer->c_chp, xfer, reason); } @@ -2000,7 +2007,7 @@ ata_probe_caps(struct
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Tue Sep 19 17:52:52 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c Log Message: seems the CMD/CCS slot is always zero at least under QEMU for successful polled commands, so go back to using it only on error path; while the value seems good on real hardware, there is no good reason for register read anyway To generate a diff of this commit: cvs rdiff -u -r1.57.6.27 -r1.57.6.28 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.27 src/sys/dev/ic/ahcisata_core.c:1.57.6.28 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.27 Sun Sep 10 19:31:15 2017 +++ src/sys/dev/ic/ahcisata_core.c Tue Sep 19 17:52:52 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.27 2017/09/10 19:31:15 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.28 2017/09/19 17:52:52 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.27 2017/09/10 19:31:15 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.28 2017/09/19 17:52:52 jdolecek Exp $"); #include #include @@ -568,7 +568,7 @@ ahci_intr_port(struct ahci_softc *sc, st uint32_t is, tfd, sact; struct ata_channel *chp = >ata_channel; struct ata_xfer *xfer; - int slot; + int slot = -1; bool recover = false; is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); @@ -585,12 +585,9 @@ ahci_intr_port(struct ahci_softc *sc, st if ((chp->ch_flags & ATACH_NCQ) == 0) { /* Non-NCQ operation */ sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)); - slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) - & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT; } else { /* NCQ operation */ sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)); - slot = -1; } /* Handle errors */ @@ -600,6 +597,14 @@ ahci_intr_port(struct ahci_softc *sc, st if (is & AHCI_P_IX_TFES) { tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); + if ((chp->ch_flags & ATACH_NCQ) == 0) { +/* Slot valid only for Non-NCQ operation */ +slot = (AHCI_READ(sc, +AHCI_P_CMD(chp->ch_channel)) +& AHCI_P_CMD_CCS_MASK) +>> AHCI_P_CMD_CCS_SHIFT; + } + aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n", AHCINAME(sc), chp->ch_channel, sact, is, tfd); } else { @@ -657,7 +662,7 @@ ahci_intr_port(struct ahci_softc *sc, st if ((aslots & __BIT(slot)) != 0 && (sact & __BIT(slot)) == 0) { xfer = ata_queue_hwslot_to_xfer(chp, slot); -xfer->c_intr(chp, xfer, 0); +xfer->c_intr(chp, xfer, tfd); } } }
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: 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/ic
Module Name:src Committed By: jdolecek Date: Mon Sep 11 22:19:23 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: wdc.c Log Message: fix condition for calling atastart() when command is done To generate a diff of this commit: cvs rdiff -u -r1.283.2.14 -r1.283.2.15 src/sys/dev/ic/wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/wdc.c diff -u src/sys/dev/ic/wdc.c:1.283.2.14 src/sys/dev/ic/wdc.c:1.283.2.15 --- src/sys/dev/ic/wdc.c:1.283.2.14 Sun Sep 10 19:31:15 2017 +++ src/sys/dev/ic/wdc.c Mon Sep 11 22:19:23 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.283.2.14 2017/09/10 19:31:15 jdolecek Exp $ */ +/* $NetBSD: wdc.c,v 1.283.2.15 2017/09/11 22:19:23 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -58,7 +58,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.14 2017/09/10 19:31:15 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.15 2017/09/11 22:19:23 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -1589,7 +1589,7 @@ __wdccommand_done(struct ata_channel *ch struct wdc_softc *wdc = CHAN_TO_WDC(chp); struct wdc_regs *wdr = >regs[chp->ch_channel]; struct ata_command *ata_c = >c_ata_c; - bool start = false; + bool start = true; ATADEBUG_PRINT(("__wdccommand_done %s:%d:%d flags 0x%x\n", device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
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
Module Name:src Committed By: jdolecek Date: Sun Sep 10 19:31:15 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c Log Message: refactor code so that xfer c_start() hook is called with channel mutex held, and hence the controller submit code no longer relies on spl tested all the affected drivers - wdc (via piixide), ahci, mvsata, siisata, both disk and atapi I/O To generate a diff of this commit: cvs rdiff -u -r1.1.2.37 -r1.1.2.38 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.30 -r1.132.8.31 src/sys/dev/ata/ata.c cvs rdiff -u -r1.105.6.8 -r1.105.6.9 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.24 -r1.92.8.25 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.57.6.26 -r1.57.6.27 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.35.6.24 -r1.35.6.25 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.30.4.36 -r1.30.4.37 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.283.2.13 -r1.283.2.14 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.123.4.12 -r1.123.4.13 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.37 src/sys/dev/ata/TODO.ncq:1.1.2.38 --- src/sys/dev/ata/TODO.ncq:1.1.2.37 Tue Aug 29 13:38:38 2017 +++ src/sys/dev/ata/TODO.ncq Sun Sep 10 19:31:15 2017 @@ -2,11 +2,13 @@ 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 +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): - 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.30 src/sys/dev/ata/ata.c:1.132.8.31 --- src/sys/dev/ata/ata.c:1.132.8.30 Sun Sep 10 19:22:56 2017 +++ src/sys/dev/ata/ata.c Sun Sep 10 19:31:15 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.30 2017/09/10 19:22:56 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 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.30 2017/09/10 19:22:56 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.31 2017/09/10 19:31:15 jdolecek Exp $"); #include "opt_ata.h" @@ -130,8 +130,12 @@ static bool atabus_suspend(device_t, con static void atabusconfig_thread(void *); static void ata_channel_idle(struct ata_channel *); +static void ata_channel_thaw_locked(struct ata_channel *); static void ata_activate_xfer_locked(struct ata_channel *, struct ata_xfer *); static void ata_channel_freeze_locked(struct ata_channel *); +static struct ata_xfer *ata_queue_get_active_xfer_locked(struct ata_channel *); +static void ata_thread_wake_locked(struct ata_channel *); + /* * atabus_init: * @@ -200,7 +204,7 @@ ata_queue_hwslot_to_xfer(struct ata_chan struct ata_queue *chq = chp->ch_queue; struct ata_xfer *xfer = NULL; - mutex_enter(>ch_lock); + ata_channel_lock(chp); KASSERTMSG(hwslot < chq->queue_openings, "hwslot %d > openings %d", hwslot, chq->queue_openings); @@ -212,7 +216,7 @@ ata_queue_hwslot_to_xfer(struct ata_chan break; } - mutex_exit(>ch_lock); + ata_channel_unlock(chp); KASSERTMSG((xfer != NULL), "%s: xfer with slot %d not found (active %x)", __func__, @@ -221,6 +225,13 @@ ata_queue_hwslot_to_xfer(struct ata_chan return xfer; } +static struct ata_xfer * +ata_queue_get_active_xfer_locked(struct ata_channel *chp) +{ + KASSERT(mutex_owned(>ch_lock)); + return TAILQ_FIRST(>ch_queue->active_xfers); +} + /* * This interface is supposed only to be used when there is exactly * one outstanding command, when there is no information about the slot, @@ -232,12 +243,12 @@ ata_queue_get_active_xfer(struct ata_cha { struct ata_xfer *xfer = NULL; - mutex_enter(>ch_lock); + ata_channel_lock(chp); KASSERT(chp->ch_queue->queue_active <= 1); - xfer = TAILQ_FIRST(>ch_queue->active_xfers); + xfer = ata_queue_get_active_xfer_locked(chp); - mutex_exit(>ch_lock); + ata_channel_unlock(chp); return xfer; } @@ -247,7 +258,7 @@ ata_queue_drive_active_xfer(struct ata_c { struct ata_xfer *xfer = NULL; - mutex_enter(>ch_lock); + ata_channel_lock(chp); TAILQ_FOREACH(xfer, >ch_queue->active_xfers, c_activechain) { if (xfer->c_drive == drive) @@ -255,7 +266,7 @@
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/ic
Module Name:src Committed By: jdolecek Date: Sun Sep 10 18:37:21 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: move mvsata_bio(), mvsata_exec_command() and mvsata_atapi_scsipi_request() just before their respective hook functions To generate a diff of this commit: cvs rdiff -u -r1.35.6.23 -r1.35.6.24 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.23 src/sys/dev/ic/mvsata.c:1.35.6.24 --- src/sys/dev/ic/mvsata.c:1.35.6.23 Sun Aug 13 11:48:53 2017 +++ src/sys/dev/ic/mvsata.c Sun Sep 10 18:37:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.24 2017/09/10 18:37:21 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.24 2017/09/10 18:37:21 jdolecek Exp $"); #include "opt_mvsata.h" @@ -688,38 +688,6 @@ mvsata_probe_drive(struct ata_channel *c } #ifndef MVSATA_WITHOUTDMA -static int -mvsata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer) -{ - struct ata_channel *chp = drvp->chnl_softc; - struct mvsata_port *mvport = (struct mvsata_port *)chp; - struct atac_softc *atac = chp->ch_atac; - struct ata_bio *ata_bio = >c_bio; - - DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, - ("%s:%d: mvsata_bio: drive=%d, blkno=%" PRId64 - ", bcount=%ld\n", device_xname(atac->atac_dev), chp->ch_channel, - drvp->drive, ata_bio->blkno, ata_bio->bcount)); - - mvsata_quetag_get(mvport, xfer->c_slot); - - if (atac->atac_cap & ATAC_CAP_NOIRQ) - ata_bio->flags |= ATA_POLL; - if (ata_bio->flags & ATA_POLL) - xfer->c_flags |= C_POLL; - if ((drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) && - (ata_bio->flags & ATA_SINGLE) == 0) - xfer->c_flags |= C_DMA; - xfer->c_drive = drvp->drive; - xfer->c_databuf = ata_bio->databuf; - xfer->c_bcount = ata_bio->bcount; - xfer->c_start = mvsata_bio_start; - xfer->c_intr = mvsata_bio_intr; - xfer->c_kill_xfer = mvsata_bio_kill_xfer; - ata_exec_xfer(chp, xfer); - return (ata_bio->flags & ATA_ITSDONE) ? ATACMD_COMPLETE : ATACMD_QUEUED; -} - static void mvsata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) { @@ -794,55 +762,6 @@ mvsata_reset_channel(struct ata_channel static int -mvsata_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer) -{ - struct ata_channel *chp = drvp->chnl_softc; - struct mvsata_port *mvport = (struct mvsata_port *)chp; - struct ata_command *ata_c = >c_ata_c; - int rv, s; - - DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, - ("%s:%d: mvsata_exec_command: drive=%d, bcount=%d," - " r_lba=0x%012"PRIx64", r_count=0x%04x, r_features=0x%04x," - " r_device=0x%02x, r_command=0x%02x\n", - device_xname(MVSATA_DEV2(mvport)), chp->ch_channel, - drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count, - ata_c->r_features, ata_c->r_device, ata_c->r_command)); - - mvsata_quetag_get(mvport, xfer->c_slot); - - if (ata_c->flags & AT_POLL) - xfer->c_flags |= C_POLL; - if (ata_c->flags & AT_WAIT) - xfer->c_flags |= C_WAIT; - xfer->c_drive = drvp->drive; - xfer->c_databuf = ata_c->data; - xfer->c_bcount = ata_c->bcount; - xfer->c_start = mvsata_wdc_cmd_start; - xfer->c_intr = mvsata_wdc_cmd_intr; - xfer->c_kill_xfer = mvsata_wdc_cmd_kill_xfer; - s = splbio(); - ata_exec_xfer(chp, xfer); -#ifdef DIAGNOSTIC - if ((ata_c->flags & AT_POLL) != 0 && - (ata_c->flags & AT_DONE) == 0) - panic("mvsata_exec_command: polled command not done"); -#endif - if (ata_c->flags & AT_DONE) - rv = ATACMD_COMPLETE; - else { - if (ata_c->flags & AT_WAIT) { - while ((ata_c->flags & AT_DONE) == 0) -tsleep(ata_c, PRIBIO, "mvsatacmd", 0); - rv = ATACMD_COMPLETE; - } else - rv = ATACMD_QUEUED; - } - splx(s); - return rv; -} - -static int mvsata_addref(struct ata_drive_datas *drvp) { @@ -899,68 +818,6 @@ mvsata_atapibus_attach(struct atabus_sof } static void -mvsata_atapi_scsipi_request(struct scsipi_channel *chan, - scsipi_adapter_req_t req, void *arg) -{ - struct scsipi_adapter *adapt = chan->chan_adapter; - struct scsipi_periph *periph; - struct scsipi_xfer *sc_xfer; - struct mvsata_softc *sc = device_private(adapt->adapt_dev); - struct atac_softc *atac = >sc_wdcdev.sc_atac; - struct ata_channel *chp = atac->atac_channels[chan->chan_channel]; - struct ata_xfer *xfer; - struct mvsata_port *mvport = (struct mvsata_port *)chp; - int drive, s; - -switch (req) { - case ADAPTER_REQ_RUN_XFER: - sc_xfer = arg; - periph = sc_xfer->xs_periph; - drive = periph->periph_target; - - if (!device_is_active(atac->atac_dev)) { - sc_xfer->error = XS_DRIVER_STUFFUP; - scsipi_done(sc_xfer); - return; - } -
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: 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/ic
Module Name:src Committed By: jakllsch Date: Tue Aug 15 20:12:29 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: Use ata_queue_free() instead of free() to deallocate chp->ch_queue during detach. To generate a diff of this commit: cvs rdiff -u -r1.30.4.35 -r1.30.4.36 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.35 src/sys/dev/ic/siisata.c:1.30.4.36 --- src/sys/dev/ic/siisata.c:1.30.4.35 Sat Aug 12 22:12:04 2017 +++ src/sys/dev/ic/siisata.c Tue Aug 15 20:12:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.36 2017/08/15 20:12:28 jakllsch Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.36 2017/08/15 20:12:28 jakllsch Exp $"); #include #include @@ -426,7 +426,8 @@ siisata_detach(struct siisata_softc *sc, bus_dmamem_free(sc->sc_dmat, >sch_prb_seg, schp->sch_prb_nseg); - free(chp->ch_queue, M_DEVBUF); + ata_queue_free(chp->ch_queue); + chp->ch_queue = NULL; chp->atabus = NULL; ata_channel_detach(chp);
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. 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/ic
Module Name:src Committed By: jdolecek Date: Sun Aug 13 11:48:53 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: put the non-NCQ KASSERT() before edma disable for bio PIO, we are not supposed to get there with NCQ command even on retries any more To generate a diff of this commit: cvs rdiff -u -r1.35.6.22 -r1.35.6.23 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.22 src/sys/dev/ic/mvsata.c:1.35.6.23 --- src/sys/dev/ic/mvsata.c:1.35.6.22 Sat Aug 12 22:43:22 2017 +++ src/sys/dev/ic/mvsata.c Sun Aug 13 11:48:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.23 2017/08/13 11:48:53 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1339,6 +1339,7 @@ do_pio: WDCC_READ : WDCC_WRITE; /* EDMA disable, if enabled this channel. */ + KASSERT((chp->ch_flags & ATACH_NCQ) == 0); if (mvport->port_edmamode_curr != nodma) mvsata_edma_disable(mvport, 10 /* ms */, wait_flags);
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: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
Module Name:src Committed By: jdolecek Date: Sat Aug 12 22:43:22 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq src/sys/dev/ic [jdolecek-ncq]: mvsata.c mvsatavar.h Log Message: add NCQ error recovery for mvsata(4) fix wait flags for mvsata_bio_start(), AT_* constants are only valid for cmd change the debug logging to similar form as ahcisata/siisata, so it's easier to selectively show To generate a diff of this commit: cvs rdiff -u -r1.1.2.34 -r1.1.2.35 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.35.6.21 -r1.35.6.22 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.2.48.3 -r1.2.48.4 src/sys/dev/ic/mvsatavar.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.34 src/sys/dev/ata/TODO.ncq:1.1.2.35 --- src/sys/dev/ata/TODO.ncq:1.1.2.34 Sat Aug 12 14:41:54 2017 +++ src/sys/dev/ata/TODO.ncq Sat Aug 12 22:43:22 2017 @@ -5,9 +5,6 @@ siisata - fix all new XXX and unmergable test wd* at umass?, confirm the ata_channel kludge works -do proper NCQ error recovery -- update mvsata to do same as ahcisata/siisata (read log ext, timeouts, et.al) - 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 Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.21 src/sys/dev/ic/mvsata.c:1.35.6.22 --- src/sys/dev/ic/mvsata.c:1.35.6.21 Sat Aug 12 14:41:54 2017 +++ src/sys/dev/ic/mvsata.c Sat Aug 12 22:43:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.21 2017/08/12 14:41:54 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.21 2017/08/12 14:41:54 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.22 2017/08/12 22:43:22 jdolecek Exp $"); #include "opt_mvsata.h" @@ -86,12 +86,16 @@ __KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1 SHADOW_REG_BLOCK_OFFSET + (reg), (val)) #ifdef MVSATA_DEBUG -#define DPRINTF(x) if (mvsata_debug) printf x -#define DPRINTFN(n,x) if (mvsata_debug >= (n)) printf x -int mvsata_debug = 2; + +#define DEBUG_INTR 0x01 +#define DEBUG_XFERS 0x02 +#define DEBUG_FUNCS 0x08 +#define DEBUG_PROBE 0x10 + +#define DPRINTF(n,x) if (mvsata_debug & (n)) printf x +int mvsata_debug = 0; #else -#define DPRINTF(x) -#define DPRINTFN(n,x) +#define DPRINTF(n,x) #endif #define ATA_DELAY 1 /* 10s for a drive I/O */ @@ -160,6 +164,7 @@ static void mvsata_bdma_start(struct mvs #endif static int mvsata_nondma_handle(struct mvsata_port *); +static void mvsata_channel_recover(struct mvsata_port *); static int mvsata_port_init(struct mvsata_hc *, int); static int mvsata_wdc_reg_init(struct mvsata_port *, struct wdc_regs *); @@ -398,7 +403,7 @@ mvsata_intr(struct mvsata_hc *mvhc) cause = MVSATA_HC_READ_4(mvhc, SATAHC_IC); - DPRINTFN(3, ("%s:%d: mvsata_intr: cause=0x%08x\n", + DPRINTF(DEBUG_INTR, ("%s:%d: mvsata_intr: cause=0x%08x\n", device_xname(MVSATA_DEV(sc)), mvhc->hc, cause)); if (cause & SATAHC_IC_SAINTCOAL) @@ -432,22 +437,23 @@ mvsata_nondma_handle(struct mvsata_port { struct ata_channel *chp = >port_ata_channel; struct ata_xfer *xfer; - int ret, quetag; + int ret; /* * The chip doesn't support several pending non-DMA commands, * and the ata middle layer never issues several non-NCQ commands, * so there must be exactly one active command at this moment. */ - for (quetag = 0; quetag < MVSATA_EDMAQ_LEN; quetag++) { - if ((mvport->port_quetagidx & __BIT(quetag)) == 0) - continue; - - break; + xfer = ata_queue_get_active_xfer(chp); + if (xfer == NULL) { + /* Can happen after error recovery, ignore */ + DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, + ("%s:%d: %s: intr without xfer\n", + device_xname(MVSATA_DEV2(mvport)), chp->ch_channel, + __func__)); + return 0; } - KASSERT(quetag < MVSATA_EDMAQ_LEN); - xfer = ata_queue_hwslot_to_xfer(chp, quetag); ret = xfer->c_intr(chp, xfer, 1); return (ret); } @@ -473,7 +479,7 @@ mvsata_error(struct mvsata_port *mvport) } MVSATA_EDMA_WRITE_4(mvport, EDMA_IEC, ~cause); - DPRINTFN(3, ("%s:%d:%d:" + DPRINTF(DEBUG_INTR, ("%s:%d:%d:" " mvsata_error: cause=0x%08x, mask=0x%08x, status=0x%08x\n", device_xname(MVSATA_DEV2(mvport)), mvport->port_hc->hc, mvport->port, cause, MVSATA_EDMA_READ_4(mvport, EDMA_IEM), @@ -492,8 +498,9 @@ mvsata_error(struct mvsata_port *mvport) if (sc->sc_gen == gen1) mvsata_devconn_gen1(mvport); - DPRINTFN(3, ("device connected\n")); + DPRINTF(DEBUG_INTR, ("device connected\n")); } + #ifndef MVSATA_WITHOUTDMA if ((sc->sc_gen == gen1 && cause & EDMA_IE_ETRANSINT) || (sc->sc_gen != gen1 &&
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
Module Name:src Committed By: jdolecek Date: Sat Aug 12 22:12:04 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: atavar.h wd.c src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c siisata.c Log Message: do not reset drive after successful NCQ error recovery To generate a diff of this commit: cvs rdiff -u -r1.92.8.23 -r1.92.8.24 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.428.2.31 -r1.428.2.32 src/sys/dev/ata/wd.c cvs rdiff -u -r1.57.6.25 -r1.57.6.26 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.30.4.34 -r1.30.4.35 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.23 src/sys/dev/ata/atavar.h:1.92.8.24 --- src/sys/dev/ata/atavar.h:1.92.8.23 Sat Aug 12 14:41:54 2017 +++ src/sys/dev/ata/atavar.h Sat Aug 12 22:12:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.92.8.23 2017/08/12 14:41:54 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.92.8.24 2017/08/12 22:12:04 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -184,6 +184,7 @@ struct ata_xfer { #define C_RECOVERY 0x0200 /* executed as part of recovery */ #define C_WAITTIMO 0x0400 /* race vs. timeout */ #define C_CHAOS 0x0800 /* forced error xfer */ +#define C_RECOVERED 0x1000 /* error recovered, no need for reset */ /* 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.31 src/sys/dev/ata/wd.c:1.428.2.32 --- src/sys/dev/ata/wd.c:1.428.2.31 Sun Jul 30 20:16:29 2017 +++ src/sys/dev/ata/wd.c Sat Aug 12 22:12:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.31 2017/07/30 20:16:29 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.32 2017/08/12 22: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.31 2017/07/30 20:16:29 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -819,7 +819,8 @@ 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, AT_POLL, NULL); + if ((xfer->c_flags & C_RECOVERED) == 0) + (*wd->atabus->ata_reset_drive)(wd->drvp, AT_POLL, NULL); retry2: mutex_enter(>sc_lock); Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.25 src/sys/dev/ic/ahcisata_core.c:1.57.6.26 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.25 Tue Aug 1 22:02:32 2017 +++ src/sys/dev/ic/ahcisata_core.c Sat Aug 12 22:12:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.26 2017/08/12 22:12:04 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.26 2017/08/12 22:12:04 jdolecek Exp $"); #include #include @@ -1592,6 +1592,7 @@ ahci_channel_recover(struct ahci_softc * /* Error out the particular NCQ xfer, then requeue the others */ if ((achp->ahcic_cmds_active & (1 << eslot)) != 0) { xfer = ata_queue_hwslot_to_xfer(chp, eslot); + xfer->c_flags |= C_RECOVERED; xfer->c_intr(chp, xfer, (err << AHCI_P_TFD_ERR_SHIFT) | st); } Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.34 src/sys/dev/ic/siisata.c:1.30.4.35 --- src/sys/dev/ic/siisata.c:1.30.4.34 Fri Aug 11 18:20:13 2017 +++ src/sys/dev/ic/siisata.c Sat Aug 12 22:12:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.35 2017/08/12 22:12:04 jdolecek Exp $"); #include #include @@ -653,6 +653,7 @@ siisata_channel_recover(struct ata_chann /* Error out the particular NCQ xfer, then requeue the others */ if ((schp->sch_active_slots & (1 << eslot)) != 0) { xfer = ata_queue_hwslot_to_xfer(chp, eslot); + xfer->c_flags |= C_RECOVERED; xfer->c_intr(chp, xfer, ATACH_ERR_ST(err, st)); } break;
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
Module Name:src Committed By: jdolecek Date: Sat Aug 12 14:41:54 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncq]: mvsata.c wdc.c src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c Log Message: convert the atabus thread to use the channel lock and a condvar, adjust code which sets the relevant channel flags to take the lock while doing so To generate a diff of this commit: cvs rdiff -u -r1.1.2.33 -r1.1.2.34 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.25 -r1.132.8.26 src/sys/dev/ata/ata.c cvs rdiff -u -r1.105.6.7 -r1.105.6.8 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.22 -r1.92.8.23 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.35.6.20 -r1.35.6.21 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.283.2.12 -r1.283.2.13 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.123.4.11 -r1.123.4.12 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.33 src/sys/dev/ata/TODO.ncq:1.1.2.34 --- src/sys/dev/ata/TODO.ncq:1.1.2.33 Sat Aug 12 09:52:28 2017 +++ src/sys/dev/ata/TODO.ncq Sat Aug 12 14:41:54 2017 @@ -15,8 +15,6 @@ active system? make sure to not trigger kill active transfers after software drive reset - race timeout vs. error recovery -atabus_thread() protect run by mutex/condvar - Other random notes (do outside the NCQ branch): - implement support for PM FIS-based switching, remove restriction in atastart() Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.25 src/sys/dev/ata/ata.c:1.132.8.26 --- src/sys/dev/ata/ata.c:1.132.8.25 Sat Aug 12 09:52:28 2017 +++ src/sys/dev/ata/ata.c Sat Aug 12 14:41:54 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52:28 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 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.25 2017/08/12 09:52:28 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.26 2017/08/12 14:41:54 jdolecek Exp $"); #include "opt_ata.h" @@ -131,7 +131,7 @@ static void atabusconfig_thread(void *); static void ata_channel_idle(struct ata_channel *); static void ata_activate_xfer_locked(struct ata_channel *, struct ata_xfer *); - +static void ata_channel_freeze_locked(struct ata_channel *); /* * atabus_init: * @@ -322,6 +322,7 @@ void ata_channel_init(struct ata_channel *chp) { mutex_init(>ch_lock, MUTEX_DEFAULT, IPL_BIO); + cv_init(>ch_thr_idle, "atath"); } /* @@ -347,6 +348,7 @@ void ata_channel_destroy(struct ata_channel *chp) { mutex_destroy(>ch_lock); + cv_destroy(>ch_thr_idle); } /* @@ -369,12 +371,12 @@ atabusconfig(struct atabus_softc *atabus struct ata_channel *chp = atabus_sc->sc_chan; struct atac_softc *atac = chp->ch_atac; struct atabus_initq *atabus_initq = NULL; - int i, s, error; + int i, error; /* we are in the atabus's thread context */ - s = splbio(); + mutex_enter(>ch_lock); chp->ch_flags |= ATACH_TH_RUN; - splx(s); + mutex_exit(>ch_lock); /* * Probe for the drives attached to controller, unless a PMP @@ -391,9 +393,9 @@ atabusconfig(struct atabus_softc *atabus } /* next operations will occurs in a separate thread */ - s = splbio(); + mutex_enter(>ch_lock); chp->ch_flags &= ~ATACH_TH_RUN; - splx(s); + mutex_exit(>ch_lock); /* Make sure the devices probe in atabus order to avoid jitter. */ mutex_enter(_qlock); @@ -405,6 +407,8 @@ atabusconfig(struct atabus_softc *atabus } mutex_exit(_qlock); + mutex_enter(>ch_lock); + /* If no drives, abort here */ if (chp->ch_drive == NULL) goto out; @@ -419,6 +423,8 @@ atabusconfig(struct atabus_softc *atabus if (chp->ch_flags & ATACH_SHUTDOWN) goto out; + mutex_exit(>ch_lock); + if ((error = kthread_create(PRI_NONE, 0, NULL, atabusconfig_thread, atabus_sc, _cfg_lwp, "%scnf", device_xname(atac->atac_dev))) != 0) @@ -427,6 +433,8 @@ atabusconfig(struct atabus_softc *atabus return; out: + mutex_exit(>ch_lock); + mutex_enter(_qlock); TAILQ_REMOVE(_initq_head, atabus_initq, atabus_initq); cv_broadcast(_qcv); @@ -578,9 +586,9 @@ atabus_thread(void *arg) struct ata_channel *chp = sc->sc_chan; struct ata_queue *chq = chp->ch_queue; struct ata_xfer *xfer; - int i, s; + int i; - s = splbio(); + mutex_enter(>ch_lock); chp->ch_flags |= ATACH_TH_RUN; /* @@ -594,32 +602,36 @@ atabus_thread(void *arg) chp->ch_drive[i].drive_flags = 0; chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; } - splx(s); + mutex_exit(>ch_lock); atabusconfig(sc); - s = splbio(); + mutex_enter(>ch_lock); for (;;) { if ((chp->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 && (chq->queue_active
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Aug 12 13:41:46 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: wdc.c Log Message: remove debug printf To generate a diff of this commit: cvs rdiff -u -r1.283.2.11 -r1.283.2.12 src/sys/dev/ic/wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/wdc.c diff -u src/sys/dev/ic/wdc.c:1.283.2.11 src/sys/dev/ic/wdc.c:1.283.2.12 --- src/sys/dev/ic/wdc.c:1.283.2.11 Sat Aug 12 09:52:28 2017 +++ src/sys/dev/ic/wdc.c Sat Aug 12 13:41:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.283.2.11 2017/08/12 09:52:28 jdolecek Exp $ */ +/* $NetBSD: wdc.c,v 1.283.2.12 2017/08/12 13:41:46 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -58,7 +58,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.11 2017/08/12 09:52:28 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.12 2017/08/12 13:41:46 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -1254,7 +1254,6 @@ wdcwait(struct ata_channel *chp, int mas */ ata_channel_freeze(chp); wakeup(>ch_thread); -printf("wdcwait_thr"); return(WDCWAIT_THR); } }
CVS commit: [jdolecek-ncq] src/sys/dev
Module Name:src Committed By: jdolecek Date: Sat Aug 12 09:52:29 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq ata.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncq]: mvsata.c wdc.c wdcvar.h src/sys/dev/pci [jdolecek-ncq]: pciide_common.c src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c Log Message: remove all logic around ATACH_IRQ_WAIT and channel-global ch_error/ch_status, so that there is less hidden state shared by commands; primary intent is to make the NCQ and non-NCQ paths more similar, and remove possibility of incorrect handling for the NCQ commands tested both disk and ATAPI - piixide(4) on QEMU, and siisata(4), ahcisata(4), mvsata(4) on real hw To generate a diff of this commit: cvs rdiff -u -r1.1.2.32 -r1.1.2.33 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.132.8.24 -r1.132.8.25 src/sys/dev/ata/ata.c cvs rdiff -u -r1.105.6.6 -r1.105.6.7 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.21 -r1.92.8.22 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.35.6.19 -r1.35.6.20 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.283.2.10 -r1.283.2.11 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.97.26.1 -r1.97.26.2 src/sys/dev/ic/wdcvar.h cvs rdiff -u -r1.62.4.1 -r1.62.4.2 src/sys/dev/pci/pciide_common.c cvs rdiff -u -r1.123.4.10 -r1.123.4.11 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.32 src/sys/dev/ata/TODO.ncq:1.1.2.33 --- src/sys/dev/ata/TODO.ncq:1.1.2.32 Tue Aug 1 22:04:48 2017 +++ src/sys/dev/ata/TODO.ncq Sat Aug 12 09:52:28 2017 @@ -7,9 +7,6 @@ test wd* at umass?, confirm the ata_chan 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 do biodone() in wddone() starting the dump to not leak bufs when dumping from active system? make sure to not trigger atastart() @@ -18,6 +15,8 @@ active system? make sure to not trigger kill active transfers after software drive reset - race timeout vs. error recovery +atabus_thread() protect run by mutex/condvar + Other random notes (do outside the NCQ branch): - implement support for PM FIS-based switching, remove restriction in atastart() Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.24 src/sys/dev/ata/ata.c:1.132.8.25 --- src/sys/dev/ata/ata.c:1.132.8.24 Tue Aug 1 21:41:25 2017 +++ src/sys/dev/ata/ata.c Sat Aug 12 09:52:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.24 2017/08/01 21:41:25 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52: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.24 2017/08/01 21:41:25 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.25 2017/08/12 09:52:28 jdolecek Exp $"); #include "opt_ata.h" @@ -622,15 +622,16 @@ atabus_thread(void *arg) ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags); } else if (chq->queue_active > 0 && chq->queue_freeze == 1) { /* - * Caller has bumped queue_freeze, decrease it. + * Caller has bumped queue_freeze, decrease it. This + * flow shalt never be executed for NCQ commands. */ + KASSERT((chp->ch_flags & ATACH_NCQ) == 0); + KASSERT(chq->queue_active == 1); + ata_channel_thaw(chp); - u_int active __diagused = 0; - TAILQ_FOREACH(xfer, >active_xfers, c_activechain) { -(*xfer->c_start)(xfer->c_chp, xfer); -active++; - } - KASSERT(active == chq->queue_active); + xfer = ata_queue_get_active_xfer(chp); + KASSERT(xfer != NULL); + (*xfer->c_start)(xfer->c_chp, xfer); } else if (chq->queue_freeze > 1) panic("ata_thread: queue_freeze"); } @@ -1430,7 +1431,7 @@ ata_free_xfer(struct ata_channel *chp, s /* finish the busmastering PIO */ (*wdc->piobm_done)(wdc->dma_arg, chp->ch_channel, xfer->c_drive); - chp->ch_flags &= ~(ATACH_DMA_WAIT | ATACH_PIOBM_WAIT | ATACH_IRQ_WAIT); + chp->ch_flags &= ~(ATACH_DMA_WAIT | ATACH_PIOBM_WAIT); } #endif @@ -1521,7 +1522,7 @@ ata_waitdrain_xfer_check(struct ata_chan /* * Check for race of normal transfer handling vs. timeout. */ -static bool +bool ata_timo_xfer_check(struct ata_xfer *xfer) { struct ata_channel *chp = xfer->c_chp; Index: src/sys/dev/ata/ata_wdc.c diff -u src/sys/dev/ata/ata_wdc.c:1.105.6.6 src/sys/dev/ata/ata_wdc.c:1.105.6.7 --- src/sys/dev/ata/ata_wdc.c:1.105.6.6 Tue Jun 27 18:36:03 2017 +++ src/sys/dev/ata/ata_wdc.c Sat Aug 12 09:52:28 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.105.6.6 2017/06/27 18:36:03 jdolecek Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.105.6.7 2017/08/12 09:52:28 jdolecek Exp $ */ /* * Copyright
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Aug 12 09:38:58 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: fix condition for switching to kernel thread for ATAPI and bio reset recovery to match atapi_wdc.c, __wdcwait() postpones to the thread whenever neither AT_POLL nor AT_WAIT flags are present fixes spurious 'timeout' for the command on mvsata, followed by 'unexpected' interrupt To generate a diff of this commit: cvs rdiff -u -r1.35.6.18 -r1.35.6.19 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.18 src/sys/dev/ic/mvsata.c:1.35.6.19 --- src/sys/dev/ic/mvsata.c:1.35.6.18 Wed Jun 28 19:59:36 2017 +++ src/sys/dev/ic/mvsata.c Sat Aug 12 09:38:58 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.19 2017/08/12 09:38:58 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.19 2017/08/12 09:38:58 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1222,7 +1222,8 @@ do_pio: * If it's not a polled command, we need the kernel * thread */ - if ((xfer->c_flags & C_POLL) == 0 && cpu_intr_p()) { + if ((xfer->c_flags & C_POLL) == 0 && + (chp->ch_flags & ATACH_TH_RUN) == 0) { ata_channel_freeze(chp); wakeup(>ch_thread); return; @@ -1910,7 +1911,8 @@ mvsata_atapi_start(struct ata_channel *c /* Do control operations specially. */ if (__predict_false(drvp->state < READY)) { /* If it's not a polled command, we need the kernel thread */ - if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 && cpu_intr_p()) { + if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 && + (chp->ch_flags & ATACH_TH_RUN) == 0) { ata_channel_freeze(chp); wakeup(>ch_thread); return;
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Fri Aug 11 18:20:13 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: replace magic 3100 with locall defined WDC_RESET_WAIT To generate a diff of this commit: cvs rdiff -u -r1.30.4.33 -r1.30.4.34 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.33 src/sys/dev/ic/siisata.c:1.30.4.34 --- src/sys/dev/ic/siisata.c:1.30.4.33 Fri Aug 4 20:53:46 2017 +++ src/sys/dev/ic/siisata.c Fri Aug 11 18:20:13 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.34 2017/08/11 18:20:13 jdolecek Exp $"); #include #include @@ -109,6 +109,7 @@ int siisata_debug_mask = 0; #endif #define ATA_DELAY 1 /* 10s for a drive I/O */ +#define WDC_RESET_WAIT 31000 /* 31s for drive reset */ #ifndef __BUS_SPACE_HAS_STREAM_METHODS #if _BYTE_ORDER == _LITTLE_ENDIAN @@ -721,6 +722,7 @@ siisata_reset_drive(struct ata_drive_dat struct ata_xfer *xfer; uint32_t pss, pis; int i; + bool timed_out; siisata_reinit_port(chp, drvp->drive); @@ -737,10 +739,13 @@ siisata_reset_drive(struct ata_drive_dat siisata_activate_prb(schp, xfer->c_slot); - for(i = 0; i < 3100; i++) { + timed_out = true; + for(i = 0; i < WDC_RESET_WAIT / 10; i++) { pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); - if ((pss & PR_PXSS(xfer->c_slot)) == 0) + if ((pss & PR_PXSS(xfer->c_slot)) == 0) { + timed_out = false; break; + } if (pss & PR_PSS_ATTENTION) break; ata_delay(10, "siiprb", flags); @@ -764,7 +769,7 @@ siisata_reset_drive(struct ata_drive_dat siisata_enable_port_interrupt(chp); - if (i == 3100) { + if (timed_out) { /* timeout */ siisata_device_reset(chp); /* XXX is this right? */ if (sigp) @@ -888,7 +893,7 @@ siisata_probe_drive(struct ata_channel * siisata_activate_prb(schp, xfer->c_slot); timed_out = 1; - for(i = 0; i < 3100; i++) { + for(i = 0; i < WDC_RESET_WAIT / 10; i++) { if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & PR_PXSS(xfer->c_slot)) == 0) { /* prb completed */
CVS commit: [jdolecek-ncq] src/sys/dev/pci
Module Name:src Committed By: jdolecek Date: Sat Aug 5 13:22:01 UTC 2017 Modified Files: src/sys/dev/pci [jdolecek-ncq]: acardide.c Log Message: kill dead code To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.31.18.1 src/sys/dev/pci/acardide.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/pci/acardide.c diff -u src/sys/dev/pci/acardide.c:1.31 src/sys/dev/pci/acardide.c:1.31.18.1 --- src/sys/dev/pci/acardide.c:1.31 Mon Oct 7 19:51:55 2013 +++ src/sys/dev/pci/acardide.c Sat Aug 5 13:22:01 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: acardide.c,v 1.31 2013/10/07 19:51:55 jakllsch Exp $ */ +/* $NetBSD: acardide.c,v 1.31.18.1 2017/08/05 13:22:01 jdolecek Exp $ */ /*- * Copyright (c) 2001 Izumi Tsutsui. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.31 2013/10/07 19:51:55 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.31.18.1 2017/08/05 13:22:01 jdolecek Exp $"); #include #include @@ -292,41 +292,3 @@ acard_setup_channel(struct ata_channel * pci_conf_write(sc->sc_pc, sc->sc_tag, ATP860_UDMA, udma_mode); } } - -#if 0 /* XXX !! */ -static int -acard_pci_intr(void *arg) -{ - struct pciide_softc *sc = arg; - struct pciide_channel *cp; - struct ata_channel *wdc_cp; - int rv = 0; - int dmastat, i, crv; - - for (i = 0; i < sc->sc_wdcdev.sc_atac.atac_nchannels; i++) { - cp = >pciide_channels[i]; - dmastat = bus_space_read_1(sc->sc_dma_iot, - cp->dma_iohs[IDEDMA_CTL], 0); - if ((dmastat & IDEDMA_CTL_INTR) == 0) - continue; - wdc_cp = >ata_channel; - if ((wdc_cp->ch_flags & ATACH_IRQ_WAIT) == 0) { - (void)wdcintr(wdc_cp); - bus_space_write_1(sc->sc_dma_iot, - cp->dma_iohs[IDEDMA_CTL], 0, dmastat); - continue; - } - crv = wdcintr(wdc_cp); - if (crv == 0) { - printf("%s:%d: bogus intr\n", - device_xname(sc->sc_wdcdev.sc_atac.atac_dev), i); - bus_space_write_1(sc->sc_dma_iot, - cp->dma_iohs[IDEDMA_CTL], 0, dmastat); - } else if (crv == 1) - rv = 1; - else if (rv == 0) - rv = crv; - } - return rv; -} -#endif
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Fri Aug 4 20:53:47 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: prb_control need to add (or) PRB_CF_INTERRUPT_MASK for polled commands, rather that set - the field may be nonzero for ATAPI or for protocol override To generate a diff of this commit: cvs rdiff -u -r1.30.4.32 -r1.30.4.33 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.32 src/sys/dev/ic/siisata.c:1.30.4.33 --- src/sys/dev/ic/siisata.c:1.30.4.32 Fri Aug 4 20:49:24 2017 +++ src/sys/dev/ic/siisata.c Fri Aug 4 20:53:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.33 2017/08/04 20:53:46 jdolecek Exp $"); #include #include @@ -1039,7 +1039,7 @@ siisata_cmd_start(struct ata_channel *ch if (xfer->c_flags & C_POLL) { /* polled command, disable interrupts */ - prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK); + prb->prb_control |= htole16(PRB_CF_INTERRUPT_MASK); siisata_disable_port_interrupt(chp); } @@ -1256,7 +1256,7 @@ siisata_bio_start(struct ata_channel *ch if (xfer->c_flags & C_POLL) { /* polled command, disable interrupts */ - prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK); + prb->prb_control |= htole16(PRB_CF_INTERRUPT_MASK); siisata_disable_port_interrupt(chp); } @@ -1849,7 +1849,7 @@ siisata_atapi_start(struct ata_channel * if (xfer->c_flags & C_POLL) { /* polled command, disable interrupts */ - prbp->prb_control = htole16(PRB_CF_INTERRUPT_MASK); + prbp->prb_control |= htole16(PRB_CF_INTERRUPT_MASK); siisata_disable_port_interrupt(chp); }
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Fri Aug 4 20:49:24 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: restore part of what was removed in 1.30.4.30 - the success of command needs to be driven by PSS so that it works also for polled commands, apparently PR_PIS_CMDCMPL is not set in that case; now do error handling again only when PSS_ATTENTION is set this fixes timeout for polled commands like standby on shutdown, and (ehm ehm), READ LOG EXT on NCQ error recovery To generate a diff of this commit: cvs rdiff -u -r1.30.4.31 -r1.30.4.32 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.31 src/sys/dev/ic/siisata.c:1.30.4.32 --- src/sys/dev/ic/siisata.c:1.30.4.31 Tue Aug 1 22:02:32 2017 +++ src/sys/dev/ic/siisata.c Fri Aug 4 20:49:24 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.31 2017/08/01 22:02:32 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.31 2017/08/01 22:02:32 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.32 2017/08/04 20:49:24 jdolecek Exp $"); #include #include @@ -262,9 +262,12 @@ siisata_init_port(struct siisata_softc * schp = >sc_channels[port]; chp = (struct ata_channel *)schp; - /* come out of reset, 64-bit activation */ + /* + * Come out of reset. Disable no clearing of PR_PIS_CMDCMPL on read + * of PR_PSS. Disable 32-bit PRB activation, we use 64-bit activation. + */ PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), - PR_PC_32BA | PR_PC_PORT_RESET); + PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET); /* initialize port */ siisata_reinit_port(chp, -1); /* enable CmdErrr+CmdCmpl interrupting */ @@ -478,22 +481,22 @@ siisata_intr_port(struct siisata_channel uint32_t pss, pis, tfd = 0; bool recover = false; - pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); + /* get slot status, clearing completion interrupt */ + pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); - SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", - SIISATANAME(sc), __func__, chp->ch_channel, pis), + SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x ", + SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR); - if (pis & PR_PIS_CMDCMPL) { - /* get slot status, clearing completion interrupt */ - pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); - - SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR); - } else { - /* commands will be killed after recovery */ - pss = 0x; + if (__predict_true((pss & PR_PSS_ATTENTION) == 0)) { + SIISATA_DEBUG_PRINT(("no attention"), DEBUG_INTR); + goto process; } + pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); + + SIISATA_DEBUG_PRINT(("pis 0x%x\n", pss), DEBUG_INTR); + if (pis & PR_PIS_CMDERRR) { uint32_t ec; @@ -552,6 +555,7 @@ siisata_intr_port(struct siisata_channel if (__predict_false(recover)) ata_channel_freeze(chp); +process: if (xfer != NULL) { xfer->c_intr(chp, xfer, tfd); } else {
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/ic
Module Name:src Committed By: jdolecek Date: Tue Aug 1 22:02:32 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c ahcisatavar.h mvsatavar.h siisata.c siisatavar.h Log Message: fix logic bug in processing of finished commands - mask of active commands can change during the loop as c_intr() callback can queue new commands, so the interrupt routine should only mark as finished those which were actually active before the loop started; otherwise the code marked as finished commands which were just started, and being executed by HBA, leading to all sorts of data corruption while here mark the active mask volatile, as it is modified from interrupt context this fixes for good the random crashes, short reads, and fatal command errors which I've been tracing down for past couple weeks thanks to Jonathan (jakllsch@) for testing, and a script to easily triggered the condition, and led to this bug being finally found and squashed To generate a diff of this commit: cvs rdiff -u -r1.57.6.24 -r1.57.6.25 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.17.6.2 -r1.17.6.3 src/sys/dev/ic/ahcisatavar.h cvs rdiff -u -r1.2.48.2 -r1.2.48.3 src/sys/dev/ic/mvsatavar.h cvs rdiff -u -r1.30.4.30 -r1.30.4.31 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.6.48.2 -r1.6.48.3 src/sys/dev/ic/siisatavar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.24 src/sys/dev/ic/ahcisata_core.c:1.57.6.25 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.24 Sat Jul 29 16:50:32 2017 +++ src/sys/dev/ic/ahcisata_core.c Tue Aug 1 22:02:32 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.25 2017/08/01 22:02:32 jdolecek Exp $"); #include #include @@ -559,7 +559,7 @@ ahci_intr(void *v) static void ahci_intr_port(struct ahci_softc *sc, struct ahci_channel *achp) { - uint32_t is, tfd, active; + uint32_t is, tfd, sact; struct ata_channel *chp = >ata_channel; struct ata_xfer *xfer; int slot; @@ -578,12 +578,12 @@ ahci_intr_port(struct ahci_softc *sc, st if ((chp->ch_flags & ATACH_NCQ) == 0) { /* Non-NCQ operation */ - active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)); + sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)); slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT; } else { /* NCQ operation */ - active = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)); + sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)); slot = -1; } @@ -595,7 +595,7 @@ ahci_intr_port(struct ahci_softc *sc, st tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n", - AHCINAME(sc), chp->ch_channel, active, is, tfd); + AHCINAME(sc), chp->ch_channel, sact, is, tfd); } else { /* mark an error, and set BSY */ tfd = (WDCE_ABRT << AHCI_P_TFD_ERR_SHIFT) | @@ -630,8 +630,8 @@ ahci_intr_port(struct ahci_softc *sc, st ata_channel_freeze(chp); if (slot >= 0) { - if ((achp->ahcic_cmds_active & (1 << slot)) != 0 && - (active & (1 << slot)) == 0) { + if ((achp->ahcic_cmds_active & __BIT(slot)) != 0 && + (sact & __BIT(slot)) == 0) { xfer = ata_queue_hwslot_to_xfer(chp, slot); xfer->c_intr(chp, xfer, tfd); } @@ -641,10 +641,15 @@ ahci_intr_port(struct ahci_softc *sc, st * and any further D2H FISes are ignored until the error * condition is cleared. Hence if a command is inactive, * it means it actually already finished successfully. + * Note: active slots can change as c_intr() callback + * can activate another command(s), so must only process + * commands active before we start processing. */ + uint32_t aslots = achp->ahcic_cmds_active; + for (slot=0; slot < sc->sc_ncmds; slot++) { - if ((achp->ahcic_cmds_active & (1 << slot)) != 0 && - (active & (1 << slot)) == 0) { + if ((aslots & __BIT(slot)) != 0 && + (sact & __BIT(slot)) == 0) { xfer = ata_queue_hwslot_to_xfer(chp, slot); xfer->c_intr(chp, xfer, 0); } Index: src/sys/dev/ic/ahcisatavar.h diff -u src/sys/dev/ic/ahcisatavar.h:1.17.6.2 src/sys/dev/ic/ahcisatavar.h:1.17.6.3 --- src/sys/dev/ic/ahcisatavar.h:1.17.6.2 Sat Jul 29 15:07:46 2017 +++ src/sys/dev/ic/ahcisatavar.h Tue Aug 1 22:02:32 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisatavar.h,v 1.17.6.2 2017/07/29 15:07:46 jdolecek Exp $ */ +/* $NetBSD: ahcisatavar.h,v 1.17.6.3 2017/08/01 22:02:32 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -82,7 +82,7 @@ struct
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Tue Aug 1 21:43:49 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: adjust code to be closer to HEAD to it's easier to compare and find regressions, undoing some changes which were actually not necessary To generate a diff of this commit: cvs rdiff -u -r1.30.4.29 -r1.30.4.30 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.29 src/sys/dev/ic/siisata.c:1.30.4.30 --- src/sys/dev/ic/siisata.c:1.30.4.29 Sun Jul 30 20:46:31 2017 +++ src/sys/dev/ic/siisata.c Tue Aug 1 21:43:49 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.30 2017/08/01 21:43:49 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.30 2017/08/01 21:43:49 jdolecek Exp $"); #include #include @@ -245,7 +245,10 @@ siisata_enable_port_interrupt(struct ata { struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; - /* enable CmdErrr+CmdCmpl interrupting */ + /* clear any interrupts */ + (void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); + PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0x); + /* and enable CmdErrr+CmdCmpl interrupting */ PRWRITE(sc, PRX(chp->ch_channel, PRO_PIES), PR_PIS_CMDERRR | PR_PIS_CMDCMPL); } @@ -259,12 +262,9 @@ siisata_init_port(struct siisata_softc * schp = >sc_channels[port]; chp = (struct ata_channel *)schp; - /* - * Come out of reset. Disable no clearing of PR_PIS_CMDCMPL on read - * of PR_PSS. Disable 32-bit PRB activation, we use 64-bit activation. - */ + /* come out of reset, 64-bit activation */ PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), - PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET); + PR_PC_32BA | PR_PC_PORT_RESET); /* initialize port */ siisata_reinit_port(chp, -1); /* enable CmdErrr+CmdCmpl interrupting */ @@ -474,29 +474,25 @@ siisata_intr_port(struct siisata_channel struct siisata_softc *sc = (struct siisata_softc *)schp->ata_channel.ch_atac; struct ata_channel *chp = >ata_channel; - struct ata_xfer *xfer; - int slot = -1; + struct ata_xfer *xfer = NULL; uint32_t pss, pis, tfd = 0; bool recover = false; - /* get slot status, clearing completion interrupt (PR_PIS_CMDCMPL) */ - pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); - - SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x\n", - SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR); - - /* if no errors, just process finished commands and we're done */ - if (__predict_true((pss & PR_PSS_ATTENTION) == 0)) - goto process; - pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc), __func__, chp->ch_channel, pis), DEBUG_INTR); - /* clear */ - PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis); + if (pis & PR_PIS_CMDCMPL) { + /* get slot status, clearing completion interrupt */ + pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); + + SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR); + } else { + /* commands will be killed after recovery */ + pss = 0x; + } if (pis & PR_PIS_CMDERRR) { uint32_t ec; @@ -510,15 +506,12 @@ siisata_intr_port(struct siisata_channel if (ec <= PR_PCE_DATAFISERROR) { if (ec == PR_PCE_DEVICEERROR && (chp->ch_flags & ATACH_NCQ) == 0) { -uint32_t ps = PRREAD(sc, -PRX(chp->ch_channel, PRO_PS)); -/* This is only relevant for non-NCQ commands */ -slot = PR_PS_ACTIVE_SLOT(ps); +xfer = ata_queue_get_active_xfer(chp); /* read in specific information about error */ uint32_t prbfis = bus_space_read_stream_4( sc->sc_prt, sc->sc_prh, -PRSX(chp->ch_channel, slot, +PRSX(chp->ch_channel, xfer->c_slot, PRSO_FIS)); /* get status and error */ @@ -528,30 +521,39 @@ siisata_intr_port(struct siisata_channel if (ATACH_ST(ntfd) & WDCS_ERR) tfd = ntfd; } + + /* + * We don't expect the recovery to trigger error, + * but handle this just in case. + */ + if (!schp->sch_recovering) +recover = true; + else { +aprint_error_dev(sc->sc_atac.atac_dev, +"error ec %x while recovering\n", ec); + +/* Command will be marked as errored out */ +pss = 0; + } } else { aprint_error_dev(sc->sc_atac.atac_dev, "fatal error %d" " on channel %d (ctx 0x%x), resetting\n", ec, chp->ch_channel, PRREAD(sc, PRX(chp->ch_channel, PRO_PCR))); - tfd |= ATACH_ERR_ST(0, WDCS_BSY); + /* okay, we have a "Fatal Error" */ + siisata_device_reset(chp); } - - if (!schp->sch_recovering) - recover = true; - } else {
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: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: 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/ic
Module Name:src Committed By: jdolecek Date: Sun Jul 30 20:46:31 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: undo debug code To generate a diff of this commit: cvs rdiff -u -r1.30.4.28 -r1.30.4.29 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.28 src/sys/dev/ic/siisata.c:1.30.4.29 --- src/sys/dev/ic/siisata.c:1.30.4.28 Sun Jul 30 20:24:45 2017 +++ src/sys/dev/ic/siisata.c Sun Jul 30 20:46:31 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.29 2017/07/30 20:46:31 jdolecek Exp $"); #include #include @@ -288,7 +288,7 @@ siisata_attach_port(struct siisata_softc sc->sc_chanarray[port] = chp; chp->ch_channel = port; chp->ch_atac = >sc_atac; - chp->ch_queue = ata_queue_alloc(4) ; //SIISATA_MAX_SLOTS); + chp->ch_queue = ata_queue_alloc(SIISATA_MAX_SLOTS); if (chp->ch_queue == NULL) { aprint_error_dev(sc->sc_atac.atac_dev, "port %d: can't allocate memory "
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sun Jul 30 20:24:45 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: adjust error recovery to similar shape as ahcisata; also switch to using siisata_reset_channel(), as that seems more reliably get the HBA to running state again after some errors besides this, change several places checking PORT_READY to use siisata_reinit_port() and properly timeout - seen several cases where it would just loop there indefinitely on some errors with no way to get into ddb and no error message, due to the tight DELAY() loop To generate a diff of this commit: cvs rdiff -u -r1.30.4.27 -r1.30.4.28 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.27 src/sys/dev/ic/siisata.c:1.30.4.28 --- src/sys/dev/ic/siisata.c:1.30.4.27 Wed Jul 19 20:24:59 2017 +++ src/sys/dev/ic/siisata.c Sun Jul 30 20:24:45 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.28 2017/07/30 20:24:45 jdolecek Exp $"); #include #include @@ -157,12 +157,12 @@ int siisata_bio_complete(struct ata_chan void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int); int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *); -static void siisata_reinit_port(struct ata_channel *); +static void siisata_reinit_port(struct ata_channel *, int); static void siisata_device_reset(struct ata_channel *); static void siisata_activate_prb(struct siisata_channel *, int); static void siisata_deactivate_prb(struct siisata_channel *, int); static int siisata_dma_setup(struct ata_channel *, int, void *, size_t, int); -static void siisata_channel_recover(struct ata_channel *, int, int); +void siisata_channel_recover(struct ata_channel *, uint32_t); #if NATAPIBUS > 0 void siisata_atapibus_attach(struct atabus_softc *); @@ -266,7 +266,7 @@ siisata_init_port(struct siisata_softc * PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET); /* initialize port */ - siisata_reinit_port(chp); + siisata_reinit_port(chp, -1); /* enable CmdErrr+CmdCmpl interrupting */ siisata_enable_port_interrupt(chp); /* enable port interrupt */ @@ -288,7 +288,7 @@ siisata_attach_port(struct siisata_softc sc->sc_chanarray[port] = chp; chp->ch_channel = port; chp->ch_atac = >sc_atac; - chp->ch_queue = ata_queue_alloc(SIISATA_MAX_SLOTS); + chp->ch_queue = ata_queue_alloc(4) ; //SIISATA_MAX_SLOTS); if (chp->ch_queue == NULL) { aprint_error_dev(sc->sc_atac.atac_dev, "port %d: can't allocate memory " @@ -471,54 +471,29 @@ siisata_intr(void *v) static void siisata_intr_port(struct siisata_channel *schp) { - struct siisata_softc *sc; - struct ata_channel *chp; + struct siisata_softc *sc = + (struct siisata_softc *)schp->ata_channel.ch_atac; + struct ata_channel *chp = >ata_channel; struct ata_xfer *xfer; - u_int slot; - uint32_t pss, pis; - - sc = (struct siisata_softc *)schp->ata_channel.ch_atac; - chp = >ata_channel; + int slot = -1; + uint32_t pss, pis, tfd = 0; + bool recover = false; /* get slot status, clearing completion interrupt (PR_PIS_CMDCMPL) */ pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); + SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x\n", SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR); - for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) { - if (((schp->sch_active_slots >> slot) & 1) == 0) { - /* there's nothing executing here, skip */ - continue; - } - if (((pss >> slot) & 1) != 0) { - /* execution is incomplete or unsuccessful, skip - * for now */ - continue; - } - xfer = ata_queue_hwslot_to_xfer(chp, slot); - if (xfer->c_intr == NULL) { - wakeup(schp); - continue; - } - KASSERT(xfer != NULL); - KASSERT(xfer->c_intr != NULL); - xfer->c_intr(chp, xfer, 0); - } - /* if no errors, we're done now */ - if ((pss & PR_PSS_ATTENTION) == 0) { - pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); - pis &= 0x; - if (pis) { - PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), - pis & 0xfffcfffc); - } - return; - } + /* if no errors, just process finished commands and we're done */ + if (__predict_true((pss & PR_PSS_ATTENTION) == 0)) + goto process; pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); - SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc), - __func__, chp->ch_channel, pis), DEBUG_INTR); + SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", + SIISATANAME(sc), __func__, chp->ch_channel, pis), +
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/ic
Module Name:src Committed By: jdolecek Date: Sat Jul 29 22:40:04 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisatareg.h Log Message: add macro for getting the slot from context register, just for reference for now To generate a diff of this commit: cvs rdiff -u -r1.7.42.3 -r1.7.42.4 src/sys/dev/ic/siisatareg.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/ic/siisatareg.h diff -u src/sys/dev/ic/siisatareg.h:1.7.42.3 src/sys/dev/ic/siisatareg.h:1.7.42.4 --- src/sys/dev/ic/siisatareg.h:1.7.42.3 Wed Jul 19 20:03:29 2017 +++ src/sys/dev/ic/siisatareg.h Sat Jul 29 22:40:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisatareg.h,v 1.7.42.3 2017/07/19 20:03:29 jdolecek Exp $ */ +/* $NetBSD: siisatareg.h,v 1.7.42.4 2017/07/29 22:40:04 jdolecek Exp $ */ /* * Copyright (c) 2007, 2008, 2009, 2010, 2011 Jonathan A. Kollasch. @@ -188,6 +188,7 @@ struct siisata_prb { #define PRO_CARX(p,s) (PRX(p, PRO_CAR) + (s) * sizeof(uint64_t)) #define PRO_PCR 0x1e04 /* port context register */ +#define PRO_PCR_SLOT(x) (((x) & __BITS(4, 0)) >> 0) /* Slot */ #define PRO_PCR_PMP(x) (((x) & __BITS(8, 5)) >> 5) /* PM Port */ #define PRO_SCONTROL 0x1f00 /* SControl */ #define PRO_SSTATUS 0x1f04 /* SStatus */
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jul 29 16:50:32 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c Log Message: whitespace To generate a diff of this commit: cvs rdiff -u -r1.57.6.23 -r1.57.6.24 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.23 src/sys/dev/ic/ahcisata_core.c:1.57.6.24 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.23 Sat Jul 29 15:07:46 2017 +++ src/sys/dev/ic/ahcisata_core.c Sat Jul 29 16:50:32 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.24 2017/07/29 16:50:32 jdolecek Exp $"); #include #include @@ -1609,7 +1609,6 @@ ahci_channel_recover(struct ahci_softc * /* * Failed to get resources to run the recovery command, must * reset the drive. This will also kill all still outstanding - * transfers. */ reset:
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jul 29 15:07:46 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c ahcisatavar.h Log Message: make compile without AHCI_DEBUG To generate a diff of this commit: cvs rdiff -u -r1.57.6.22 -r1.57.6.23 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.17.6.1 -r1.17.6.2 src/sys/dev/ic/ahcisatavar.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/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.22 src/sys/dev/ic/ahcisata_core.c:1.57.6.23 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.22 Sat Jul 29 14:50:58 2017 +++ src/sys/dev/ic/ahcisata_core.c Sat Jul 29 15:07:46 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.23 2017/07/29 15:07:46 jdolecek Exp $"); #include #include @@ -967,9 +967,9 @@ ahci_exec_command(struct ata_drive_datas int ret; int s; - struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; AHCIDEBUG_PRINT(("ahci_exec_command port %d CI 0x%x\n", - chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), + chp->ch_channel, + AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS); if (ata_c->flags & AT_POLL) xfer->c_flags |= C_POLL; @@ -1007,17 +1007,17 @@ ahci_exec_command(struct ata_drive_datas static void ahci_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) { - struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; + struct ahci_softc *sc = AHCI_CH2SC(chp); struct ahci_channel *achp = (struct ahci_channel *)chp; struct ata_command *ata_c = >c_ata_c; int slot = xfer->c_slot; struct ahci_cmd_tbl *cmd_tbl; struct ahci_cmd_header *cmd_h; int i; - int channel = chp->ch_channel; AHCIDEBUG_PRINT(("ahci_cmd_start CI 0x%x timo %d\n slot %d", - AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)), ata_c->timeout, slot), + AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)), + ata_c->timeout, slot), DEBUG_XFERS); KASSERT((achp->ahcic_cmds_active & (1 << slot)) == 0); @@ -1072,11 +1072,14 @@ ahci_cmd_start(struct ata_channel *chp, ahci_intr_port(sc, achp); ata_delay(10, "ahcipl", ata_c->flags); } - AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), channel, + AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel, AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS), - AHCI_READ(sc, AHCI_P_CLBU(channel)), AHCI_READ(sc, AHCI_P_CLB(channel)), - AHCI_READ(sc, AHCI_P_FBU(channel)), AHCI_READ(sc, AHCI_P_FB(channel)), - AHCI_READ(sc, AHCI_P_CMD(channel)), AHCI_READ(sc, AHCI_P_CI(channel))), + AHCI_READ(sc, AHCI_P_CLBU(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_CLB(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_FBU(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_FB(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS); if ((ata_c->flags & AT_DONE) == 0) { ata_c->flags |= AT_TIMEOU; @@ -1127,12 +1130,12 @@ static int ahci_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int tfd) { struct ata_command *ata_c = >c_ata_c; - struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; struct ahci_channel *achp = (struct ahci_channel *)chp; AHCIDEBUG_PRINT(("ahci_cmd_complete channel %d CMD 0x%x CI 0x%x\n", - chp->ch_channel, AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)), - AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), + chp->ch_channel, + AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CMD(chp->ch_channel)), + AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))), DEBUG_FUNCS); if (ata_waitdrain_xfer_check(chp, xfer)) @@ -1217,9 +1220,9 @@ ahci_ata_bio(struct ata_drive_datas *drv struct ata_channel *chp = drvp->chnl_softc; struct ata_bio *ata_bio = >c_bio; - struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; AHCIDEBUG_PRINT(("ahci_ata_bio port %d CI 0x%x\n", - chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), + chp->ch_channel, + AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS); if (ata_bio->flags & ATA_POLL) xfer->c_flags |= C_POLL; @@ -1242,7 +1245,6 @@ ahci_bio_start(struct ata_channel *chp, struct ahci_cmd_tbl *cmd_tbl; struct ahci_cmd_header *cmd_h; int i; - int channel = chp->ch_channel; AHCIDEBUG_PRINT(("ahci_bio_start CI 0x%x\n", AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS); @@ -1297,11
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jul 29 14:50:58 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c Log Message: make ahci_channel_recover() non-static, so that it's visible in backtrace, and can set a separate breakpoint there To generate a diff of this commit: cvs rdiff -u -r1.57.6.21 -r1.57.6.22 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.21 src/sys/dev/ic/ahcisata_core.c:1.57.6.22 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.21 Sat Jul 29 13:02:50 2017 +++ src/sys/dev/ic/ahcisata_core.c Sat Jul 29 14:50:58 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek Exp $"); #include #include @@ -77,8 +77,7 @@ static void ahci_bio_kill_xfer(struct at static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, int, int); -static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, -int); +void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, int); static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); #if NATAPIBUS > 0 @@ -627,7 +626,7 @@ ahci_intr_port(struct ahci_softc *sc, st tfd = 0; } - if (recover) + if (__predict_false(recover)) ata_channel_freeze(chp); if (slot >= 0) { @@ -652,7 +651,7 @@ ahci_intr_port(struct ahci_softc *sc, st } } - if (recover) { + if (__predict_false(recover)) { ata_channel_thaw(chp); ahci_channel_recover(sc, chp, tfd); }
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jul 29 13:04:43 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisatareg.h Log Message: fix AHCI_P_CMD_CCS_SHIFT - must shift only by 8, otherwise the result would be always 0 To generate a diff of this commit: cvs rdiff -u -r1.12.26.1 -r1.12.26.2 src/sys/dev/ic/ahcisatareg.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/ic/ahcisatareg.h diff -u src/sys/dev/ic/ahcisatareg.h:1.12.26.1 src/sys/dev/ic/ahcisatareg.h:1.12.26.2 --- src/sys/dev/ic/ahcisatareg.h:1.12.26.1 Wed Jul 19 20:21:42 2017 +++ src/sys/dev/ic/ahcisatareg.h Sat Jul 29 13:04:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisatareg.h,v 1.12.26.1 2017/07/19 20:21:42 jdolecek Exp $ */ +/* $NetBSD: ahcisatareg.h,v 1.12.26.2 2017/07/29 13:04:43 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -234,8 +234,8 @@ struct ahci_r_fis { #define AHCI_P_CMD_CR 0x8000 /* command list running */ #define AHCI_P_CMD_FR 0x4000 /* FIS receive running */ #define AHCI_P_CMD_MPSS 0x2000 /* mechanical switch state */ -#define AHCI_P_CMD_CCS_MASK 0x1f00 /* current command slot */ -#define AHCI_P_CMD_CCS_SHIFT 12 +#define AHCI_P_CMD_CCS_MASK __BITS(12, 8) /* current command slot */ +#define AHCI_P_CMD_CCS_SHIFT 8 #define AHCI_P_CMD_FRE 0x0010 /* FIS receive enable */ #define AHCI_P_CMD_CLO 0x0008 /* command list override */ #define AHCI_P_CMD_POD 0x0004 /* power on device */
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jul 29 13:02:50 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c Log Message: do not do the drive reset on non-fatal recovery - spec explicitely says says the READ LOG EXT should only be done when neither COMRESET nor software reset was done, and indeed it returns junk in this case use C_RECOVERY slot for drive reset, so that it now will always succeed in getting a slot, in cases when it would be necessary adjust code and comments on the recovery path to explain better what's going on with this AHCI error recovery works with real hardware without timeouts again To generate a diff of this commit: cvs rdiff -u -r1.57.6.20 -r1.57.6.21 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.20 src/sys/dev/ic/ahcisata_core.c:1.57.6.21 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.20 Sun Jul 23 14:14:43 2017 +++ src/sys/dev/ic/ahcisata_core.c Sat Jul 29 13:02:50 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $"); #include #include @@ -568,10 +568,12 @@ ahci_intr_port(struct ahci_softc *sc, st is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is); - AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x TFD 0x%x\n", + AHCIDEBUG_PRINT(( + "ahci_intr_port %s port %d is 0x%x CI 0x%x SACT 0x%x TFD 0x%x\n", AHCINAME(sc), chp->ch_channel, is, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)), AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))), DEBUG_INTR); @@ -613,8 +615,9 @@ ahci_intr_port(struct ahci_softc *sc, st tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); /* D2H Register FIS or Set Device Bits */ - if ((tfd & WDCS_ERR) != 0 && !achp->ahcic_recovering) { - recover = true; + if ((tfd & WDCS_ERR) != 0) { + if (!achp->ahcic_recovering) +recover = true; aprint_error("%s port %d: transfer aborted 0x%x\n", AHCINAME(sc), chp->ch_channel, tfd); @@ -757,11 +760,7 @@ again: /* polled command, assume interrupts are disabled */ /* use available slot to send reset, if none available fail */ - xfer = ata_get_xfer_ext(chp, false, 0); - if (xfer == NULL) { - printf("%s: no xfer\n", __func__); - return 1; - } + xfer = ata_get_xfer_ext(chp, C_RECOVERY, 0); cmd_h = >ahcic_cmdh[xfer->c_slot]; cmd_tbl = achp->ahcic_cmd_tbl[xfer->c_slot]; @@ -1556,22 +1555,16 @@ ahci_channel_recover(struct ahci_softc * /* * If BSY or DRQ bits are set, must execute COMRESET to return - * device to idle state. Otherwise, commands can be reissued - * after resetting CMD.ST. After resetting CMD.ST, need to execute - * READ LOG EXT for NCQ to unblock device processing if COMRESET - * was not done. + * device to idle state. If drive is idle, it's enough to just + * reset CMD.ST, it's not necessary to do software reset. + * After resetting CMD.ST, need to execute READ LOG EXT for NCQ + * to unblock device processing if COMRESET was not done. */ if (reset || (AHCI_TFD_ST(tfd) & (WDCS_BSY|WDCS_DRQ)) != 0) goto reset; KASSERT(drive >= 0); ahci_channel_stop(sc, chp, AT_POLL); - if (ahci_do_reset_drive(chp, drive, AT_POLL, NULL) != 0) { -reset: - /* This will also kill all still outstanding transfers */ - ahci_reset_channel(chp, AT_POLL); - goto out; - } ahci_channel_start(sc, chp, AT_POLL, (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0); @@ -1585,18 +1578,48 @@ reset: ahci_unhold(achp); - if (error == 0) { + switch (error) { + case 0: /* Error out the particular NCQ xfer, then requeue the others */ - xfer = ata_queue_hwslot_to_xfer(chp, eslot); - xfer->c_intr(chp, xfer, (err << AHCI_P_TFD_ERR_SHIFT) | st); - } else if (error == EOPNOTSUPP) { - /* command already processed before entering recovery */ - KASSERT(achp->ahcic_cmds_active == 0); - } else { + if ((achp->ahcic_cmds_active & (1 << eslot)) != 0) { + xfer = ata_queue_hwslot_to_xfer(chp, eslot); + xfer->c_intr(chp, xfer, + (err << AHCI_P_TFD_ERR_SHIFT) | st); + } + break; + + case EOPNOTSUPP: + /* + * Non-NCQ command error, just find the slot and end with + * the error. + */ + for (slot = 0; slot < sc->sc_ncmds; slot++) { + if ((achp->ahcic_cmds_active & (1 << slot)) != 0) { +xfer = ata_queue_hwslot_to_xfer(chp, slot); +xfer->c_intr(chp, xfer, tfd); + } + } + break; + +
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: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/scsipi
Module Name:src Committed By: jdolecek Date: Sat Jul 29 09:04:39 UTC 2017 Modified Files: src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c Log Message: do not use freed xfer in error message in wdc_atapi_get_params() To generate a diff of this commit: cvs rdiff -u -r1.123.4.9 -r1.123.4.10 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/scsipi/atapi_wdc.c diff -u src/sys/dev/scsipi/atapi_wdc.c:1.123.4.9 src/sys/dev/scsipi/atapi_wdc.c:1.123.4.10 --- src/sys/dev/scsipi/atapi_wdc.c:1.123.4.9 Tue Jun 27 18:36:03 2017 +++ src/sys/dev/scsipi/atapi_wdc.c Sat Jul 29 09:04:39 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: atapi_wdc.c,v 1.123.4.9 2017/06/27 18:36:03 jdolecek Exp $ */ +/* $NetBSD: atapi_wdc.c,v 1.123.4.10 2017/07/29 09:04:39 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.9 2017/06/27 18:36:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.10 2017/07/29 09:04:39 jdolecek Exp $"); #ifndef ATADEBUG #define ATADEBUG @@ -242,9 +242,9 @@ wdc_atapi_get_params(struct scsipi_chann delay(5000); if (ata_get_params(>ch_drive[drive], AT_WAIT, id) != 0) { ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_IDENTIFY_DEVICE " - "failed for drive %s:%d:%d: error 0x%x\n", - device_xname(atac->atac_dev), chp->ch_channel, drive, - xfer->c_ata_c.r_error), DEBUG_PROBE); + "failed for drive %s:%d:%d\n", + device_xname(atac->atac_dev), chp->ch_channel, drive), + DEBUG_PROBE); rv = -1; goto out; }
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/ic
Module Name:src Committed By: jdolecek Date: Sun Jul 23 14:14:44 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c Log Message: rework the error handling and recovery, so that errors during the recovery are handled correctly, and the recovery more closely follows the spec this fixes e.g. NCQ error handling under QEMU, which doesn't implement READ LOG EXT - previous code actually made the call 'succeed', returning bogus (zero) slot/error/status finished xfers are still handled before entering recovery (with channel frozen) to avoid unnecessary retries To generate a diff of this commit: cvs rdiff -u -r1.57.6.19 -r1.57.6.20 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.19 src/sys/dev/ic/ahcisata_core.c:1.57.6.20 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.19 Fri Jul 21 18:36:47 2017 +++ src/sys/dev/ic/ahcisata_core.c Sun Jul 23 14:14:43 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.20 2017/07/23 14:14:43 jdolecek Exp $"); #include #include @@ -77,7 +77,8 @@ static void ahci_bio_kill_xfer(struct at static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, int, int); -static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *); +static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, +int); static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); #if NATAPIBUS > 0 @@ -563,6 +564,7 @@ ahci_intr_port(struct ahci_softc *sc, st struct ata_channel *chp = >ata_channel; struct ata_xfer *xfer; int slot; + bool recover = false; is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is); @@ -573,34 +575,30 @@ ahci_intr_port(struct ahci_softc *sc, st AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))), DEBUG_INTR); - active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) - | AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)); - - /* Complete all successful commands first */ - for (slot=0; slot < sc->sc_ncmds; slot++) { - if ((achp->ahcic_cmds_active & (1 << slot)) == 0) - continue; - if ((active & (1 << slot)) == 0) { - xfer = ata_queue_hwslot_to_xfer(chp, slot); - xfer->c_intr(chp, xfer, 0); - } + if ((chp->ch_flags & ATACH_NCQ) == 0) { + /* Non-NCQ operation */ + active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)); + slot = (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) + & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT; + } else { + /* NCQ operation */ + active = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)); + slot = -1; } /* Handle errors */ if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS | AHCI_P_IX_IFS | AHCI_P_IX_OFS | AHCI_P_IX_UFS)) { + /* Fatal errors */ if (is & AHCI_P_IX_TFES) { tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); - if ((AHCI_TFD_ST(tfd) & (WDCS_DRQ|WDCS_BSY)) == 0 && - !achp->ahcic_recovering) -goto recover; - aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n", AHCINAME(sc), chp->ch_channel, active, is, tfd); } else { - /* emulate a CRC error */ - tfd = (WDCE_CRC << AHCI_P_TFD_ERR_SHIFT) | WDCS_ERR; + /* mark an error, and set BSY */ + tfd = (WDCE_ABRT << AHCI_P_TFD_ERR_SHIFT) | + WDCS_ERR | WDCS_BSY; } if (is & AHCI_P_IX_IFS) { @@ -609,29 +607,52 @@ ahci_intr_port(struct ahci_softc *sc, st AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel))); } - /* Request channel reset */ - ata_reset_channel(chp, 0); - return; + if (!achp->ahcic_recovering) + recover = true; } else if (is & (AHCI_P_IX_DHRS|AHCI_P_IX_SDBS)) { - /* D2H Register FIS or Set Device Bits */ tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); + + /* D2H Register FIS or Set Device Bits */ if ((tfd & WDCS_ERR) != 0 && !achp->ahcic_recovering) { -recover: + recover = true; + aprint_error("%s port %d: transfer aborted 0x%x\n", AHCINAME(sc), chp->ch_channel, tfd); - /* - * Device indicated transfer aborted without any fatal - * error. Transfers can be reissued after resetting - * CMD.ST. Need to execute READ LOG EXT for NCQ - * commands. - */ - ahci_channel_stop(sc, chp, AT_POLL); - ahci_channel_start(sc, chp, AT_POLL, - (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0); - ahci_channel_recover(sc, chp); + } + } else { + tfd = 0; + } + + if (recover) +
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: 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/ic
Module Name:src Committed By: jdolecek Date: Fri Jul 21 18:36:47 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c Log Message: use free slot for drive reset, rather than always using slot zero; if we can't get the slot, fallback to channel reset as usual note this increases the odds of not being able to do the reset, when all slots happen to be active this is in same area as problem reported by PR kern/52372 but I don't believe that this change actually make any change for it - during probe/attach there shouldn't be any paralell request with drive reset To generate a diff of this commit: cvs rdiff -u -r1.57.6.18 -r1.57.6.19 src/sys/dev/ic/ahcisata_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.18 src/sys/dev/ic/ahcisata_core.c:1.57.6.19 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.18 Wed Jul 19 20:21:42 2017 +++ src/sys/dev/ic/ahcisata_core.c Fri Jul 21 18:36:47 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.19 2017/07/21 18:36:47 jdolecek Exp $"); #include #include @@ -650,7 +650,7 @@ ahci_reset_drive(struct ata_drive_datas /* return error code from ata_bio */ static int -ahci_exec_fis(struct ata_channel *chp, int timeout, int flags) +ahci_exec_fis(struct ata_channel *chp, int timeout, int flags, int slot) { struct ahci_channel *achp = (struct ahci_channel *)chp; struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; @@ -667,11 +667,13 @@ ahci_exec_fis(struct ata_channel *chp, i else timeout = timeout / 10; - AHCI_CMDH_SYNC(sc, achp, 0, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + AHCI_CMDH_SYNC(sc, achp, slot, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* start command */ - AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << 0); + AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << slot); for (i = 0; i < timeout; i++) { - if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & 1 << 0) == 0) + if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & (1 << slot)) == + 0) return 0; is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS | @@ -708,6 +710,7 @@ ahci_do_reset_drive(struct ata_channel * struct ahci_cmd_header *cmd_h; int i; uint32_t sig; + struct ata_xfer *xfer = NULL; KASSERT((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) == 0); again: @@ -732,9 +735,15 @@ again: goto skip_reset; /* polled command, assume interrupts are disabled */ - /* use slot 0 to send reset, the channel is idle */ - cmd_h = >ahcic_cmdh[0]; - cmd_tbl = achp->ahcic_cmd_tbl[0]; + /* use available slot to send reset, if none available fail */ + xfer = ata_get_xfer_ext(chp, false, 0); + if (xfer == NULL) { + printf("%s: no xfer\n", __func__); + return 1; + } + + cmd_h = >ahcic_cmdh[xfer->c_slot]; + cmd_tbl = achp->ahcic_cmd_tbl[xfer->c_slot]; cmd_h->cmdh_flags = htole16(AHCI_CMDH_F_RST | AHCI_CMDH_F_CBSY | RHD_FISLEN / 4 | (drive << AHCI_CMDH_F_PMP_SHIFT)); cmd_h->cmdh_prdbc = 0; @@ -742,7 +751,7 @@ again: cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE; cmd_tbl->cmdt_cfis[rhd_c] = drive; cmd_tbl->cmdt_cfis[rhd_control] = WDCTL_RST; - switch(ahci_exec_fis(chp, 100, flags)) { + switch(ahci_exec_fis(chp, 100, flags, xfer->c_slot)) { case ERR_DF: case TIMEOUT: aprint_error("%s channel %d: setting WDCTL_RST failed " @@ -760,7 +769,7 @@ again: cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE; cmd_tbl->cmdt_cfis[rhd_c] = drive; cmd_tbl->cmdt_cfis[rhd_control] = 0; - switch(ahci_exec_fis(chp, 310, flags)) { + switch(ahci_exec_fis(chp, 310, flags, xfer->c_slot)) { case ERR_DF: case TIMEOUT: if ((sc->sc_ahci_quirks & AHCI_QUIRK_BADPMPRESET) != 0 && @@ -811,6 +820,8 @@ skip_reset: AHCINAME(sc), chp->ch_channel, sig, AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE); end: + if (xfer != NULL) + ata_free_xfer(chp, xfer); ahci_channel_stop(sc, chp, flags); ata_delay(500, "ahcirst", flags); /* clear port interrupt register */
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: 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/ic
Module Name:src Committed By: jdolecek Date: Wed Jul 19 20:24:59 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: forced commit to get into history - previous commit removed also the siisata-specific downgrade of SATA channel speed on CRC, as it doesn't really fit with error/state not being available after c_intr(); as noted this handling should be in generic code, and it's overly harsh to do this after single error anyway, particularly since there is no way to get back To generate a diff of this commit: cvs rdiff -u -r1.30.4.26 -r1.30.4.27 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.26 src/sys/dev/ic/siisata.c:1.30.4.27 --- src/sys/dev/ic/siisata.c:1.30.4.26 Wed Jul 19 20:02:40 2017 +++ src/sys/dev/ic/siisata.c Wed Jul 19 20:24:59 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.27 2017/07/19 20:24:59 jdolecek Exp $"); #include #include
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Wed Jul 19 20:21:42 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c ahcisatareg.h ahcisatavar.h Log Message: update error handling: - switch to ata_timeout() - stop using ch_status/ch_error for passing state/error, stop setting ATACH_IRQ_WAIT in ch_flags; pass the state via the last parameter to c_intr() routine - add NCQ recovery and KILL_REQUEUE - only call atastart() in c_intr() if there was no error ahcisata-specific tweaks: - add some handling for PM in the error recovery using FBS register, according to spec it should be independant of actual FBSS feature; untested as my hw doesn't support PM To generate a diff of this commit: cvs rdiff -u -r1.57.6.17 -r1.57.6.18 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.12 -r1.12.26.1 src/sys/dev/ic/ahcisatareg.h cvs rdiff -u -r1.17 -r1.17.6.1 src/sys/dev/ic/ahcisatavar.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/ic/ahcisata_core.c diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.17 src/sys/dev/ic/ahcisata_core.c:1.57.6.18 --- src/sys/dev/ic/ahcisata_core.c:1.57.6.17 Tue Jun 27 18:36:03 2017 +++ src/sys/dev/ic/ahcisata_core.c Wed Jul 19 20:21:42 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.57.6.17 2017/06/27 18:36:03 jdolecek Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.17 2017/06/27 18:36:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.18 2017/07/19 20:21:42 jdolecek Exp $"); #include #include @@ -68,7 +68,7 @@ static void ahci_killpending(struct ata_ static void ahci_cmd_start(struct ata_channel *, struct ata_xfer *); static int ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int); -static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *); +static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int); static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *); static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); static void ahci_bio_start(struct ata_channel *, struct ata_xfer *); @@ -77,7 +77,7 @@ static void ahci_bio_kill_xfer(struct at static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, int, int); -static void ahci_timeout(void *); +static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *); static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); #if NATAPIBUS > 0 @@ -566,8 +566,11 @@ ahci_intr_port(struct ahci_softc *sc, st is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is); - AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x\n", AHCINAME(sc), - chp->ch_channel, is, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), + AHCIDEBUG_PRINT(("ahci_intr_port %s port %d is 0x%x CI 0x%x TFD 0x%x\n", + AHCINAME(sc), + chp->ch_channel, is, + AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)), + AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))), DEBUG_INTR); active = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) @@ -584,38 +587,50 @@ ahci_intr_port(struct ahci_softc *sc, st } /* Handle errors */ - if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_IFS | - AHCI_P_IX_OFS | AHCI_P_IX_UFS)) { - /* stop channel */ - ahci_channel_stop(sc, chp, 0); + if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS | + AHCI_P_IX_IFS | AHCI_P_IX_OFS | AHCI_P_IX_UFS)) { if (is & AHCI_P_IX_TFES) { tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); - chp->ch_error = - (tfd & AHCI_P_TFD_ERR_MASK) >> AHCI_P_TFD_ERR_SHIFT; - chp->ch_status = (tfd & 0xff); + + if ((AHCI_TFD_ST(tfd) & (WDCS_DRQ|WDCS_BSY)) == 0 && + !achp->ahcic_recovering) +goto recover; + + aprint_error("%s port %d: active %x is 0x%x tfd 0x%x\n", + AHCINAME(sc), chp->ch_channel, active, is, tfd); } else { /* emulate a CRC error */ - chp->ch_error = WDCE_CRC; - chp->ch_status = WDCS_ERR; + tfd = (WDCE_CRC << AHCI_P_TFD_ERR_SHIFT) | WDCS_ERR; } + if (is & AHCI_P_IX_IFS) { aprint_error("%s port %d: SERR 0x%x\n", AHCINAME(sc), chp->ch_channel, AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel))); } - /* complete all pending commands with error statuses */ - for (slot=0; slot < sc->sc_ncmds; slot++) { - if ((achp->ahcic_cmds_active & (1 << slot)) == 0) -continue; - if ((active & (1 << slot)) == 1) { -xfer = ata_queue_hwslot_to_xfer(chp, slot); -xfer->c_intr(chp, xfer, is); - } + + /* Request channel reset */ + ata_reset_channel(chp, 0); + return; + } else if (is & (AHCI_P_IX_DHRS|AHCI_P_IX_SDBS)) { +
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Wed Jul 19 20:03:29 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisatareg.h siisatavar.h Log Message: header changes for siisata switch to new error handling world order To generate a diff of this commit: cvs rdiff -u -r1.7.42.2 -r1.7.42.3 src/sys/dev/ic/siisatareg.h cvs rdiff -u -r1.6.48.1 -r1.6.48.2 src/sys/dev/ic/siisatavar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisatareg.h diff -u src/sys/dev/ic/siisatareg.h:1.7.42.2 src/sys/dev/ic/siisatareg.h:1.7.42.3 --- src/sys/dev/ic/siisatareg.h:1.7.42.2 Mon Jun 12 23:51:40 2017 +++ src/sys/dev/ic/siisatareg.h Wed Jul 19 20:03:29 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisatareg.h,v 1.7.42.2 2017/06/12 23:51:40 jakllsch Exp $ */ +/* $NetBSD: siisatareg.h,v 1.7.42.3 2017/07/19 20:03:29 jdolecek Exp $ */ /* * Copyright (c) 2007, 2008, 2009, 2010, 2011 Jonathan A. Kollasch. @@ -164,6 +164,8 @@ struct siisata_prb { #define PRSO_RTC 0x04 /* recieved transfer count */ #define PRSO_FIS 0x08 /* base of FIS */ +#define PRO_PMPSTS(i) (0x0f80 + i * 8) +#define PRO_PMPQACT(i) (0x0f80 + i * 8 + 4) #define PRO_PCS 0x1000 /* (write) port control set */ #define PRO_PS PRO_PCS /* (read) port status */ #define PRO_PCC 0x1004 /* port control clear */ @@ -186,6 +188,7 @@ struct siisata_prb { #define PRO_CARX(p,s) (PRX(p, PRO_CAR) + (s) * sizeof(uint64_t)) #define PRO_PCR 0x1e04 /* port context register */ +#define PRO_PCR_PMP(x) (((x) & __BITS(8, 5)) >> 5) /* PM Port */ #define PRO_SCONTROL 0x1f00 /* SControl */ #define PRO_SSTATUS 0x1f04 /* SStatus */ #define PRO_SERROR 0x1f08 /* SError */ Index: src/sys/dev/ic/siisatavar.h diff -u src/sys/dev/ic/siisatavar.h:1.6.48.1 src/sys/dev/ic/siisatavar.h:1.6.48.2 --- src/sys/dev/ic/siisatavar.h:1.6.48.1 Tue Jun 13 00:02:19 2017 +++ src/sys/dev/ic/siisatavar.h Wed Jul 19 20:03:29 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisatavar.h,v 1.6.48.1 2017/06/13 00:02:19 jakllsch Exp $ */ +/* $NetBSD: siisatavar.h,v 1.6.48.2 2017/07/19 20:03:29 jdolecek Exp $ */ /* from ahcisatavar.h */ @@ -101,6 +101,8 @@ struct siisata_softc { bus_dmamap_t sch_datad[SIISATA_MAX_SLOTS]; uint32_t sch_active_slots; + uint32_t sch_hold_slots; + bool sch_recovering; } sc_channels[SIISATA_MAX_PORTS]; };
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Wed Jul 19 20:02:40 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: convert over to new error handling world order: - switch to ata_timeout() - stop using ch_status/ch_error for passing state/error, stop setting ATACH_IRQ_WAIT in ch_flags; pass the state via the last parameter to c_intr() routine - add NCQ recovery and KILL_REQUEUE - only call atastart() in c_intr() if there was no error several siisata specific tweaks: - improve reset to better handle PM - need to reset couple more registers - add timeouts for unbusy wait - ATA_DELAY (10s) - siisata_bio_complete() do not use PRSO_RTC for byte count for NCQ transfers, they never return partial reads; and that register might contain some random junk, at least that's the case with ahcisata cmdh_prdbc To generate a diff of this commit: cvs rdiff -u -r1.30.4.25 -r1.30.4.26 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.25 src/sys/dev/ic/siisata.c:1.30.4.26 --- src/sys/dev/ic/siisata.c:1.30.4.25 Tue Jun 27 20:13:56 2017 +++ src/sys/dev/ic/siisata.c Wed Jul 19 20:02:40 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.26 2017/07/19 20:02:40 jdolecek Exp $"); #include #include @@ -148,7 +148,7 @@ void siisata_killpending(struct ata_driv void siisata_cmd_start(struct ata_channel *, struct ata_xfer *); int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int); -void siisata_cmd_done(struct ata_channel *, struct ata_xfer *); +void siisata_cmd_done(struct ata_channel *, struct ata_xfer *, int); static void siisata_cmd_done_end(struct ata_channel *, struct ata_xfer *); void siisata_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); @@ -157,14 +157,12 @@ int siisata_bio_complete(struct ata_chan void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int); int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *); -void siisata_timeout(void *); - static void siisata_reinit_port(struct ata_channel *); static void siisata_device_reset(struct ata_channel *); static void siisata_activate_prb(struct siisata_channel *, int); static void siisata_deactivate_prb(struct siisata_channel *, int); -static int siisata_dma_setup(struct ata_channel *chp, int, void *, -size_t, int); +static int siisata_dma_setup(struct ata_channel *, int, void *, size_t, int); +static void siisata_channel_recover(struct ata_channel *, int, int); #if NATAPIBUS > 0 void siisata_atapibus_attach(struct atabus_softc *); @@ -478,7 +476,6 @@ siisata_intr_port(struct siisata_channel struct ata_xfer *xfer; u_int slot; uint32_t pss, pis; - uint32_t prbfis; sc = (struct siisata_softc *)schp->ata_channel.ch_atac; chp = >ata_channel; @@ -489,12 +486,15 @@ siisata_intr_port(struct siisata_channel SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR); for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) { - if (((schp->sch_active_slots >> slot) & 1) == 0) + if (((schp->sch_active_slots >> slot) & 1) == 0) { /* there's nothing executing here, skip */ continue; - if (((pss >> slot) & 1) != 0) - /* execution is incomplete or unsuccessful, skip for now */ + } + if (((pss >> slot) & 1) != 0) { + /* execution is incomplete or unsuccessful, skip + * for now */ continue; + } xfer = ata_queue_hwslot_to_xfer(chp, slot); if (xfer->c_intr == NULL) { wakeup(schp); @@ -520,54 +520,145 @@ siisata_intr_port(struct siisata_channel SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc), __func__, chp->ch_channel, pis), DEBUG_INTR); + /* clear */ + PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis); + if (pis & PR_PIS_CMDERRR) { uint32_t ec; - uint32_t ps; - ps = PRREAD(sc, PRX(chp->ch_channel, PRO_PS)); ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)); SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR); - slot = PR_PS_ACTIVE_SLOT(ps); /* XXX invalid for NCQ? */ - /* emulate a CRC error by default */ - chp->ch_status = WDCS_ERR; - chp->ch_error = WDCE_CRC; + int tfd = ATACH_ERR_ST(WDCE_CRC, WDCS_ERR); - if (ec <= PR_PCE_DATAFISERROR) { - if (ec == PR_PCE_DEVICEERROR) { -/* read in specific information about error */ -prbfis = bus_space_read_stream_4( -sc->sc_prt, sc->sc_prh, - PRSX(chp->ch_channel, slot, -PRSO_FIS)); -/* set ch_status and ch_error */ -satafis_rdh_parse(chp, (uint8_t *)); - } -
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: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/usb
Module Name:src Committed By: jdolecek Date: Sun Jul 16 21:41:47 UTC 2017 Modified Files: src/sys/dev/usb [jdolecek-ncq]: umass_isdata.c Log Message: fix comment To generate a diff of this commit: cvs rdiff -u -r1.33.4.6 -r1.33.4.7 src/sys/dev/usb/umass_isdata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/usb/umass_isdata.c diff -u src/sys/dev/usb/umass_isdata.c:1.33.4.6 src/sys/dev/usb/umass_isdata.c:1.33.4.7 --- src/sys/dev/usb/umass_isdata.c:1.33.4.6 Sat Jun 24 00:23:39 2017 +++ src/sys/dev/usb/umass_isdata.c Sun Jul 16 21:41:47 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.33.4.7 2017/07/16 21:41:47 jdolecek Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.7 2017/07/16 21:41:47 jdolecek Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -556,7 +556,7 @@ uisdata_get_params(struct ata_drive_data xfer->c_ata_c.data = tb; xfer->c_ata_c.bcount = DEV_BSIZE; if (uisdata_exec_command(drvp, xfer) != ATACMD_COMPLETE) { - DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n")); + DPRINTF(("uisdata_get_parms: uisdata_exec_command failed\n")); rv = CMD_AGAIN; goto out; }
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 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/ic
Module Name:src Committed By: jdolecek Date: Wed Jun 28 19:59:36 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: enable ATAPI on mvsata(4); it seems to work fine for my cdrom To generate a diff of this commit: cvs rdiff -u -r1.35.6.17 -r1.35.6.18 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.17 src/sys/dev/ic/mvsata.c:1.35.6.18 --- src/sys/dev/ic/mvsata.c:1.35.6.17 Tue Jun 27 18:36:03 2017 +++ src/sys/dev/ic/mvsata.c Wed Jun 28 19:59:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.17 2017/06/27 18:36:03 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.17 2017/06/27 18:36:03 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.18 2017/06/28 19:59:36 jdolecek Exp $"); #include "opt_mvsata.h" @@ -760,10 +760,8 @@ mvsata_atapibus_attach(struct atabus_sof chan->chan_ntargets = 1; chan->chan_nluns = 1; -#if 0 /* XXX ATAPI implementation not finished. */ chp->atapibus = config_found_ia(ata_sc->sc_dev, "atapi", chan, atapiprint); -#endif } static void
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/ic
Module Name:src Committed By: jdolecek Date: Tue Jun 27 20:13:56 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: need to explicitely call siisata_timeout() also for polled bio command when it times out to clean up; this should avoid the 'polled command has been queued' panic from wddump() To generate a diff of this commit: cvs rdiff -u -r1.30.4.24 -r1.30.4.25 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.24 src/sys/dev/ic/siisata.c:1.30.4.25 --- src/sys/dev/ic/siisata.c:1.30.4.24 Tue Jun 27 18:36:04 2017 +++ src/sys/dev/ic/siisata.c Tue Jun 27 20:13:56 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.24 2017/06/27 18:36:04 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.24 2017/06/27 18:36:04 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.25 2017/06/27 20:13:56 jdolecek Exp $"); #include #include @@ -1169,6 +1169,10 @@ siisata_bio_start(struct ata_channel *ch DELAY(100); } + if ((ata_bio->flags & ATA_ITSDONE) == 0) { + siisata_timeout(xfer); + } + siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT(("%s: %s: done\n",
CVS commit: [jdolecek-ncq] src/sys/dev
Module Name:src Committed By: jdolecek Date: Tue Jun 27 18:36:04 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c ata_wdc.c atavar.h src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c Log Message: attend error paths, more strict asserts and code consistency - atastart() and ata_kill_pending() now KASSERT() that all xfers on queue have same channel - inactive xfers are killed via new reason KILL_GONE_INACTIVE, controller code must not call any resource deactivation in that case - c_intr() must call ata_waitdrain_xfer_check() as first thing, and must not further touch any xfer structures on exit path; any resource cleanup is supposed to be done in c_kill_xfer() - c_kill_xfer() should never call atastart() - ata_waitdrain_check() removed, replaced by ata_waitdrain_xfer_check() - ATA_DRIVE_WAITDRAIN handling converted to use condvar - removed unused ata_c callback To generate a diff of this commit: cvs rdiff -u -r1.132.8.17 -r1.132.8.18 src/sys/dev/ata/ata.c cvs rdiff -u -r1.105.6.5 -r1.105.6.6 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.92.8.15 -r1.92.8.16 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.57.6.16 -r1.57.6.17 src/sys/dev/ic/ahcisata_core.c cvs rdiff -u -r1.35.6.16 -r1.35.6.17 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.30.4.23 -r1.30.4.24 src/sys/dev/ic/siisata.c cvs rdiff -u -r1.283.2.9 -r1.283.2.10 src/sys/dev/ic/wdc.c cvs rdiff -u -r1.123.4.8 -r1.123.4.9 src/sys/dev/scsipi/atapi_wdc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.17 src/sys/dev/ata/ata.c:1.132.8.18 --- src/sys/dev/ata/ata.c:1.132.8.17 Sat Jun 24 14:57:17 2017 +++ src/sys/dev/ata/ata.c Tue Jun 27 18:36:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.17 2017/06/24 14:57:17 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.18 2017/06/27 18:36:03 jdolecek Exp $"); #include "opt_ata.h" @@ -275,6 +275,7 @@ ata_queue_alloc(uint8_t openings) ata_queue_reset(chq); cv_init(>queue_busy, "ataqbusy"); + cv_init(>queue_drain, "atdrn"); for (uint8_t i = 0; i < openings; i++) ata_xfer_init(>queue_xfers[i], false); @@ -288,6 +289,9 @@ ata_queue_free(struct ata_queue *chq) for (uint8_t i = 0; i < chq->queue_openings; i++) ata_xfer_destroy(>queue_xfers[i]); + cv_destroy(>queue_busy); + cv_destroy(>queue_drain); + free(chq, M_DEVBUF); } @@ -1140,6 +1144,9 @@ atastart(struct ata_channel *chp) if ((xfer = TAILQ_FIRST(>ch_queue->queue_xfer)) == NULL) goto out; + /* all xfers on same queue must belong to the same channel */ + KASSERT(xfer->c_chp == chp); + /* * Can only take NCQ command if there are no current active * commands, or if the active commands are NCQ. Need only check @@ -1149,10 +1156,6 @@ atastart(struct ata_channel *chp) if (axfer && (axfer->c_flags & C_NCQ) == 0) goto out; - /* adjust chp, in case we have a shared queue */ - chp = xfer->c_chp; - KASSERT(chp->ch_queue == chq); - struct ata_drive_datas * const drvp = >ch_drive[xfer->c_drive]; /* @@ -1322,29 +1325,37 @@ ata_deactivate_xfer(struct ata_channel * mutex_exit(>ch_lock); } - -bool -ata_waitdrain_check(struct ata_channel *chp, int drive) -{ - if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { - chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; - wakeup(>ch_queue->active_xfers); - return true; - } - return false; -} - +/* + * Called in c_intr hook. Must be called before before any deactivations + * are done - if there is drain pending, it calls c_kill_xfer hook which + * deactivates the xfer. + * Calls c_kill_xfer with channel lock free. + * Returns true if caller should just exit without further processing. + * Caller must not further access any part of xfer or any related controller + * structures in that case, it should just return. + */ bool ata_waitdrain_xfer_check(struct ata_channel *chp, struct ata_xfer *xfer) { int drive = xfer->c_drive; + bool draining = false; + + mutex_enter(>ch_lock); + if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { + mutex_exit(>ch_lock); + (*xfer->c_kill_xfer)(chp, xfer, KILL_GONE); + + mutex_enter(>ch_lock); chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; - wakeup(>ch_queue->active_xfers); - return true; + cv_signal(>ch_queue->queue_drain); + draining = true; } - return false; + + mutex_exit(>ch_lock); + + return draining; } /* @@ -1367,38 +1378,58 @@ ata_kill_active(struct ata_channel *chp, } /* - * Kill off all pending xfers for a ata_channel. - * - * Must be
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/ic
Module Name:src Committed By: jdolecek Date: Mon Jun 26 20:36:14 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: when reducing DELAY(), it's necessary to appropriately increase number of iteration, or command can timeout too soon adjust also siisata_atapi_start() to use DELAY(100) for the polled command, mostly for consistency, ATAPI devices are quite slow so likely won't have real effect To generate a diff of this commit: cvs rdiff -u -r1.30.4.22 -r1.30.4.23 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.22 src/sys/dev/ic/siisata.c:1.30.4.23 --- src/sys/dev/ic/siisata.c:1.30.4.22 Sat Jun 24 11:34:33 2017 +++ src/sys/dev/ic/siisata.c Mon Jun 26 20:36:14 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.23 2017/06/26 20:36:14 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.23 2017/06/26 20:36:14 jdolecek Exp $"); #include #include @@ -944,7 +944,7 @@ siisata_cmd_start(struct ata_channel *ch /* * polled command */ - for (i = 0; i < ata_c->timeout / 10; i++) { + for (i = 0; i < ata_c->timeout * 10; i++) { if (ata_c->flags & AT_DONE) break; siisata_intr_port(schp); @@ -1148,7 +1148,7 @@ siisata_bio_start(struct ata_channel *ch /* * polled command */ - for (i = 0; i < ATA_DELAY / 10; i++) { + for (i = 0; i < ATA_DELAY * 10; i++) { if (ata_bio->flags & ATA_ITSDONE) break; siisata_intr_port(schp); @@ -1693,11 +1693,11 @@ siisata_atapi_start(struct ata_channel * /* * polled command */ - for (i = 0; i < ATA_DELAY / 10; i++) { + for (i = 0; i < ATA_DELAY * 10; i++) { if (sc_xfer->xs_status & XS_STS_DONE) break; siisata_intr_port(schp); - DELAY(1000); + DELAY(100); } if ((sc_xfer->xs_status & XS_STS_DONE) == 0) { siisata_timeout(xfer);
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jun 24 14:59:10 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: mvsata.c Log Message: fix confusion around AT_WAIT vs AT_POLL for mvsata_edma_disable(), and switch all the tsleep()/delay() ifs to just use ata_delay() To generate a diff of this commit: cvs rdiff -u -r1.35.6.15 -r1.35.6.16 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.15 src/sys/dev/ic/mvsata.c:1.35.6.16 --- src/sys/dev/ic/mvsata.c:1.35.6.15 Sat Jun 24 14:33:06 2017 +++ src/sys/dev/ic/mvsata.c Sat Jun 24 14:59:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.16 2017/06/24 14:59:10 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.16 2017/06/24 14:59:10 jdolecek Exp $"); #include "opt_mvsata.h" @@ -1081,7 +1081,7 @@ mvsata_bio_start(struct ata_channel *chp struct wdc_softc *wdc = CHAN_TO_WDC(chp); struct ata_bio *ata_bio = >c_bio; struct ata_drive_datas *drvp = >ch_drive[xfer->c_drive]; - int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; + int wait_flags = ata_bio->flags & AT_WAIT; u_int16_t cyl; u_int8_t head, sect, cmd = 0; int nblks, error; @@ -3206,10 +3206,10 @@ mvsata_reset_hc(struct mvsata_hc *mvhc) #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY) static uint32_t -mvsata_softreset(struct mvsata_port *mvport, int waitok) +mvsata_softreset(struct mvsata_port *mvport, int flags) { uint32_t sig0 = ~0; - int timeout, nloop; + int timeout; uint8_t st0; MVSATA_WDC_WRITE_1(mvport, SRB_CAS, WDCTL_RST | WDCTL_IDS | WDCTL_4BIT); @@ -3218,13 +3218,8 @@ mvsata_softreset(struct mvsata_port *mvp MVSATA_WDC_WRITE_1(mvport, SRB_CAS, WDCTL_IDS | WDCTL_4BIT); delay(10); - if (!waitok) - nloop = WDCNDELAY_RST; - else - nloop = WDC_RESET_WAIT * hz / 1000; - /* wait for BSY to deassert */ - for (timeout = 0; timeout < nloop; timeout++) { + for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) { st0 = MVSATA_WDC_READ_1(mvport, SRB_CS); if ((st0 & WDCS_BSY) == 0) { @@ -3234,10 +3229,7 @@ mvsata_softreset(struct mvsata_port *mvp sig0 |= MVSATA_WDC_READ_1(mvport, SRB_LBAH) << 24; goto out; } - if (!waitok) - delay(WDCDELAY); - else - tsleep(, PRIBIO, "atarst", 1); + ata_delay(WDCDELAY, "atarst", flags); } out: @@ -3270,7 +3262,7 @@ mvsata_edma_enable(struct mvsata_port *m } static int -mvsata_edma_disable(struct mvsata_port *mvport, int timeout, int waitok) +mvsata_edma_disable(struct mvsata_port *mvport, int timeout, int wflags) { uint32_t status, command; int ms; @@ -3280,11 +3272,7 @@ mvsata_edma_disable(struct mvsata_port * status = MVSATA_EDMA_READ_4(mvport, EDMA_S); if (status & EDMA_S_EDMAIDLE) break; - if (waitok) -tsleep(, PRIBIO, "mvsata_edma1", -mstohz(1)); - else -delay(1000); + ata_delay(1, "mvsata_edma1", wflags); } if (ms == timeout) { aprint_error("%s:%d:%d: unable to disable EDMA\n", @@ -3300,11 +3288,7 @@ mvsata_edma_disable(struct mvsata_port * command = MVSATA_EDMA_READ_4(mvport, EDMA_CMD); if (!(command & EDMA_CMD_EENEDMA)) break; - if (waitok) -tsleep(, PRIBIO, "mvsata_edma2", -mstohz(1)); - else -delay(1000); + ata_delay(1, "mvsata_edma2", wflags); } if (ms == timeout) { aprint_error("%s:%d:%d: unable to re-enable EDMA\n",
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
Module Name:src Committed By: jdolecek Date: Sat Jun 24 14:33:06 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq src/sys/dev/ic [jdolecek-ncq]: mvsata.c mvsatavar.h Log Message: fix dump on mvsata - there was misplaced mvsata_bio_intr() call causing diagnostic panic, and we also need to switch controller to appropriate DMA mode (NCQ vs. non-NCQ DMA) while here, also reduce delay for the polled command wait to 100 us, same as siisata(4) and ahcisata(4) To generate a diff of this commit: cvs rdiff -u -r1.1.2.25 -r1.1.2.26 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.35.6.14 -r1.35.6.15 src/sys/dev/ic/mvsata.c cvs rdiff -u -r1.2.48.1 -r1.2.48.2 src/sys/dev/ic/mvsatavar.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.25 src/sys/dev/ata/TODO.ncq:1.1.2.26 --- src/sys/dev/ata/TODO.ncq:1.1.2.25 Sat Jun 24 00:23:39 2017 +++ src/sys/dev/ata/TODO.ncq Sat Jun 24 14:33:06 2017 @@ -1,9 +1,6 @@ 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 test wd* at umass?, confirm the ata_channel kludge works Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.35.6.14 src/sys/dev/ic/mvsata.c:1.35.6.15 --- src/sys/dev/ic/mvsata.c:1.35.6.14 Wed Jun 21 19:38:43 2017 +++ src/sys/dev/ic/mvsata.c Sat Jun 24 14:33:06 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.35.6.14 2017/06/21 19:38:43 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.14 2017/06/21 19:38:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.15 2017/06/24 14:33:06 jdolecek Exp $"); #include "opt_mvsata.h" @@ -182,7 +182,7 @@ static uint32_t mvsata_softreset(struct static void mvsata_edma_reset_qptr(struct mvsata_port *); static inline void mvsata_edma_enable(struct mvsata_port *); static int mvsata_edma_disable(struct mvsata_port *, int, int); -static void mvsata_edma_config(struct mvsata_port *, int); +static void mvsata_edma_config(struct mvsata_port *, enum mvsata_edmamode); static void mvsata_edma_setup_crqb(struct mvsata_port *, int, struct ata_xfer *); @@ -501,7 +501,7 @@ mvsata_error(struct mvsata_port *mvport) #ifndef MVSATA_WITHOUTDMA if ((sc->sc_gen == gen1 && cause & EDMA_IE_ETRANSINT) || (sc->sc_gen != gen1 && cause & EDMA_IE_ESELFDIS)) { - switch (mvport->port_edmamode) { + switch (mvport->port_edmamode_curr) { case dma: case queued: case ncq: @@ -653,7 +653,7 @@ mvsata_reset_channel(struct ata_channel ata_kill_active(chp, KILL_RESET, flags); - mvsata_edma_config(mvport, mvport->port_edmamode); + mvsata_edma_config(mvport, mvport->port_edmamode_curr); mvsata_edma_reset_qptr(mvport); mvsata_edma_enable(mvport); return; @@ -1093,7 +1093,6 @@ mvsata_bio_start(struct ata_channel *chp if (drvp->n_xfers <= NXFER) drvp->n_xfers++; -again: /* * * When starting a multi-sector transfer, or doing single-sector @@ -1129,9 +1128,16 @@ again: /* Transfer is okay now. */ } if (xfer->c_flags & C_DMA) { + enum mvsata_edmamode dmamode; + ata_bio->nblks = nblks; ata_bio->nbytes = xfer->c_bcount; + /* switch to appropriate dma mode if necessary */ + dmamode = (xfer->c_flags & C_NCQ) ? ncq : dma; + if (mvport->port_edmamode_curr != dmamode) +mvsata_edma_config(mvport, dmamode); + if (xfer->c_flags & C_POLL) sc->sc_enable_intr(mvport, 0 /*off*/); error = mvsata_edma_enqueue(mvport, xfer); @@ -1201,7 +1207,7 @@ do_pio: WDCC_READ : WDCC_WRITE; /* EDMA disable, if enabled this channel. */ - if (mvport->port_edmamode != nodma) + if (mvport->port_edmamode_curr != nodma) mvsata_edma_disable(mvport, 10 /* ms */, wait_flags); mvsata_pmp_select(mvport, xfer->c_drive); @@ -1300,9 +1306,8 @@ intr: sc->sc_enable_intr(mvport, 1 /*on*/); chp->ch_flags &= ~ATACH_DMA_WAIT; } - mvsata_bio_intr(chp, xfer, 0); if ((ata_bio->flags & ATA_ITSDONE) == 0) - goto again; + mvsata_bio_intr(chp, xfer, 0); } return; @@ -1421,7 +1426,7 @@ mvsata_bio_kill_xfer(struct ata_channel device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive)); /* EDMA restart, if enabled */ - if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode != nodma) { + if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode_curr != nodma) { mvsata_edma_reset_qptr(mvport); mvsata_edma_enable(mvport); } @@ -1460,7 +1465,7 @@ mvsata_bio_done(struct ata_channel *chp, callout_stop(>c_timo_callout); /* EDMA restart, if enabled */ - if (!(xfer->c_flags & C_DMA) && mvport->port_edmamode !=
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Sat Jun 24 11:34:33 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: reduce the polling interval also for siisata_cmd_start() To generate a diff of this commit: cvs rdiff -u -r1.30.4.21 -r1.30.4.22 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.21 src/sys/dev/ic/siisata.c:1.30.4.22 --- src/sys/dev/ic/siisata.c:1.30.4.21 Fri Jun 23 23:49:20 2017 +++ src/sys/dev/ic/siisata.c Sat Jun 24 11:34:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.22 2017/06/24 11:34:33 jdolecek Exp $"); #include #include @@ -948,7 +948,7 @@ siisata_cmd_start(struct ata_channel *ch if (ata_c->flags & AT_DONE) break; siisata_intr_port(schp); - DELAY(1000); + DELAY(100); } if ((ata_c->flags & AT_DONE) == 0) {
CVS commit: [jdolecek-ncq] src/sys/dev
Module Name:src Committed By: jdolecek Date: Sat Jun 24 00:23:39 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq src/sys/dev/usb [jdolecek-ncq]: umass.c umass_isdata.c umass_isdata.h Log Message: add detach code for umass_isdata; compile-tested only To generate a diff of this commit: cvs rdiff -u -r1.1.2.24 -r1.1.2.25 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.157 -r1.157.4.1 src/sys/dev/usb/umass.c cvs rdiff -u -r1.33.4.5 -r1.33.4.6 src/sys/dev/usb/umass_isdata.c cvs rdiff -u -r1.3 -r1.3.6.1 src/sys/dev/usb/umass_isdata.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.24 src/sys/dev/ata/TODO.ncq:1.1.2.25 --- src/sys/dev/ata/TODO.ncq:1.1.2.24 Sat Jun 24 00:00:10 2017 +++ src/sys/dev/ata/TODO.ncq Sat Jun 24 00:23:39 2017 @@ -7,7 +7,6 @@ fix crashdump for mvsata - request times siisata - fix all new XXX and unmergable bits test wd* at umass?, confirm the ata_channel kludge works -+ add detach code (channel detach, free queue) test device error handling (currently appears to not work well, at least in NCQ case) Index: src/sys/dev/usb/umass.c diff -u src/sys/dev/usb/umass.c:1.157 src/sys/dev/usb/umass.c:1.157.4.1 --- src/sys/dev/usb/umass.c:1.157 Mon Nov 21 08:27:30 2016 +++ src/sys/dev/usb/umass.c Sat Jun 24 00:23:39 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: umass.c,v 1.157 2016/11/21 08:27:30 skrll Exp $ */ +/* $NetBSD: umass.c,v 1.157.4.1 2017/06/24 00:23:39 jdolecek Exp $ */ /* * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -124,7 +124,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.157 2016/11/21 08:27:30 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.157.4.1 2017/06/24 00:23:39 jdolecek Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -819,6 +819,21 @@ umass_detach(device_t self, int flags) if (scbus != NULL) { if (scbus->sc_child != NULL) rv = config_detach(scbus->sc_child, flags); + + switch (sc->sc_cmd) { + case UMASS_CPROTO_ISD_ATA: +#if NWD > 0 + umass_isdata_detach(sc); +#else + aprint_error_dev(self, "isdata not configured\n"); +#endif + break; + + default: + /* nothing to do */ + break; + } + free(scbus, M_DEVBUF); sc->bus = NULL; } Index: src/sys/dev/usb/umass_isdata.c diff -u src/sys/dev/usb/umass_isdata.c:1.33.4.5 src/sys/dev/usb/umass_isdata.c:1.33.4.6 --- src/sys/dev/usb/umass_isdata.c:1.33.4.5 Wed Jun 21 19:38:43 2017 +++ src/sys/dev/usb/umass_isdata.c Sat Jun 24 00:23:39 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.c,v 1.33.4.5 2017/06/21 19:38:43 jdolecek Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.5 2017/06/21 19:38:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.6 2017/06/24 00:23:39 jdolecek Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -233,6 +233,16 @@ umass_isdata_attach(struct umass_softc * return 0; } +void +umass_isdata_detach(struct umass_softc *sc) +{ + struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus; + + ata_queue_free(scbus->sc_channel.ch_queue); + scbus->sc_channel.ch_queue = NULL; + + ata_channel_destroy(>sc_channel); +} void uisdata_bio_cb(struct umass_softc *sc, void *priv, int residue, int status) Index: src/sys/dev/usb/umass_isdata.h diff -u src/sys/dev/usb/umass_isdata.h:1.3 src/sys/dev/usb/umass_isdata.h:1.3.6.1 --- src/sys/dev/usb/umass_isdata.h:1.3 Sat Apr 23 10:15:32 2016 +++ src/sys/dev/usb/umass_isdata.h Sat Jun 24 00:23:39 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.h,v 1.3 2016/04/23 10:15:32 skrll Exp $ */ +/* $NetBSD: umass_isdata.h,v 1.3.6.1 2017/06/24 00:23:39 jdolecek Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -31,3 +31,4 @@ */ int umass_isdata_attach(struct umass_softc *); +void umass_isdata_detach(struct umass_softc *);
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
Module Name:src Committed By: jdolecek Date: Fri Jun 23 23:49:20 UTC 2017 Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: fix dump for siisata(4) to work - need to call drv_done() callback in order to not leak xfers while here, reduce the DELAY() for polled bio to make it go much faster, same value as used in ahcisata(4) needs also rev. 1.252 src/sys/arch/x86/x86/pmap.c to not trigger the assertion, the pmap.c fix committed only on HEAD To generate a diff of this commit: cvs rdiff -u -r1.1.2.22 -r1.1.2.23 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.30.4.20 -r1.30.4.21 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.22 src/sys/dev/ata/TODO.ncq:1.1.2.23 --- src/sys/dev/ata/TODO.ncq:1.1.2.22 Fri Jun 23 20:40:51 2017 +++ src/sys/dev/ata/TODO.ncq Fri Jun 23 23:49:20 2017 @@ -6,12 +6,6 @@ fix crashdump for mvsata - request times 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 (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) @@ -31,6 +25,8 @@ not non-FIS Other random notes (do outside the NCQ branch): - +queue is allocated regardless if there are any drives, fix? + change wd(4) to use dksubr dump to unopened disk fails (e.g. dump do wd1b when wd1a not mounted), due Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.20 src/sys/dev/ic/siisata.c:1.30.4.21 --- src/sys/dev/ic/siisata.c:1.30.4.20 Fri Jun 23 23:45:56 2017 +++ src/sys/dev/ic/siisata.c Fri Jun 23 23:49:20 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.21 2017/06/23 23:49:20 jdolecek Exp $"); #include #include
CVS commit: [jdolecek-ncq] src/sys/dev/ic
Module Name:src Committed By: jdolecek Date: Fri Jun 23 23:45:56 UTC 2017 Modified Files: src/sys/dev/ic [jdolecek-ncq]: siisata.c Log Message: ata/TODO.ncq To generate a diff of this commit: cvs rdiff -u -r1.30.4.19 -r1.30.4.20 src/sys/dev/ic/siisata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/dev/ic/siisata.c diff -u src/sys/dev/ic/siisata.c:1.30.4.19 src/sys/dev/ic/siisata.c:1.30.4.20 --- src/sys/dev/ic/siisata.c:1.30.4.19 Wed Jun 21 19:38:43 2017 +++ src/sys/dev/ic/siisata.c Fri Jun 23 23:45:56 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.30.4.19 2017/06/21 19:38:43 jdolecek Exp $ */ +/* $NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.19 2017/06/21 19:38:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.20 2017/06/23 23:45:56 jdolecek Exp $"); #include #include @@ -590,6 +590,7 @@ siisata_reset_drive(struct ata_drive_dat */ xfer = ata_get_xfer_ext(chp, false, 0); if (xfer == NULL) { + printf("%s: no xfer\n", __func__); siisata_reset_channel(chp, flags); return; } @@ -1151,7 +1152,7 @@ siisata_bio_start(struct ata_channel *ch if (ata_bio->flags & ATA_ITSDONE) break; siisata_intr_port(schp); - DELAY(1000); + DELAY(100); } siisata_enable_port_interrupt(chp); @@ -1245,8 +1246,6 @@ siisata_bio_complete(struct ata_channel ata_bio->bcount = 0; } SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); - if (ata_bio->flags & ATA_POLL) - return 1; (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); atastart(chp); return 0;