DF-1990 / fix.diff
diff --git a/sys/dev/crypto/tpm/tpm_crb.c b/sys/dev/crypto/tpm/tpm_crb.c --- a/sys/dev/crypto/tpm/tpm_crb.c +++ b/sys/dev/crypto/tpm/tpm_crb.c @@ -308,7 +308,7 @@ { struct tpmcrb_sc *crb_sc; uint32_t mask, curr_cmd; - int timeout, bytes_available; + int timeout, bytes_available, errval = 0; crb_sc = (struct tpmcrb_sc *)sc; @@ -342,7 +342,8 @@ mask, mask, TPM_TIMEOUT_C)) { device_printf(sc->dev, "Failed to transition to idle state\n"); - return (EIO); + errval = EIO; + goto err_locality; } } /* Switch to ready state */ @@ -353,7 +354,8 @@ mask, !mask, TPM_TIMEOUT_C)) { device_printf(sc->dev, "Failed to transition to ready state\n"); - return (EIO); + errval = EIO; + goto err_locality; } /* @@ -377,8 +379,10 @@ if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START, mask, ~mask, timeout)) { device_printf(sc->dev, "Timeout while waiting for device to process cmd\n"); - if (!tpmcrb_cancel_cmd(sc)) - return (EIO); + if (!tpmcrb_cancel_cmd(sc)) { + errval = EIO; + goto err_locality; + } } /* Read response header. Length is passed in bytes 2 - 6. */ @@ -390,18 +394,21 @@ device_printf(sc->dev, "Incorrect response size: %d\n", bytes_available); - return (EIO); + errval = EIO; + goto err_locality; } 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); +err_locality: OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE); tpmcrb_relinquish_locality(sc); - sc->pending_data_length = bytes_available; + if (errval == 0) + sc->pending_data_length = bytes_available; - return (0); + return (errval); } /* ACPI Driver */ |