Date: Wed, 13 Jul 2011 21:07:50 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r223989 - head/sys/dev/usb/input Message-ID: <201107132107.p6DL7ojq099900@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Wed Jul 13 21:07:50 2011 New Revision: 223989 URL: http://svn.freebsd.org/changeset/base/223989 Log: Fix for dump after shutdown with USB keyboard plugged in. It appears that the system timer is stopped during shutdown and that the pause() statement in ukbd causes infinite hang in this regard. The fix is to use mi_switch() instead of pause() to do the required task switch to ensure that the required USB processes get executed. Reported by: Mike_Karels@mcafee.com MFC after: 1 week Modified: head/sys/dev/usb/input/ukbd.c Modified: head/sys/dev/usb/input/ukbd.c ============================================================================== --- head/sys/dev/usb/input/ukbd.c Wed Jul 13 21:07:41 2011 (r223988) +++ head/sys/dev/usb/input/ukbd.c Wed Jul 13 21:07:50 2011 (r223989) @@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$"); #include <sys/callout.h> #include <sys/malloc.h> #include <sys/priv.h> +#include <sys/proc.h> +#include <sys/sched.h> #include <sys/kdb.h> #include <dev/usb/usb.h> @@ -386,6 +388,33 @@ ukbd_put_key(struct ukbd_softc *sc, uint } static void +ukbd_yield(void) +{ + struct thread *td = curthread; + uint32_t old_prio; + + DROP_GIANT(); + + thread_lock(td); + + /* get current priority */ + old_prio = td->td_base_pri; + + /* set new priority */ + sched_prio(td, td->td_user_pri); + + /* cause a task switch */ + mi_switch(SW_INVOL | SWT_RELINQUISH, NULL); + + /* restore priority */ + sched_prio(td, old_prio); + + thread_unlock(td); + + PICKUP_GIANT(); +} + +static void ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait) { DPRINTFN(2, "polling\n"); @@ -396,8 +425,9 @@ ukbd_do_poll(struct ukbd_softc *sc, uint if (kdb_active == 0) { while (sc->sc_inputs == 0) { - /* make sure the USB code gets a chance to run */ - pause("UKBD", 1); + + /* give USB threads a chance to run */ + ukbd_yield(); /* check if we should wait */ if (!wait)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107132107.p6DL7ojq099900>