diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index c68e5fad0f9d..99cc334b7945 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -181,24 +181,6 @@ void chn_cb_negotiate(void *context) 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); @@ -348,7 +330,6 @@ static void vmbus_process_offer(struct work_struct *work) struct vmbus_channel *channel; bool fnew = true; int ret; - int cnt; unsigned long flags; /* The next possible work is rescind handling */ @@ -410,23 +391,6 @@ static void vmbus_process_offer(struct work_struct *work) * 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); - - } - } } } diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c index ff0d9ab2e4a1..9aa9ede0ee87 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/staging/hv/hv_kvp.c @@ -177,6 +177,13 @@ kvp_respond_to_host(char *key, char *value, int error) 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 *) diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index a1539a7814d4..faa66074cc21 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -269,19 +269,32 @@ static int util_probe(struct hv_device *dev, 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); @@ -321,51 +334,15 @@ static struct hv_driver util_drv = { 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); }