summaryrefslogtreecommitdiff
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorthorpej <thorpej@NetBSD.org>2004-08-20 23:26:53 +0000
committerthorpej <thorpej@NetBSD.org>2004-08-20 23:26:53 +0000
commite975b9caee6983271aaeb3b9bf08fde23ccbb2b8 (patch)
tree187499f2b4e5339591c5294c17d60250aaf634c7 /sys/dev/ata
parente09640d6eb1b1510ff2ff775c8a22625abc3dd33 (diff)
- Add an (*ata_reset_channel)() member to ata_bustype.
- Add an ata_reset_channel() function that performs the common parts of resetting an ATA channel, which uses the (*ata_reset_channel)() callback to do the heavy lifting. Adjust callers to use ata_reset_channel() instead of wdc_reset_channel(). This removes the last wdc-specific code from ata.c!
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata.c58
-rw-r--r--sys/dev/ata/ata_wdc.c5
-rw-r--r--sys/dev/ata/atavar.h6
3 files changed, 58 insertions, 11 deletions
diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c
index f7d44ca67e2..e841fc18ae7 100644
--- a/sys/dev/ata/ata.c
+++ b/sys/dev/ata/ata.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata.c,v 1.54 2004/08/20 22:26:23 thorpej Exp $ */
+/* $NetBSD: ata.c,v 1.55 2004/08/20 23:26:53 thorpej Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.54 2004/08/20 22:26:23 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.55 2004/08/20 23:26:53 thorpej Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@@ -54,7 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.54 2004/08/20 22:26:23 thorpej Exp $");
#include <dev/ata/atareg.h>
#include <dev/ata/atavar.h>
-#include <dev/ic/wdcvar.h>
#include "locators.h"
@@ -332,11 +331,11 @@ atabus_thread(void *arg)
s = splbio();
if (chp->ch_flags & ATACH_TH_RESET) {
/*
- * wdc_reset_channel() will freeze 2 times, so
+ * ata_reset_channel() will freeze 2 times, so
* unfreeze one time. Not a problem as we're at splbio
*/
chp->ch_queue->queue_freeze--;
- wdc_reset_channel(chp, AT_WAIT | chp->ch_reset_flags);
+ ata_reset_channel(chp, AT_WAIT | chp->ch_reset_flags);
} else if (chp->ch_queue->active_xfer != NULL &&
chp->ch_queue->queue_freeze == 1) {
/*
@@ -818,6 +817,51 @@ ata_kill_pending(struct ata_drive_datas *drvp)
splx(s);
}
+/*
+ * ata_reset_channel:
+ *
+ * Reset and ATA channel.
+ */
+void
+ata_reset_channel(struct ata_channel *chp, int flags)
+{
+ struct atac_softc *atac = chp->ch_atac;
+ int drive;
+
+ chp->ch_queue->queue_freeze++;
+
+ /*
+ * If we can poll or wait it's OK, otherwise wake up the
+ * kernel thread to do it for us.
+ */
+ if ((flags & (AT_POLL | AT_WAIT)) == 0) {
+ if (chp->ch_flags & ATACH_TH_RESET) {
+ /* No need to schedule a reset more than one time. */
+ return;
+ }
+ chp->ch_flags |= ATACH_TH_RESET;
+ chp->ch_reset_flags = flags & (AT_RST_EMERG | AT_RST_NOCMD);
+ wakeup(&chp->ch_thread);
+ return;
+ }
+
+ (*atac->atac_bustype_ata->ata_reset_channel)(chp, flags);
+
+ for (drive = 0; drive < chp->ch_ndrive; drive++)
+ chp->ch_drive[drive].state = 0;
+
+ chp->ch_flags &= ~ATACH_TH_RESET;
+ if ((flags & AT_RST_EMERG) == 0) {
+ chp->ch_queue->queue_freeze--;
+ atastart(chp);
+ } else {
+ /* make sure that we can use polled commands */
+ TAILQ_INIT(&chp->ch_queue->queue_xfer);
+ chp->ch_queue->queue_freeze = 0;
+ chp->ch_queue->active_xfer = NULL;
+ }
+}
+
int
ata_addref(struct ata_channel *chp)
{
@@ -929,7 +973,7 @@ ata_downgrade_mode(struct ata_drive_datas *drvp, int flags)
(*atac->atac_set_modes)(chp);
ata_print_modes(chp);
/* reset the channel, which will shedule all drives for setup */
- wdc_reset_channel(chp, flags | AT_RST_NOCMD);
+ ata_reset_channel(chp, flags | AT_RST_NOCMD);
return 1;
}
@@ -1219,7 +1263,7 @@ atabusioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
switch (cmd) {
case ATABUSIORESET:
s = splbio();
- wdc_reset_channel(sc->sc_chan, AT_WAIT | AT_POLL);
+ ata_reset_channel(sc->sc_chan, AT_WAIT | AT_POLL);
splx(s);
error = 0;
break;
diff --git a/sys/dev/ata/ata_wdc.c b/sys/dev/ata/ata_wdc.c
index 349a7c3ac1f..3d4000546a8 100644
--- a/sys/dev/ata/ata_wdc.c
+++ b/sys/dev/ata/ata_wdc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_wdc.c,v 1.73 2004/08/20 06:39:38 thorpej Exp $ */
+/* $NetBSD: ata_wdc.c,v 1.74 2004/08/20 23:26:53 thorpej Exp $ */
/*
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.73 2004/08/20 06:39:38 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.74 2004/08/20 23:26:53 thorpej Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@@ -133,6 +133,7 @@ const struct ata_bustype wdc_ata_bustype = {
SCSIPI_BUSTYPE_ATA,
wdc_ata_bio,
wdc_reset_drive,
+ wdc_reset_channel,
wdc_exec_command,
ata_get_params,
wdc_ata_addref,
diff --git a/sys/dev/ata/atavar.h b/sys/dev/ata/atavar.h
index 73789d617fa..cf91a565045 100644
--- a/sys/dev/ata/atavar.h
+++ b/sys/dev/ata/atavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: atavar.h,v 1.63 2004/08/20 22:17:06 thorpej Exp $ */
+/* $NetBSD: atavar.h,v 1.64 2004/08/20 23:26:54 thorpej Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -271,7 +271,8 @@ struct ata_bustype {
int bustype_type; /* symbolic name of type */
int (*ata_bio)(struct ata_drive_datas *, struct ata_bio *);
void (*ata_reset_drive)(struct ata_drive_datas *, int);
-/* extra flags for ata_reset_drive(), in addition to AT_* */
+ void (*ata_reset_channel)(struct ata_channel *, int);
+/* extra flags for ata_reset_*(), in addition to AT_* */
#define AT_RST_EMERG 0x10000 /* emergency - e.g. for a dump */
#define AT_RST_NOCMD 0x20000 /* XXX has to go - temporary until we have tagged queuing */
@@ -425,6 +426,7 @@ void ata_free_xfer(struct ata_channel *, struct ata_xfer *);
void ata_exec_xfer(struct ata_channel *, struct ata_xfer *);
void ata_kill_pending(struct ata_drive_datas *);
+void ata_reset_channel(struct ata_channel *, int);
int ata_addref(struct ata_channel *);
void ata_delref(struct ata_channel *);