diff options
| author | jmcneill <jmcneill@NetBSD.org> | 2007-12-09 20:27:42 +0000 |
|---|---|---|
| committer | jmcneill <jmcneill@NetBSD.org> | 2007-12-09 20:27:42 +0000 |
| commit | 4c1d81b2b5fa658e9fd5e7151eb40ba71ba676da (patch) | |
| tree | 3f8b0d6c63745bde8809b8c6f9e4f6b1514f335e /sys/dev/ata | |
| parent | 3947df41d16da8b387239b9b87789bfbe950a3b2 (diff) | |
Merge jmcneill-pm branch.
Diffstat (limited to 'sys/dev/ata')
| -rw-r--r-- | sys/dev/ata/ata.c | 67 | ||||
| -rw-r--r-- | sys/dev/ata/atavar.h | 3 | ||||
| -rw-r--r-- | sys/dev/ata/wd.c | 48 | ||||
| -rw-r--r-- | sys/dev/ata/wdvar.h | 4 |
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; |
