1 /* $FreeBSD: releng/8.3/sys/dev/usb/usb_process.c 227287 2011-11-06 23:34:40Z hselasky $ */
2 /*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #define USB_DEBUG_VAR usb_proc_debug
28
29 #include <sys/stdint.h>
30 #include <sys/stddef.h>
31 #include <sys/param.h>
32 #include <sys/queue.h>
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/bus.h>
37 #include <sys/module.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/condvar.h>
41 #include <sys/sysctl.h>
42 #include <sys/sx.h>
43 #include <sys/unistd.h>
44 #include <sys/callout.h>
45 #include <sys/malloc.h>
46 #include <sys/priv.h>
47
48 #include <dev/usb/usb.h>
49 #include <dev/usb/usbdi.h>
50 #include <dev/usb/usbdi_util.h>
51 #include <dev/usb/usb_process.h>
52 #include <dev/usb/usb_debug.h>
53 #include <dev/usb/usb_util.h>
54
55 #include <sys/proc.h>
56 #include <sys/kthread.h>
57 #include <sys/sched.h>
58
59 #if (__FreeBSD_version < 700000)
60 #define thread_lock(td) mtx_lock_spin(&sched_lock)
61 #define thread_unlock(td) mtx_unlock_spin(&sched_lock)
62 #endif
63
64 #if (__FreeBSD_version >= 800000)
65 static struct proc *usbproc;
66 static int usb_pcount;
67 #define USB_THREAD_CREATE(f, s, p, ...) \
68 kproc_kthread_add((f), (s), &usbproc, (p), RFHIGHPID, \
69 0, "usb", __VA_ARGS__)
70 #if (__FreeBSD_version >= 900000)
71 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check()
72 #else
73 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check(curthread)
74 #endif
75 #define USB_THREAD_SUSPEND(p) kthread_suspend(p,0)
76 #define USB_THREAD_EXIT(err) kthread_exit()
77 #else
78 #define USB_THREAD_CREATE(f, s, p, ...) \
79 kthread_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__)
80 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check(curproc)
81 #define USB_THREAD_SUSPEND(p) kthread_suspend(p,0)
82 #define USB_THREAD_EXIT(err) kthread_exit(err)
83 #endif
84
85 #ifdef USB_DEBUG
86 static int usb_proc_debug;
87
88 SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process");
89 SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RW, &usb_proc_debug, 0,
90 "Debug level");
91
92 TUNABLE_INT("hw.usb.proc.debug", &usb_proc_debug);
93 #endif
94
95 /*------------------------------------------------------------------------*
96 * usb_process
97 *
98 * This function is the USB process dispatcher.
99 *------------------------------------------------------------------------*/
100 static void
101 usb_process(void *arg)
102 {
103 struct usb_process *up = arg;
104 struct usb_proc_msg *pm;
105 struct thread *td;
106
107 /* in case of attach error, check for suspended */
108 USB_THREAD_SUSPEND_CHECK();
109
110 /* adjust priority */
111 td = curthread;
112 thread_lock(td);
113 sched_prio(td, up->up_prio);
114 thread_unlock(td);
115
116 mtx_lock(up->up_mtx);
117
118 up->up_curtd = td;
119
120 while (1) {
121
122 if (up->up_gone)
123 break;
124
125 /*
126 * NOTE to reimplementors: dequeueing a command from the
127 * "used" queue and executing it must be atomic, with regard
128 * to the "up_mtx" mutex. That means any attempt to queue a
129 * command by another thread must be blocked until either:
130 *
131 * 1) the command sleeps
132 *
133 * 2) the command returns
134 *
135 * Here is a practical example that shows how this helps
136 * solving a problem:
137 *
138 * Assume that you want to set the baud rate on a USB serial
139 * device. During the programming of the device you don't
140 * want to receive nor transmit any data, because it will be
141 * garbage most likely anyway. The programming of our USB
142 * device takes 20 milliseconds and it needs to call
143 * functions that sleep.
144 *
145 * Non-working solution: Before we queue the programming
146 * command, we stop transmission and reception of data. Then
147 * we queue a programming command. At the end of the
148 * programming command we enable transmission and reception
149 * of data.
150 *
151 * Problem: If a second programming command is queued while the
152 * first one is sleeping, we end up enabling transmission
153 * and reception of data too early.
154 *
155 * Working solution: Before we queue the programming command,
156 * we stop transmission and reception of data. Then we queue
157 * a programming command. Then we queue a second command
158 * that only enables transmission and reception of data.
159 *
160 * Why it works: If a second programming command is queued
161 * while the first one is sleeping, then the queueing of a
162 * second command to enable the data transfers, will cause
163 * the previous one, which is still on the queue, to be
164 * removed from the queue, and re-inserted after the last
165 * baud rate programming command, which then gives the
166 * desired result.
167 */
168 pm = TAILQ_FIRST(&up->up_qhead);
169
170 if (pm) {
171 DPRINTF("Message pm=%p, cb=%p (enter)\n",
172 pm, pm->pm_callback);
173
174 (pm->pm_callback) (pm);
175
176 if (pm == TAILQ_FIRST(&up->up_qhead)) {
177 /* nothing changed */
178 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
179 pm->pm_qentry.tqe_prev = NULL;
180 }
181 DPRINTF("Message pm=%p (leave)\n", pm);
182
183 continue;
184 }
185 /* end if messages - check if anyone is waiting for sync */
186 if (up->up_dsleep) {
187 up->up_dsleep = 0;
188 cv_broadcast(&up->up_drain);
189 }
190 up->up_msleep = 1;
191 cv_wait(&up->up_cv, up->up_mtx);
192 }
193
194 up->up_ptr = NULL;
195 cv_signal(&up->up_cv);
196 mtx_unlock(up->up_mtx);
197 #if (__FreeBSD_version >= 800000)
198 /* Clear the proc pointer if this is the last thread. */
199 if (--usb_pcount == 0)
200 usbproc = NULL;
201 #endif
202
203 USB_THREAD_EXIT(0);
204 }
205
206 /*------------------------------------------------------------------------*
207 * usb_proc_create
208 *
209 * This function will create a process using the given "prio" that can
210 * execute callbacks. The mutex pointed to by "p_mtx" will be applied
211 * before calling the callbacks and released after that the callback
212 * has returned. The structure pointed to by "up" is assumed to be
213 * zeroed before this function is called.
214 *
215 * Return values:
216 * 0: success
217 * Else: failure
218 *------------------------------------------------------------------------*/
219 int
220 usb_proc_create(struct usb_process *up, struct mtx *p_mtx,
221 const char *pmesg, uint8_t prio)
222 {
223 up->up_mtx = p_mtx;
224 up->up_prio = prio;
225
226 TAILQ_INIT(&up->up_qhead);
227
228 cv_init(&up->up_cv, "-");
229 cv_init(&up->up_drain, "usbdrain");
230
231 if (USB_THREAD_CREATE(&usb_process, up,
232 &up->up_ptr, "%s", pmesg)) {
233 DPRINTFN(0, "Unable to create USB process.");
234 up->up_ptr = NULL;
235 goto error;
236 }
237 #if (__FreeBSD_version >= 800000)
238 usb_pcount++;
239 #endif
240 return (0);
241
242 error:
243 usb_proc_free(up);
244 return (ENOMEM);
245 }
246
247 /*------------------------------------------------------------------------*
248 * usb_proc_free
249 *
250 * NOTE: If the structure pointed to by "up" is all zero, this
251 * function does nothing.
252 *
253 * NOTE: Messages that are pending on the process queue will not be
254 * removed nor called.
255 *------------------------------------------------------------------------*/
256 void
257 usb_proc_free(struct usb_process *up)
258 {
259 /* check if not initialised */
260 if (up->up_mtx == NULL)
261 return;
262
263 usb_proc_drain(up);
264
265 cv_destroy(&up->up_cv);
266 cv_destroy(&up->up_drain);
267
268 /* make sure that we do not enter here again */
269 up->up_mtx = NULL;
270 }
271
272 /*------------------------------------------------------------------------*
273 * usb_proc_msignal
274 *
275 * This function will queue one of the passed USB process messages on
276 * the USB process queue. The first message that is not already queued
277 * will get queued. If both messages are already queued the one queued
278 * last will be removed from the queue and queued in the end. The USB
279 * process mutex must be locked when calling this function. This
280 * function exploits the fact that a process can only do one callback
281 * at a time. The message that was queued is returned.
282 *------------------------------------------------------------------------*/
283 void *
284 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
285 {
286 struct usb_proc_msg *pm0 = _pm0;
287 struct usb_proc_msg *pm1 = _pm1;
288 struct usb_proc_msg *pm2;
289 usb_size_t d;
290 uint8_t t;
291
292 /* check if gone, return dummy value */
293 if (up->up_gone)
294 return (_pm0);
295
296 mtx_assert(up->up_mtx, MA_OWNED);
297
298 t = 0;
299
300 if (pm0->pm_qentry.tqe_prev) {
301 t |= 1;
302 }
303 if (pm1->pm_qentry.tqe_prev) {
304 t |= 2;
305 }
306 if (t == 0) {
307 /*
308 * No entries are queued. Queue "pm0" and use the existing
309 * message number.
310 */
311 pm2 = pm0;
312 } else if (t == 1) {
313 /* Check if we need to increment the message number. */
314 if (pm0->pm_num == up->up_msg_num) {
315 up->up_msg_num++;
316 }
317 pm2 = pm1;
318 } else if (t == 2) {
319 /* Check if we need to increment the message number. */
320 if (pm1->pm_num == up->up_msg_num) {
321 up->up_msg_num++;
322 }
323 pm2 = pm0;
324 } else if (t == 3) {
325 /*
326 * Both entries are queued. Re-queue the entry closest to
327 * the end.
328 */
329 d = (pm1->pm_num - pm0->pm_num);
330
331 /* Check sign after subtraction */
332 if (d & 0x80000000) {
333 pm2 = pm0;
334 } else {
335 pm2 = pm1;
336 }
337
338 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
339 } else {
340 pm2 = NULL; /* panic - should not happen */
341 }
342
343 DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num);
344
345 /* Put message last on queue */
346
347 pm2->pm_num = up->up_msg_num;
348 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
349
350 /* Check if we need to wakeup the USB process. */
351
352 if (up->up_msleep) {
353 up->up_msleep = 0; /* save "cv_signal()" calls */
354 cv_signal(&up->up_cv);
355 }
356 return (pm2);
357 }
358
359 /*------------------------------------------------------------------------*
360 * usb_proc_is_gone
361 *
362 * Return values:
363 * 0: USB process is running
364 * Else: USB process is tearing down
365 *------------------------------------------------------------------------*/
366 uint8_t
367 usb_proc_is_gone(struct usb_process *up)
368 {
369 if (up->up_gone)
370 return (1);
371
372 /*
373 * Allow calls when up_mtx is NULL, before the USB process
374 * structure is initialised.
375 */
376 if (up->up_mtx != NULL)
377 mtx_assert(up->up_mtx, MA_OWNED);
378 return (0);
379 }
380
381 /*------------------------------------------------------------------------*
382 * usb_proc_mwait
383 *
384 * This function will return when the USB process message pointed to
385 * by "pm" is no longer on a queue. This function must be called
386 * having "up->up_mtx" locked.
387 *------------------------------------------------------------------------*/
388 void
389 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
390 {
391 struct usb_proc_msg *pm0 = _pm0;
392 struct usb_proc_msg *pm1 = _pm1;
393
394 /* check if gone */
395 if (up->up_gone)
396 return;
397
398 mtx_assert(up->up_mtx, MA_OWNED);
399
400 if (up->up_curtd == curthread) {
401 /* Just remove the messages from the queue. */
402 if (pm0->pm_qentry.tqe_prev) {
403 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
404 pm0->pm_qentry.tqe_prev = NULL;
405 }
406 if (pm1->pm_qentry.tqe_prev) {
407 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
408 pm1->pm_qentry.tqe_prev = NULL;
409 }
410 } else
411 while (pm0->pm_qentry.tqe_prev ||
412 pm1->pm_qentry.tqe_prev) {
413 /* check if config thread is gone */
414 if (up->up_gone)
415 break;
416 up->up_dsleep = 1;
417 cv_wait(&up->up_drain, up->up_mtx);
418 }
419 }
420
421 /*------------------------------------------------------------------------*
422 * usb_proc_drain
423 *
424 * This function will tear down an USB process, waiting for the
425 * currently executing command to return.
426 *
427 * NOTE: If the structure pointed to by "up" is all zero,
428 * this function does nothing.
429 *------------------------------------------------------------------------*/
430 void
431 usb_proc_drain(struct usb_process *up)
432 {
433 /* check if not initialised */
434 if (up->up_mtx == NULL)
435 return;
436 /* handle special case with Giant */
437 if (up->up_mtx != &Giant)
438 mtx_assert(up->up_mtx, MA_NOTOWNED);
439
440 mtx_lock(up->up_mtx);
441
442 /* Set the gone flag */
443
444 up->up_gone = 1;
445
446 while (up->up_ptr) {
447
448 /* Check if we need to wakeup the USB process */
449
450 if (up->up_msleep || up->up_csleep) {
451 up->up_msleep = 0;
452 up->up_csleep = 0;
453 cv_signal(&up->up_cv);
454 }
455 /* Check if we are still cold booted */
456
457 if (cold) {
458 USB_THREAD_SUSPEND(up->up_ptr);
459 printf("WARNING: A USB process has "
460 "been left suspended\n");
461 break;
462 }
463 cv_wait(&up->up_cv, up->up_mtx);
464 }
465 /* Check if someone is waiting - should not happen */
466
467 if (up->up_dsleep) {
468 up->up_dsleep = 0;
469 cv_broadcast(&up->up_drain);
470 DPRINTF("WARNING: Someone is waiting "
471 "for USB process drain!\n");
472 }
473 mtx_unlock(up->up_mtx);
474 }
475
476 /*------------------------------------------------------------------------*
477 * usb_proc_rewakeup
478 *
479 * This function is called to re-wakeup the given USB
480 * process. This usually happens after that the USB system has been in
481 * polling mode, like during a panic. This function must be called
482 * having "up->up_mtx" locked.
483 *------------------------------------------------------------------------*/
484 void
485 usb_proc_rewakeup(struct usb_process *up)
486 {
487 /* check if not initialised */
488 if (up->up_mtx == NULL)
489 return;
490 /* check if gone */
491 if (up->up_gone)
492 return;
493
494 mtx_assert(up->up_mtx, MA_OWNED);
495
496 if (up->up_msleep == 0) {
497 /* re-wakeup */
498 cv_signal(&up->up_cv);
499 }
500 }
Cache object: 8c84601258b3f72f32d0ce4c46d98e56
|