Lines Matching +full:up +full:- +full:to
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
82 /*------------------------------------------------------------------------*
86 *------------------------------------------------------------------------*/
90 struct usb_process *up = arg; in usb_process() local
100 sched_prio(td, up->up_prio); in usb_process()
103 USB_MTX_LOCK(up->up_mtx); in usb_process()
105 up->up_curtd = td; in usb_process()
108 if (up->up_gone) in usb_process()
112 * NOTE to reimplementors: dequeueing a command from the in usb_process()
114 * to the "up_mtx" mutex. That means any attempt to queue a in usb_process()
124 * Assume that you want to set the baud rate on a USB serial in usb_process()
126 * want to receive nor transmit any data, because it will be in usb_process()
128 * device takes 20 milliseconds and it needs to call in usb_process()
131 * Non-working solution: Before we queue the programming in usb_process()
138 * first one is sleeping, we end up enabling transmission in usb_process()
148 * second command to enable the data transfers, will cause in usb_process()
149 * the previous one, which is still on the queue, to be in usb_process()
150 * removed from the queue, and re-inserted after the last in usb_process()
154 pm = TAILQ_FIRST(&up->up_qhead); in usb_process()
158 pm, pm->pm_callback); in usb_process()
160 (pm->pm_callback) (pm); in usb_process()
162 if (pm == TAILQ_FIRST(&up->up_qhead)) { in usb_process()
164 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry); in usb_process()
165 pm->pm_qentry.tqe_prev = NULL; in usb_process()
171 /* end of messages - check if anyone is waiting for sync */ in usb_process()
172 if (up->up_dsleep) { in usb_process()
173 up->up_dsleep = 0; in usb_process()
174 cv_broadcast(&up->up_drain); in usb_process()
176 up->up_msleep = 1; in usb_process()
177 cv_wait(&up->up_cv, up->up_mtx); in usb_process()
180 up->up_ptr = NULL; in usb_process()
181 cv_signal(&up->up_cv); in usb_process()
182 USB_MTX_UNLOCK(up->up_mtx); in usb_process()
184 if (--usb_pcount == 0) in usb_process()
190 /*------------------------------------------------------------------------*
194 * execute callbacks. The mutex pointed to by "p_mtx" will be applied
196 * has returned. The structure pointed to by "up" is assumed to be
202 *------------------------------------------------------------------------*/
204 usb_proc_create(struct usb_process *up, struct mtx *p_mtx, in usb_proc_create() argument
207 up->up_mtx = p_mtx; in usb_proc_create()
208 up->up_prio = prio; in usb_proc_create()
210 TAILQ_INIT(&up->up_qhead); in usb_proc_create()
212 cv_init(&up->up_cv, "-"); in usb_proc_create()
213 cv_init(&up->up_drain, "usbdrain"); in usb_proc_create()
215 if (USB_THREAD_CREATE(&usb_process, up, in usb_proc_create()
216 &up->up_ptr, "%s", pmesg)) { in usb_proc_create()
217 DPRINTFN(0, "Unable to create USB process."); in usb_proc_create()
218 up->up_ptr = NULL; in usb_proc_create()
225 usb_proc_free(up); in usb_proc_create()
229 /*------------------------------------------------------------------------*
232 * NOTE: If the structure pointed to by "up" is all zero, this
237 *------------------------------------------------------------------------*/
239 usb_proc_free(struct usb_process *up) in usb_proc_free() argument
242 if (up->up_mtx == NULL) in usb_proc_free()
245 usb_proc_drain(up); in usb_proc_free()
247 cv_destroy(&up->up_cv); in usb_proc_free()
248 cv_destroy(&up->up_drain); in usb_proc_free()
251 up->up_mtx = NULL; in usb_proc_free()
254 /*------------------------------------------------------------------------*
264 *------------------------------------------------------------------------*/
266 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1) in usb_proc_msignal() argument
275 if (up->up_gone != 0 || in usb_proc_msignal()
279 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); in usb_proc_msignal()
283 if (pm0->pm_qentry.tqe_prev) { in usb_proc_msignal()
286 if (pm1->pm_qentry.tqe_prev) { in usb_proc_msignal()
296 /* Check if we need to increment the message number. */ in usb_proc_msignal()
297 if (pm0->pm_num == up->up_msg_num) { in usb_proc_msignal()
298 up->up_msg_num++; in usb_proc_msignal()
302 /* Check if we need to increment the message number. */ in usb_proc_msignal()
303 if (pm1->pm_num == up->up_msg_num) { in usb_proc_msignal()
304 up->up_msg_num++; in usb_proc_msignal()
309 * Both entries are queued. Re-queue the entry closest to in usb_proc_msignal()
312 d = (pm1->pm_num - pm0->pm_num); in usb_proc_msignal()
321 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry); in usb_proc_msignal()
323 pm2 = NULL; /* panic - should not happen */ in usb_proc_msignal()
326 DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num); in usb_proc_msignal()
330 pm2->pm_num = up->up_msg_num; in usb_proc_msignal()
331 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry); in usb_proc_msignal()
333 /* Check if we need to wakeup the USB process. */ in usb_proc_msignal()
335 if (up->up_msleep) { in usb_proc_msignal()
336 up->up_msleep = 0; /* save "cv_signal()" calls */ in usb_proc_msignal()
337 cv_signal(&up->up_cv); in usb_proc_msignal()
342 /*------------------------------------------------------------------------*
348 *------------------------------------------------------------------------*/
350 usb_proc_is_gone(struct usb_process *up) in usb_proc_is_gone() argument
352 if (up->up_gone) in usb_proc_is_gone()
359 if (up->up_mtx != NULL) in usb_proc_is_gone()
360 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); in usb_proc_is_gone()
365 usb_proc_mwait_impl(struct usb_process *up, void *_pm0, void *_pm1, in usb_proc_mwait_impl() argument
373 if (up->up_gone) in usb_proc_mwait_impl()
376 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); in usb_proc_mwait_impl()
379 if (up->up_curtd == curthread) { in usb_proc_mwait_impl()
381 if (pm0->pm_qentry.tqe_prev) { in usb_proc_mwait_impl()
382 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry); in usb_proc_mwait_impl()
383 pm0->pm_qentry.tqe_prev = NULL; in usb_proc_mwait_impl()
385 if (pm1->pm_qentry.tqe_prev) { in usb_proc_mwait_impl()
386 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry); in usb_proc_mwait_impl()
387 pm1->pm_qentry.tqe_prev = NULL; in usb_proc_mwait_impl()
390 while (error == 0 && (pm0->pm_qentry.tqe_prev || in usb_proc_mwait_impl()
391 pm1->pm_qentry.tqe_prev)) { in usb_proc_mwait_impl()
393 if (up->up_gone) in usb_proc_mwait_impl()
395 up->up_dsleep = 1; in usb_proc_mwait_impl()
397 error = cv_wait_sig(&up->up_drain, up->up_mtx); in usb_proc_mwait_impl()
407 cv_wait(&up->up_drain, up->up_mtx); in usb_proc_mwait_impl()
416 /*------------------------------------------------------------------------*
419 * This function will return when the USB process message pointed to
421 * having "up->up_mtx" locked.
422 *------------------------------------------------------------------------*/
424 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) in usb_proc_mwait() argument
427 (void)usb_proc_mwait_impl(up, _pm0, _pm1, false); in usb_proc_mwait()
430 /*------------------------------------------------------------------------*
433 * This function will return when the USB process message pointed to
435 * having "up->up_mtx" locked. This version of usb_proc_mwait is
437 *------------------------------------------------------------------------*/
439 usb_proc_mwait_sig(struct usb_process *up, void *_pm0, void *_pm1) in usb_proc_mwait_sig() argument
442 return (usb_proc_mwait_impl(up, _pm0, _pm1, true)); in usb_proc_mwait_sig()
445 /*------------------------------------------------------------------------*
449 * currently executing command to return.
451 * NOTE: If the structure pointed to by "up" is all zero,
453 *------------------------------------------------------------------------*/
455 usb_proc_drain(struct usb_process *up) in usb_proc_drain() argument
458 if (up->up_mtx == NULL) in usb_proc_drain()
461 if (up->up_mtx != &Giant) in usb_proc_drain()
462 USB_MTX_ASSERT(up->up_mtx, MA_NOTOWNED); in usb_proc_drain()
464 USB_MTX_LOCK(up->up_mtx); in usb_proc_drain()
468 up->up_gone = 1; in usb_proc_drain()
470 while (up->up_ptr) { in usb_proc_drain()
471 /* Check if we need to wakeup the USB process */ in usb_proc_drain()
473 if (up->up_msleep || up->up_csleep) { in usb_proc_drain()
474 up->up_msleep = 0; in usb_proc_drain()
475 up->up_csleep = 0; in usb_proc_drain()
476 cv_signal(&up->up_cv); in usb_proc_drain()
481 USB_THREAD_SUSPEND(up->up_ptr); in usb_proc_drain()
487 cv_wait(&up->up_cv, up->up_mtx); in usb_proc_drain()
489 /* Check if someone is waiting - should not happen */ in usb_proc_drain()
491 if (up->up_dsleep) { in usb_proc_drain()
492 up->up_dsleep = 0; in usb_proc_drain()
493 cv_broadcast(&up->up_drain); in usb_proc_drain()
497 USB_MTX_UNLOCK(up->up_mtx); in usb_proc_drain()
500 /*------------------------------------------------------------------------*
503 * This function is called to re-wakeup the given USB
506 * having "up->up_mtx" locked.
507 *------------------------------------------------------------------------*/
509 usb_proc_rewakeup(struct usb_process *up) in usb_proc_rewakeup() argument
512 if (up->up_mtx == NULL) in usb_proc_rewakeup()
515 if (up->up_gone) in usb_proc_rewakeup()
518 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); in usb_proc_rewakeup()
520 if (up->up_msleep == 0) { in usb_proc_rewakeup()
521 /* re-wakeup */ in usb_proc_rewakeup()
522 cv_signal(&up->up_cv); in usb_proc_rewakeup()
526 /*------------------------------------------------------------------------*
529 * This function will return non-zero if called from inside the USB
531 *------------------------------------------------------------------------*/
533 usb_proc_is_called_from(struct usb_process *up) in usb_proc_is_called_from() argument
535 return (up->up_curtd == curthread); in usb_proc_is_called_from()