blob: 01c5345f7cb28885172088a75975e316cbfb0098 [file] [log] [blame]
Will Drewryd4ae5282017-01-03 22:06:26 -06001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Will Drewryde2cad72017-03-10 15:53:34 -060017#include "include/ese/ese.h"
18#include "include/ese/log.h"
Will Drewryd4ae5282017-01-03 22:06:26 -060019
Will Drewryd4ae5282017-01-03 22:06:26 -060020static const char kUnknownHw[] = "unknown hw";
21static const char kNullEse[] = "NULL EseInterface";
22static const char *kEseErrorMessages[] = {
23 "Hardware supplied no transceive implementation.",
24 "Timed out polling for value.",
25};
26#define ESE_MESSAGES(x) (sizeof(x) / sizeof((x)[0]))
27
Will Drewry8f367fc2017-03-30 22:07:48 -050028ESE_API const char *ese_name(const struct EseInterface *ese) {
Will Drewryde2cad72017-03-10 15:53:34 -060029 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060030 return kNullEse;
Will Drewryde2cad72017-03-10 15:53:34 -060031 }
32 if (ese->ops->name) {
Will Drewryd4ae5282017-01-03 22:06:26 -060033 return ese->ops->name;
Will Drewryde2cad72017-03-10 15:53:34 -060034 }
Will Drewryd4ae5282017-01-03 22:06:26 -060035 return kUnknownHw;
36}
37
Will Drewry8f367fc2017-03-30 22:07:48 -050038ESE_API int ese_open(struct EseInterface *ese, void *hw_opts) {
Will Drewryde2cad72017-03-10 15:53:34 -060039 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060040 return -1;
Will Drewryde2cad72017-03-10 15:53:34 -060041 }
Will Drewryd4ae5282017-01-03 22:06:26 -060042 ALOGV("opening interface '%s'", ese_name(ese));
Will Drewry7be2c3f2017-04-21 14:12:17 -050043 ese->error.is_err = false;
44 ese->error.code = 0;
Will Drewryde2cad72017-03-10 15:53:34 -060045 if (ese->ops->open) {
Will Drewryd4ae5282017-01-03 22:06:26 -060046 return ese->ops->open(ese, hw_opts);
Will Drewryde2cad72017-03-10 15:53:34 -060047 }
Will Drewryd4ae5282017-01-03 22:06:26 -060048 return 0;
49}
50
Will Drewry8f367fc2017-03-30 22:07:48 -050051ESE_API const char *ese_error_message(const struct EseInterface *ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060052 return ese->error.message;
53}
54
Will Drewry8f367fc2017-03-30 22:07:48 -050055ESE_API int ese_error_code(const struct EseInterface *ese) {
Will Drewryde2cad72017-03-10 15:53:34 -060056 return ese->error.code;
57}
Will Drewryd4ae5282017-01-03 22:06:26 -060058
Will Drewry8f367fc2017-03-30 22:07:48 -050059ESE_API bool ese_error(const struct EseInterface *ese) {
60 return ese->error.is_err;
61}
Will Drewryd4ae5282017-01-03 22:06:26 -060062
Will Drewry8f367fc2017-03-30 22:07:48 -050063ESE_API void ese_set_error(struct EseInterface *ese, int code) {
Will Drewryde2cad72017-03-10 15:53:34 -060064 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060065 return;
Will Drewryde2cad72017-03-10 15:53:34 -060066 }
Will Drewry8f367fc2017-03-30 22:07:48 -050067 /* Negative values are reserved for ESE_API wide messages. */
Will Drewryd4ae5282017-01-03 22:06:26 -060068 ese->error.code = code;
Will Drewryde2cad72017-03-10 15:53:34 -060069 ese->error.is_err = true;
Will Drewryd4ae5282017-01-03 22:06:26 -060070 if (code < 0) {
71 code = -(code + 1); /* Start at 0. */
Will Drewryde2cad72017-03-10 15:53:34 -060072 if ((uint32_t)(code) >= ESE_MESSAGES(kEseErrorMessages)) {
Will Drewryd4ae5282017-01-03 22:06:26 -060073 LOG_ALWAYS_FATAL("Unknown global error code passed to ese_set_error(%d)",
74 code);
75 }
76 ese->error.message = kEseErrorMessages[code];
77 return;
78 }
Will Drewryde2cad72017-03-10 15:53:34 -060079 if ((uint32_t)(code) >= ese->ops->errors_count) {
Will Drewryd4ae5282017-01-03 22:06:26 -060080 LOG_ALWAYS_FATAL("Unknown hw error code passed to ese_set_error(%d)", code);
81 }
Will Drewryde2cad72017-03-10 15:53:34 -060082 ese->error.message = ese->ops->errors[code];
Will Drewryd4ae5282017-01-03 22:06:26 -060083}
84
85/* Blocking. */
Will Drewry8f367fc2017-03-30 22:07:48 -050086ESE_API int ese_transceive(struct EseInterface *ese, const uint8_t *tx_buf,
87 uint32_t tx_len, uint8_t *rx_buf, uint32_t rx_max) {
88 const struct EseSgBuffer tx = {
89 .c_base = tx_buf, .len = tx_len,
90 };
91 struct EseSgBuffer rx = {
92 .base = rx_buf, .len = rx_max,
93 };
94 return ese_transceive_sg(ese, &tx, 1, &rx, 1);
95}
96
97ESE_API int ese_transceive_sg(struct EseInterface *ese,
98 const struct EseSgBuffer *tx_bufs,
99 uint32_t tx_segs, struct EseSgBuffer *rx_bufs,
100 uint32_t rx_segs) {
Will Drewryde2cad72017-03-10 15:53:34 -0600101 uint32_t recvd = 0;
102 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -0600103 return -1;
Will Drewryed4a7a72017-03-10 11:03:59 -0600104 }
Will Drewry7be2c3f2017-04-21 14:12:17 -0500105 if (ese->error.is_err) {
106 return -1;
107 }
Will Drewryde2cad72017-03-10 15:53:34 -0600108 if (ese->ops->transceive) {
Will Drewry8f367fc2017-03-30 22:07:48 -0500109 recvd = ese->ops->transceive(ese, tx_bufs, tx_segs, rx_bufs, rx_segs);
Will Drewryde2cad72017-03-10 15:53:34 -0600110 return ese_error(ese) ? -1 : recvd;
111 }
112
113 ese_set_error(ese, kEseGlobalErrorNoTransceive);
114 return -1;
Will Drewryd4ae5282017-01-03 22:06:26 -0600115}
116
Will Drewry8f367fc2017-03-30 22:07:48 -0500117ESE_API void ese_close(struct EseInterface *ese) {
Will Drewryde2cad72017-03-10 15:53:34 -0600118 if (!ese) {
119 return;
120 }
Will Drewryd4ae5282017-01-03 22:06:26 -0600121 ALOGV("closing interface '%s'", ese_name(ese));
Will Drewryde2cad72017-03-10 15:53:34 -0600122 if (!ese->ops->close) {
123 return;
124 }
125 ese->ops->close(ese);
Will Drewryd4ae5282017-01-03 22:06:26 -0600126}