summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2010-07-02 09:21:59 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2010-07-02 09:21:59 +0000
commit91cb8c154b7e31c9d85c8eb9d8b66d0e2457c332 (patch)
treeb213de93b3422e50d721d887c52af684bc8be8f6 /sys/dev
parentcd6ccffddddc24f67b61d2155e9afd2c39e3463f (diff)
On resume, detach and then force a re-attach of the card, since we don't
know if it is the same card or if it got modified while we were not paying attention. Tested on x40 under apm, and some acpi machines. ok mlarkin kettenis
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sdmmc/sdhc.c4
-rw-r--r--sys/dev/sdmmc/sdmmc.c32
2 files changed, 33 insertions, 3 deletions
diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c
index 73c598c76ff..8195801caee 100644
--- a/sys/dev/sdmmc/sdhc.c
+++ b/sys/dev/sdmmc/sdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
+/* $OpenBSD: sdhc.c,v 1.26 2010/07/02 09:21:58 deraadt Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -282,6 +282,8 @@ sdhc_power(int why, void *arg)
for (i = 0; i < sizeof hp->regs; i++)
HWRITE1(hp, i, hp->regs[i]);
}
+ config_activate_children((struct device *)sc,
+ DVACT_RESUME);
break;
}
}
diff --git a/sys/dev/sdmmc/sdmmc.c b/sys/dev/sdmmc/sdmmc.c
index 92aa6314452..0aa21a3b21d 100644
--- a/sys/dev/sdmmc/sdmmc.c
+++ b/sys/dev/sdmmc/sdmmc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdmmc.c,v 1.20 2009/04/07 16:35:52 blambert Exp $ */
+/* $OpenBSD: sdmmc.c,v 1.21 2010/07/02 09:21:58 deraadt Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -50,6 +50,8 @@
int sdmmc_match(struct device *, void *, void *);
void sdmmc_attach(struct device *, struct device *, void *);
int sdmmc_detach(struct device *, int);
+int sdmmc_activate(struct device *, int);
+
void sdmmc_create_thread(void *);
void sdmmc_task_thread(void *);
void sdmmc_discover_task(void *);
@@ -76,7 +78,8 @@ void sdmmc_dump_command(struct sdmmc_softc *, struct sdmmc_command *);
#endif
struct cfattach sdmmc_ca = {
- sizeof(struct sdmmc_softc), sdmmc_match, sdmmc_attach, sdmmc_detach
+ sizeof(struct sdmmc_softc), sdmmc_match, sdmmc_attach, sdmmc_detach,
+ sdmmc_activate
};
struct cfdriver sdmmc_cd = {
@@ -140,6 +143,21 @@ sdmmc_detach(struct device *self, int flags)
return 0;
}
+int
+sdmmc_activate(struct device *self, int act)
+{
+ struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_RESUME:
+ sc->sc_dying = -1; /* "bump" the task for a retry */
+ wakeup(&sc->sc_tskq);
+ break;
+ }
+ return (rv);
+}
+
void
sdmmc_create_thread(void *arg)
{
@@ -161,6 +179,7 @@ sdmmc_task_thread(void *arg)
struct sdmmc_task *task;
int s;
+restart:
sdmmc_needs_discover(&sc->sc_dev);
s = splsdmmc();
@@ -182,6 +201,15 @@ sdmmc_task_thread(void *arg)
SDMMC_UNLOCK(sc);
}
+ /*
+ * During a suspend, the card is detached since we do not know
+ * if it is the same upon wakeup. Go re-discover the bus.
+ */
+ if (sc->sc_dying == -1) {
+ CLR(sc->sc_flags, SMF_CARD_PRESENT);
+ sc->sc_dying = 0;
+ goto restart;
+ }
sc->sc_task_thread = NULL;
wakeup(sc);
kthread_exit(0);