/*------------------------------------------------------------------------* * usb_proc_drain * * This function will tear down an USB process, waiting for the * currently executing command to return. * * NOTE: If the structure pointed to by "up" is all zero, * this function does nothing. *------------------------------------------------------------------------*/ void usb_proc_drain(struct usb_process *up) { /* check if not initialised */ if (up->up_mtx == NULL) return; /* handle special case with Giant */ if (up->up_mtx != &Giant) mtx_assert(up->up_mtx, MA_NOTOWNED); mtx_lock(up->up_mtx); /* Set the gone flag */ up->up_gone = 1; while (up->up_ptr) { /* Check if we need to wakeup the USB process */ if (up->up_msleep || up->up_csleep) { up->up_msleep = 0; up->up_csleep = 0; cv_signal(&up->up_cv); } /* Check if we are still cold booted */ if (cold) { #ifndef __rtems__ USB_THREAD_SUSPEND(up->up_ptr); printf("WARNING: A USB process has " "been left suspended\n"); break; #else /* __rtems__ */ BSD_ASSERT(0); #endif /* __rtems__ */ } cv_wait(&up->up_cv, up->up_mtx); } /* Check if someone is waiting - should not happen */ if (up->up_dsleep) { up->up_dsleep = 0; cv_broadcast(&up->up_drain); DPRINTF("WARNING: Someone is waiting " "for USB process drain!\n"); } mtx_unlock(up->up_mtx); }
/*------------------------------------------------------------------------* * usb_proc_drain * * This function will tear down an USB process, waiting for the * currently executing command to return. * * NOTE: If the structure pointed to by "up" is all zero, * this function does nothing. *------------------------------------------------------------------------*/ void usb_proc_drain(struct usb_process *up) { /* check if not initialised */ if (up->up_lock == NULL) return; #if 0 /* XXX */ /* handle special case with Giant */ if (up->up_mtx != &Giant) mtx_assert(up->up_mtx, MA_NOTOWNED); #else KKASSERT(!lockowned(up->up_lock)); lockmgr(up->up_lock, LK_EXCLUSIVE); #endif /* Set the gone flag */ up->up_gone = 1; while (up->up_ptr) { /* Check if we need to wakeup the USB process */ if (up->up_msleep || up->up_csleep) { up->up_msleep = 0; up->up_csleep = 0; cv_signal(&up->up_cv); } /* Check if we are still cold booted */ if (cold) { USB_THREAD_SUSPEND(up->up_ptr); kprintf("WARNING: A USB process has " "been left suspended\n"); break; } cv_wait(&up->up_cv, up->up_lock); } /* Check if someone is waiting - should not happen */ if (up->up_dsleep) { up->up_dsleep = 0; cv_broadcast(&up->up_drain); DPRINTF("WARNING: Someone is waiting " "for USB process drain!\n"); } lockmgr(up->up_lock, LK_RELEASE); }