The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=cca34aa1d005ffc859704331a3221b8c506d2f06

commit cca34aa1d005ffc859704331a3221b8c506d2f06
Author:     Kyle Evans <[email protected]>
AuthorDate: 2025-11-15 02:22:10 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2025-11-15 02:22:10 +0000

    tpm: crb: factor out idle/ready state transitions
    
    Some TPM implementations have a different start method that requires
    an additional notification for some state changes; for instance, the
    "Pluton" start method.  Just factor these transitions out for now, and
    the coming commits will introduce points that the start method can hook
    in at.
    
    Reviewed by:    obrien
    Differential Revision:  https://reviews.freebsd.org/D53682
---
 sys/dev/tpm/tpm_crb.c | 61 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 11 deletions(-)

diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c
index 017ebd45c7ea..28b4f21eccfb 100644
--- a/sys/dev/tpm/tpm_crb.c
+++ b/sys/dev/tpm/tpm_crb.c
@@ -301,6 +301,48 @@ tpmcrb_cancel_cmd(struct tpm_sc *sc)
        return (true);
 }
 
+static bool
+tpmcrb_state_idle(struct tpmcrb_sc *crb_sc, bool wait)
+{
+       struct tpm_sc *sc;
+       int mask, timeout;
+
+       timeout = wait ? TPM_TIMEOUT_C : 0;
+
+       sc = &crb_sc->base;
+       OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
+
+       if (timeout > 0) {
+               mask = TPM_CRB_CTRL_STS_IDLE_BIT;
+               if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, mask,
+                   timeout))
+                       return (false);
+       }
+
+       return (true);
+}
+
+static bool
+tpmcrb_state_ready(struct tpmcrb_sc *crb_sc, bool wait)
+{
+       struct tpm_sc *sc;
+       int mask, timeout;
+
+       timeout = wait ? TPM_TIMEOUT_C : 0;
+
+       sc = &crb_sc->base;
+       OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
+
+       if (timeout > 0) {
+               mask = TPM_CRB_CTRL_REQ_GO_READY;
+               if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, !mask,
+                   timeout))
+                       return (false);
+       }
+
+       return (true);
+}
+
 int
 tpmcrb_transmit(device_t dev, size_t length)
 {
@@ -335,22 +377,15 @@ tpmcrb_transmit(device_t dev, size_t length)
 
        /* Switch device to idle state if necessary */
        if (!(TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
-               OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
-
-               mask = TPM_CRB_CTRL_STS_IDLE_BIT;
-               if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
-                           mask, mask, TPM_TIMEOUT_C)) {
+               if (!tpmcrb_state_idle(crb_sc, true)) {
                        device_printf(dev,
                            "Failed to transition to idle state\n");
                        return (EIO);
                }
        }
-       /* Switch to ready state */
-       OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
 
-       mask = TPM_CRB_CTRL_REQ_GO_READY;
-       if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
-                   mask, !mask, TPM_TIMEOUT_C)) {
+       /* Switch to ready state */
+       if (!tpmcrb_state_ready(crb_sc, true)) {
                device_printf(dev,
                    "Failed to transition to ready state\n");
                return (EIO);
@@ -394,7 +429,11 @@ tpmcrb_transmit(device_t dev, size_t length)
        bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE,
              &sc->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
 
-       OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
+       if (!tpmcrb_state_idle(crb_sc, false)) {
+               device_printf(dev,
+                   "Failed to transition to idle state post-send\n");
+               return (EIO);
+       }
 
        tpmcrb_relinquish_locality(sc);
        sc->pending_data_length = bytes_available;

Reply via email to