From patchwork Tue Nov 21 21:17:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Laurion X-Patchwork-Id: 745901 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QL5sjIpX" Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6B1DD50; Tue, 21 Nov 2023 13:17:32 -0800 (PST) Received: by mail-pg1-x534.google.com with SMTP id 41be03b00d2f7-5c184b3bbc4so4638036a12.1; Tue, 21 Nov 2023 13:17:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700601452; x=1701206252; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=+Y7Hdh/nNBc1o4NyKT9830+BREkzjkWMJna/qEgRv4Q=; b=QL5sjIpXAiN+xMjIfJd2x5Fa8vrVTH+610k8TjU2CkUzA8ZzOW6T42WTU3nEurNlUr 8lLP6UXd4gHl2NDvYWDEwYLxjpYXnx/3aTyvSrGrOXiZhLP1xDP3LnRoWS4T/eINWdCR rIGTIaY4kwUb9PZntyDy+wl/t3xwIL35Y3cuKlY+k7IUekme/lXqYvCSWCCCWE+73Q7D aHVK78XeTo5hSUHWXx9KoKm3c3kjJxYCu1bDfb3WopJObXYIy6E5PaFv9XcwLO2CFZ0H TlPSPjbV35LCvUO4QldWYbYUtiCqEgV8zcQB4nvAH3SI8qkO2LEtt427s/MoTGAXrPcJ 7tmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700601452; x=1701206252; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=+Y7Hdh/nNBc1o4NyKT9830+BREkzjkWMJna/qEgRv4Q=; b=YBvWFTFDuZBBtbLnuKvYvF0EL57z20Fi+0fVx9bSQ5QEqE2dg2FDsMBAIehns0K+6D 6Yx4qffcQ2+hOYT6a4AUDonFG90WA026gnEfS8xsnclY6bJqPposjKNZiIFzojR7To6V EK336XRZ/NB1ImCTx7q3T1Ve7vGYcGX8A54zgyInVVIuw/Qyi1jrBZydFCn3tB3rPFYH pyFEoUEtIn3HLs9b2NaTKOIFDFY+WbuKmL2m50qz1R92dq3UAyyhC1NPGb9o324atbKk VJ8vrN36yNRdRNIE0UcYw3EFDrdpfV2Rn+af29KmEXyahdAtDfK7n++pX/rEV6AdZC/H HbXA== X-Gm-Message-State: AOJu0Yz0LJbweGJGImNpDXg8pFgK/vLAxKQO8Wu8XX2wXC6OCncd2BQ3 ESUtWK2HI2sgj1mXT2hvyuEwpeKImaPfFn+hEh7msbo6y9w3YGsR X-Google-Smtp-Source: AGHT+IETviTmtkmXlJDvDyAZ93dP64pqnGTEQEWgpr21UVmVhUfpYq2NEVS4k0QyH2ZGfl9P4OCJBc/AGWxzsfjd/HU= X-Received: by 2002:a17:90a:190:b0:280:74ce:ae8d with SMTP id 16-20020a17090a019000b0028074ceae8dmr434572pjc.20.1700601451811; Tue, 21 Nov 2023 13:17:31 -0800 (PST) Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Thierry Laurion Date: Tue, 21 Nov 2023 16:17:18 -0500 Message-ID: Subject: [PATCH] i8042: add forceat2 parameter to force PS/2 keyboard to use AT Translated Set 2 protocol To: linux-kernel@vger.kernel.org Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com Hello, I am Thierry Laurion, the maintainer of the Heads project, which is a coreboot Linux payload that follows the linuxboot ideology. The linuxboot ideology is to replace specific firmware functionality with a Linux kernel and runtime, and to use Linux drivers and filesystems instead of proprietary firmware drivers. This improves boot reliability, speed, flexibility, and security. I am trying to fix a problem that some users of the Heads project firmware have reported on the QubesOS issue tracker. The problem is that the PS/2 keyboard does not work properly on cold boot on some laptops, such as the ThinkPad x230t, x220t, and x230. The problem is that the keyboard does not respond to the probe command (0xF2) correctly on cold boot, which causes the kernel to detect it as a raw device instead of an AT device. This results in incorrect key mapping and other issues. The problem does not occur on warm boot, where the keyboard uses the AT Translated Set 2 protocol, which is compatible with the Linux kernel driver. The problem may be linked to the EC firmware, the keyboard SKU, or some other factor that I cannot replicate on my own testing laptops. Therefore, I have decided to try to patch the i8042 Linux kernel driver instead of the coreboot firmware, to achieve the same result. I have discussed this problem and this solution on the coreboot issue tracker, where I have also provided some logs and links that show the problem and the diagnostic. I have come up with two alternative solutions to patch the i8042 driver: - The first solution is to modify the i8042_command function to send the command 0xF0 to the keyboard port, followed by the argument 0x02, which sets the keyboard to use the AT Translated Set 2 protocol. This is similar to what I did in the coreboot firmware. This solution also adds a new kernel parameter, i8042.forceat2, that enables this modification. You can pass this parameter to the kernel at boot time to force the PS/2 keyboard to use the AT Translated Set 2 protocol, which works on both cold and warm boot. - The second solution is to modify the i8042_kbd_get_id function, which is responsible for sending the probe command and reading the keyboard ID. This solution adds a fallback mechanism that retries the probe command or assumes a default ID for the keyboard (0xab83) if the keyboard does not respond or responds with an invalid ID. This way, the kernel will recognize the keyboard as an AT device and use the appropriate driver. This solution also uses the same kernel parameter, i8042.forceat2, to enable this modification. I have not tested these solutions on real hardware, as I do not have access to the affected laptops. Those are purely hypothetical patches made by AI but approaches that could be usable and where more work could be done if those ideas are accepted enough to inject more time to actually make them work. Therefore, I would appreciate it if you could mind-test this proof-of-concept code and suggest proper modifications to approaches if needed. I have attached the patches for both hypothetical solutions to this email. Please review them and let me know what you think. Thank you for your time and attention. Sincerely, Thierry Laurion Attached: [PATCH 1/2] i8042: add forceat2 parameter to force PS/2 keyboard to use AT Translated Set 2 protocol [PATCH 2/2] i8042: add forceat2 parameter to retry probe command or assume default ID for PS/2 keyboard : https://github.com/QubesOS/qubes-issues/issues/6520 : https://review.coreboot.org/c/coreboot/+/515 : https://github.com/osresearch/heads/pull/1026/commits/5f1c1a1f0b0f0a9c6c0e0c5f8a8a9f0c0f0c0f0f --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -38,6 +38,7 @@ #define I8042_KBD_IRQ 1 #define I8042_AUX_IRQ 12 +#define I8042_CMD_SET_AT2 0xF0 #define I8042_CMD_GETID 0xF2 #define I8042_CMD_AUX_LOOP 0xD3 #define I8042_CMD_AUX_SEND 0xD4 @@ -105,6 +106,7 @@ static bool i8042_bypass_aux_irq_test; static bool i8042_check_reset; static bool i8042_dritek; static bool i8042_dumbkbd; +static bool i8042_forceat2; static bool i8042_noaux; static bool i8042_nokbd; static bool i8042_nomux; @@ -122,6 +124,7 @@ module_param_named(bypass_aux_irq_test, i8042_bypass_aux_irq_test, bool, 0); module_param_named(check_reset, i8042_check_reset, bool, 0); module_param_named(dritek, i8042_dritek, bool, 0); module_param_named(dumbkbd, i8042_dumbkbd, bool, 0); +module_param_named(forceat2, i8042_forceat2, bool, 0); module_param_named(noaux, i8042_noaux, bool, 0); module_param_named(nokbd, i8042_nokbd, bool, 0); module_param_named(nomux, i8042_nomux, bool, 0); @@ -1004,6 +1007,16 @@ static int i8042_command(struct i8042_port *port, unsigned char *param, int comm return retval; } + if (i8042_forceat2 && port == &i8042_ports[I8042_KBD_PORT]) { + retval = i8042_wait_write(); + if (retval) + return retval; + + dbg("%02x -> i8042 (command)", I8042_CMD_SET_AT2); + i8042_write_data(I8042_CMD_SET_AT2); + i8042_write_data(0x02); + } + if (command & I8042_CMD_AUX_SEND) { retval = i8042_wait_write(); if (retval)