channel->onchannel_callback = NULL;
 }
 
-static int vmbus_close_internal(struct vmbus_channel *channel)
+void vmbus_reset_channel_cb(struct vmbus_channel *channel)
 {
-       struct vmbus_channel_close_channel *msg;
-       int ret;
-
        /*
         * vmbus_on_event(), running in the per-channel tasklet, can race
         * with vmbus_close_internal() in the case of SMP guest, e.g., when
         */
        tasklet_disable(&channel->callback_event);
 
+       channel->sc_creation_callback = NULL;
+
+       /* Stop the callback asap */
+       if (channel->target_cpu != get_cpu()) {
+               put_cpu();
+               smp_call_function_single(channel->target_cpu, reset_channel_cb,
+                                        channel, true);
+       } else {
+               reset_channel_cb(channel);
+               put_cpu();
+       }
+
+       /* Re-enable tasklet for use on re-open */
+       tasklet_enable(&channel->callback_event);
+}
+
+static int vmbus_close_internal(struct vmbus_channel *channel)
+{
+       struct vmbus_channel_close_channel *msg;
+       int ret;
+
+       vmbus_reset_channel_cb(channel);
+
        /*
         * In case a device driver's probe() fails (e.g.,
         * util_probe() -> vmbus_open() returns -ENOMEM) and the device is
        }
 
        channel->state = CHANNEL_OPEN_STATE;
-       channel->sc_creation_callback = NULL;
-       /* Stop callback and cancel the timer asap */
-       if (channel->target_cpu != get_cpu()) {
-               put_cpu();
-               smp_call_function_single(channel->target_cpu, reset_channel_cb,
-                                        channel, true);
-       } else {
-               reset_channel_cb(channel);
-               put_cpu();
-       }
 
        /* Send a closing message */
 
                get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 
 out:
-       /* re-enable tasklet for use on re-open */
-       tasklet_enable(&channel->callback_event);
        return ret;
 }