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
This commit is contained in:
hselasky 2011-07-13 21:07:50 +00:00
parent e3d33b853d
commit ced2dc53dd

View File

@ -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>
@ -385,6 +387,33 @@ ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
}
}
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)
{
@ -396,8 +425,9 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
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)