]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/staging/hv/hv_utils.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / staging / hv / hv_utils.c
index a99e900ec4c9faf8f5f96aa815cc3af5d01766c1..0074581f20e86f939abb6b408375d95451a43d2f 100644 (file)
 #include "vmbus_api.h"
 #include "utils.h"
 
+static u8 *shut_txf_buf;
+static u8 *time_txf_buf;
+static u8 *hbeat_txf_buf;
 
 static void shutdown_onchannelcallback(void *context)
 {
        struct vmbus_channel *channel = context;
-       u8 *buf;
-       u32 buflen, recvlen;
+       u32 recvlen;
        u64 requestid;
        u8  execute_shutdown = false;
 
@@ -52,24 +54,23 @@ static void shutdown_onchannelcallback(void *context)
        struct icmsg_hdr *icmsghdrp;
        struct icmsg_negotiate *negop = NULL;
 
-       buflen = PAGE_SIZE;
-       buf = kmalloc(buflen, GFP_ATOMIC);
-
-       vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
+       vmbus_recvpacket(channel, shut_txf_buf,
+                        PAGE_SIZE, &recvlen, &requestid);
 
        if (recvlen > 0) {
                DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld",
                           recvlen, requestid);
 
-               icmsghdrp = (struct icmsg_hdr *)&buf[
+               icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[
                        sizeof(struct vmbuspipe_hdr)];
 
                if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
-                       prep_negotiate_resp(icmsghdrp, negop, buf);
+                       prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
                } else {
-                       shutdown_msg = (struct shutdown_msg_data *)&buf[
-                               sizeof(struct vmbuspipe_hdr) +
-                               sizeof(struct icmsg_hdr)];
+                       shutdown_msg =
+                               (struct shutdown_msg_data *)&shut_txf_buf[
+                                       sizeof(struct vmbuspipe_hdr) +
+                                       sizeof(struct icmsg_hdr)];
 
                        switch (shutdown_msg->flags) {
                        case 0:
@@ -93,13 +94,11 @@ static void shutdown_onchannelcallback(void *context)
                icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
                        | ICMSGHDRFLAG_RESPONSE;
 
-               vmbus_sendpacket(channel, buf,
+               vmbus_sendpacket(channel, shut_txf_buf,
                                       recvlen, requestid,
                                       VmbusPacketTypeDataInBand, 0);
        }
 
-       kfree(buf);
-
        if (execute_shutdown == true)
                orderly_poweroff(false);
 }
@@ -150,28 +149,25 @@ static inline void adj_guesttime(u64 hosttime, u8 flags)
 static void timesync_onchannelcallback(void *context)
 {
        struct vmbus_channel *channel = context;
-       u8 *buf;
-       u32 buflen, recvlen;
+       u32 recvlen;
        u64 requestid;
        struct icmsg_hdr *icmsghdrp;
        struct ictimesync_data *timedatap;
 
-       buflen = PAGE_SIZE;
-       buf = kmalloc(buflen, GFP_ATOMIC);
-
-       vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
+       vmbus_recvpacket(channel, time_txf_buf,
+                        PAGE_SIZE, &recvlen, &requestid);
 
        if (recvlen > 0) {
                DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld",
                        recvlen, requestid);
 
-               icmsghdrp = (struct icmsg_hdr *)&buf[
+               icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
                                sizeof(struct vmbuspipe_hdr)];
 
                if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
-                       prep_negotiate_resp(icmsghdrp, NULL, buf);
+                       prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
                } else {
-                       timedatap = (struct ictimesync_data *)&buf[
+                       timedatap = (struct ictimesync_data *)&time_txf_buf[
                                sizeof(struct vmbuspipe_hdr) +
                                sizeof(struct icmsg_hdr)];
                        adj_guesttime(timedatap->parenttime, timedatap->flags);
@@ -180,12 +176,10 @@ static void timesync_onchannelcallback(void *context)
                icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
                        | ICMSGHDRFLAG_RESPONSE;
 
-               vmbus_sendpacket(channel, buf,
+               vmbus_sendpacket(channel, time_txf_buf,
                                recvlen, requestid,
                                VmbusPacketTypeDataInBand, 0);
        }
-
-       kfree(buf);
 }
 
 /*
@@ -196,30 +190,28 @@ static void timesync_onchannelcallback(void *context)
 static void heartbeat_onchannelcallback(void *context)
 {
        struct vmbus_channel *channel = context;
-       u8 *buf;
-       u32 buflen, recvlen;
+       u32 recvlen;
        u64 requestid;
        struct icmsg_hdr *icmsghdrp;
        struct heartbeat_msg_data *heartbeat_msg;
 
-       buflen = PAGE_SIZE;
-       buf = kmalloc(buflen, GFP_ATOMIC);
-
-       vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
+       vmbus_recvpacket(channel, hbeat_txf_buf,
+                        PAGE_SIZE, &recvlen, &requestid);
 
        if (recvlen > 0) {
                DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld",
                           recvlen, requestid);
 
-               icmsghdrp = (struct icmsg_hdr *)&buf[
+               icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
                                sizeof(struct vmbuspipe_hdr)];
 
                if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
-                       prep_negotiate_resp(icmsghdrp, NULL, buf);
+                       prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
                } else {
-                       heartbeat_msg = (struct heartbeat_msg_data *)&buf[
-                               sizeof(struct vmbuspipe_hdr) +
-                               sizeof(struct icmsg_hdr)];
+                       heartbeat_msg =
+                               (struct heartbeat_msg_data *)&hbeat_txf_buf[
+                                       sizeof(struct vmbuspipe_hdr) +
+                                       sizeof(struct icmsg_hdr)];
 
                        DPRINT_DBG(VMBUS, "heartbeat seq = %lld",
                                   heartbeat_msg->seq_num);
@@ -230,12 +222,10 @@ static void heartbeat_onchannelcallback(void *context)
                icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
                        | ICMSGHDRFLAG_RESPONSE;
 
-               vmbus_sendpacket(channel, buf,
+               vmbus_sendpacket(channel, hbeat_txf_buf,
                                       recvlen, requestid,
                                       VmbusPacketTypeDataInBand, 0);
        }
-
-       kfree(buf);
 }
 
 static const struct pci_device_id __initconst
@@ -268,15 +258,28 @@ static int __init init_hyperv_utils(void)
        if (!dmi_check_system(hv_utils_dmi_table))
                return -ENODEV;
 
-       hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
+       shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+
+       if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
+               printk(KERN_INFO
+                      "Unable to allocate memory for receive buffer\n");
+               kfree(shut_txf_buf);
+               kfree(time_txf_buf);
+               kfree(hbeat_txf_buf);
+               return -ENOMEM;
+       }
+
+       hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
                &shutdown_onchannelcallback;
        hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
 
-       hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback =
+       hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
                &timesync_onchannelcallback;
        hv_cb_utils[HV_TIMESYNC_MSG].callback = &timesync_onchannelcallback;
 
-       hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback =
+       hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
                &heartbeat_onchannelcallback;
        hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
 
@@ -287,17 +290,21 @@ static void exit_hyperv_utils(void)
 {
        printk(KERN_INFO "De-Registered HyperV Utility Driver\n");
 
-       hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
+       hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
                &chn_cb_negotiate;
        hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate;
 
-       hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback =
+       hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
                &chn_cb_negotiate;
        hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate;
 
-       hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback =
+       hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
                &chn_cb_negotiate;
        hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate;
+
+       kfree(shut_txf_buf);
+       kfree(time_txf_buf);
+       kfree(hbeat_txf_buf);
 }
 
 module_init(init_hyperv_utils);