summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2010-04-11 16:58:07 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2010-04-11 16:58:07 +0000
commit5f481821f98626e834fb6d0ec1974a225a87767e (patch)
tree5fa693a234521b8c973ac4c067b49df392f30add /sys
parentccf04ea2b34dd74589c83b99def187a1a5dcbe11 (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.c15
-rw-r--r--sys/dev/pci/pciide.c24
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)
{