Home | History | Annotate | Download | only in libese
      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 
     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 
     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 
     51 ESE_API const char *ese_error_message(const struct EseInterface *ese) {
     52   return ese->error.message;
     53 }
     54 
     55 ESE_API int ese_error_code(const struct EseInterface *ese) {
     56   return ese->error.code;
     57 }
     58 
     59 ESE_API bool ese_error(const struct EseInterface *ese) {
     60   return ese->error.is_err;
     61 }
     62 
     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. */
     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 
     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 
    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