DAHDI in kernel 4.15: Switch to new timer_setup interface.
authorShaun Ruffell <sruffell@sruffell.net>
Fri, 10 Aug 2018 05:13:52 +0000 (00:13 -0500)
committerShaun Ruffell <sruffell@sruffell.net>
Mon, 3 Sep 2018 15:27:18 +0000 (10:27 -0500)
Upstream kernel 4.14, in commit (686fef928bba6b "timer: Prepare to change timer
callback argument type") [1], introduced the timer_setup interface to replace
the init_timer/setup_timer interfaces. The primary change is that the timer
callback functions now follow the standard kernel pattern where the structure
the callback sits in is passed to the callback instead of storing a pointer to
an unassociated data type.

The setup_timer functions were removed in upstream kernel v4.15, and therefore
this change is needed in order to compile DAHDI for kernels >= 4.15.

This change follows the same strategy that was done in the kernel to while the
existing users of setup_timer were migrated to the new interface.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=686fef928bba6b

13 files changed:
drivers/dahdi/dahdi-base.c
drivers/dahdi/dahdi_dummy.c
drivers/dahdi/dahdi_dynamic.c
drivers/dahdi/dahdi_dynamic_ethmf.c
drivers/dahdi/datamods/syncppp.c
drivers/dahdi/voicebus/voicebus.c
drivers/dahdi/wctc4xxp/base.c
drivers/dahdi/wcte12xp/base.c
drivers/dahdi/wcte13xp-base.c
drivers/dahdi/wcte43x-base.c
drivers/dahdi/xpp/xbus-core.c
drivers/dahdi/xpp/xbus-pcm.c
include/dahdi/kernel.h

index c6f95f0..38df9c4 100644 (file)
@@ -10069,7 +10069,7 @@ static inline unsigned long msecs_processed(const struct core_timer *const ct)
        return atomic_read(&ct->count) * DAHDI_MSECS_PER_CHUNK;
 }
 
-static void coretimer_func(unsigned long param)
+static void coretimer_func(TIMER_DATA_TYPE unused)
 {
        unsigned long flags;
        unsigned long ms_since_start;
@@ -10150,16 +10150,14 @@ static void coretimer_func(unsigned long param)
 
 static void coretimer_init(void)
 {
-       init_timer(&core_timer.timer);
-       core_timer.timer.function = coretimer_func;
+       timer_setup(&core_timer.timer, coretimer_func, 0);
        ktime_get_ts(&core_timer.start_interval);
        atomic_set(&core_timer.count, 0);
        atomic_set(&core_timer.shutdown, 0);
        core_timer.interval = max(msecs_to_jiffies(DAHDI_MSECS_PER_CHUNK), 1UL);
        if (core_timer.interval < (HZ/250))
                core_timer.interval = (HZ/250);
-       core_timer.timer.expires = jiffies + core_timer.interval;
-       add_timer(&core_timer.timer);
+       mod_timer(&core_timer.timer, jiffies + core_timer.interval);
 }
 
 static void coretimer_cleanup(void)
@@ -10455,7 +10453,7 @@ static const struct file_operations dahdi_chan_fops = {
 #ifdef CONFIG_DAHDI_WATCHDOG
 static struct timer_list watchdogtimer;
 
-static void watchdog_check(unsigned long ignored)
+static void watchdog_check(TIMER_DATA_TYPE ignored)
 {
        unsigned long flags;
        static int wdcheck=0;
@@ -10496,10 +10494,7 @@ static void watchdog_check(unsigned long ignored)
 
 static int __init watchdog_init(void)
 {
-       init_timer(&watchdogtimer);
-       watchdogtimer.expires = 0;
-       watchdogtimer.data =0;
-       watchdogtimer.function = watchdog_check;
+       timer_setup(&watchdogtimer, watchdog_check, 0);
        /* Run every couple of jiffy or so */
        mod_timer(&watchdogtimer, jiffies + 2);
        return 0;
index 5358f3d..b75c6a6 100644 (file)
@@ -157,7 +157,7 @@ static unsigned long timespec_diff_ms(struct timespec *t0, struct timespec *t1)
        return ms;
 }
 
-static void dahdi_dummy_timer(unsigned long param)
+static void dahdi_dummy_timer(struct timer_timer *unused)
 {
        unsigned long ms_since_start;
        struct timespec now;
@@ -258,12 +258,10 @@ int init_module(void)
        hrtimer_start(&zaptimer, ktime_set(0, DAHDI_TIME_NS), HRTIMER_MODE_REL);
        printk(KERN_INFO "dahdi_dummy: High Resolution Timer started, good to go\n");
 #else
-       init_timer(&timer);
-       timer.function = dahdi_dummy_timer;
+       timer_setup(&timer, dahdi_dummy_timer);
        ztd->start_interval = current_kernel_time();
-       timer.expires = jiffies + JIFFIES_INTERVAL;
        atomic_set(&shutdown, 0);
-       add_timer(&timer);
+       mod_timer(&timer, jiffies + JIFFIES_INTERVAL);
 #endif
 
        if (debug)
index 7811f9d..b1df408 100644 (file)
@@ -831,7 +831,7 @@ EXPORT_SYMBOL(dahdi_dynamic_unregister_driver);
 
 static struct timer_list alarmcheck;
 
-static void check_for_red_alarm(unsigned long ignored)
+static void check_for_red_alarm(TIMER_DATA_TYPE unused)
 {
        int newalarm;
        int alarmchanged = 0;
@@ -867,10 +867,7 @@ static const struct dahdi_dynamic_ops dahdi_dynamic_ops = {
 static int dahdi_dynamic_init(void)
 {
        /* Start process to check for RED ALARM */
-       init_timer(&alarmcheck);
-       alarmcheck.expires = 0;
-       alarmcheck.data = 0;
-       alarmcheck.function = check_for_red_alarm;
+       timer_setup(&alarmcheck, check_for_red_alarm, 0);
        /* Check once per second */
        mod_timer(&alarmcheck, jiffies + 1 * HZ);
 #ifdef ENABLE_TASKLETS
index dec368b..90e4e6d 100644 (file)
@@ -681,16 +681,13 @@ static int ethmf_delay_dec(void)
  * Timer callback function to allow all spans to be added, prior to any of
  * them being used.
  */
-static void timer_callback(unsigned long param)
+static void timer_callback(TIMER_DATA_TYPE unused)
 {
        if (ethmf_delay_dec()) {
-               if (!atomic_read(&timer_deleted)) {
-                       timer.expires = jiffies + HZ;
-                       add_timer(&timer);
-               }
+               if (!atomic_read(&timer_deleted))
+                       mod_timer(&timer, jiffies + HZ);
        } else {
                printk(KERN_INFO "All TDMoE multiframe span groups are active.\n");
-               del_timer(&timer);
        }
 }
 
@@ -764,11 +761,8 @@ static const struct file_operations ztdethmf_proc_fops = {
 
 static int __init ztdethmf_init(void)
 {
-       init_timer(&timer);
-       timer.expires = jiffies + HZ;
-       timer.function = &timer_callback;
-       if (!timer_pending(&timer))
-               add_timer(&timer);
+       timer_setup(&timer, timer_callback, 0);
+       mod_timer(&timer, jiffies + HZ);
 
        dev_add_pack(&ztdethmf_ptype);
        register_netdevice_notifier(&ztdethmf_nblock);
index 1a59caf..0e79a23 100644 (file)
@@ -148,7 +148,7 @@ static void sppp_lcp_open (struct sppp *sp);
 static void sppp_ipcp_open (struct sppp *sp);
 static int sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h,
        int len, u32 *magic);
-static void sppp_cp_timeout (unsigned long arg);
+static void sppp_cp_timeout (TIMER_DATA_TYPE timer);
 static char *sppp_lcp_type_name (u8 type);
 static char *sppp_ipcp_type_name (u8 type);
 static void sppp_print_bytes (u8 *p, u16 len);
@@ -189,12 +189,9 @@ static void sppp_set_timeout(struct sppp *p,int s)
 {
        if (! (p->pp_flags & PP_TIMO)) 
        {
-               init_timer(&p->pp_timer);
-               p->pp_timer.function=sppp_cp_timeout;
-               p->pp_timer.expires=jiffies+s*HZ;
-               p->pp_timer.data=(unsigned long)p;
                p->pp_flags |= PP_TIMO;
-               add_timer(&p->pp_timer);
+               timer_setup(&p->pp_timer, sppp_cp_timeout, 0);
+               mod_timer(&p->pp_timer, jiffies + s*HZ);
        }
 }
 
index 7ee7763..fb8c60c 100644 (file)
@@ -1000,6 +1000,7 @@ __vb_rx_demand_poll(struct voicebus *vb)
                __vb_setctl(vb, 0x0010, 0x00000000);
 }
 
+#ifndef CONFIG_VOICEBUS_TIMER
 static void
 __vb_enable_interrupts(struct voicebus *vb)
 {
@@ -1008,6 +1009,7 @@ __vb_enable_interrupts(struct voicebus *vb)
        else
                __vb_setctl(vb, IER_CSR7, DEFAULT_NORMAL_INTERRUPTS);
 }
+#endif
 
 static void
 __vb_disable_interrupts(struct voicebus *vb)
@@ -1033,8 +1035,7 @@ static void start_packet_processing(struct voicebus *vb)
        clear_bit(VOICEBUS_STOP, &vb->flags);
        clear_bit(VOICEBUS_STOPPED, &vb->flags);
 #if defined(CONFIG_VOICEBUS_TIMER)
-       vb->timer.expires = jiffies + HZ/1000;
-       add_timer(&vb->timer);
+       mod_timer(&vb->timer, jiffies + HZ/1000);
 #else
        /* Clear the interrupt status register. */
        __vb_setctl(vb, SR_CSR5, 0xffffffff);
@@ -1746,18 +1747,17 @@ vb_isr(int irq, void *dev_id)
  * the timer.
  */
 static void
-vb_timer(unsigned long data)
+vb_timer(TIMER_DATA_TYPE timer)
 {
        unsigned long start = jiffies;
-       struct voicebus *vb = (struct voicebus *)data;
+       struct voicebus *vb = from_timer(vb, timer, timer);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
        vb_isr(0, vb, 0);
 #else
        vb_isr(0, vb);
 #endif
        if (!test_bit(VOICEBUS_STOPPED, &vb->flags)) {
-               vb->timer.expires = start + HZ/1000;
-               add_timer(&vb->timer);
+               mod_timer(&vb->timer, start + HZ/1000);
        }
 }
 #endif
@@ -1800,9 +1800,7 @@ __voicebus_init(struct voicebus *vb, const char *board_name,
        INIT_LIST_HEAD(&vb->free_rx);
 
 #if defined(CONFIG_VOICEBUS_TIMER)
-       init_timer(&vb->timer);
-       vb->timer.function = vb_timer;
-       vb->timer.data = (unsigned long)vb;
+       timer_setup(&vb->timer, vb_timer, 0);
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
index 0d76d6a..88d3865 100644 (file)
@@ -3701,9 +3701,9 @@ wctc4xxp_send_commands(struct wcdte *wc, struct list_head *to_send)
 }
 
 static void
-wctc4xxp_watchdog(unsigned long data)
+wctc4xxp_watchdog(TIMER_DATA_TYPE timer)
 {
-       struct wcdte *wc = (struct wcdte *)data;
+       struct wcdte *wc = from_timer(wc, timer, watchdog);
        struct tcb *cmd, *temp;
        LIST_HEAD(cmds_to_retry);
        const int MAX_RETRIES = 5;
@@ -4090,13 +4090,7 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                        goto error_exit_swinit;
        }
 
-#      if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
-       wc->watchdog.function = wctc4xxp_watchdog;
-       wc->watchdog.data = (unsigned long)wc;
-       init_timer(&wc->watchdog);
-#      else
-       setup_timer(&wc->watchdog, wctc4xxp_watchdog, (unsigned long)wc);
-#      endif
+       timer_setup(&wc->watchdog, wctc4xxp_watchdog, 0);
 
        /* ------------------------------------------------------------------
         * Load the firmware and start the DTE.
index 2164e63..9932656 100644 (file)
@@ -2766,10 +2766,10 @@ static void vpm_check_func(struct work_struct *work)
        return;
 }
 
-static void te12xp_timer(unsigned long data)
+static void te12xp_timer(TIMER_DATA_TYPE timer)
 {
        unsigned long flags;
-       struct t1 *wc = (struct t1 *)data;
+       struct t1 *wc = from_timer(wc, timer, timer);
 
        if (unlikely(!test_bit(INITIALIZED, &wc->bit_flags)))
                return;
@@ -2944,7 +2944,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
        spin_lock_init(&wc->reglock);
        INIT_LIST_HEAD(&wc->active_cmds);
        INIT_LIST_HEAD(&wc->pending_cmds);
-       setup_timer(&wc->timer, te12xp_timer, (unsigned long)wc);
+       timer_setup(&wc->timer, te12xp_timer, 0);
 
 #      if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
        INIT_WORK(&wc->timer_work, timer_work_func, wc);
index bb80f15..ef9b5cd 100644 (file)
@@ -2382,9 +2382,9 @@ static void te13x_handle_interrupt(struct wcxb *xb, u32 pending)
        }
 }
 
-static void te13xp_timer(unsigned long data)
+static void te13xp_timer(TIMER_DATA_TYPE timer)
 {
-       struct t13x *wc = (struct t13x *)data;
+       struct t13x *wc = from_timer(wc, timer, timer);
 
        if (unlikely(!test_bit(INITIALIZED, &wc->bit_flags)))
                return;
@@ -2583,7 +2583,7 @@ static int __devinit te13xp_init_one(struct pci_dev *pdev,
        wc->ledstate = -1;
        spin_lock_init(&wc->reglock);
        mutex_init(&wc->lock);
-       setup_timer(&wc->timer, te13xp_timer, (unsigned long)wc);
+       timer_setup(&wc->timer, te13xp_timer, 0);
 
 #      if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
        INIT_WORK(&wc->timer_work, timer_work_func, wc);
index c9b7978..74018ea 100644 (file)
@@ -3204,9 +3204,9 @@ static void t43x_handle_interrupt(struct wcxb *xb, u32 pending)
                wc->intr_span = 0;
 }
 
-static void t43x_timer(unsigned long data)
+static void t43x_timer(TIMER_DATA_TYPE timer)
 {
-       struct t43x *wc = (struct t43x *)data;
+       struct t43x *wc = from_timer(wc, timer, timer);
 
        if (!is_initialized(wc))
                return;
@@ -3432,7 +3432,7 @@ static int __devinit t43x_init_one(struct pci_dev *pdev,
                goto fail_exit;
 
        mutex_init(&wc->lock);
-       setup_timer(&wc->timer, t43x_timer, (unsigned long)wc);
+       timer_setup(&wc->timer, t43x_timer, 0);
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
        INIT_WORK(&wc->timer_work, timer_work_func, wc);
index 4281f1c..565d267 100644 (file)
@@ -1612,7 +1612,6 @@ xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size,
        transport_init(xbus, ops, max_send_size, transport_device, priv);
        spin_lock_init(&xbus->lock);
        init_waitqueue_head(&xbus->command_queue_empty);
-       init_timer(&xbus->command_timer);
        atomic_set(&xbus->pcm_rx_counter, 0);
        xbus->min_tx_sync = INT_MAX;
        xbus->min_rx_sync = INT_MAX;
index 32f04fa..37f9260 100644 (file)
@@ -353,9 +353,9 @@ static void xpp_set_syncer(xbus_t *xbus, bool on)
                         (syncer) ? syncer->busname : "NO-SYNC");
 }
 
-static void xbus_command_timer(unsigned long param)
+static void xbus_command_timer(TIMER_DATA_TYPE timer)
 {
-       xbus_t *xbus = (xbus_t *)param;
+       xbus_t *xbus = from_timer(xbus, timer, command_timer);
        struct timeval now;
 
        BUG_ON(!xbus);
@@ -371,10 +371,9 @@ void xbus_set_command_timer(xbus_t *xbus, bool on)
        if (on) {
                if (!timer_pending(&xbus->command_timer)) {
                        XBUS_DBG(SYNC, xbus, "add_timer\n");
-                       xbus->command_timer.function = xbus_command_timer;
-                       xbus->command_timer.data = (unsigned long)xbus;
-                       xbus->command_timer.expires = jiffies + 1;
-                       add_timer(&xbus->command_timer);
+                       timer_setup(&xbus->command_timer,
+                               xbus_command_timer, 0);
+                       mod_timer(&xbus->command_timer, jiffies + 1);
                }
        } else if (timer_pending(&xbus->command_timer)) {
                XBUS_DBG(SYNC, xbus, "del_timer\n");
index c946fa3..5431652 100644 (file)
@@ -1404,6 +1404,33 @@ static inline short dahdi_txtone_nextsample(struct dahdi_chan *ss)
 /*! Maximum audio mask */
 #define DAHDI_FORMAT_AUDIO_MASK        ((1 << 16) - 1)
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+
+#ifndef TIMER_DATA_TYPE
+#define TIMER_DATA_TYPE unsigned long
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
+
+/**
+ * timer_setup - Added in 4.13.0.  We can make a direct translation to the
+ * setup_timer interface since DAHDI does not pass any flags to any of the
+ * timer_setup functions.
+ *
+ */
+static inline void
+timer_setup(struct timer_list *timer,
+           void (*timer_callback)(TIMER_DATA_TYPE data),
+           unsigned long flags)
+{
+       WARN_ON(flags != 0);
+       setup_timer(timer, timer_callback, (TIMER_DATA_TYPE)timer);
+}
+
+#define from_timer(var, callback_timer, timer_fieldname) \
+       container_of((struct timer_list *)(callback_timer), \
+                    typeof(*var), timer_fieldname)
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
 #define refcount_read atomic_read
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
@@ -1536,6 +1563,14 @@ static inline int strcasecmp(const char *s1, const char *s2)
 #endif /* 3.10.0 */
 #endif /* 3.16.0 */
 #endif /* 4.11.0 */
+#endif /* 4.13.0 */
+#else /* >= 4.15.0 */
+
+#ifndef TIMER_DATA_TYPE
+#define TIMER_DATA_TYPE struct timer_list *
+#endif
+
+#endif /* 4.15.0 */
 
 #ifndef DEFINE_SPINLOCK
 #define DEFINE_SPINLOCK(x)      spinlock_t x = SPIN_LOCK_UNLOCKED