diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-04-11 16:58:07 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-04-11 16:58:07 +0000 |
commit | 5f481821f98626e834fb6d0ec1974a225a87767e (patch) | |
tree | 5fa693a234521b8c973ac4c067b49df392f30add /sys | |
parent | ccf04ea2b34dd74589c83b99def187a1a5dcbe11 (diff) |
Send "STANDBY IMMEDIATE" command to ATA disks upon suspend. For this to work,
pciide(4) needs to formward DVACT_SUSPEND and DVACT_RESUME events to its
children, so do that.
Gets rid of the nasty "click" sound from the disk on many laptops.
ok marco@, jsg@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ata/wd.c | 15 | ||||
-rw-r--r-- | sys/dev/pci/pciide.c | 24 |
2 files changed, 35 insertions, 4 deletions
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index 35ead361038..5a6182a946a 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wd.c,v 1.77 2009/10/13 19:33:16 pirofti Exp $ */ +/* $OpenBSD: wd.c,v 1.78 2010/04/11 16:58:06 kettenis Exp $ */ /* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */ /* @@ -377,6 +377,8 @@ wdattach(struct device *parent, struct device *self, void *aux) int wdactivate(struct device *self, int act) { + struct wd_softc *wd = (void *)self; + struct wdc_command wdc_c; int rv = 0; switch (act) { @@ -388,6 +390,17 @@ wdactivate(struct device *self, int act) * Nothing to do; we key off the device's DVF_ACTIVATE. */ break; + case DVACT_SUSPEND: + bzero(&wdc_c, sizeof(struct wdc_command)); + + wdc_c.r_command = WDCC_STANDBY_IMMED; + wdc_c.timeout = 1000; + wdc_c.flags = at_poll; + if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { + printf("%s: enter standby command didn't complete\n", + wd->sc_dev.dv_xname); + } + break; } return (rv); } diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index 2248ff71a4c..0002f515519 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide.c,v 1.306 2009/11/21 14:34:20 jsg Exp $ */ +/* $OpenBSD: pciide.c,v 1.307 2010/04/11 16:58:06 kettenis Exp $ */ /* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */ /* @@ -1265,13 +1265,16 @@ const struct pciide_vendor_desc pciide_vendors[] = { int pciide_match(struct device *, void *, void *); void pciide_attach(struct device *, struct device *, void *); int pciide_detach(struct device *, int); +int pciide_activate(struct device *, int); struct cfattach pciide_pci_ca = { - sizeof(struct pciide_softc), pciide_match, pciide_attach, pciide_detach, + sizeof(struct pciide_softc), pciide_match, pciide_attach, + pciide_detach, pciide_activate }; struct cfattach pciide_jmb_ca = { - sizeof(struct pciide_softc), pciide_match, pciide_attach, pciide_detach, + sizeof(struct pciide_softc), pciide_match, pciide_attach, + pciide_detach, pciide_activate }; struct cfdriver pciide_cd = { @@ -1403,6 +1406,21 @@ pciide_detach(struct device *self, int flags) } int +pciide_activate(struct device *self, int act) +{ + int rv = 0; + + switch (act) { + case DVACT_SUSPEND: + case DVACT_RESUME: + rv = config_activate_children(self, act); + break; + } + + return (rv); +} + +int pciide_mapregs_compat(struct pci_attach_args *pa, struct pciide_channel *cp, int compatchan, bus_size_t *cmdsizep, bus_size_t *ctlsizep) { |