Skip to content

Commit

Permalink
support/usb: enable/disable USB functions on power events
Browse files Browse the repository at this point in the history
Re-create USB functions that are needed from target_on() and
uninstall all of them from target_off().

Closes: #214
Signed-off-by: Cedric Hombourger <[email protected]>
  • Loading branch information
chombourger committed Nov 30, 2022
1 parent 4ba7c8d commit 2dc70ce
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 21 deletions.
39 changes: 38 additions & 1 deletion mtda/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import mtda.video.controller
import mtda.utils
from mtda import __version__
from mtda.support.usb import Composite

try:
www_support = True
Expand Down Expand Up @@ -131,6 +132,33 @@ def command(self, args, session=None):
self.mtda.debug(3, "main.command(): %s" % str(result))
return result

def _composite_start(self):
self.mtda.debug(3, "main._composite_start()")

result = True
storage = self.storage_controller
if storage is not None and storage.variant == 'usbf':
status, _, _ = self.storage_status()
enabled = status == CONSTS.STORAGE.ON_TARGET
self.mtda.debug(3, "main._composite_start(): "
"with storage? {}".format(enabled))
Composite.storage_toggle(enabled)
result = Composite.install()

self.mtda.debug(3, "main._composite_start(): {}".format(result))
return result

def _composite_stop(self):
self.mtda.debug(3, "main._composite_stop()")

result = None
storage = self.storage_controller
if storage is not None and storage.variant == 'usbf':
Composite.remove()

self.mtda.debug(3, "main._composite_stop(): {}".format(result))
return result

def config_set_power_timeout(self, timeout, session=None):
self.mtda.debug(3, "main.config_set_power_timeout()")

Expand Down Expand Up @@ -846,7 +874,14 @@ def _target_on(self, session=None):

result = False
if self.power_locked(session) is False:
result = self.power_controller.on()
# Toggle the mass storage functions of the usbf controller
result = self._composite_start()

# Turn the DUT on
if result is True:
result = self.power_controller.on()

# Resume logging
if result is True:
if self.console_logger is not None:
self.console_logger.resume()
Expand Down Expand Up @@ -922,6 +957,7 @@ def _target_off(self, session=None):
result = True
if self.power_controller is not None:
result = self.power_controller.off()
self._composite_stop()
self._power_event(CONSTS.POWER.OFF)

self.mtda.debug(3, "main._target_off(): {}".format(result))
Expand Down Expand Up @@ -1315,6 +1351,7 @@ def load_storage_config(self, parser):
mod = importlib.import_module("mtda.storage." + variant)
factory = getattr(mod, 'instantiate')
self.storage_controller = factory(self)
self.storage_controller.variant = variant
self._writer = AsyncImageWriter(self, self.storage_controller)
# Configure the storage controller
self.storage_controller.configure(dict(parser.items('storage')))
Expand Down
2 changes: 1 addition & 1 deletion mtda/storage/usbf.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def probe(self):
"device!".format(self.device))
if self.file is not None:
if os.path.exists(self.file) is True:
result = Composite.install()
result = True
else:
self.mtda.debug(1, "storage.usbf.probe(): "
"{} not found!".format(self.file))
Expand Down
76 changes: 57 additions & 19 deletions mtda/support/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ class Composite:
_storage = None
_installed = False

functions = []
path = "/sys/kernel/config/usb_gadget/" + product.lower().replace(" ", "_")

def debug(level, msg):
if Composite.mtda is not None:
Composite.mtda.debug(level, msg)

def configure(what, conf):
Composite.debug(3, "composite.configure()")
Composite.debug(3, "composite.configure('{}')".format(what))

with Composite.lock:
result = Composite._configure(what, conf)
Expand All @@ -45,18 +44,18 @@ def configure(what, conf):

def _configure(what, conf):
result = True
if what == 'console':
Composite.functions.append(Composite.console_function)
elif what == 'monitor':
Composite.functions.append(Composite.monitor_function)
elif what == 'keyboard':
Composite.functions.append(Composite.hid_function)
elif what == 'storage':
if 'file' in conf:
Composite._storage = conf['file']
Composite.functions.append(Composite.ms_function)
if what == 'storage' and 'file' in conf:
Composite._storage = conf['file']
if what in Composite.functions:
Composite.functions[what]['configured'] = True
Composite.functions[what]['enabled'] = True
Composite.debug(2, "composite.configure(): "
"{} configured & enabled".format(what))
else:
Composite.debug(1, "composite.configure(): "
"not supported")
result = False

return result

def _enable():
Expand Down Expand Up @@ -86,6 +85,18 @@ def _install():

Composite._remove()

enabled = False
for function in Composite.functions.values():
if function['enabled'] is True:
enabled = True
break

if enabled is False:
# Nothing to install
Composite.debug(2, "composite.install(): "
"no functions were enabled")
return True

atexit.register(Composite.remove)
path = Composite.path
create_dirs(path)
Expand All @@ -106,13 +117,17 @@ def _install():

Composite._create_functions()

if Composite._storage is not None:
if Composite.functions['storage']['enabled'] is True:
lun = path + "/functions/mass_storage.usb0/lun.0/"
file = Composite._storage
write(lun + "cdrom", "0")
write(lun + "ro", "0")
write(lun + "nofua", "0")
write(lun + "file", Composite._storage)
write(lun + "file", file)
Composite.debug(2, "composite.install(): "
"storage device/file: {}".format(file))
Composite._installed = Composite._enable()
return Composite._installed

def remove():
Composite.debug(3, "composite.remove()")
Expand Down Expand Up @@ -145,9 +160,12 @@ def _remove():
Composite._installed = False

def _create_functions():
functions = Composite.functions
for function in functions:
for function in Composite.functions.values():
name = function['name']
if function['configured'] is False:
continue
if function['enabled'] is False:
continue
Composite.debug(2, "composite._create_functions: "
"registering {}".format(name))
path = Composite.path + "/functions/" + name
Expand All @@ -165,8 +183,15 @@ def _create_functions():
if not os.path.exists(config):
os.symlink(path, config, True)

def storage_toggle(enabled):
with Composite.lock:
if Composite.functions['storage']['configured'] is True:
Composite.functions['storage']['enabled'] = enabled

hid_function = {
"name": "hid.usb0",
"configured": False,
"enabled": False,
"protocol": "1",
"subclass": "1",
"report_length": "8",
Expand Down Expand Up @@ -207,15 +232,28 @@ def _create_functions():
}

console_function = {
"name": "acm.GS0"
"name": "acm.GS0",
"configured": False,
"enabled": False
}

monitor_function = {
"name": "acm.GS1"
"name": "acm.GS1",
"configured": False,
"enabled": False
}

ms_function = {
"name": "mass_storage.usb0"
"name": "mass_storage.usb0",
"configured": False,
"enabled": False
}

functions = {
"console": console_function,
"monitor": monitor_function,
"keyboard": hid_function,
"storage": ms_function
}


Expand Down

0 comments on commit 2dc70ce

Please sign in to comment.