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(-)
@@ -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),
};
@@ -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 */