Module Name: src Committed By: jdolecek Date: Sun Oct 14 14:50:55 UTC 2018
Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: TODO.ncq src/sys/dev/ic [jdolecek-ncqfixes]: mvsata.c Log Message: adjust mvsata_bio_intr() so it recognizes the 'tfd' parameter as passed by recovery and hence works; use it also for passing state from mvsata_edma_handle() To generate a diff of this commit: cvs rdiff -u -r1.4.2.13 -r1.4.2.14 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.41.2.9 -r1.41.2.10 src/sys/dev/ic/mvsata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.4.2.13 src/sys/dev/ata/TODO.ncq:1.4.2.14 --- src/sys/dev/ata/TODO.ncq:1.4.2.13 Thu Oct 11 20:57:51 2018 +++ src/sys/dev/ata/TODO.ncq Sun Oct 14 14:50:54 2018 @@ -4,8 +4,6 @@ jdolecek-ncqfixes goals: - run recovery via atathread, move to new function and share ahci/siisata/mvsata - maybe do device error handling in not-interrupt-context (maybe this should be done on a mpata branch?) -- adjust mvsata() intr code to accept tfd (instead of irq 0/1) so that - ata_recovery_resume() works properly for it Bugs ---- Index: src/sys/dev/ic/mvsata.c diff -u src/sys/dev/ic/mvsata.c:1.41.2.9 src/sys/dev/ic/mvsata.c:1.41.2.10 --- src/sys/dev/ic/mvsata.c:1.41.2.9 Sat Oct 13 09:31:46 2018 +++ src/sys/dev/ic/mvsata.c Sun Oct 14 14:50:55 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.41.2.9 2018/10/13 09:31:46 jdolecek Exp $ */ +/* $NetBSD: mvsata.c,v 1.41.2.10 2018/10/14 14:50:55 jdolecek Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.9 2018/10/13 09:31:46 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.41.2.10 2018/10/14 14:50:55 jdolecek Exp $"); #include "opt_mvsata.h" @@ -549,7 +549,7 @@ static void mvsata_channel_recover(struct mvsata_port *mvport) { struct ata_channel *chp = &mvport->port_ata_channel; - int drive, tfd = 1; + int drive, tfd = ATACH_ERR_ST(0, WDCS_ERR); ata_channel_lock(chp); KASSERT(!ISSET(chp->ch_flags, ATACH_RECOVERING)); @@ -571,16 +571,6 @@ mvsata_channel_recover(struct mvsata_por * as if nothing happened. */ -#if 0 - XXX recheck - mvsata used to have this to handle the successful - recovery via read_log_ext: - - xfer = ata_queue_hwslot_to_xfer(chp, eslot); - xfer->c_flags |= C_RECOVERED; - xfer->c_bio.error = ERROR; - xfer->c_bio.r_error = err; - xfer->ops->c_intr(chp, xfer, 1); -#endif ata_recovery_resume(chp, drive, tfd, AT_POLL); /* Drive unblocked, back to normal operation */ @@ -1244,6 +1234,11 @@ do_pio: } intr: + KASSERTMSG(((xfer->c_flags & C_DMA) != 0) + == (mvport->port_edmamode_curr != nodma), + "DMA mode mismatch: flags %x vs edmamode %d != %d", + xfer->c_flags, mvport->port_edmamode_curr, nodma); + /* Wait for IRQ (either real or polled) */ if ((ata_bio->flags & ATA_POLL) != 0) return ATASTART_POLL; @@ -1279,20 +1274,35 @@ mvsata_bio_poll(struct ata_channel *chp, } static int -mvsata_bio_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq) +mvsata_bio_intr(struct ata_channel *chp, struct ata_xfer *xfer, int intr_arg) { struct atac_softc *atac = chp->ch_atac; struct wdc_softc *wdc = CHAN_TO_WDC(chp); struct ata_bio *ata_bio = &xfer->c_bio; struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; - int tfd; + int irq = ISSET(xfer->c_flags, (C_POLL|C_TIMEOU)) ? 0 : 1; + int tfd = 0; + + if (ISSET(xfer->c_flags, C_DMA|C_RECOVERED) && irq) { + /* Invoked via mvsata_edma_handle() or recovery */ + tfd = intr_arg; + + if (tfd > 0 && ata_bio->error == NOERROR) { + if (ATACH_ST(tfd) & WDCS_ERR) + ata_bio->error = ERROR; + if (ATACH_ST(tfd) & WDCS_BSY) + ata_bio->error = TIMEOUT; + ata_bio->r_error = ATACH_ERR(tfd); + } + } DPRINTF(DEBUG_FUNCS|DEBUG_XFERS, ("%s:%d: %s: drive=%d\n", device_xname(atac->atac_dev), chp->ch_channel, __func__, xfer->c_drive)); - if (xfer->c_flags & C_TIMEOU && !irq) { - /* Cleanup EDMA if invoked from timeout handler */ + /* Cleanup EDMA if invoked from wdctimeout()/ata_timeout() */ + if (ISSET(xfer->c_flags, C_TIMEOU) && ISSET(xfer->c_flags, C_DMA) + && !ISSET(xfer->c_flags, C_POLL)) { mvsata_edma_rqq_remove((struct mvsata_port *)chp, xfer); } @@ -2814,17 +2824,14 @@ mvsata_edma_handle(struct mvsata_port *m ata_bio = &xfer->c_bio; ata_bio->error = NOERROR; - ata_bio->r_error = 0; - if (st & WDCS_ERR) - ata_bio->error = ERROR; - if (st & WDCS_BSY) - ata_bio->error = TIMEOUT; if (dmaerr != 0) ata_bio->error = ERR_DMA; mvsata_dma_bufunload(mvport, quetag, ata_bio->flags); - mvsata_bio_intr(chp, xfer, 1); + KASSERT(xfer->c_flags & C_DMA); + mvsata_bio_intr(chp, xfer, ATACH_ERR_ST(0, st)); + if (xfer1 == NULL) handled++; else if (xfer == xfer1) {