svn commit: r212280 - in user/weongyo/usb/sys: dev/usb
modules/usb/usb
Weongyo Jeong
weongyo at FreeBSD.org
Mon Sep 6 23:52:05 UTC 2010
Author: weongyo
Date: Mon Sep 6 23:52:04 2010
New Revision: 212280
URL: http://svn.freebsd.org/changeset/base/212280
Log:
Adds `sleepout' prototype which is a comic combination of callout(9) and
taskqueue(8) only for USB drivers to implement one step timer. In
current USB drivers using callout(9) interface they all have two step
execution flow as follows:
1. callout callback is fired by the interrupt context. Then it needs
to pass it to USB process context because it could sleep(!) while
callout(9) don't allow it.
2. In the USB process context it operates USB commands that most of
times it'd be blocked at least 125 us (it'd be always true for USB)
In a view of driver developer it'd be more convenient if USB stack has a
feature like this (timer supporting blocking). This's an experimental.
Added:
user/weongyo/usb/sys/dev/usb/usb_sleepout.c (contents, props changed)
user/weongyo/usb/sys/dev/usb/usb_sleepout.h (contents, props changed)
Modified:
user/weongyo/usb/sys/modules/usb/usb/Makefile
Added: user/weongyo/usb/sys/dev/usb/usb_sleepout.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/weongyo/usb/sys/dev/usb/usb_sleepout.c Mon Sep 6 23:52:04 2010 (r212280)
@@ -0,0 +1,123 @@
+/*-
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+
+#include <dev/usb/usb_sleepout.h>
+
+void
+sleepout_create(struct sleepout *s, const char *name)
+{
+
+ s->s_taskqueue = taskqueue_create(name, M_WAITOK,
+ taskqueue_thread_enqueue, &s->s_taskqueue);
+ /* XXX adjusts the priority. */
+ taskqueue_start_threads(&s->s_taskqueue, 1, PI_NET, "%s sleepout",
+ name);
+}
+
+void
+sleepout_free(struct sleepout *s)
+{
+
+ taskqueue_free(s->s_taskqueue);
+}
+
+static void
+_sleepout_taskqueue_callback(void *arg, int pending)
+{
+ struct sleepout_task *st = arg;
+
+ (void)pending;
+
+ if (st->st_mtx != NULL)
+ mtx_lock(st->st_mtx);
+
+ st->st_func(st->st_arg);
+
+ if (st->st_mtx != NULL)
+ mtx_unlock(st->st_mtx);
+}
+
+void
+sleepout_init(struct sleepout *s, struct sleepout_task *st, int mpsafe)
+{
+
+ st->st_sleepout = s;
+ callout_init(&st->st_callout, mpsafe);
+ TASK_INIT(&st->st_task, 0, _sleepout_taskqueue_callback, st);
+ st->st_mtx = NULL;
+}
+
+void
+sleepout_init_mtx(struct sleepout *s, struct sleepout_task *st, struct mtx *mtx,
+ int flags)
+{
+
+ st->st_sleepout = s;
+ callout_init_mtx(&st->st_callout, mtx, flags);
+ TASK_INIT(&st->st_task, 0, _sleepout_taskqueue_callback, st);
+ st->st_mtx = mtx;
+}
+
+static void
+_sleepout_callout_callback(void *arg)
+{
+ struct sleepout_task *st = arg;
+ struct sleepout *s = st->st_sleepout;
+
+ taskqueue_enqueue(s->s_taskqueue, &st->st_task);
+}
+
+int
+sleepout_reset(struct sleepout_task *st, int to_ticks, sleepout_func_t ftn,
+ void *arg)
+{
+
+ st->st_func = ftn;
+ st->st_arg = arg;
+ return (callout_reset(&st->st_callout, to_ticks,
+ _sleepout_callout_callback, st));
+}
+
+int
+sleepout_pending(struct sleepout_task *st)
+{
+
+ return (callout_pending(&st->st_callout));
+}
+
+int
+sleepout_stop(struct sleepout_task *st)
+{
+
+ return (callout_stop(&st->st_callout));
+}
+
+int
+sleepout_drain(struct sleepout_task *st)
+{
+ struct sleepout *s = st->st_sleepout;
+
+ taskqueue_drain(s->s_taskqueue, &st->st_task);
+ return (callout_drain(&st->st_callout));
+
+}
Added: user/weongyo/usb/sys/dev/usb/usb_sleepout.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/weongyo/usb/sys/dev/usb/usb_sleepout.h Mon Sep 6 23:52:04 2010 (r212280)
@@ -0,0 +1,48 @@
+/*-
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _USB_SLEEPOUT_H_
+#define _USB_SLEEPOUT_H_
+
+#include <sys/callout.h>
+#include <sys/taskqueue.h>
+
+struct sleepout {
+ struct taskqueue *s_taskqueue;
+};
+
+typedef void (*sleepout_func_t)(void *);
+
+struct sleepout_task {
+ struct sleepout *st_sleepout;
+ struct callout st_callout;
+ struct task st_task;
+ struct mtx *st_mtx;
+ sleepout_func_t st_func;
+ void *st_arg;
+};
+
+void sleepout_create(struct sleepout *, const char *);
+void sleepout_free(struct sleepout *);
+void sleepout_init(struct sleepout *, struct sleepout_task *, int);
+void sleepout_init_mtx(struct sleepout *, struct sleepout_task *,
+ struct mtx *, int);
+int sleepout_reset(struct sleepout_task *, int, sleepout_func_t, void *);
+int sleepout_pending(struct sleepout_task *);
+int sleepout_stop(struct sleepout_task *);
+int sleepout_drain(struct sleepout_task *);
+
+#endif
Modified: user/weongyo/usb/sys/modules/usb/usb/Makefile
==============================================================================
--- user/weongyo/usb/sys/modules/usb/usb/Makefile Mon Sep 6 23:11:56 2010 (r212279)
+++ user/weongyo/usb/sys/modules/usb/usb/Makefile Mon Sep 6 23:52:04 2010 (r212280)
@@ -33,10 +33,11 @@ KMOD= usb
SRCS= bus_if.h device_if.h usb_if.h usb_if.c vnode_if.h \
opt_usb.h opt_bus.h opt_ddb.h \
usbdevs.h usbdevs_data.h \
+ usb_sleepout.h \
usb_busdma.c usb_controller.c usb_compat_linux.c usb_core.c usb_debug.c \
usb_dev.c usb_device.c usb_dynamic.c usb_error.c usb_generic.c \
usb_handle_request.c usb_hid.c usb_hub.c usb_lookup.c usb_mbuf.c \
usb_msctest.c usb_parse.c usb_process.c usb_request.c \
- usb_transfer.c usb_util.c
+ usb_sleepout.c usb_transfer.c usb_util.c
.include <bsd.kmod.mk>
More information about the svn-src-user
mailing list