PERFORCE change 167734 for review
Prashant Vaibhav
pvaibhav at FreeBSD.org
Mon Aug 24 14:32:01 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167734
Change 167734 by pvaibhav at 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 <sys/sleepqueue.h>
#include <sys/sysctl.h>
#include <sys/smp.h>
+#include <sys/time.h>
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_ */
More information about the p4-projects
mailing list