summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2011-11-19 11:17:27 +0000
committerhselasky <hselasky@FreeBSD.org>2011-11-19 11:17:27 +0000
commit1b8ad7ed8ef38e1a06f631089cb1b7ab758fc406 (patch)
tree857ccda22917502e79fea61b91da7a1a2f54d359
parent3bcdb8772aed66918259718d05cb24d56914ab89 (diff)
downloadFreeBSD-src-1b8ad7ed8ef38e1a06f631089cb1b7ab758fc406.zip
FreeBSD-src-1b8ad7ed8ef38e1a06f631089cb1b7ab758fc406.tar.gz
Simplify the usb_pause_mtx() function by factoring out the generic parts
to the kernel's pause() function. The pause() function can now be used when cold != 0. Also assert that the timeout in system ticks must be positive. Suggested by: Bruce Evans MFC after: 1 week
-rw-r--r--sys/dev/usb/usb_util.c28
-rw-r--r--sys/kern/kern_synch.c28
2 files changed, 31 insertions, 25 deletions
diff --git a/sys/dev/usb/usb_util.c b/sys/dev/usb/usb_util.c
index a9b1d6f..4fe79c5 100644
--- a/sys/dev/usb/usb_util.c
+++ b/sys/dev/usb/usb_util.c
@@ -115,33 +115,21 @@ device_set_usb_desc(device_t dev)
*
* This function will delay the code by the passed number of system
* ticks. The passed mutex "mtx" will be dropped while waiting, if
- * "mtx" is not NULL.
+ * "mtx" is different from NULL.
*------------------------------------------------------------------------*/
void
-usb_pause_mtx(struct mtx *mtx, int _ticks)
+usb_pause_mtx(struct mtx *mtx, int timo)
{
if (mtx != NULL)
mtx_unlock(mtx);
- if (cold) {
- /* convert to milliseconds */
- _ticks = (_ticks * 1000) / hz;
- /* convert to microseconds, rounded up */
- _ticks = (_ticks + 1) * 1000;
- DELAY(_ticks);
+ /*
+ * Add one tick to the timeout so that we don't return too
+ * early! Note that pause() will assert that the passed
+ * timeout is positive and non-zero!
+ */
+ pause("USBWAIT", timo + 1);
- } else {
-
- /*
- * Add one to the number of ticks so that we don't return
- * too early!
- */
- _ticks++;
-
- if (pause("USBWAIT", _ticks)) {
- /* ignore */
- }
- }
if (mtx != NULL)
mtx_lock(mtx);
}
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index a2c26ae..f4a8494 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -325,16 +325,34 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
}
/*
- * pause() is like tsleep() except that the intention is to not be
- * explicitly woken up by another thread. Instead, the current thread
- * simply wishes to sleep until the timeout expires. It is
- * implemented using a dummy wait channel.
+ * pause() is almost like tsleep() except that the intention is to not
+ * be explicitly woken up by another thread. Instead, the current
+ * thread simply wishes to sleep until the timeout expires. It is
+ * implemented using a dummy wait channel. During cold bootup pause()
+ * will use the DELAY() function instead of tsleep() to wait the given
+ * number of system ticks. The passed "timo" argument must not be
+ * negative and also greater than zero.
*/
int
pause(const char *wmesg, int timo)
{
- KASSERT(timo != 0, ("pause: timeout required"));
+ KASSERT(timo > 0, ("pause: a positive and non-zero "
+ "timeout is required"));
+
+ if (cold) {
+ /*
+ * We delay one HZ at a time to avoid overflowing the
+ * DELAY() argument:
+ */
+ while (timo >= hz) {
+ DELAY(1000000);
+ timo -= hz;
+ }
+ if (timo > 0)
+ DELAY(timo * tick);
+ return (0);
+ }
return (tsleep(&pause_wchan, 0, wmesg, timo));
}
OpenPOWER on IntegriCloud