From owner-freebsd-usb@FreeBSD.ORG Sat Oct 30 23:19:04 2010 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9719F1065673; Sat, 30 Oct 2010 23:19:04 +0000 (UTC) (envelope-from weongyo.jeong@gmail.com) Received: from mail-gy0-f182.google.com (mail-gy0-f182.google.com [209.85.160.182]) by mx1.freebsd.org (Postfix) with ESMTP id 384628FC12; Sat, 30 Oct 2010 23:19:03 +0000 (UTC) Received: by gya6 with SMTP id 6so2840352gya.13 for ; Sat, 30 Oct 2010 16:19:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:received:from:date:to:cc :subject:message-id:reply-to:mime-version:content-type :content-disposition:user-agent:organization:x-operation-sytem; bh=R8D5+dbnhdrpaubOpgcO7FKcK+Nc2sXu5viXkA1gYCQ=; b=lDo8F1lNQuUgmkNBALMypk+ctVaTUQ56+z0Y8evMyvTfap+WgQ+9+2iIqQY4QmjxvX 8xnCNkxQ20xtejdh/znO3kTTvmVThSy6XqkA6tWnRa+/k583M6sbDCedIKfBZHjU680X lhW9ujRYNfp5ltcl8zxQC7sUF+XgRHWcNPyis= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:date:to:cc:subject:message-id:reply-to:mime-version :content-type:content-disposition:user-agent:organization :x-operation-sytem; b=x+tHbYi3687C5/hulXNv8ScvIEV1hVChD1GSD3dRpIZ66Nn075Yh9BotCh9IvCqqkR sWhuNi6UjvVV335qjY+0WgWiopvPjzV7cDZdAWQbeml797Mrdb8ueQOyB5bpQsFkvXSh 86MOAgJI2PQDb/STzfNPVZAjMyS07u8XHm4Vk= Received: by 10.150.178.16 with SMTP id a16mr25262063ybf.437.1288480743262; Sat, 30 Oct 2010 16:19:03 -0700 (PDT) Received: from weongyo ([174.35.1.224]) by mx.google.com with ESMTPS id j27sm1088955yha.30.2010.10.30.16.19.00 (version=SSLv3 cipher=RC4-MD5); Sat, 30 Oct 2010 16:19:02 -0700 (PDT) Received: by weongyo (sSMTP sendmail emulation); Sat, 30 Oct 2010 16:19:01 -0700 From: Weongyo Jeong Date: Sat, 30 Oct 2010 16:19:01 -0700 To: freebsd-usb@freebsd.org Message-ID: <20101030231901.GA83161@weongyo> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.3i Organization: CDNetworks. X-Operation-Sytem: FreeBSD Cc: Subject: [CFR] add usb_sleepout.[ch] X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Weongyo Jeong List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Oct 2010 23:19:04 -0000 Hello USB guys, The following patch is to add a implementation, called `sleepout'. Please reviews. I'd like to commit it into HEAD if no objections. 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). regards, Weongyo Jeong Index: usb_sleepout.c =================================================================== --- usb_sleepout.c (revision 0) +++ usb_sleepout.c (revision 0) @@ -0,0 +1,122 @@ +/*- + * 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 +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include +#include + +#include + +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)); +} Property changes on: usb_sleepout.c ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Added: svn:eol-style + native Index: usb_sleepout.h =================================================================== --- usb_sleepout.h (revision 0) +++ usb_sleepout.h (revision 0) @@ -0,0 +1,53 @@ +/*- + * 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 +#include + +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; +}; + +#define SLEEPOUT_RUNTASK(_so, _task) \ + taskqueue_enqueue((_so)->s_taskqueue, (_task)) +#define SLEEPOUT_DRAINTASK(_so, _task) \ + taskqueue_drain((_so)->s_taskqueue, (_task)) + +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 Property changes on: usb_sleepout.h ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Added: svn:eol-style + native