svn commit: r212584 - in user/weongyo/usb/sys/dev/usb: . controller
Weongyo Jeong
weongyo at FreeBSD.org
Mon Sep 13 22:27:53 UTC 2010
Author: weongyo
Date: Mon Sep 13 22:27:52 2010
New Revision: 212584
URL: http://svn.freebsd.org/changeset/base/212584
Log:
`struct usb_process' for giant_callback_proc, non_giant_callback_proc
and control_xfer_proc are changed to taskqueue(9) based implmentation.
From this point AFAIK there's no consumers to use usb_process.[ch] files
so as further works it'll be removed.
Modified:
user/weongyo/usb/sys/dev/usb/controller/usb_controller.c
user/weongyo/usb/sys/dev/usb/usb_bus.h
user/weongyo/usb/sys/dev/usb/usb_device.c
user/weongyo/usb/sys/dev/usb/usb_device.h
user/weongyo/usb/sys/dev/usb/usb_transfer.c
user/weongyo/usb/sys/dev/usb/usb_transfer.h
Modified: user/weongyo/usb/sys/dev/usb/controller/usb_controller.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/controller/usb_controller.c Mon Sep 13 20:29:09 2010 (r212583)
+++ user/weongyo/usb/sys/dev/usb/controller/usb_controller.c Mon Sep 13 22:27:52 2010 (r212584)
@@ -173,17 +173,12 @@ usb_detach(device_t dev)
taskqueue_enqueue(bus->explore_tq, &bus->detach_task);
taskqueue_drain(bus->explore_tq, &bus->detach_task);
- /* Get rid of USB callback processes */
-
- usb_proc_free(&bus->giant_callback_proc);
- usb_proc_free(&bus->non_giant_callback_proc);
-
+ /* Get rid of USB taskqueues */
+ taskqueue_free(bus->giant_callback_tq);
+ taskqueue_free(bus->non_giant_callback_tq);
+ taskqueue_free(bus->control_xfer_tq);
taskqueue_free(bus->explore_tq);
- /* Get rid of control transfer process */
-
- usb_proc_free(&bus->control_xfer_proc);
-
return (0);
}
@@ -214,9 +209,9 @@ usb_bus_explore(void *arg, int npending)
* The following three lines of code are only here to
* recover from DDB:
*/
- usb_proc_rewakeup(&bus->control_xfer_proc);
- usb_proc_rewakeup(&bus->giant_callback_proc);
- usb_proc_rewakeup(&bus->non_giant_callback_proc);
+ taskqueue_unblock(bus->control_xfer_tq);
+ taskqueue_unblock(bus->giant_callback_tq);
+ taskqueue_unblock(bus->non_giant_callback_tq);
#endif
USB_BUS_UNLOCK(bus);
@@ -412,27 +407,26 @@ usb_attach_sub(device_t dev, struct usb_
TASK_INIT(&bus->detach_task, 0, usb_bus_detach, bus);
TASK_INIT(&bus->explore_task, 0, usb_bus_explore, bus);
- /* Create USB explore and callback processes */
-
- if (usb_proc_create(&bus->giant_callback_proc,
- &bus->bus_mtx, pname, USB_PRI_MED)) {
- printf("WARNING: Creation of USB Giant "
- "callback process failed.\n");
- } else if (usb_proc_create(&bus->non_giant_callback_proc,
- &bus->bus_mtx, pname, USB_PRI_HIGH)) {
- printf("WARNING: Creation of USB non-Giant "
- "callback process failed.\n");
- } else if (usb_proc_create(&bus->control_xfer_proc,
- &bus->bus_mtx, pname, USB_PRI_MED)) {
- printf("WARNING: Creation of USB control transfer "
- "process failed.\n");
- } else {
- /* Get final attach going */
- taskqueue_enqueue(bus->explore_tq, &bus->attach_task);
-
- /* Do initial explore */
- usb_needs_explore(bus, 1);
- }
+ /* Creates USB taskqueues for callback and control transfer */
+ bus->giant_callback_tq = taskqueue_create("usb_giant_callback_taskq",
+ M_WAITOK, taskqueue_thread_enqueue, &bus->giant_callback_tq);
+ bus->non_giant_callback_tq =
+ taskqueue_create("usb_non_giant_callback_taskq", M_WAITOK,
+ taskqueue_thread_enqueue, &bus->non_giant_callback_tq);
+ bus->control_xfer_tq = taskqueue_create("usb_ctrlxfer_taskq", M_WAITOK,
+ taskqueue_thread_enqueue, &bus->control_xfer_tq);
+ /* Creates taskqueue threads */
+ taskqueue_start_threads(&bus->giant_callback_tq, 1, USB_PRI_MED,
+ "%s giant callback taskq", pname);
+ taskqueue_start_threads(&bus->non_giant_callback_tq, 1, USB_PRI_HIGH,
+ "%s non giant callback taskq", pname);
+ taskqueue_start_threads(&bus->control_xfer_tq, 1, USB_PRI_MED,
+ "%s control xfer taskq", pname);
+
+ /* Get final attach going */
+ taskqueue_enqueue(bus->explore_tq, &bus->attach_task);
+ /* Do initial explore */
+ usb_needs_explore(bus, 1);
}
SYSUNINIT(usb_bus_unload, SI_SUB_KLD, SI_ORDER_ANY, usb_bus_unload, NULL);
Modified: user/weongyo/usb/sys/dev/usb/usb_bus.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/usb_bus.h Mon Sep 13 20:29:09 2010 (r212583)
+++ user/weongyo/usb/sys/dev/usb/usb_bus.h Mon Sep 13 22:27:52 2010 (r212584)
@@ -55,15 +55,14 @@ struct usb_bus {
struct usb_bus_stat stats_ok;
struct root_hold_token *bus_roothold;
/*
- * There are two callback processes. One for Giant locked
+ * There are two taskqueues for callback. One for Giant locked
* callbacks. One for non-Giant locked callbacks. This should
* avoid congestion and reduce response time in most cases.
*/
- struct usb_process giant_callback_proc;
- struct usb_process non_giant_callback_proc;
-
- /* Control request process */
- struct usb_process control_xfer_proc;
+ struct taskqueue *giant_callback_tq;
+ struct taskqueue *non_giant_callback_tq;
+ /* Control request taskqueue */
+ struct taskqueue *control_xfer_tq;
/* Explore taskqueue */
struct taskqueue *explore_tq;
Modified: user/weongyo/usb/sys/dev/usb/usb_device.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/usb_device.c Mon Sep 13 20:29:09 2010 (r212583)
+++ user/weongyo/usb/sys/dev/usb/usb_device.c Mon Sep 13 22:27:52 2010 (r212584)
@@ -89,7 +89,7 @@ static void usb_init_attach_arg(struct u
struct usb_attach_arg *);
static void usb_suspend_resume_sub(struct usb_device *, device_t,
uint8_t);
-static void usbd_clear_stall_proc(struct usb_proc_msg *_pm);
+static void usbd_clear_stall_proc(void *, int);
usb_error_t usb_config_parse(struct usb_device *, uint8_t, uint8_t);
static void usbd_set_device_strings(struct usb_device *);
#if USB_HAVE_UGEN
@@ -1437,21 +1437,15 @@ usb_suspend_resume(struct usb_device *ud
* This function performs generic USB clear stall operations.
*------------------------------------------------------------------------*/
static void
-usbd_clear_stall_proc(struct usb_proc_msg *_pm)
+usbd_clear_stall_proc(void *arg, int npending)
{
- struct usb_clear_stall_msg *pm = (void *)_pm;
- struct usb_device *udev = pm->udev;
+ struct usb_device *udev = arg;
- /* Change lock */
- USB_BUS_UNLOCK(udev->bus);
mtx_lock(&udev->device_mtx);
-
/* Start clear stall callback */
usbd_transfer_start(udev->ctrl_xfer[1]);
-
/* Change lock */
mtx_unlock(&udev->device_mtx);
- USB_BUS_LOCK(udev->bus);
}
/*------------------------------------------------------------------------*
@@ -1529,10 +1523,7 @@ usb_alloc_device(device_t parent_dev, st
mtx_init(&udev->device_mtx, "USB device mutex", NULL, MTX_DEF);
/* initialise generic clear stall */
- udev->cs_msg[0].hdr.pm_callback = &usbd_clear_stall_proc;
- udev->cs_msg[0].udev = udev;
- udev->cs_msg[1].hdr.pm_callback = &usbd_clear_stall_proc;
- udev->cs_msg[1].udev = udev;
+ TASK_INIT(&udev->cs_task, 0, usbd_clear_stall_proc, udev);
/* initialise some USB device fields */
udev->parent_hub = parent_hub;
@@ -2058,10 +2049,7 @@ usb_free_device(struct usb_device *udev,
* Make sure that our clear-stall messages are not queued
* anywhere:
*/
- USB_BUS_LOCK(udev->bus);
- usb_proc_mwait(&udev->bus->non_giant_callback_proc,
- &udev->cs_msg[0], &udev->cs_msg[1]);
- USB_BUS_UNLOCK(udev->bus);
+ taskqueue_drain(udev->bus->non_giant_callback_tq, &udev->cs_task);
sx_destroy(&udev->ctrl_sx);
sx_destroy(&udev->enum_sx);
Modified: user/weongyo/usb/sys/dev/usb/usb_device.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/usb_device.h Mon Sep 13 20:29:09 2010 (r212583)
+++ user/weongyo/usb/sys/dev/usb/usb_device.h Mon Sep 13 22:27:52 2010 (r212584)
@@ -27,6 +27,8 @@
#ifndef _USB_DEVICE_H_
#define _USB_DEVICE_H_
+#include <sys/taskqueue.h>
+
struct usb_symlink; /* UGEN */
struct usb_device; /* linux compat */
@@ -43,11 +45,6 @@ struct usb_device; /* linux compat */
#define USB_UNCFG_FLAG_NONE 0x00
#define USB_UNCFG_FLAG_FREE_EP0 0x02 /* endpoint zero is freed */
-struct usb_clear_stall_msg {
- struct usb_proc_msg hdr;
- struct usb_device *udev;
-};
-
/* The following four structures makes up a tree, where we have the
* leaf structure, "usb_host_endpoint", first, and the root structure,
* "usb_device", last. The four structures below mirror the structure
@@ -111,8 +108,8 @@ struct usb_power_save {
* these structures for every USB device.
*/
struct usb_device {
- struct usb_clear_stall_msg cs_msg[2]; /* generic clear stall
- * messages */
+ struct task cs_task; /* generic clear stall messages */
+
struct sx ctrl_sx;
struct sx enum_sx;
struct sx sr_sx;
Modified: user/weongyo/usb/sys/dev/usb/usb_transfer.c
==============================================================================
--- user/weongyo/usb/sys/dev/usb/usb_transfer.c Mon Sep 13 20:29:09 2010 (r212583)
+++ user/weongyo/usb/sys/dev/usb/usb_transfer.c Mon Sep 13 22:27:52 2010 (r212584)
@@ -106,7 +106,7 @@ static void usbd_update_max_frame_size(s
static void usbd_transfer_unsetup_sub(struct usb_xfer_root *, uint8_t);
static void usbd_control_transfer_init(struct usb_xfer *);
static int usbd_setup_ctrl_transfer(struct usb_xfer *);
-static void usb_callback_proc(struct usb_proc_msg *);
+static void usb_callback_proc(void *, int);
static void usbd_callback_ss_done_defer(struct usb_xfer *);
static void usbd_callback_wrapper(struct usb_xfer_queue *);
static void usb_dma_delay_done_cb(void *);
@@ -843,10 +843,7 @@ usbd_transfer_setup(struct usb_device *u
TAILQ_INIT(&info->dma_q.head);
info->dma_q.command = &usb_bdma_work_loop;
#endif
- info->done_m[0].hdr.pm_callback = &usb_callback_proc;
- info->done_m[0].xroot = info;
- info->done_m[1].hdr.pm_callback = &usb_callback_proc;
- info->done_m[1].xroot = info;
+ TASK_INIT(&info->done_task, 0, usb_callback_proc, info);
/*
* In device side mode control endpoint
@@ -855,14 +852,12 @@ usbd_transfer_setup(struct usb_device *u
* deadlock!
*/
if (setup_start == usb_control_ep_cfg)
- info->done_p =
- &udev->bus->control_xfer_proc;
+ info->done_tq = udev->bus->control_xfer_tq;
else if (xfer_mtx == &Giant)
- info->done_p =
- &udev->bus->giant_callback_proc;
+ info->done_tq = udev->bus->giant_callback_tq;
else
- info->done_p =
- &udev->bus->non_giant_callback_proc;
+ info->done_tq =
+ udev->bus->non_giant_callback_tq;
}
/* reset sizes */
@@ -1105,11 +1100,11 @@ usbd_transfer_unsetup_sub(struct usb_xfe
}
}
- /* make sure that our done messages are not queued anywhere */
- usb_proc_mwait(info->done_p, &info->done_m[0], &info->done_m[1]);
-
USB_BUS_UNLOCK(info->bus);
+ /* make sure that our done messages are not queued anywhere */
+ taskqueue_drain(info->done_tq, &info->done_task);
+
#if USB_HAVE_BUSDMA
/* free DMA'able memory, if any */
pc = info->dma_page_cache_start;
@@ -1992,13 +1987,9 @@ usbd_xfer_set_frame_len(struct usb_xfer
* This function performs USB callbacks.
*------------------------------------------------------------------------*/
static void
-usb_callback_proc(struct usb_proc_msg *_pm)
+usb_callback_proc(void *arg, int npending)
{
- struct usb_done_msg *pm = (void *)_pm;
- struct usb_xfer_root *info = pm->xroot;
-
- /* Change locking order */
- USB_BUS_UNLOCK(info->bus);
+ struct usb_xfer_root *info = arg;
/*
* We exploit the fact that the mutex is the same for all
@@ -2012,6 +2003,7 @@ usb_callback_proc(struct usb_proc_msg *_
info->done_q.curr);
mtx_unlock(info->xfer_mtx);
+ USB_BUS_UNLOCK(info->bus);
}
/*------------------------------------------------------------------------*
@@ -2038,10 +2030,7 @@ usbd_callback_ss_done_defer(struct usb_x
* will have a Lock Order Reversal, LOR, if we try to
* proceed !
*/
- if (usb_proc_msignal(info->done_p,
- &info->done_m[0], &info->done_m[1])) {
- /* ignore */
- }
+ taskqueue_enqueue(info->done_tq, &info->done_task);
} else {
/* clear second recurse flag */
pq->recurse_2 = 0;
@@ -2078,10 +2067,7 @@ usbd_callback_wrapper(struct usb_xfer_qu
* will have a Lock Order Reversal, LOR, if we try to
* proceed !
*/
- if (usb_proc_msignal(info->done_p,
- &info->done_m[0], &info->done_m[1])) {
- /* ignore */
- }
+ taskqueue_enqueue(info->done_tq, &info->done_task);
return;
}
/*
@@ -2441,9 +2427,9 @@ usbd_pipe_start(struct usb_xfer_queue *p
udev, NULL, ep, &did_stall);
} else if (udev->ctrl_xfer[1]) {
info = udev->ctrl_xfer[1]->xroot;
- usb_proc_msignal(
- &info->bus->non_giant_callback_proc,
- &udev->cs_msg[0], &udev->cs_msg[1]);
+ taskqueue_enqueue(
+ info->bus->non_giant_callback_tq,
+ &udev->cs_task);
} else {
/* should not happen */
DPRINTFN(0, "No stall handler\n");
@@ -2958,7 +2944,7 @@ usbd_transfer_poll(struct usb_xfer **ppx
struct usb_xfer *xfer;
struct usb_xfer_root *xroot;
struct usb_device *udev;
- struct usb_proc_msg *pm;
+ struct task *task;
uint16_t n;
uint16_t drop_bus;
uint16_t drop_xfer;
@@ -2996,33 +2982,28 @@ usbd_transfer_poll(struct usb_xfer **ppx
}
/* Make sure cv_signal() and cv_broadcast() is not called */
- udev->bus->control_xfer_proc.up_msleep = 0;
+ taskqueue_block(udev->bus->giant_callback_tq);
+ taskqueue_block(udev->bus->non_giant_callback_tq);
+ taskqueue_block(udev->bus->control_xfer_tq);
taskqueue_block(udev->bus->explore_tq);
- udev->bus->giant_callback_proc.up_msleep = 0;
- udev->bus->non_giant_callback_proc.up_msleep = 0;
/* poll USB hardware */
(udev->bus->methods->xfer_poll) (udev->bus);
- USB_BUS_LOCK(xroot->bus);
-
/* check for clear stall */
if (udev->ctrl_xfer[1] != NULL) {
/* poll clear stall start */
- pm = &udev->cs_msg[0].hdr;
- (pm->pm_callback) (pm);
+ task = &udev->cs_task;
+ task->ta_func(task->ta_context, task->ta_pending);
/* poll clear stall done thread */
- pm = &udev->ctrl_xfer[1]->
- xroot->done_m[0].hdr;
- (pm->pm_callback) (pm);
+ task = &udev->ctrl_xfer[1]->xroot->done_task;
+ task->ta_func(task->ta_context, task->ta_pending);
}
/* poll done thread */
- pm = &xroot->done_m[0].hdr;
- (pm->pm_callback) (pm);
-
- USB_BUS_UNLOCK(xroot->bus);
+ task = &xroot->done_task;
+ task->ta_func(task->ta_context, task->ta_pending);
/* restore transfer mutex */
while (drop_xfer--)
Modified: user/weongyo/usb/sys/dev/usb/usb_transfer.h
==============================================================================
--- user/weongyo/usb/sys/dev/usb/usb_transfer.h Mon Sep 13 20:29:09 2010 (r212583)
+++ user/weongyo/usb/sys/dev/usb/usb_transfer.h Mon Sep 13 22:27:52 2010 (r212584)
@@ -27,14 +27,7 @@
#ifndef _USB_TRANSFER_H_
#define _USB_TRANSFER_H_
-/*
- * The following structure defines the messages that is used to signal
- * the "done_p" USB process.
- */
-struct usb_done_msg {
- struct usb_proc_msg hdr;
- struct usb_xfer_root *xroot;
-};
+#include <sys/taskqueue.h>
#define USB_DMATAG_TO_XROOT(dpt) \
((struct usb_xfer_root *)( \
@@ -52,10 +45,10 @@ struct usb_xfer_root {
struct usb_xfer_queue dma_q;
#endif
struct usb_xfer_queue done_q;
- struct usb_done_msg done_m[2];
+ struct taskqueue *done_tq; /* pointer to callback taskqueue */
+ struct task done_task;
struct cv cv_drain;
- struct usb_process *done_p; /* pointer to callback process */
void *memory_base;
struct mtx *xfer_mtx; /* cannot be changed during operation */
#if USB_HAVE_BUSDMA
More information about the svn-src-user
mailing list