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