Subject: Re: ep driver lossage
To: Jason Thorpe <thorpej@nas.nasa.gov>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-net
Date: 04/13/1999 13:35:32
hi Jason,
Below is the kludged-up patch i sent various people for testing, which
should be enough to identify the problem.
Polling for command_complete with a timeout is nicer; I'm not sure how
to do it without adding overhead to cardss that do implement it, tho.
Did you mean something simple like
for (i = 0; i < 1000; i++) {
if (bus_space_read_2(iot, ioh, ELINK_STATUS) & S_COMMAND_IN_PROGRESS)
break;
DELAY(100);
}
or something fancier?
--- elink3.c Tue Apr 13 13:03:06 1999
+++ elink3.c.jrs-shutdown-hack Tue Apr 13 12:55:19 1999
@@ -224,6 +224,14 @@
u_int cmd, u_int arg));
static __inline int ep_w1_reg __P((struct ep_softc *, int));
+/*
+ * How long to delay when waiting for a reset to complete. (We cannot
+ * use S_COMMAND_IN_PROGRESS since some older boards do not implement
+ * that on RESET commands). Documentation says we need at least 1 ms,
+ * but be generous for original 3c509 boards.
+ */
+#define ELINK_RESET_DELAY 100000
+
/*
* Some chips (3c515 [Corkscrew] and 3c574 [RoadRunner]) have
* Window 1 registers offset!
@@ -274,7 +282,7 @@
;
else
#else
- DELAY(100000); /* need at least 1 ms, but be generous. */
+ DELAY(ELINK_RESET_DELAY); /* need at least 1 ms, be generous. */
#endif
}
@@ -690,8 +698,15 @@
bus_space_handle_t ioh = sc->sc_ioh;
int i;
+#if 0 /*
+ * cannot use S_COMMAND_IN_PROGRESS, since we may be in a RESET,
+ * and some boards do not implement it there. See ep_complete_cmd().
+ */
while (bus_space_read_2(iot, ioh, ELINK_STATUS) & S_COMMAND_IN_PROGRESS)
;
+#else
+ DELAY(ELINK_RESET_DELAY);
+#endif
if (sc->bustype != ELINK_BUS_PCI) {
GO_WINDOW(0);
@@ -1836,8 +1851,11 @@
register struct ep_softc *sc = arg;
if (sc->enabled) {
+ int s = splnet();
+
epstop(sc);
ep_complete_cmd(sc, ELINK_COMMAND, GLOBAL_RESET);
+ splx(s);
}
}