From owner-p4-projects@FreeBSD.ORG Mon Aug 24 14:32:01 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A62B5106568D; Mon, 24 Aug 2009 14:32:01 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 522761065690 for ; Mon, 24 Aug 2009 14:32:01 +0000 (UTC) (envelope-from pvaibhav@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 3F6638FC0A for ; Mon, 24 Aug 2009 14:32:01 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n7OEW0lH074359 for ; Mon, 24 Aug 2009 14:32:00 GMT (envelope-from pvaibhav@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n7OEW00x074357 for perforce@freebsd.org; Mon, 24 Aug 2009 14:32:00 GMT (envelope-from pvaibhav@FreeBSD.org) Date: Mon, 24 Aug 2009 14:32:00 GMT Message-Id: <200908241432.n7OEW00x074357@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to pvaibhav@FreeBSD.org using -f From: Prashant Vaibhav To: Perforce Change Reviews Cc: Subject: PERFORCE change 167734 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Aug 2009 14:32:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=167734 Change 167734 by pvaibhav@pvaibhav_matrix on 2009/08/24 14:31:35 The new callout API has been implemented as a wrapper around the existing API. The iwi driver was modified to use the new API, as a quick test case. Unfinished implementation of Kobj interface and class for a generic timer is also added. Note that the iwi driver doesn't use or test *all* the features of the new API yet. Affected files ... .. //depot/projects/soc2009/calloutapi/src/sys/dev/iwi/if_iwi.c#2 edit .. //depot/projects/soc2009/calloutapi/src/sys/kern/kern_timeout.c#6 edit .. //depot/projects/soc2009/calloutapi/src/sys/kern/timer_hz.c#1 add .. //depot/projects/soc2009/calloutapi/src/sys/kern/timer_hz.h#1 add .. //depot/projects/soc2009/calloutapi/src/sys/kern/timer_if.c#1 add .. //depot/projects/soc2009/calloutapi/src/sys/kern/timer_if.h#1 add .. //depot/projects/soc2009/calloutapi/src/sys/kern/timer_if.m#1 add .. //depot/projects/soc2009/calloutapi/src/sys/sys/callout.h#3 edit Differences ... ==== //depot/projects/soc2009/calloutapi/src/sys/dev/iwi/if_iwi.c#2 (text+ko) ==== @@ -128,6 +128,9 @@ { 0, 0, NULL } }; +static hwclocktick_t onesec; +static hwclocktick_t twosec; + static struct ieee80211vap *iwi_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], @@ -293,9 +296,14 @@ TASK_INIT(&sc->sc_disassoctask, 0, iwi_disassoc, sc); TASK_INIT(&sc->sc_wmetask, 0, iwi_update_wme, sc); + /* callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0); + */ + time_interval_to_hw_time(1, &onesec, TIMESCALE_SECOND); + time_interval_to_hw_time(2, &twosec, TIMESCALE_SECOND); + if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { device_printf(dev, "chip is in D%d power mode " "-- setting to D0\n", pci_get_powerstate(dev)); @@ -2016,7 +2024,7 @@ ieee80211_runtask(ic, &sc->sc_restarttask); } } - callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); + callout_arm(&sc->sc_wdtimer, onesec, iwi_watchdog, sc, 0, &sc->sc_mtx); } static int @@ -3121,7 +3129,7 @@ goto fail2; } - callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); + callout_arm(&sc->sc_wdtimer, onesec, iwi_watchdog, sc, 0, &sc->sc_mtx); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; return; @@ -3158,11 +3166,11 @@ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); if (sc->sc_softled) { - callout_stop(&sc->sc_ledtimer); + callout_cancel(&sc->sc_ledtimer); sc->sc_blinking = 0; } - callout_stop(&sc->sc_wdtimer); - callout_stop(&sc->sc_rftimer); + callout_cancel(&sc->sc_wdtimer); + callout_cancel(&sc->sc_rftimer); iwi_stop_master(sc); @@ -3243,7 +3251,7 @@ ieee80211_runtask(ic, &sc->sc_radiontask); return; } - callout_reset(&sc->sc_rftimer, 2*hz, iwi_rfkill_poll, sc); + callout_arm(&sc->sc_rftimer, twosec, iwi_rfkill_poll, sc, 0, &sc->sc_mtx); } static void @@ -3365,7 +3373,9 @@ v = iwi_read_event(sc); v &= ~sc->sc_ledpin; iwi_write_event(sc, iwi_toggle_event(v)); - callout_reset(&sc->sc_ledtimer, sc->sc_ledoff, iwi_led_done, sc); + hwclocktick_t ledoff; + time_interval_to_hw_time(sc->sc_ledoff, &ledoff, TIMESCALE_MS); + callout_arm(&sc->sc_ledtimer, ledoff, iwi_led_done, sc, 0, &sc->sc_mtx); } /* @@ -3381,7 +3391,9 @@ iwi_write_event(sc, iwi_toggle_event(v)); sc->sc_blinking = 1; sc->sc_ledoff = off; - callout_reset(&sc->sc_ledtimer, on, iwi_led_off, sc); + hwclocktick_t ledon; + time_interval_to_hw_time(on, &ledon, TIMESCALE_MS); + callout_arm(&sc->sc_ledtimer, ledon, iwi_led_off, sc, 0, &sc->sc_mtx); } static void @@ -3441,8 +3453,7 @@ break; } /* XXX beware of overflow */ - iwi_led_blink(sc, (blinkrates[j].timeOn * hz) / 1000, - (blinkrates[j].timeOff * hz) / 1000); + iwi_led_blink(sc, blinkrates[j].timeOn, blinkrates[j].timeOff); #undef N } @@ -3477,8 +3488,9 @@ sc->sc_blinking = 0; sc->sc_ledstate = 1; sc->sc_ledidle = (2700*hz)/1000; /* 2.7sec */ + /* callout_init_mtx(&sc->sc_ledtimer, &sc->sc_mtx, 0); - + */ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "softled", CTLTYPE_INT | CTLFLAG_RW, sc, 0, iwi_sysctl_softled, "I", "enable/disable software LED support"); ==== //depot/projects/soc2009/calloutapi/src/sys/kern/kern_timeout.c#6 (text+ko) ==== @@ -55,6 +55,7 @@ #include #include #include +#include SDT_PROVIDER_DEFINE(callout_execute); SDT_PROBE_DEFINE(callout_execute, kernel, , callout_start); @@ -843,3 +844,74 @@ return; } #endif /* APM_FIXUP_CALLTODO */ + +/* + * Wrapper implementations for the new callout API. To be replaced + * with Kobj calls to the currently selected timer. + * Ref: kern/timer.m kern/timer_hz.c + */ + +void absolute_time_to_hw_time(const struct timespec* a, hwclocktick_t* t) +{ + *t = a->tv_sec * hz; + *t += ((uint64_t) a->tv_nsec) * hz / 1000000000ull; +} + +void hw_time_to_absolute_time(const hwclocktick_t* t, struct timespec* a) +{ + a->tv_sec = *t / hz; + a->tv_nsec = (*t % hz) * 1000000000ull; +} + +void time_interval_to_hw_time(int ti, hwclocktick_t* t, enum time_scale ts) +{ + struct timespec tsec; + tsec.tv_sec = tsec.tv_nsec = 0; + switch (ts) + { + case TIMESCALE_MS: + tsec.tv_sec = ti / 1000; + tsec.tv_nsec = (ti % 1000) * 1000000; + break; + case TIMESCALE_US: + tsec.tv_sec = ti / 1000000; + tsec.tv_nsec = (ti % 1000000) * 1000; + break; + case TIMESCALE_NS: + tsec.tv_sec = ti / 1000000000; + tsec.tv_nsec = (ti % 1000000000); + break; + case TIMESCALE_MINUTE: + tsec.tv_sec = ti * 60; + break; + default: + /* what do we do? default to seconds? */ + case TIMESCALE_SECOND: + tsec.tv_sec = ti; + break; + }; + absolute_time_to_hw_time(&tsec, t); + CTR3(KTR_CALLOUT, "converted %d scale %u into %llu hwtick", ti, ts, *t); +} + +int _callout_arm(callout_handle_t* c, + hwclocktick_t when, + void (*func)(void*), + void* arg, int flags, + struct lock_object* mtx) +{ + /* There is no callout_init in the new API, so make sure + * the passed in callout struct is initialized first. + */ + _callout_init_lock((struct callout*) c, mtx, flags); + /* Schedule it */ + return callout_reset((struct callout*) c, when, func, arg); +} + +int callout_rearm(callout_handle_t* c, hwclocktick_t when) +{ + /* TODO: maybe skip this 2nd indirection and call callout_reset_on + * directly here + */ + return callout_schedule((struct callout*) c, when); +} ==== //depot/projects/soc2009/calloutapi/src/sys/sys/callout.h#3 (text+ko) ==== @@ -74,7 +74,6 @@ #define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE) #define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE) -#define callout_drain(c) _callout_stop_safe(c, 1) void callout_init(struct callout *, int); void _callout_init_lock(struct callout *, struct lock_object *, int); #define callout_init_mtx(c, mtx, flags) \ @@ -98,6 +97,38 @@ void callout_tick(void); +/* Data types and functions for new callout subsystem */ +typedef uint64_t hwclocktick_t; +typedef struct callout callout_handle_t; + +enum time_scale { + TIMESCALE_SECOND = 0, + TIMESCALE_MS, + TIMESCALE_US, + TIMESCALE_NS, + TIMESCALE_MINUTE +}; + +void absolute_time_to_hw_time(const struct timespec* a, hwclocktick_t* t); +void hw_time_to_absolute_time(const hwclocktick_t* t, struct timespec* a); +void time_interval_to_hw_time(int ti, hwclocktick_t* t, enum time_scale ts); + +int _callout_arm(callout_handle_t* c, + hwclocktick_t when, + void (*func) (void*), + void* arg, int flags, struct lock_object* mtx); +#define callout_arm(c, when, f, arg, fl, mtx) \ + _callout_arm((c), (when), (f), (arg), (fl), \ + ((mtx) != NULL) ? &(mtx)->lock_object : NULL) +#define callout_arm_within(c, from, to, f, arg, flags, mtx) \ + _callout_arm((c), (to), (f), (arg), (fl), \ + ((mtx) != NULL) ? &(mtx)->lock_object : NULL) +int callout_rearm(callout_handle_t* c, hwclocktick_t when); +#define callout_rearm_within(c, from, to) callout_rearm(c, to) +#define callout_cancel(c) _callout_stop_safe((struct callout*) (c), 0) +#define callout_drain(c) _callout_stop_safe((struct callout*) (c), 1) + + #endif #endif /* _SYS_CALLOUT_H_ */