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