1# Copyright 2016 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import time 7 8from autotest_lib.client.common_lib import error 9from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10from autotest_lib.server.cros.servo import pd_device 11 12class firmware_PDResetHard(FirmwareTest): 13 """ 14 USB PD hard reset test. 15 16 Hard resets are issued by both ends of the connection. If the DUT 17 is dualrole capable, then a power role swap is executed, and the 18 test is repeated with the DUT in the opposite power role. Pass 19 criteria is that all attempted hard resets are successful. 20 21 """ 22 23 version = 1 24 RESET_ITERATIONS = 5 25 DELAY_BETWEEN_ITERATIONS = 1 26 PD_CONNECT_DELAY = 10 27 28 def _test_hard_reset(self, port_pair): 29 """Tests hard reset initated by both ends of PD connection 30 31 @param port_pair: list of 2 connected PD devices 32 """ 33 for dev in port_pair: 34 for _ in range(self.RESET_ITERATIONS): 35 try: 36 time.sleep(self.PD_CONNECT_DELAY) 37 if dev.hard_reset() == False: 38 raise error.TestFail('Hard Reset Failed') 39 time.sleep(self.DELAY_BETWEEN_ITERATIONS) 40 except NotImplementedError: 41 logging.warning('Device cant hard reset ... skipping') 42 break 43 44 def initialize(self, host, cmdline_args, flip_cc=False, dts_mode=False, 45 init_power_mode=None): 46 super(firmware_PDResetHard, self).initialize(host, cmdline_args) 47 self.setup_pdtester(flip_cc, dts_mode, min_batt_level=10) 48 # Only run in normal mode 49 self.switcher.setup_mode('normal') 50 if init_power_mode: 51 # Set the DUT to suspend or shutdown mode 52 self.set_ap_off_power_mode(init_power_mode) 53 # Turn off console prints, except for USBPD. 54 self.usbpd.enable_console_channel('usbpd') 55 56 def cleanup(self): 57 self.usbpd.send_command('chan 0xffffffff') 58 self.restore_ap_on_power_mode() 59 super(firmware_PDResetHard, self).cleanup() 60 61 def run_once(self): 62 """Execute Power Role swap test. 63 64 1. Verify that pd console is accessible 65 2. Verify that DUT has a valid PD contract 66 3. Make sure dualrole mode is enabled on both ends 67 4. Test Hard Reset initiated by both ends of connection 68 5. Attempt to change power roles 69 If power role changed, then retest soft resets 70 Else end test. 71 72 """ 73 # Create list of available UART consoles 74 consoles = [self.usbpd, self.pdtester] 75 port_partner = pd_device.PDPortPartner(consoles) 76 # Identify a valid test port pair 77 port_pair = port_partner.identify_pd_devices() 78 if not port_pair: 79 raise error.TestFail('No PD connection found!') 80 81 # Test hard resets initiated by both ends 82 self._test_hard_reset(port_pair) 83 84 # Swap power roles (if possible). Note the pr swap is attempted 85 # for both devices in the connection. This ensures that a device 86 # such as Plankton, which is dualrole capable, but has this mode 87 # disabled by default, won't prevent the device pair from role swapping. 88 swappable_dev = None; 89 for dev in port_pair: 90 try: 91 if dev.pr_swap(): 92 swappable_dev = dev 93 break 94 except NotImplementedError: 95 logging.warning('Power role swap not supported on the device') 96 97 if swappable_dev: 98 try: 99 # Power role has been swapped, retest. 100 self._test_hard_reset(port_pair) 101 finally: 102 # Swap power role again, back to the original 103 if not swappable_dev.pr_swap(): 104 logging.error('Failed to swap power role to the original') 105 else: 106 logging.warning('Device pair could not perform power role swap, ' 107 'ending test') 108