[Concept,07/16] tkey: Allow modelling the tkey being disconnected

Message ID 20251115185212.539268-8-sjg@u-boot.org
State New
Headers
Series Continue TKey development |

Commit Message

Simon Glass Nov. 15, 2025, 6:51 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Provide some plat data which tracks whether the emulated tkey is
connected or not, to allow testing of re-inserting a tkey to reset the
passphrase.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 drivers/misc/tkey_emul.c | 41 +++++++++++++++++++++++++++++++++++++++-
 include/tkey.h           | 13 +++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)
  

Patch

diff --git a/drivers/misc/tkey_emul.c b/drivers/misc/tkey_emul.c
index d8d81280486..5f7a4aa2f09 100644
--- a/drivers/misc/tkey_emul.c
+++ b/drivers/misc/tkey_emul.c
@@ -45,6 +45,15 @@ 
 #define STATUS_OK		0x00
 #define STATUS_ERROR		0x01
 
+/*
+ * struct tkey_emul_plat - TKey emulator platform data (persists across remove)
+ *
+ * @disconnected: Whether device is disconnected (for testing removal)
+ */
+struct tkey_emul_plat {
+	bool disconnected;
+};
+
 /*
  * struct tkey_emul_priv - TKey emulator state
  *
@@ -200,10 +209,15 @@  static int handle_app_cmd(struct udevice *dev, u8 cmd)
 
 static int tkey_emul_write(struct udevice *dev, const void *buf, int len)
 {
+	struct tkey_emul_plat *plat = dev_get_plat(dev);
 	const u8 *data = buf;
 	u8 header, endpoint, cmd;
 	int ret;
 
+	/* Simulate device disconnection */
+	if (plat->disconnected)
+		return -EIO;
+
 	if (len < 2)
 		return -EINVAL;
 
@@ -229,8 +243,15 @@  static int tkey_emul_write(struct udevice *dev, const void *buf, int len)
 static int tkey_emul_read_all(struct udevice *dev, void *buf, int maxlen,
 			      int timeout_ms)
 {
+	struct tkey_emul_plat *plat = dev_get_plat(dev);
 	struct tkey_emul_priv *priv = dev_get_priv(dev);
-	int len = min(priv->resp_len, maxlen);
+	int len;
+
+	/* Simulate device disconnection */
+	if (plat->disconnected)
+		return -EIO;
+
+	len = min(priv->resp_len, maxlen);
 
 	log_debug("read_all: %d bytes max, returning %d bytes\n", maxlen, len);
 
@@ -241,11 +262,28 @@  static int tkey_emul_read_all(struct udevice *dev, void *buf, int maxlen,
 	return len;
 }
 
+int tkey_emul_set_connected_for_test(struct udevice *dev, bool connected)
+{
+	struct tkey_emul_plat *plat = dev_get_plat(dev);
+
+	plat->disconnected = !connected;
+	log_debug("Set emulator %s\n", connected ? "connected" : "disconnected");
+
+	return 0;
+}
+
 static int tkey_emul_probe(struct udevice *dev)
 {
+	struct tkey_emul_plat *plat = dev_get_plat(dev);
 	struct tkey_emul_priv *priv = dev_get_priv(dev);
 	int i;
 
+	/* Fail probe if device is disconnected */
+	if (plat->disconnected) {
+		log_debug("probe failed - device disconnected\n");
+		return -ENODEV;
+	}
+
 	/* Generate a deterministic UDI based on device name */
 	for (i = 0; i < 8; i++)
 		priv->udi[i] = 0xa0 + i;
@@ -281,4 +319,5 @@  U_BOOT_DRIVER(tkey_emul) = {
 	.probe		= tkey_emul_probe,
 	.ops		= &tkey_emul_ops,
 	.priv_auto	= sizeof(struct tkey_emul_priv),
+	.plat_auto	= sizeof(struct tkey_emul_plat),
 };
diff --git a/include/tkey.h b/include/tkey.h
index a16447795b1..14ad3ebc9e9 100644
--- a/include/tkey.h
+++ b/include/tkey.h
@@ -229,4 +229,17 @@  int tkey_derive_disk_key(struct udevice *dev, const void *app_data,
 int tkey_derive_wrapping_key(struct udevice *dev, const char *password,
 			     void *wrapping_key);
 
+/**
+ * tkey_emul_set_connected_for_test() - Simulate device connection state
+ *
+ * This is a back-door function for tests to simulate physical insertion or
+ * removal of the TKey device. When disconnected, all I/O operations and
+ * probe attempts will fail.
+ *
+ * @dev: TKey device (must be tkey-emul)
+ * @connected: true to simulate device present, false to simulate removal
+ * Return: 0 on success, -ve error on failure
+ */
+int tkey_emul_set_connected_for_test(struct udevice *dev, bool connected);
+
 #endif /* _TKEY_UCLASS_H */