Date: Mon, 13 Sep 2010 22:27:52 +0000 (UTC) From: Weongyo Jeong <weongyo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r212584 - in user/weongyo/usb/sys/dev/usb: . controller Message-ID: <201009132227.o8DMRqn3036970@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009132227.o8DMRqn3036970>