From patchwork Thu Sep 5 09:52:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Pigott X-Patchwork-Id: 19769 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qe0-f70.google.com (mail-qe0-f70.google.com [209.85.128.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id A9A5F24869 for ; Thu, 5 Sep 2013 09:52:32 +0000 (UTC) Received: by mail-qe0-f70.google.com with SMTP id b4sf1809707qen.9 for ; Thu, 05 Sep 2013 02:52:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mime-version:to:from:subject :message-id:date:reply-to:sender:errors-to:precedence :x-original-sender:x-original-authentication-results:mailing-list :list-id:list-post:list-help:list-archive:list-unsubscribe :content-type; bh=cipsrWdxWVMA6AI4esXS8PMElZiwovwWbEeRCvvfwnc=; b=ZAAOF4xpQOclDVHVEu0YWR4FvnMGMuY7nAZokcN18sWn4XFdrC96l93h+paFrdiKPu eRgBKZBTbydSaWfqGx+yGoCE08DaSPWWc0Ek9YV4r9i0E2NQ5hRejvglI+vBbArbWsrf Qes1GVi6c5ma4/ljOE7mk8nIVOz6rkcZibO1GwT1J3EjP4dwpxZvakU23bHWmitAd2vK YeL7jBqlagzJsyQdbFp2t4lUxdrR2WN+XnMPTgYUtJ09Zy3acVA+C5T9Thaba55h+mZ2 c0VXsCs7nXgDckMndonipXOY/Puv7n6P0t+u45xAGvappfTgniOoCvQ2HWg5ZAK+WcED Zd2w== X-Received: by 10.236.172.34 with SMTP id s22mr2673835yhl.25.1378374751844; Thu, 05 Sep 2013 02:52:31 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.47.82 with SMTP id b18ls423398qen.53.gmail; Thu, 05 Sep 2013 02:52:31 -0700 (PDT) X-Received: by 10.52.164.16 with SMTP id ym16mr559950vdb.32.1378374751729; Thu, 05 Sep 2013 02:52:31 -0700 (PDT) Received: from mail-ve0-f179.google.com (mail-ve0-f179.google.com [209.85.128.179]) by mx.google.com with ESMTPS id wp10si6579991vdb.58.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Sep 2013 02:52:31 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.128.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.179; Received: by mail-ve0-f179.google.com with SMTP id c14so319285vea.24 for ; Thu, 05 Sep 2013 02:52:31 -0700 (PDT) X-Gm-Message-State: ALoCoQlU3COEk6sp4issqFJRBAnK9k66DZX31AiRhAWwAzzidMbT+5AI9g1G3U1fFqzfZqYbz65j X-Received: by 10.52.118.73 with SMTP id kk9mr1732848vdb.13.1378374751576; Thu, 05 Sep 2013 02:52:31 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp270470vcz; Thu, 5 Sep 2013 02:52:30 -0700 (PDT) X-Received: by 10.180.108.2 with SMTP id hg2mr5642058wib.7.1378374750215; Thu, 05 Sep 2013 02:52:30 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id wa3si10756433wjc.149.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 05 Sep 2013 02:52:30 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1VHWEm-0002xW-Lo for ; Thu, 05 Sep 2013 09:52:28 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 7BC6EE90FF for ; Thu, 5 Sep 2013 09:52:28 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: lava-dispatcher X-Launchpad-Branch: ~linaro-validation/lava-dispatcher/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 667 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-validation/lava-dispatcher/trunk] Rev 667: Add sdmux and general lmp functionality Message-Id: <20130905095228.25045.22026.launchpad@ackee.canonical.com> Date: Thu, 05 Sep 2013 09:52:28 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: list X-Generated-By: Launchpad (canonical.com); Revision="16758"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 537e762b49cdb1353c8e7d83f472de31b9223dca X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: noreply@launchpad.net X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Merge authors: Dave Pigott (dpigott) Related merge proposals: https://code.launchpad.net/~dpigott/lava-dispatcher/add-sdmux-and-lmp-functionality/+merge/183131 proposed by: Dave Pigott (dpigott) review: Approve - Tyler Baker (tyler-baker) review: Approve - Antonio Terceiro (terceiro) review: Resubmit - Dave Pigott (dpigott) ------------------------------------------------------------ revno: 667 [merge] committer: Dave Pigott branch nick: trunk timestamp: Thu 2013-09-05 10:51:15 +0100 message: Add sdmux and general lmp functionality removed: lava_dispatcher/device/sdmux.sh added: lava_dispatcher/actions/lmp/ lava_dispatcher/actions/lmp/__init__.py lava_dispatcher/actions/lmp/board.py lava_dispatcher/actions/lmp/ethsata.py lava_dispatcher/actions/lmp/hdmi.py lava_dispatcher/actions/lmp/lsgpio.py lava_dispatcher/actions/lmp/sdmux.py lava_dispatcher/actions/lmp/usb.py modified: lava_dispatcher/config.py lava_dispatcher/default-config/lava-dispatcher/device-defaults.conf lava_dispatcher/device/sdmux.py setup.py --- lp:lava-dispatcher https://code.launchpad.net/~linaro-validation/lava-dispatcher/trunk You are subscribed to branch lp:lava-dispatcher. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-dispatcher/trunk/+edit-subscription === added directory 'lava_dispatcher/actions/lmp' === added file 'lava_dispatcher/actions/lmp/__init__.py' --- lava_dispatcher/actions/lmp/__init__.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/__init__.py 2013-09-04 10:19:58 +0000 @@ -0,0 +1,1 @@ +__author__ = 'dpigott' === added file 'lava_dispatcher/actions/lmp/board.py' --- lava_dispatcher/actions/lmp/board.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/board.py 2013-09-05 08:59:44 +0000 @@ -0,0 +1,132 @@ +# Copyright (C) 2013 Linaro Limited +# +# Author: Dave Pigott +# +# This file is part of LAVA Dispatcher. +# +# LAVA Dispatcher is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LAVA Dispatcher is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along +# with this program; if not, see . + +import serial +import json +import logging +from serial import ( + serialutil +) +from lava_dispatcher.errors import ( + CriticalError, +) + +class LAVALmpDeviceSerial(object): + def __init__(self, serialno, board_type): + device_map = { + "sdmux": "0a", + "sata": "19", + "lsgpio": "09", + "hdmi": "0c", + "usb": "04" + } + self.serialno = "LL" + device_map[board_type] + serialno.zfill(12) + logging.debug("LMP Serial #: %s" % self.serialno) + self.lmpType = "org.linaro.lmp." + board_type + self.board_type = board_type + try: + self.port = serial.Serial("/dev/serial/by-id/usb-Linaro_Ltd_LavaLMP_" + self.serialno + "-if00", timeout=1) + except serial.serialutil.SerialException as e: + logging.error("LMP: Error opening {0:s}: {1:s}".format(self.serialno, e)) + raise + self.START_FRAME = '\x02' + self.END_FRAME = '\x04' + self.send_frame('{"schema":"org.linaro.lmp.info"}') + message = self.get_response("board") + if message['serial'] != self.serialno: + raise CriticalError("Lmp %s not connected" % serial) + # With the sdmux, we must wait until the device has switched to the requested state. Not all Lmp boards provide + # the required state information in the report + # TODO: Fix firmware so that they all do + if board_type == "sdmux": + self.wait_for_confirmation = True + else: + self.wait_for_confirmation = False + + def send_command(self, mode, selection): + message = '{"schema":"' + self.lmpType + '",' + \ + '"serial":"' + self.serialno + '",' + \ + '"modes":[{"name":"' + mode + '",' + \ + '"option":"' + selection + '"}]}' + + self.send_frame(message) + + if self.wait_for_confirmation: + device_in_mode = False + + while not device_in_mode: + try: + response = self.get_frame() + except ValueError as e: + logging.warning("LMP Frame read error: %s" % e) + continue + else: + for i in response["report"]: + if i["name"] == "modes": + modes = dict(i) + for j in modes["modes"]: + state = dict(j) + if state["name"] == mode and state["mode"] == selection: + logging.debug("LMP %s: %s now in mode %s" % (self.board_type, mode, selection)) + device_in_mode = True + + def send_frame(self, command): + logging.debug("LMP: Sending %s" % command) + payload = self.START_FRAME + command + self.END_FRAME + self.port.write(payload) + + def get_response(self, schema): + got_schema = False + + result = self.get_frame() + + while not got_schema: + if result['schema'] == "org.linaro.lmp." + schema: + got_schema = True + else: + result = self.get_frame() + + return result + + def get_frame(self): + char = self.port.read() + + while char != self.START_FRAME: + char = self.port.read() + + response = "" + + while char != self.END_FRAME: + char = self.port.read() + if char != self.END_FRAME: + response += char + + logging.debug("LMP: Got %s" % response) + + return json.loads(response) + + def close(self): + self.port.close() + + +def lmp_send_command(serial, lmp_type, mode, state): + lmp = LAVALmpDeviceSerial(serial, lmp_type) + lmp.send_command(mode, state) + lmp.close() === added file 'lava_dispatcher/actions/lmp/ethsata.py' --- lava_dispatcher/actions/lmp/ethsata.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/ethsata.py 2013-09-04 15:09:05 +0000 @@ -0,0 +1,29 @@ +# Copyright (C) 2013 Linaro Limited +# +# Author: Dave Pigott +# +# This file is part of LAVA Dispatcher. +# +# LAVA Dispatcher is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LAVA Dispatcher is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along +# with this program; if not, see . + +from lava_dispatcher.actions.lmp.board import lmp_send_command + + +def disconnect(serial): + lmp_send_command(serial, "sata", "sata", "disconnect") + + +def passthru(serial): + lmp_send_command(serial, "sata", "sata", "passthru") === added file 'lava_dispatcher/actions/lmp/hdmi.py' --- lava_dispatcher/actions/lmp/hdmi.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/hdmi.py 2013-09-04 15:09:05 +0000 @@ -0,0 +1,33 @@ +# Copyright (C) 2013 Linaro Limited +# +# Author: Dave Pigott +# +# This file is part of LAVA Dispatcher. +# +# LAVA Dispatcher is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LAVA Dispatcher is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along +# with this program; if not, see . + +from lava_dispatcher.actions.lmp.board import lmp_send_command + + +def disconnect(serial): + lmp_send_command(serial, "hdmi", "hdmi", "disconnect") + + +def passthru(serial): + lmp_send_command(serial, "hdmi", "hdmi", "passthru") + + +def fake(serial): + lmp_send_command(serial, "hdmi", "hdmi", "fake") === added file 'lava_dispatcher/actions/lmp/lsgpio.py' --- lava_dispatcher/actions/lmp/lsgpio.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/lsgpio.py 2013-09-04 15:09:05 +0000 @@ -0,0 +1,45 @@ +# Copyright (C) 2013 Linaro Limited +# +# Author: Dave Pigott +# +# This file is part of LAVA Dispatcher. +# +# LAVA Dispatcher is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LAVA Dispatcher is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along +# with this program; if not, see . + +from lava_dispatcher.actions.lmp.board import lmp_send_command + + +def audio_disconnect(serial): + lmp_send_command(serial, "lsgpio", "audio", "disconnect") + + +def audio_passthru(serial): + lmp_send_command(serial, "lsgpio", "audio", "passthru") + + +def a_dir_in(serial): + lmp_send_command(serial, "lsgpio", "a-dir", "in") + + +def a_dir_out(serial): + lmp_send_command(serial, "lsgpio", "a-dir", "out") + + +def b_dir_in(serial): + lmp_send_command(serial, "lsgpio", "b-dir", "in") + + +def b_dir_out(serial): + lmp_send_command(serial, "lsgpio", "b-dir", "out") === added file 'lava_dispatcher/actions/lmp/sdmux.py' --- lava_dispatcher/actions/lmp/sdmux.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/sdmux.py 2013-09-04 15:09:05 +0000 @@ -0,0 +1,53 @@ +# Copyright (C) 2013 Linaro Limited +# +# Author: Dave Pigott +# +# This file is part of LAVA Dispatcher. +# +# LAVA Dispatcher is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LAVA Dispatcher is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along +# with this program; if not, see . + +from lava_dispatcher.actions.lmp.board import lmp_send_command + + +def dut_disconnect(serial): + lmp_send_command(serial, "sdmux", "dut", "disconnect") + + +def dut_usda(serial): + lmp_send_command(serial, "sdmux", "dut", "uSDA") + + +def dut_usdb(serial): + lmp_send_command(serial, "sdmux", "dut", "uSDB") + + +def host_disconnect(serial): + lmp_send_command(serial, "sdmux", "host", "disconnect") + + +def host_usda(serial): + lmp_send_command(serial, "sdmux", "host", "uSDA") + + +def host_usdb(serial): + lmp_send_command(serial, "sdmux", "host", "uSDB") + + +def dut_power_off(serial): + lmp_send_command(serial, "sdmux", "dut-power", "short-for-off") + + +def dut_power_on(serial): + lmp_send_command(serial, "sdmux", "dut-power", "short-for-on") === added file 'lava_dispatcher/actions/lmp/usb.py' --- lava_dispatcher/actions/lmp/usb.py 1970-01-01 00:00:00 +0000 +++ lava_dispatcher/actions/lmp/usb.py 2013-09-04 15:09:05 +0000 @@ -0,0 +1,33 @@ +# Copyright (C) 2013 Linaro Limited +# +# Author: Dave Pigott +# +# This file is part of LAVA Dispatcher. +# +# LAVA Dispatcher is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LAVA Dispatcher is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along +# with this program; if not, see . + +from lava_dispatcher.actions.lmp.board import lmp_send_command + + +def device(serial): + lmp_send_command(serial, "usb", "usb", "device") + + +def host(serial): + lmp_send_command(serial, "usb", "usb", "host") + + +def disconnect(serial): + lmp_send_command(serial, "usb", "usb", "disconnect") === modified file 'lava_dispatcher/config.py' --- lava_dispatcher/config.py 2013-08-28 14:55:50 +0000 +++ lava_dispatcher/config.py 2013-09-04 11:07:28 +0000 @@ -81,6 +81,9 @@ testboot_offset = schema.IntOption(fatal=True) # see doc/sdmux.rst for details sdmux_id = schema.StringOption() + sdmux_usb_id = schema.StringOption() + sdmux_mount_retry_seconds = schema.IntOption(default=20) + sdmux_mount_wait_seconds = schema.IntOption(default=10) sdmux_version = schema.StringOption(default="unknown") simulator_version_command = schema.StringOption() === modified file 'lava_dispatcher/default-config/lava-dispatcher/device-defaults.conf' --- lava_dispatcher/default-config/lava-dispatcher/device-defaults.conf 2013-08-28 14:55:50 +0000 +++ lava_dispatcher/default-config/lava-dispatcher/device-defaults.conf 2013-09-04 11:07:28 +0000 @@ -133,3 +133,9 @@ # How many times the dispatcher should try to reboot master and test images before failing boot_retries = 3 + +# For an sdmux enabled device, maximum amount of time to wait for the /dev/sdX to appear after device has been switched +# to host mode +sdmux_mount_retry_seconds = 20 +# How long to wait after the /dev/sdX entry has turned up before trying to unmount anything attached to it +sdmux_mount_wait_seconds = 10 === modified file 'lava_dispatcher/device/sdmux.py' --- lava_dispatcher/device/sdmux.py 2013-08-30 22:15:05 +0000 +++ lava_dispatcher/device/sdmux.py 2013-09-05 09:51:15 +0000 @@ -1,6 +1,7 @@ -# Copyright (C) 2012 Linaro Limited +# Copyright (C) 2012-2013 Linaro Limited # # Author: Andy Doan +# Dave Pigott # # This file is part of LAVA Dispatcher. # @@ -21,8 +22,10 @@ import contextlib import logging import os +import glob import subprocess import time +import lava_dispatcher.actions.lmp.sdmux as sdmux from lava_dispatcher.errors import ( CriticalError, @@ -64,26 +67,19 @@ This adds support for the "sd mux" device. An SD-MUX device is a piece of hardware that allows the host and target to both connect to the same SD card. The control of the SD card can then be toggled between the target - and host via software. The schematics and pictures of this device can be - found at: - http://people.linaro.org/~doanac/sdmux/ - - Documentation for setting this up is located under doc/sdmux.rst. - - NOTE: please read doc/sdmux.rst about kernel versions - """ + and host via software. +""" def __init__(self, context, config): super(SDMuxTarget, self).__init__(context, config) self.proc = None + if not config.sdmux_usb_id: + raise CriticalError('Device config requires "sdmux_usb_id"') + if not config.sdmux_id: raise CriticalError('Device config requires "sdmux_id"') - if not config.power_on_cmd: - raise CriticalError('Device config requires "power_on_cmd"') - if not config.power_off_cmd: - raise CriticalError('Device config requires "power_off_cmd"') if config.pre_connect_command: self.context.run_command(config.pre_connect_command) @@ -118,27 +114,19 @@ self._customize_android(img) self._write_image(img) - def _as_chunks(self, fname, bsize): - with open(fname, 'r') as fd: - while True: - data = fd.read(bsize) - if not data: - break - yield data - def _write_image(self, image): + sdmux.dut_disconnect(self.config.sdmux_id) + sdmux.host_usda(self.config.sdmux_id) + with self.mux_device() as device: logging.info("dd'ing image to device (%s)", device) - with open(device, 'w') as of: - written = 0 - size = os.path.getsize(image) - # 4M chunks work well for SD cards - for chunk in self._as_chunks(image, 4 << 20): - of.write(chunk) - written += len(chunk) - if written % (20 * (4 << 20)) == 0: # only log every 80MB - logging.info("wrote %d of %d bytes", written, size) - logging.info('closing %s, could take a while...', device) + dd_cmd = 'dd if=%s of=%s bs=4096 conv=fsync' % (image, device) + dd_proc = subprocess.Popen(dd_cmd, shell=True) + dd_proc.wait() + if dd_proc.returncode != 0: + raise CriticalError("Failed to dd image to device (Error code %d)" % dd_proc.returncode) + + sdmux.host_disconnect(self.config.sdmux_id) @contextlib.contextmanager def mux_device(self): @@ -153,23 +141,36 @@ the USB device connect to the sdmux will be powered off so that the target will be able to safely access it. """ - muxid = self.config.sdmux_id - source_dir = os.path.abspath(os.path.dirname(__file__)) - muxscript = os.path.join(source_dir, 'sdmux.sh') - self.power_off(self.proc) self.proc = None - try: - deventry = subprocess.check_output([muxscript, '-d', muxid, 'on']) - deventry = deventry.strip() - logging.info('returning sdmux device as: %s', deventry) + syspath = "/sys/bus/usb/devices/" + self.config.sdmux_usb_id + \ + "/" + self.config.sdmux_usb_id + \ + "*/host*/target*/*:0:0:0/block/*" + + retrycount = 0 + deventry = "" + + while retrycount < self.config.sdmux_mount_retry_seconds: + device_list = glob.glob(syspath) + for device in device_list: + deventry = os.path.join("/dev/", os.path.basename(device)) + break + if deventry != "": + break + time.sleep(1) + retrycount += 1 + + if deventry != "": + logging.debug('found sdmux device %s: Waiting %ds for any mounts to complete' + % (deventry, self.config.sdmux_mount_wait_seconds)) + time.sleep(self.config.sdmux_mount_wait_seconds) + logging.debug("Unmounting %s*", deventry) + os.system("umount %s*" % deventry) + logging.debug('returning sdmux device as: %s', deventry) yield deventry - except subprocess.CalledProcessError: + else: raise CriticalError('Unable to access sdmux device') - finally: - logging.info('powering off sdmux') - self.context.run_command([muxscript, '-d', muxid, 'off'], failok=False) @contextlib.contextmanager def file_system(self, partition, directory): @@ -219,10 +220,14 @@ def power_off(self, proc): super(SDMuxTarget, self).power_off(proc) self.context.run_command(self.config.power_off_cmd) + sdmux.dut_disconnect(self.config.sdmux_id) def power_on(self): self.proc = connect_to_serial(self.context) + sdmux.host_disconnect(self.config.sdmux_id) + sdmux.dut_usda(self.config.sdmux_id) + logging.info('powering on') self.context.run_command(self.config.power_on_cmd) === removed file 'lava_dispatcher/device/sdmux.sh' --- lava_dispatcher/device/sdmux.sh 2013-01-28 23:59:47 +0000 +++ lava_dispatcher/device/sdmux.sh 1970-01-01 00:00:00 +0000 @@ -1,79 +0,0 @@ -#!/bin/bash -# based on https://github.com/liyan/suspend-usb-device - -#set -e - -usage() -{ - cat<&2 echo "cannot find appropriate parent USB device, " - 1>&2 echo "perhaps ${DEV} is not an USB device?" - exit 1 - fi - - # the trailing basename of ${DEVICE} is DEV_BUS_ID - DEV_BUS_ID=${DEVICE##*/} - echo Device: ${DEVICE} - echo Bus ID: ${DEV_BUS_ID} - -elif [ -n "$ID" ] ; then - ACTION=${!OPTIND:-} - DIR=/sys/bus/usb/devices/${ID}/${ID}*/host*/target*/*:0:0:0/block - if [ $ACTION == "on" ] ; then - if [ -d $DIR ] ; then - echo " already on" 1>&2 - else - echo -n "${ID}" > /sys/bus/usb/drivers/usb/bind - sleep 4 - fi - device_path=`ls $DIR 2>/dev/null` - if [ $? -ne 0 ] ; then - echo " No sdmux found at ${DIR}" 1>&2 - exit 1 - fi - echo /dev/${device_path} - - elif [ $ACTION = "off" ] ; then - echo " Powering off sdmux: $ID" - echo -n "${ID}" > /sys/bus/usb/drivers/usb/unbind - sleep 1 - echo -n '0' > /sys/bus/usb/devices/$ID/power/autosuspend_delay_ms - sleep 1 - echo -n 'auto' > /sys/bus/usb/devices/$ID/power/control - sleep 2 - elif [ $ACTION = "deventry" ] ; then - echo /dev/`ls $DIR` - else - echo "ERROR: Action must be on/off" - usage; exit 1 - fi -else - usage -fi === modified file 'setup.py' --- setup.py 2013-07-18 14:01:21 +0000 +++ setup.py 2013-08-30 11:24:26 +0000 @@ -53,6 +53,7 @@ "configglue", "PyYAML", 'versiontools >= 1.8', + "pyserial", ], setup_requires=[ 'versiontools >= 1.8',