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