• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "include/ese/ese.h"
18 #include "include/ese/log.h"
19 
20 static const char kUnknownHw[] = "unknown hw";
21 static const char kNullEse[] = "NULL EseInterface";
22 static 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 
ese_name(const struct EseInterface * ese)28 ESE_API const char *ese_name(const struct EseInterface *ese) {
29   if (!ese) {
30     return kNullEse;
31   }
32   if (ese->ops->name) {
33     return ese->ops->name;
34   }
35   return kUnknownHw;
36 }
37 
ese_open(struct EseInterface * ese,void * hw_opts)38 ESE_API int ese_open(struct EseInterface *ese, void *hw_opts) {
39   if (!ese) {
40     return -1;
41   }
42   ALOGV("opening interface '%s'", ese_name(ese));
43   ese->error.is_err = false;
44   ese->error.code = 0;
45   if (ese->ops->open) {
46     return ese->ops->open(ese, hw_opts);
47   }
48   return 0;
49 }
50 
ese_error_message(const struct EseInterface * ese)51 ESE_API const char *ese_error_message(const struct EseInterface *ese) {
52   return ese->error.message;
53 }
54 
ese_error_code(const struct EseInterface * ese)55 ESE_API int ese_error_code(const struct EseInterface *ese) {
56   return ese->error.code;
57 }
58 
ese_error(const struct EseInterface * ese)59 ESE_API bool ese_error(const struct EseInterface *ese) {
60   return ese->error.is_err;
61 }
62 
ese_set_error(struct EseInterface * ese,int code)63 ESE_API void ese_set_error(struct EseInterface *ese, int code) {
64   if (!ese) {
65     return;
66   }
67   /* Negative values are reserved for ESE_API wide messages. */
68   ese->error.code = code;
69   ese->error.is_err = true;
70   if (code < 0) {
71     code = -(code + 1); /* Start at 0. */
72     if ((uint32_t)(code) >= ESE_MESSAGES(kEseErrorMessages)) {
73       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   }
79   if ((uint32_t)(code) >= ese->ops->errors_count) {
80     LOG_ALWAYS_FATAL("Unknown hw error code passed to ese_set_error(%d)", code);
81   }
82   ese->error.message = ese->ops->errors[code];
83 }
84 
85 /* Blocking. */
ese_transceive(struct EseInterface * ese,const uint8_t * tx_buf,uint32_t tx_len,uint8_t * rx_buf,uint32_t rx_max)86 ESE_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 
ese_transceive_sg(struct EseInterface * ese,const struct EseSgBuffer * tx_bufs,uint32_t tx_segs,struct EseSgBuffer * rx_bufs,uint32_t rx_segs)97 ESE_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) {
101   uint32_t recvd = 0;
102   if (!ese) {
103     return -1;
104   }
105   if (ese->error.is_err) {
106     return -1;
107   }
108   if (ese->ops->transceive) {
109     recvd = ese->ops->transceive(ese, tx_bufs, tx_segs, rx_bufs, rx_segs);
110     return ese_error(ese) ? -1 : recvd;
111   }
112 
113   ese_set_error(ese, kEseGlobalErrorNoTransceive);
114   return -1;
115 }
116 
ese_close(struct EseInterface * ese)117 ESE_API void ese_close(struct EseInterface *ese) {
118   if (!ese) {
119     return;
120   }
121   ALOGV("closing interface '%s'", ese_name(ese));
122   if (!ese->ops->close) {
123     return;
124   }
125   ese->ops->close(ese);
126 }
127