Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jdolecek-ncqfixes]: src/sys/dev adjust mvsata_bio_intr() so it recognize...
details: https://anonhg.NetBSD.org/src/rev/274c802c83f1
branches: jdolecek-ncqfixes
changeset: 1025100:274c802c83f1
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Oct 14 14:50:54 2018 +0000
description:
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()
diffstat:
sys/dev/ata/TODO.ncq | 2 -
sys/dev/ic/mvsata.c | 53 +++++++++++++++++++++++++++++----------------------
2 files changed, 30 insertions(+), 25 deletions(-)
diffs (129 lines):
diff -r 3ca6fb42d122 -r 274c802c83f1 sys/dev/ata/TODO.ncq
--- a/sys/dev/ata/TODO.ncq Sat Oct 13 09:31:46 2018 +0000
+++ b/sys/dev/ata/TODO.ncq Sun Oct 14 14:50:54 2018 +0000
@@ -4,8 +4,6 @@
- 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
----
diff -r 3ca6fb42d122 -r 274c802c83f1 sys/dev/ic/mvsata.c
--- a/sys/dev/ic/mvsata.c Sat Oct 13 09:31:46 2018 +0000
+++ b/sys/dev/ic/mvsata.c Sun Oct 14 14:50:54 2018 +0000
@@ -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 @@
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 @@
* 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 @@
}
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 @@
}
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 @@
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) {
Home |
Main Index |
Thread Index |
Old Index