| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2013, Microsoft Corporation. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 5 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 6 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 9 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 10 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 11 | | - * more details. |
|---|
| 12 | 4 | */ |
|---|
| 13 | 5 | |
|---|
| 14 | 6 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 83 | 75 | |
|---|
| 84 | 76 | #define HK_MAXIMUM_MESSAGE_SIZE 256 |
|---|
| 85 | 77 | |
|---|
| 86 | | -#define KBD_VSC_SEND_RING_BUFFER_SIZE (10 * PAGE_SIZE) |
|---|
| 87 | | -#define KBD_VSC_RECV_RING_BUFFER_SIZE (10 * PAGE_SIZE) |
|---|
| 78 | +#define KBD_VSC_SEND_RING_BUFFER_SIZE VMBUS_RING_SIZE(36 * 1024) |
|---|
| 79 | +#define KBD_VSC_RECV_RING_BUFFER_SIZE VMBUS_RING_SIZE(36 * 1024) |
|---|
| 88 | 80 | |
|---|
| 89 | 81 | #define XTKBD_EMUL0 0xe0 |
|---|
| 90 | 82 | #define XTKBD_EMUL1 0xe1 |
|---|
| .. | .. |
|---|
| 267 | 259 | u32 proto_status; |
|---|
| 268 | 260 | int error; |
|---|
| 269 | 261 | |
|---|
| 262 | + reinit_completion(&kbd_dev->wait_event); |
|---|
| 263 | + |
|---|
| 270 | 264 | request = &kbd_dev->protocol_req; |
|---|
| 271 | 265 | memset(request, 0, sizeof(struct synth_kbd_protocol_request)); |
|---|
| 272 | 266 | request->header.type = __cpu_to_le32(SYNTH_KBD_PROTOCOL_REQUEST); |
|---|
| .. | .. |
|---|
| 388 | 382 | return 0; |
|---|
| 389 | 383 | } |
|---|
| 390 | 384 | |
|---|
| 385 | +static int hv_kbd_suspend(struct hv_device *hv_dev) |
|---|
| 386 | +{ |
|---|
| 387 | + vmbus_close(hv_dev->channel); |
|---|
| 388 | + |
|---|
| 389 | + return 0; |
|---|
| 390 | +} |
|---|
| 391 | + |
|---|
| 392 | +static int hv_kbd_resume(struct hv_device *hv_dev) |
|---|
| 393 | +{ |
|---|
| 394 | + int ret; |
|---|
| 395 | + |
|---|
| 396 | + ret = vmbus_open(hv_dev->channel, |
|---|
| 397 | + KBD_VSC_SEND_RING_BUFFER_SIZE, |
|---|
| 398 | + KBD_VSC_RECV_RING_BUFFER_SIZE, |
|---|
| 399 | + NULL, 0, |
|---|
| 400 | + hv_kbd_on_channel_callback, |
|---|
| 401 | + hv_dev); |
|---|
| 402 | + if (ret == 0) |
|---|
| 403 | + ret = hv_kbd_connect_to_vsp(hv_dev); |
|---|
| 404 | + |
|---|
| 405 | + return ret; |
|---|
| 406 | +} |
|---|
| 407 | + |
|---|
| 391 | 408 | static const struct hv_vmbus_device_id id_table[] = { |
|---|
| 392 | 409 | /* Keyboard guid */ |
|---|
| 393 | 410 | { HV_KBD_GUID, }, |
|---|
| .. | .. |
|---|
| 401 | 418 | .id_table = id_table, |
|---|
| 402 | 419 | .probe = hv_kbd_probe, |
|---|
| 403 | 420 | .remove = hv_kbd_remove, |
|---|
| 421 | + .suspend = hv_kbd_suspend, |
|---|
| 422 | + .resume = hv_kbd_resume, |
|---|
| 404 | 423 | .driver = { |
|---|
| 405 | 424 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
|---|
| 406 | 425 | }, |
|---|
| .. | .. |
|---|
| 417 | 436 | } |
|---|
| 418 | 437 | |
|---|
| 419 | 438 | MODULE_LICENSE("GPL"); |
|---|
| 439 | +MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Keyboard Driver"); |
|---|
| 440 | + |
|---|
| 420 | 441 | module_init(hv_kbd_init); |
|---|
| 421 | 442 | module_exit(hv_kbd_exit); |
|---|