From 310004badb0db64c29ebdd1b5cf89489f10da743 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 21 Dec 2021 02:18:55 +0300 Subject: [PATCH] external: control the board using external program Control the board using external program. It will be called with 3 arguments: , where command is one of "power", "usb", "key-fastboot", "key-power". Signed-off-by: Dmitry Baryshkov --- device.h | 1 + device_parser.c | 3 ++ external.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 1 + 4 files changed, 130 insertions(+) create mode 100644 external.c diff --git a/device.h b/device.h index 2dba972..b41e66a 100644 --- a/device.h +++ b/device.h @@ -90,6 +90,7 @@ extern const struct control_ops alpaca_ops; extern const struct control_ops cdb_assist_ops; extern const struct control_ops conmux_ops; extern const struct control_ops ftdi_gpio_ops; +extern const struct control_ops external_ops; extern const struct control_ops qcomlt_dbg_ops; extern const struct console_ops conmux_console_ops; diff --git a/device_parser.c b/device_parser.c index e4a386f..d9f2800 100644 --- a/device_parser.c +++ b/device_parser.c @@ -147,6 +147,9 @@ static void parse_board(struct device_parser *dp) } else if (!strcmp(key, "ftdi_gpio")) { dev->control_dev = strdup(value); set_control_ops(dev, &ftdi_gpio_ops); + } else if (!strcmp(key, "external")) { + dev->control_dev = strdup(value); + set_control_ops(dev, &external_ops); } else if (!strcmp(key, "qcomlt_debug_board")) { dev->control_dev = strdup(value); set_control_ops(dev, &qcomlt_dbg_ops); diff --git a/external.c b/external.c new file mode 100644 index 0000000..0fb82e1 --- /dev/null +++ b/external.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021-2023, Linaro Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include + +#include "cdba-server.h" +#include "device.h" + +struct external { + const char *path; + const char *board; +}; + +static int external_helper(struct external *ext, const char *command, bool on) +{ + pid_t pid, pid_ret; + int status; + + pid = fork(); + switch (pid) { + case 0: + /* Do not clobber stdout with program messages or cdba will become confused */ + dup2(2, 1); + return execlp(ext->path, ext->path, ext->board, command, on ? "on": "off", NULL); + case -1: + return -1; + default: + break; + } + + pid_ret = waitpid(pid, &status, 0); + if (pid_ret < 0) + return pid_ret; + + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + errno = -EINTR; + else + errno = -EIO; + + return -1; +} + +static void *external_open(struct device *dev) +{ + struct external *ext; + + dev->has_power_key = true; + + ext = calloc(1, sizeof(*ext)); + + ext->path = dev->control_dev; + ext->board = dev->board; + + return ext; +} + +static int external_power(struct device *dev, bool on) +{ + struct external *ext = dev->cdb; + + return external_helper(ext, "power", on); +} + +static void external_usb(struct device *dev, bool on) +{ + struct external *ext = dev->cdb; + + external_helper(ext, "usb", on); +} + +static void external_key(struct device *dev, int key, bool asserted) +{ + struct external *ext = dev->cdb; + + switch (key) { + case DEVICE_KEY_FASTBOOT: + external_helper(ext, "key-fastboot", asserted); + break; + case DEVICE_KEY_POWER: + external_helper(ext, "key-power", asserted); + break; + } +} + +const struct control_ops external_ops = { + .open = external_open, + .power = external_power, + .usb = external_usb, + .key = external_key, +}; diff --git a/meson.build b/meson.build index 0392b0e..15254b6 100644 --- a/meson.build +++ b/meson.build @@ -61,6 +61,7 @@ server_srcs = ['cdba-server.c', 'conmux.c', 'device.c', 'device_parser.c', + 'external.c', 'fastboot.c', 'alpaca.c', 'ftdi-gpio.c',