struct icmsg_hdr *icmsghdrp;
        struct icmsg_negotiate *negop = NULL;
 
-       if (channel->util_index >= 0) {
-               /*
-                * This is a properly initialized util channel.
-                * Route this callback appropriately and setup state
-                * so that we don't need to reroute again.
-                */
-               if (hv_cb_utils[channel->util_index].callback != NULL) {
-                       /*
-                        * The util driver has established a handler for
-                        * this service; do the magic.
-                        */
-                       channel->onchannel_callback =
-                       hv_cb_utils[channel->util_index].callback;
-                       (hv_cb_utils[channel->util_index].callback)(channel);
-                       return;
-               }
-       }
-
        buflen = PAGE_SIZE;
        buf = kmalloc(buflen, GFP_ATOMIC);
 
        struct vmbus_channel *channel;
        bool fnew = true;
        int ret;
-       int cnt;
        unsigned long flags;
 
        /* The next possible work is rescind handling */
                 * can cleanup properly
                 */
                newchannel->state = CHANNEL_OPEN_STATE;
-               newchannel->util_index = -1; /* Invalid index */
-
-               /* Open IC channels */
-               for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
-                       if (!uuid_le_cmp(newchannel->offermsg.offer.if_type,
-                                  hv_cb_utils[cnt].data) &&
-                               vmbus_open(newchannel, 2 * PAGE_SIZE,
-                                                2 * PAGE_SIZE, NULL, 0,
-                                                chn_cb_negotiate,
-                                                newchannel) == 0) {
-                               hv_cb_utils[cnt].channel = newchannel;
-                               newchannel->util_index = cnt;
-
-                               pr_info("%s\n", hv_cb_utils[cnt].log_msg);
-
-                       }
-               }
        }
 }
 
 
        channel = kvp_transaction.recv_channel;
        req_id = kvp_transaction.recv_req_id;
 
+       if (channel->onchannel_callback == NULL)
+               /*
+                * We have raced with util driver being unloaded;
+                * silently return.
+                */
+               return;
+
        icmsghdrp = (struct icmsg_hdr *)
                        &recv_buffer[sizeof(struct vmbuspipe_hdr)];
        kvp_msg = (struct hv_kvp_msg *)
 
        if (srv->util_init) {
                ret = srv->util_init(srv);
                if (ret) {
-                       kfree(srv->recv_buffer);
-                       return -ENODEV;
+                       ret = -ENODEV;
+                       goto error1;
                }
        }
 
+       ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
+                       srv->util_cb, dev->channel);
+       if (ret)
+               goto error;
+
        hv_set_drvdata(dev, srv);
        return 0;
+
+error:
+       if (srv->util_deinit)
+               srv->util_deinit();
+error1:
+       kfree(srv->recv_buffer);
+       return ret;
 }
 
 static int util_remove(struct hv_device *dev)
 {
        struct hv_util_service *srv = hv_get_drvdata(dev);
 
+       vmbus_close(dev->channel);
        if (srv->util_deinit)
                srv->util_deinit();
        kfree(srv->recv_buffer);
 
 static int __init init_hyperv_utils(void)
 {
-       int ret;
        pr_info("Registering HyperV Utility Driver\n");
 
-
-       ret = vmbus_driver_register(&util_drv);
-
-       if (ret != 0)
-               return ret;
-
-       hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
-
-       hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback;
-
-       hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
-
-       hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback;
-
-       return 0;
-
+       return vmbus_driver_register(&util_drv);
 }
 
 static void exit_hyperv_utils(void)
 {
        pr_info("De-Registered HyperV Utility Driver\n");
 
-       if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL)
-               hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
-                       &chn_cb_negotiate;
-       hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL;
-
-       if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL)
-               hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
-                       &chn_cb_negotiate;
-       hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL;
-
-       if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL)
-               hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
-                       &chn_cb_negotiate;
-       hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL;
-
-       if (hv_cb_utils[HV_KVP_MSG].channel != NULL)
-               hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
-                       &chn_cb_negotiate;
-       hv_cb_utils[HV_KVP_MSG].callback = NULL;
-
        vmbus_driver_unregister(&util_drv);
 }