int md_get_uint32be(struct mdchain *mdp, u_int32_t *x) { u_int32_t v; int error; error = md_get_uint32(mdp, &v); *x = betohl(v); return error; }
static int i2ctpm_xmit(TpmOps *me, const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len) { I2cTpm *tpm = container_of(me, I2cTpm, ops); if (!tpm->initialized && i2ctpm_init(tpm)) return -1; uint32_t count, ordinal; memcpy(&count, sendbuf + TpmCmdCountOffset, sizeof(count)); count = betohl(count); memcpy(&ordinal, sendbuf + TpmCmdOrdinalOffset, sizeof(ordinal)); ordinal = betohl(ordinal); if (count == 0) { printf("%s: No data.\n", __func__); return -1; } if (count > sbuf_size) { printf("%s: Invalid count value %x, max %zx.\n", __func__, count, sbuf_size); return -1; } assert(tpm->chip_ops.send); ssize_t rc = tpm->chip_ops.send(&tpm->chip_ops, sendbuf, count); if (rc < 0) { printf("%s: tpm_send: error %zd\n", __func__, rc); *rbuf_len = 0; return -1; } uint64_t start = timer_us(0); while (1) { assert(tpm->chip_ops.status); uint8_t status = tpm->chip_ops.status(&tpm->chip_ops); if ((status & tpm->req_complete_mask) == tpm->req_complete_val) { break; } if (status == tpm->req_canceled) { printf("%s: Operation canceled.\n", __func__); return -1; } mdelay(1); // Two minute timeout. if (timer_us(start) > 2 * 60 * 1000 * 1000) { if (tpm->chip_ops.cancel) tpm->chip_ops.cancel(&tpm->chip_ops); printf("%s: Operation timed out.\n", __func__); return -1; } } ssize_t len = tpm->chip_ops.recv(&tpm->chip_ops, recvbuf, *rbuf_len); if (len < 0) { printf("%s: tpm_recv: error %zd\n", __func__, len); *rbuf_len = 0; return -1; } if (len < 10) { printf("%s: Too few bytes received (%zd).\n", __func__, len); *rbuf_len = 0; return -1; } if (len > *rbuf_len) { printf("%s: Too many bytes received (%zd).\n", __func__, len); *rbuf_len = len; return -1; } *rbuf_len = len; return 0; }