summaryrefslogtreecommitdiff
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorjmcneill <jmcneill@NetBSD.org>2007-12-09 20:27:42 +0000
committerjmcneill <jmcneill@NetBSD.org>2007-12-09 20:27:42 +0000
commit4c1d81b2b5fa658e9fd5e7151eb40ba71ba676da (patch)
tree3f8b0d6c63745bde8809b8c6f9e4f6b1514f335e /sys/dev/ata
parent3947df41d16da8b387239b9b87789bfbe950a3b2 (diff)
Merge jmcneill-pm branch.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata.c67
-rw-r--r--sys/dev/ata/atavar.h3
-rw-r--r--sys/dev/ata/wd.c48
-rw-r--r--sys/dev/ata/wdvar.h4
4 files changed, 59 insertions, 63 deletions
diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c
index bd1f556f060..fa55e3929d8 100644
--- a/sys/dev/ata/ata.c
+++ b/sys/dev/ata/ata.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata.c,v 1.91 2007/10/19 11:59:36 ad Exp $ */
+/* $NetBSD: ata.c,v 1.92 2007/12/09 20:27:54 jmcneill 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.91 2007/10/19 11:59:36 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.92 2007/12/09 20:27:54 jmcneill Exp $");
#include "opt_ata.h"
@@ -106,7 +106,8 @@ const struct cdevsw atabus_cdevsw = {
extern struct cfdriver atabus_cd;
-static void atabus_powerhook(int, void *);
+static bool atabus_resume(device_t);
+static bool atabus_suspend(device_t);
/*
* atabusprint:
@@ -416,11 +417,8 @@ atabus_attach(struct device *parent, struct device *self, void *aux)
aprint_error("%s: unable to create kernel thread: error %d\n",
sc->sc_dev.dv_xname, error);
- sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
- atabus_powerhook, sc);
- if (sc->sc_powerhook == NULL)
- printf("%s: WARNING: unable to establish power hook\n",
- sc->sc_dev.dv_xname);
+ if (!pmf_device_register(self, atabus_suspend, atabus_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
/*
@@ -502,10 +500,6 @@ atabus_detach(struct device *self, int flags)
while (chp->ch_thread != NULL)
(void) tsleep(&chp->ch_flags, PRIBIO, "atadown", 0);
- /* power hook */
- if (sc->sc_powerhook)
- powerhook_disestablish(sc->sc_powerhook);
-
/*
* Detach atapibus and its children.
*/
@@ -1475,33 +1469,38 @@ atabusioctl(dev_t dev, u_long cmd, void *addr, int flag,
return (error);
};
-static void
-atabus_powerhook(int why, void *hdl)
+static bool
+atabus_suspend(device_t dv)
{
- struct atabus_softc *sc = (struct atabus_softc *)hdl;
+ struct atabus_softc *sc = device_private(dv);
+ struct ata_channel *chp = sc->sc_chan;
+
+ ata_queue_idle(chp->ch_queue);
+
+ return true;
+}
+
+static bool
+atabus_resume(device_t dv)
+{
+ struct atabus_softc *sc = device_private(dv);
struct ata_channel *chp = sc->sc_chan;
int s;
- switch (why) {
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- /* freeze the queue and wait for the controller to be idle */
- ata_queue_idle(chp->ch_queue);
- break;
- case PWR_RESUME:
- printf("%s: resuming...\n", sc->sc_dev.dv_xname);
- s = splbio();
- KASSERT(chp->ch_queue->queue_freeze > 0);
- /* unfreeze the queue and reset drives (to wake them up) */
- chp->ch_queue->queue_freeze--;
- ata_reset_channel(chp, AT_WAIT);
+ /*
+ * XXX joerg: with wdc, the first channel unfreezes the controler.
+ * Move this the reset and queue idling into wdc.
+ */
+ s = splbio();
+ if (chp->ch_queue->queue_freeze == 0) {
splx(s);
- break;
- case PWR_SUSPEND:
- case PWR_STANDBY:
- case PWR_SOFTRESUME:
- break;
+ return true;
}
+ KASSERT(chp->ch_queue->queue_freeze > 0);
+ /* unfreeze the queue and reset drives */
+ chp->ch_queue->queue_freeze--;
+ ata_reset_channel(chp, AT_WAIT);
+ splx(s);
- return;
+ return true;
}
diff --git a/sys/dev/ata/atavar.h b/sys/dev/ata/atavar.h
index 3460505104a..b5e5bd0688b 100644
--- a/sys/dev/ata/atavar.h
+++ b/sys/dev/ata/atavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: atavar.h,v 1.74 2007/07/09 21:00:31 ad Exp $ */
+/* $NetBSD: atavar.h,v 1.75 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -102,7 +102,6 @@ struct atabus_softc {
struct ata_channel *sc_chan;
int sc_flags;
#define ATABUSCF_OPEN 0x01
- void *sc_powerhook;
};
/*
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c
index 94358fb8622..8c87abc7b27 100644
--- a/sys/dev/ata/wd.c
+++ b/sys/dev/ata/wd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.350 2007/11/07 08:59:03 itohy Exp $ */
+/* $NetBSD: wd.c,v 1.351 2007/12/09 20:27:54 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.350 2007/11/07 08:59:03 itohy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.351 2007/12/09 20:27:54 jmcneill Exp $");
#include "opt_ata.h"
@@ -139,6 +139,8 @@ int wdactivate(struct device *, enum devact);
int wdprint(void *, char *);
void wdperror(const struct wd_softc *);
+static bool wd_suspend(device_t);
+
CFATTACH_DECL(wd, sizeof(struct wd_softc),
wdprobe, wdattach, wddetach, wdactivate);
@@ -189,9 +191,8 @@ void __wdstart(struct wd_softc*, struct buf *);
void wdrestart(void *);
void wddone(void *);
int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
-int wd_standby(struct wd_softc *, int);
+static int wd_standby(struct wd_softc *, int);
int wd_flushcache(struct wd_softc *, int);
-void wd_shutdown(void *);
int wd_getcache(struct wd_softc *, int *);
int wd_setcache(struct wd_softc *, int);
@@ -414,10 +415,6 @@ wdattach(struct device *parent, struct device *self, void *aux)
disk_init(&wd->sc_dk, wd->sc_dev.dv_xname, &wddkdriver);
disk_attach(&wd->sc_dk);
wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
- wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
- if (wd->sc_sdhook == NULL)
- aprint_error("%s: WARNING: unable to establish shutdown hook\n",
- wd->sc_dev.dv_xname);
#if NRND > 0
rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,
RND_TYPE_DISK, 0);
@@ -425,6 +422,20 @@ wdattach(struct device *parent, struct device *self, void *aux)
/* Discover wedges on this disk. */
dkwedge_discover(&wd->sc_dk);
+
+ if (!pmf_device_register(self, wd_suspend, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static bool
+wd_suspend(device_t dv)
+{
+ struct wd_softc *sc = device_private(dv);
+
+ wd_flushcache(sc, AT_WAIT | AT_POLL);
+ wd_standby(sc, AT_WAIT | AT_POLL);
+
+ return true;
}
int
@@ -489,9 +500,7 @@ wddetach(struct device *self, int flags)
sc->sc_bscount = 0;
#endif
- /* Get rid of the shutdown hook. */
- if (sc->sc_sdhook != NULL)
- shutdownhook_disestablish(sc->sc_sdhook);
+ pmf_device_deregister(self);
#if NRND > 0
/* Unhook the entropy source. */
@@ -1857,7 +1866,7 @@ wd_setcache(struct wd_softc *wd, int bits)
return 0;
}
-int
+static int
wd_standby(struct wd_softc *wd, int flags)
{
struct ata_command ata_c;
@@ -1869,8 +1878,8 @@ wd_standby(struct wd_softc *wd, int flags)
ata_c.flags = flags;
ata_c.timeout = 30000; /* 30s timeout */
if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
- printf("%s: standby immediate command didn't complete\n",
- wd->sc_dev.dv_xname);
+ aprint_error_dev(&wd->sc_dev,
+ "standby immediate command didn't complete\n");
return EIO;
}
if (ata_c.flags & AT_ERROR) {
@@ -1880,8 +1889,7 @@ wd_standby(struct wd_softc *wd, int flags)
if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
char sbuf[sizeof(at_errbits) + 64];
bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
- printf("%s: wd_standby: status=%s\n", wd->sc_dev.dv_xname,
- sbuf);
+ aprint_error_dev(&wd->sc_dev, "wd_standby: status=%s\n", sbuf);
return EIO;
}
return 0;
@@ -1929,14 +1937,6 @@ wd_flushcache(struct wd_softc *wd, int flags)
return 0;
}
-void
-wd_shutdown(void *arg)
-{
-
- struct wd_softc *wd = arg;
- wd_flushcache(wd, AT_POLL);
-}
-
/*
* Allocate space for a ioctl queue structure. Mostly taken from
* scsipi_ioctl.c
diff --git a/sys/dev/ata/wdvar.h b/sys/dev/ata/wdvar.h
index 5bd337fda8b..f909abab5c0 100644
--- a/sys/dev/ata/wdvar.h
+++ b/sys/dev/ata/wdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.32 2005/12/11 12:21:14 christos Exp $ */
+/* $NetBSD: wdvar.h,v 1.33 2007/12/09 20:27:55 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -66,8 +66,6 @@ struct wd_softc {
int retries; /* number of xfer retry */
- void *sc_sdhook; /* our shutdown hook */
-
#ifdef WD_SOFTBADSECT
SLIST_HEAD(, disk_badsectors) sc_bslist;
u_int sc_bscount;