Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Cancel active transfers on aic/wdc detach.
details: https://anonhg.NetBSD.org/src/rev/11b462d963e4
branches: trunk
changeset: 477543:11b462d963e4
user: enami <enami%NetBSD.org@localhost>
date: Wed Oct 20 15:22:24 1999 +0000
description:
Cancel active transfers on aic/wdc detach.
Also makes LS-120 drive works for me again.
diffstat:
sys/dev/ata/ata_wdc.c | 34 ++++++++++++++++++++++++++++-
sys/dev/ata/atavar.h | 3 +-
sys/dev/ata/wd.c | 7 +++++-
sys/dev/ata/wdvar.h | 3 +-
sys/dev/ic/aic6360.c | 23 ++++++++++++++++++-
sys/dev/ic/aic6360var.h | 6 ++--
sys/dev/ic/wdc.c | 30 +++++++++++++++++++++++--
sys/dev/ic/wdcvar.h | 5 +++-
sys/dev/pcmcia/aic_pcmcia.c | 51 +++++++++++++------------------------------
sys/dev/pcmcia/wdc_pcmcia.c | 25 +++++++++++----------
sys/dev/scsipi/atapi_wdc.c | 35 +++++++++++++++++++++++++++++-
sys/dev/scsipi/atapiconf.c | 3 +-
sys/dev/scsipi/atapiconf.h | 3 +-
sys/dev/scsipi/scsi_base.c | 20 ++++++++++++++++-
sys/dev/scsipi/scsiconf.c | 3 +-
sys/dev/scsipi/scsiconf.h | 3 +-
sys/dev/scsipi/scsipi_base.c | 15 ++++++------
sys/dev/scsipi/scsipiconf.h | 3 +-
18 files changed, 197 insertions(+), 75 deletions(-)
diffs (truncated from 680 to 300 lines):
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ata/ata_wdc.c
--- a/sys/dev/ata/ata_wdc.c Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ata/ata_wdc.c Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $ */
+/* $NetBSD: ata_wdc.c,v 1.22 1999/10/20 15:22:24 enami Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@@ -119,6 +119,7 @@
void wdc_ata_bio_start __P((struct channel_softc *,struct wdc_xfer *));
void _wdc_ata_bio_start __P((struct channel_softc *,struct wdc_xfer *));
int wdc_ata_bio_intr __P((struct channel_softc *, struct wdc_xfer *, int));
+void wdc_ata_bio_kill_xfer __P((struct channel_softc *,struct wdc_xfer *));
void wdc_ata_bio_done __P((struct channel_softc *, struct wdc_xfer *));
int wdc_ata_ctrl_intr __P((struct channel_softc *, struct wdc_xfer *, int));
int wdc_ata_err __P((struct ata_drive_datas *, struct ata_bio *));
@@ -152,6 +153,7 @@
xfer->c_bcount = ata_bio->bcount;
xfer->c_start = wdc_ata_bio_start;
xfer->c_intr = wdc_ata_bio_intr;
+ xfer->c_kill_xfer = wdc_ata_bio_kill_xfer;
wdc_exec_xfer(chp, xfer);
return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED;
}
@@ -568,6 +570,36 @@
}
void
+wdc_ata_kill_pending(drvp)
+ struct ata_drive_datas *drvp;
+{
+ struct channel_softc *chp = drvp->chnl_softc;
+
+ wdc_kill_pending(chp);
+}
+
+void
+wdc_ata_bio_kill_xfer(chp, xfer)
+ struct channel_softc *chp;
+ struct wdc_xfer *xfer;
+{
+ struct ata_bio *ata_bio = xfer->cmd;
+ int drive = xfer->drive;
+
+ untimeout(wdctimeout, chp);
+ /* remove this command from xfer queue */
+ wdc_free_xfer(chp, xfer);
+
+ ata_bio->flags |= ATA_ITSDONE;
+ ata_bio->error = ERR_NODEV;
+ ata_bio->r_error = WDCE_ABRT;
+ if ((ata_bio->flags & ATA_POLL) == 0) {
+ WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
+ wddone(chp->ch_drive[drive].drv_softc);
+ }
+}
+
+void
wdc_ata_bio_done(chp, xfer)
struct channel_softc *chp;
struct wdc_xfer *xfer;
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ata/atavar.h
--- a/sys/dev/ata/atavar.h Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ata/atavar.h Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atavar.h,v 1.13 1999/03/10 13:11:43 bouyer Exp $ */
+/* $NetBSD: atavar.h,v 1.14 1999/10/20 15:22:25 enami Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@@ -153,6 +153,7 @@
int wdc_ata_addref __P((struct ata_drive_datas *));
void wdc_ata_delref __P((struct ata_drive_datas *));
+void wdc_ata_kill_pending __P((struct ata_drive_datas *));
struct ataparams;
int ata_get_params __P((struct ata_drive_datas*, u_int8_t,
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ata/wd.c Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.196 1999/09/23 11:04:29 enami Exp $ */
+/* $NetBSD: wd.c,v 1.197 1999/10/20 15:22:25 enami Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer. All rights reserved.
@@ -601,6 +601,11 @@
noerror: if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
printf("%s: soft error (corrected)\n",
wd->sc_dev.dv_xname);
+ break;
+ case ERR_NODEV:
+ bp->b_flags |= B_ERROR;
+ bp->b_error = EIO;
+ break;
}
disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid));
#if NRND > 0
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ata/wdvar.h
--- a/sys/dev/ata/wdvar.h Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ata/wdvar.h Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.3 1998/11/11 19:38:27 bouyer Exp $ */
+/* $NetBSD: wdvar.h,v 1.4 1999/10/20 15:22:25 enami Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@@ -57,6 +57,7 @@
#define ERR_DF 2 /* Drive fault */
#define ERR_DMA 3 /* DMA error */
#define TIMEOUT 4 /* device timed out */
+#define ERR_NODEV 5 /* device has been gone */
u_int8_t r_error; /* copy of error register */
daddr_t badsect[127]; /* 126 plus trailing -1 marker */
};
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ic/aic6360.c
--- a/sys/dev/ic/aic6360.c Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ic/aic6360.c Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aic6360.c,v 1.63 1999/09/30 23:04:40 thorpej Exp $ */
+/* $NetBSD: aic6360.c,v 1.64 1999/10/20 15:22:26 enami Exp $ */
#include "opt_ddb.h"
#ifdef DDB
@@ -311,8 +311,11 @@
break;
case DVACT_DEACTIVATE:
- if (sc->sc_child != NULL)
+ if (sc->sc_child != NULL && !sc->sc_dying) {
rv = config_deactivate(sc->sc_child);
+ if (rv == 0)
+ sc->sc_dying = 1;
+ }
break;
}
splx(s);
@@ -552,6 +555,16 @@
AIC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
sc_link->scsipi_scsi.target));
+ if (sc->sc_dying) {
+ xs->xs_status |= XS_STS_DONE;
+ xs->error = XS_DRIVER_STUFFUP;
+ scsipi_done(xs);
+ if ((xs->xs_control & XS_CTL_POLL) == 0)
+ return (SUCCESSFULLY_QUEUED);
+ else
+ return (COMPLETE);
+ }
+
flags = xs->xs_control;
if ((acb = aic_get_acb(sc, flags)) == NULL) {
xs->error = XS_DRIVER_STUFFUP;
@@ -790,6 +803,9 @@
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
+ if (sc->sc_dying)
+ return;
+
/*
* Find first acb in ready queue that is for a target/lunit pair that
* is not busy.
@@ -1699,6 +1715,9 @@
struct aic_tinfo *ti;
int n;
+ if (sc->sc_dying)
+ return (0);
+
/*
* Clear INTEN. We enable it again before returning. This makes the
* interrupt esssentially level-triggered.
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ic/aic6360var.h
--- a/sys/dev/ic/aic6360var.h Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ic/aic6360var.h Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aic6360var.h,v 1.4 1999/09/26 08:14:57 enami Exp $ */
+/* $NetBSD: aic6360var.h,v 1.5 1999/10/20 15:22:26 enami Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Charles M. Hannum. All rights reserved.
@@ -148,6 +148,8 @@
#define AIC_ABORTING 0x02 /* Bailing out */
#define AIC_DOINGDMA 0x04 /* The FIFO data path is active! */
u_char sc_selid; /* Reselection ID */
+ struct device *sc_child;/* Our child */
+ u_char sc_dying; /* true if device is going */
/* Message stuff */
u_char sc_msgpriq; /* Messages we want to send */
@@ -173,8 +175,6 @@
int sc_freq; /* Clock frequency in MHz */
int sc_minsync; /* Minimum sync period / 4 */
int sc_maxsync; /* Maximum sync period / 4 */
-
- struct device *sc_child; /* Our child */
};
#if AIC_DEBUG
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ic/wdc.c Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdc.c,v 1.74 1999/09/23 11:04:32 enami Exp $ */
+/* $NetBSD: wdc.c,v 1.75 1999/10/20 15:22:26 enami Exp $ */
/*
@@ -120,6 +120,7 @@
void __wdccommand_start __P((struct channel_softc *, struct wdc_xfer *));
int __wdccommand_intr __P((struct channel_softc *, struct wdc_xfer *, int));
int wdprint __P((void *, const char *));
+void wdc_kill_pending __P((struct channel_softc *));
#define DEBUG_INTR 0x01
@@ -473,6 +474,8 @@
break;
case DVACT_DEACTIVATE:
+ if (wdc->sc_dying != 0)
+ goto out;
for (i = 0; i < wdc->nchannels; i++) {
chp = wdc->channels[i];
@@ -503,6 +506,7 @@
}
}
}
+ wdc->sc_dying = 1;
break;
}
@@ -557,6 +561,8 @@
goto out;
}
}
+
+ wdc_kill_pending(chp);
}
out:
@@ -1169,6 +1175,7 @@
xfer->cmd = wdc_c;
xfer->c_start = __wdccommand_start;
xfer->c_intr = __wdccommand_intr;
+ xfer->c_kill_xfer = __wdccommand_done;
s = splbio();
wdc_exec_xfer(chp, xfer);
@@ -1292,8 +1299,8 @@
wdc_c->r_error = chp->ch_error;
}
wdc_c->flags |= AT_DONE;
- if (wdc_c->flags & AT_READREG && (wdc_c->flags & (AT_ERROR | AT_DF))
- == 0) {
+ if ((wdc_c->flags & AT_READREG) != 0 && chp->wdc->sc_dying != 0 &&
+ (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
wdc_c->r_head = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
wd_sdh);
wdc_c->r_cyl = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
@@ -1434,6 +1441,23 @@
splx(s);
}
+/*
+ * Kill off all pending xfers for a channel_softc.
+ *
+ * Must be called at splbio().
+ */
+void
+wdc_kill_pending(chp)
+ struct channel_softc *chp;
+{
+ struct wdc_xfer *xfer;
+
+ while ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) != NULL) {
+ chp = xfer->chp;
+ (*xfer->c_kill_xfer)(chp, xfer);
+ }
+}
+
static void
__wdcerror(chp, msg)
struct channel_softc *chp;
diff -r 22252054c79d -r 11b462d963e4 sys/dev/ic/wdcvar.h
--- a/sys/dev/ic/wdcvar.h Wed Oct 20 15:09:58 1999 +0000
+++ b/sys/dev/ic/wdcvar.h Wed Oct 20 15:22:24 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdcvar.h,v 1.19 1999/09/23 11:04:32 enami Exp $ */
+/* $NetBSD: wdcvar.h,v 1.20 1999/10/20 15:22:26 enami Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -103,6 +103,7 @@
* The reference count here is used for both IDE and ATAPI devices.
Home |
Main Index |
Thread Index |
Old Index