diff options
| author | thorpej <thorpej@NetBSD.org> | 2004-08-20 23:26:53 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2004-08-20 23:26:53 +0000 |
| commit | e975b9caee6983271aaeb3b9bf08fde23ccbb2b8 (patch) | |
| tree | 187499f2b4e5339591c5294c17d60250aaf634c7 /sys/dev/ata | |
| parent | e09640d6eb1b1510ff2ff775c8a22625abc3dd33 (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.c | 58 | ||||
| -rw-r--r-- | sys/dev/ata/ata_wdc.c | 5 | ||||
| -rw-r--r-- | sys/dev/ata/atavar.h | 6 |
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 *); |
