summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguido <guido@FreeBSD.org>1998-02-04 20:19:39 +0000
committerguido <guido@FreeBSD.org>1998-02-04 20:19:39 +0000
commit1c9cf806f13759df7b86517904f3a7f7b0f9c628 (patch)
treeeb0d231aa848b7e1b504178ddb0fad129a9c7d8d
parent13eef94007a8aa8da83a505a87e104867aa61262 (diff)
downloadFreeBSD-src-1c9cf806f13759df7b86517904f3a7f7b0f9c628.zip
FreeBSD-src-1c9cf806f13759df7b86517904f3a7f7b0f9c628.tar.gz
This seems to fix my problem that after resume/suspend, sometimes
pccard claims that the driver is already allocated. It works around a race when pccardd gets woken up too late after a resume. This is a 2.2.6 candidate. Reviewed by: nate@freebsd.org
-rw-r--r--usr.sbin/pccard/pccardd/cardd.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/usr.sbin/pccard/pccardd/cardd.c b/usr.sbin/pccard/pccardd/cardd.c
index a631615..17dd99d 100644
--- a/usr.sbin/pccard/pccardd/cardd.c
+++ b/usr.sbin/pccard/pccardd/cardd.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id: cardd.c,v 1.22 1997/11/25 19:15:59 nate Exp $";
+ "$Id: cardd.c,v 1.23 1997/12/08 06:35:07 nate Exp $";
#endif /* not lint */
#include <fcntl.h>
@@ -220,19 +220,31 @@ slot_change(struct slot *sp)
if (state.state == sp->state)
logmsg("State same as before, continuing anyway");
#endif
- sp->state = state.state;
- switch (sp->state) {
+ switch (state.state) {
case empty:
case noslot:
card_removed(sp);
break;
case filled:
+ /*
+ * If state was already filled, fake a removal first to get
+ * our state in sync with the kernel. This happens when the
+ * systems resumes and we only get to process the state
+ * change from suspend to empty after inserted() has run.
+ * In that case the kernel state is perfectly normal.
+ *
+ * The reason for not doing nothing is that the kernel
+ * has to be informed again about IRQ and IO window.
+ */
+ if (state.state == sp->state)
+ card_removed(sp);
card_inserted(sp);
break;
case suspend:
/* ignored */
break;
}
+ sp->state = state.state;
}
/*
OpenPOWER on IntegriCloud