summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-hyperv.c
diff options
context:
space:
mode:
authorDexuan Cui <decui@microsoft.com>2019-08-20 05:56:34 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-11-06 14:43:06 +0300
commit8cb0ef81ba927d776dabe7fd3f649c580d2cdeba (patch)
treed047bcf4c862d5259daf53d1bd8209d772e12cfc /drivers/hid/hid-hyperv.c
parenta7913a4126e513f7c3e312dfdddc86ab53c05b51 (diff)
downloadlinux-8cb0ef81ba927d776dabe7fd3f649c580d2cdeba.tar.xz
HID: hyperv: Use in-place iterator API in the channel callback
[ Upstream commit 6a297c90efa68b2864483193b8bfb0d19478600c ] Simplify the ring buffer handling with the in-place API. Also avoid the dynamic allocation and the memory leak in the channel callback function. Signed-off-by: Dexuan Cui <decui@microsoft.com> Acked-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/hid/hid-hyperv.c')
-rw-r--r--drivers/hid/hid-hyperv.c56
1 files changed, 10 insertions, 46 deletions
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index 5f1de24206ab..220b3e5c9c39 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -322,60 +322,24 @@ static void mousevsc_on_receive(struct hv_device *device,
static void mousevsc_on_channel_callback(void *context)
{
- const int packet_size = 0x100;
- int ret;
struct hv_device *device = context;
- u32 bytes_recvd;
- u64 req_id;
struct vmpacket_descriptor *desc;
- unsigned char *buffer;
- int bufferlen = packet_size;
-
- buffer = kmalloc(bufferlen, GFP_ATOMIC);
- if (!buffer)
- return;
-
- do {
- ret = vmbus_recvpacket_raw(device->channel, buffer,
- bufferlen, &bytes_recvd, &req_id);
-
- switch (ret) {
- case 0:
- if (bytes_recvd <= 0) {
- kfree(buffer);
- return;
- }
- desc = (struct vmpacket_descriptor *)buffer;
-
- switch (desc->type) {
- case VM_PKT_COMP:
- break;
-
- case VM_PKT_DATA_INBAND:
- mousevsc_on_receive(device, desc);
- break;
-
- default:
- pr_err("unhandled packet type %d, tid %llx len %d\n",
- desc->type, req_id, bytes_recvd);
- break;
- }
+ foreach_vmbus_pkt(desc, device->channel) {
+ switch (desc->type) {
+ case VM_PKT_COMP:
break;
- case -ENOBUFS:
- kfree(buffer);
- /* Handle large packet */
- bufferlen = bytes_recvd;
- buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
-
- if (!buffer)
- return;
+ case VM_PKT_DATA_INBAND:
+ mousevsc_on_receive(device, desc);
+ break;
+ default:
+ pr_err("Unhandled packet type %d, tid %llx len %d\n",
+ desc->type, desc->trans_id, desc->len8 * 8);
break;
}
- } while (1);
-
+ }
}
static int mousevsc_connect_to_vsp(struct hv_device *device)