Defer USB enumeration until the SI_SUB_KICK_SCHEDULER is executed to avoid

boot panics in conjunction with the recently added EARLY_AP_STARTUP feature.
The panics happen due to using kernel facilities like callouts too early.

Tested by:	jhb @
MFC after:	1 week
This commit is contained in:
hselasky 2016-12-19 09:28:12 +00:00
parent 25e2f31232
commit c28fd6c494
2 changed files with 27 additions and 1 deletions

@ -2261,6 +2261,11 @@ usb_needs_explore(struct usb_bus *bus, uint8_t do_probe)
DPRINTF("\n");
if (cold != 0) {
DPRINTF("Cold\n");
return;
}
if (bus == NULL) {
DPRINTF("No bus pointer!\n");
return;
@ -2325,6 +2330,26 @@ usb_needs_explore_all(void)
}
}
/*------------------------------------------------------------------------*
* usb_needs_explore_init
*
* This function will ensure that the USB controllers are not enumerated
* until the "cold" variable is cleared.
*------------------------------------------------------------------------*/
static void
usb_needs_explore_init(void *arg)
{
/*
* The cold variable should be cleared prior to this function
* being called:
*/
if (cold == 0)
usb_needs_explore_all();
else
DPRINTFN(-1, "Cold variable is still set!\n");
}
SYSINIT(usb_needs_explore_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND, usb_needs_explore_init, NULL);
/*------------------------------------------------------------------------*
* usb_bus_power_update
*

@ -455,14 +455,15 @@ usb_proc_drain(struct usb_process *up)
up->up_csleep = 0;
cv_signal(&up->up_cv);
}
#ifndef EARLY_AP_STARTUP
/* Check if we are still cold booted */
if (cold) {
USB_THREAD_SUSPEND(up->up_ptr);
printf("WARNING: A USB process has "
"been left suspended\n");
break;
}
#endif
cv_wait(&up->up_cv, up->up_mtx);
}
/* Check if someone is waiting - should not happen */