diff --git a/Kconfig b/Kconfig index 07801f8d..4691a019 100644 --- a/Kconfig +++ b/Kconfig @@ -135,8 +135,8 @@ config CONSOLE_VARIANT string "Console variant" default "qemu" help - Select a shared storage variant from 'docker', 'qemu', 'samsung' - and 'usbf'. + Select a shared storage variant from 'docker', 'qemu', 'samsung', + 'usbsdmux' and 'usbf'. endmenu menu "Video Settings" diff --git a/docs/config.rst b/docs/config.rst index cd2dbb0a..553aeb84 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -128,8 +128,8 @@ General settings selected with ``variant``. * ``variant``: string [required] - Select a shared storage variant from ``docker``, ``qemu``, ``samsung`` - and ``usbf``. + Select a shared storage variant from ``docker``, ``qemu``, ``samsung``, + ``usbsdmux`` and ``usbf``. * ``usb``: section [optional] Specify how many USB ports may be controlled from this agent. @@ -388,6 +388,21 @@ a SD card between the DUT and host. The following settings are supported: Identifier of the sdmux/sdwire device to use. Use ``sd-mux-ctrl`` to list available devices. When not specified, the first device is auto-detected. +``usbsdmux`` driver settings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``usbsdmux`` driver supports SD card switcher based on the Microchip +USB2642 card reader chip. A tool with this name is available for several +distributions and via pip. The following settings are supported: + +* ``device``: string [optional] + Block device for the shared storage as seen on the host (defaults to + ``/dev/sda``) + +* ``control-device``: string [optional] + Control device used for talking to the switcher on the host (defaults to + ``/dev/sg0``) + ``usbf`` driver settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/meta-isar/recipes-core/images/mtda-image.bb b/meta-isar/recipes-core/images/mtda-image.bb index 3b8d761d..49028244 100644 --- a/meta-isar/recipes-core/images/mtda-image.bb +++ b/meta-isar/recipes-core/images/mtda-image.bb @@ -54,6 +54,7 @@ IMAGE_PREINSTALL += " \ ssh \ sudo \ systemd-timesyncd \ + usbsdmux \ vim \ wireless-regdb \ wireless-tools \ diff --git a/mtda.ini b/mtda.ini index 86fe0582..7d9dd4c8 100644 --- a/mtda.ini +++ b/mtda.ini @@ -159,6 +159,7 @@ variant=aviosys_8800 # - docker # - qemu # - samsung +# - usbsdmux # - usbf # --------------------------------------------------------------------------- # Note: this section is ignored when connecting to a remote agent diff --git a/mtda/storage/qemu.py b/mtda/storage/qemu.py index d1ec2bbc..d4d2a765 100644 --- a/mtda/storage/qemu.py +++ b/mtda/storage/qemu.py @@ -33,7 +33,7 @@ def configure(self, conf): self.mtda.debug(3, "storage.qemu.configure()") self.lock.acquire() - result = None + result = True if 'file' in conf: self.file = os.path.realpath(conf['file']) d = os.path.dirname(self.file) diff --git a/mtda/storage/usbsdmux.py b/mtda/storage/usbsdmux.py new file mode 100644 index 00000000..46cb34a5 --- /dev/null +++ b/mtda/storage/usbsdmux.py @@ -0,0 +1,114 @@ +# --------------------------------------------------------------------------- +# Storage driver for usbsdmux on MTDA +# --------------------------------------------------------------------------- +# +# This software is a part of MTDA. +# Copyright (C) 2024 Siemens AG +# +# --------------------------------------------------------------------------- +# SPDX-License-Identifier: MIT +# --------------------------------------------------------------------------- + +# System imports +import subprocess + +# Local imports +import mtda.constants as CONSTS +from mtda.storage.helpers.image import Image + + +class UsbSdMuxStorageController(Image): + + def __init__(self, mtda): + super().__init__(mtda) + self.file = "/dev/sda" + self.control_device = "/dev/sg0" + + """ Configure this storage controller from the provided configuration""" + def configure(self, conf): + self.mtda.debug(3, "storage.usbsdmux.configure()") + + result = True + if 'device' in conf: + self.file = conf['device'] + if 'control-device' in conf: + self.control_device = conf['control-device'] + self.mtda.debug(3, f"storage.usbsdmux.configure(): {str(result)}") + return result + + """ Check presence of the sdmux""" + def probe(self): + self.mtda.debug(3, "storage.usbsdmux.probe()") + + result = True + try: + subprocess.check_output([ + "usbsdmux", self.control_device, "get" + ]) + except subprocess.CalledProcessError: + result = False + + self.mtda.debug(3, f"storage.usbsdmux.probe(): {str(result)}") + return result + + """ Attach the SD card to the host""" + def to_host(self): + self.mtda.debug(3, "storage.usbsdmux.to_host()") + + result = True + try: + subprocess.check_output([ + "usbsdmux", self.control_device, "host" + ]) + except subprocess.CalledProcessError: + result = False + + self.mtda.debug(3, f"storage.usbsdmux.to_host(): {str(result)}") + return result + + """ Attach the SD card to the target""" + def to_target(self): + self.mtda.debug(3, "storage.usbsdmux.to_target()") + self.lock.acquire() + + result = self._close() + if result is True: + result = self._umount() + if result is True: + try: + subprocess.check_output([ + "usbsdmux", self.control_device, "dut" + ]) + except subprocess.CalledProcessError: + result = False + + self.mtda.debug(3, f"storage.usbsdmux.to_target(): {str(result)}") + self.lock.release() + return result + + """ Determine where is the SD card attached""" + def _status(self): + self.mtda.debug(3, "storage.usbsdmux.status()") + + try: + status = subprocess.check_output([ + "usbsdmux", self.control_device, "get" + ]).decode("utf-8").splitlines() + result = CONSTS.STORAGE.UNKNOWN + for s in status: + if s == "host": + result = CONSTS.STORAGE.ON_HOST + break + elif s == "dut": + result = CONSTS.STORAGE.ON_TARGET + break + except subprocess.CalledProcessError: + self.mtda.debug(1, "storage.usbsdmux.status(): usbsdmux failed!") + result = CONSTS.STORAGE.UNKNOWN + + self.mtda.debug(3, f"storage.usbsdmux.status(): {str(result)}") + return result + + +def instantiate(mtda): + return UsbSdMuxStorageController(mtda)