1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2018-2019, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 ******************************************************************************/
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "tss2_fapi.h"
15 #include "fapi_int.h"
16 #include "fapi_util.h"
17 #include "tss2_esys.h"
18 #define LOGMODULE fapi
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 /** Retrieve handles for polling
23 *
24 * Returns an array of handles that can be polled on to get notified when
25 * data from the TPM or from a disk operation is available.
26 *
27 * The corresponding code should look similar to follows:
28 * do { r = Fapi_GetPollHandles(fc, &ph, &nph);
29 if (r == TSS2_RC_SUCCESS) { poll(ph, nph, -1); Fapi_Free(ph); }
30 * r = Fapi_*_Finish(fc, ...); } while (r == TSS2_FAPI_RC_TRY_AGAIN);
31 *
32 * @param[in,out] context The FAPI_CONTEXT
33 * @param[out] handles An array of poll handle entries
34 * @param[out] num_handles The size of the array in handles
35 *
36 * @retval TSS2_RC_SUCCESS: if the function call was a success.
37 * @retval TSS2_FAPI_RC_BAD_REFERENCE: if context or data is NULL.
38 * @retval TSS2_FAPI_RC_BAD_CONTEXT: if context corruption is detected.
39 * @retval TSS2_FAPI_RC_BAD_SEQUENCE: if the context has no asynchronous
40 * operation pending.
41 * @retval TSS2_FAPI_RC_NO_HANDLE: if there are no handles to poll on
42 * @retval TSS2_FAPI_RC_MEMORY: if the FAPI cannot allocate enough memory for
43 * internal operations or return parameters.
44 */
45 TSS2_RC
Fapi_GetPollHandles(FAPI_CONTEXT * context,FAPI_POLL_HANDLE ** handles,size_t * num_handles)46 Fapi_GetPollHandles(
47 FAPI_CONTEXT *context,
48 FAPI_POLL_HANDLE **handles,
49 size_t *num_handles)
50 {
51 LOG_TRACE("called for context:%p", context);
52
53 TSS2_RC r;
54
55 /* Check for NULL parameters */
56 check_not_null(context);
57 check_not_null(handles);
58 check_not_null(num_handles);
59
60 /* Check the correct state for poll handle retrieval. */
61 if (context->state == _FAPI_STATE_INIT) {
62 LOG_ERROR("PollHandles can only be returned while an operation is running");
63 return TSS2_FAPI_RC_BAD_SEQUENCE;
64 }
65
66 /* First we check for poll handles from IO operations. */
67 r = ifapi_io_poll_handles(&context->io, handles, num_handles);
68 if (r == TSS2_RC_SUCCESS) {
69 LOG_DEBUG("Returning %zi IO poll handles.", *num_handles);
70 return r;
71 }
72 if (r != TSS2_FAPI_RC_NO_HANDLE)
73 return_if_error(r, "Retrieving poll handles failed");
74
75 /* Then we check for poll handles from ESYS operations. */
76 /* If we are running in none-TPM mode then we are already done trying. */
77 return_if_null(context->esys, "No non-TPM based poll handles found.",
78 TSS2_FAPI_RC_NO_HANDLE);
79
80 /* Retrieve the actual poll handles from ESYS. */
81 r = Esys_GetPollHandles(context->esys, handles, num_handles);
82 if (r) {
83 LOG_DEBUG("Returning TSS2_FAPI_RC_NO_HANDLE");
84 return TSS2_FAPI_RC_NO_HANDLE;
85 }
86
87 LOG_DEBUG("Returning %zi ESYS poll handles.", *num_handles);
88 LOG_TRACE("finished");
89 return r;
90 }
91