1*3045d7f0SStephen Warren# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. 2*3045d7f0SStephen Warren# 3*3045d7f0SStephen Warren# SPDX-License-Identifier: GPL-2.0 4*3045d7f0SStephen Warren 5*3045d7f0SStephen Warren# Test U-Boot's "ums" command. At present, this test only ensures that a UMS 6*3045d7f0SStephen Warren# device can be enumerated by the host/test machine. In the future, this test 7*3045d7f0SStephen Warren# should be enhanced to validate disk IO. 8*3045d7f0SStephen Warren 9*3045d7f0SStephen Warrenimport os 10*3045d7f0SStephen Warrenimport pytest 11*3045d7f0SStephen Warrenimport time 12*3045d7f0SStephen Warren 13*3045d7f0SStephen Warren''' 14*3045d7f0SStephen WarrenNote: This test relies on: 15*3045d7f0SStephen Warren 16*3045d7f0SStephen Warrena) boardenv_* to contain configuration values to define which USB ports are 17*3045d7f0SStephen Warrenavailable for testing. Without this, this test will be automatically skipped. 18*3045d7f0SStephen WarrenFor example: 19*3045d7f0SStephen Warren 20*3045d7f0SStephen Warrenenv__usb_dev_ports = ( 21*3045d7f0SStephen Warren {'tgt_usb_ctlr': '0', 'host_ums_dev_node': '/dev/disk/by-path/pci-0000:00:14.0-usb-0:13:1.0-scsi-0:0:0:0'}, 22*3045d7f0SStephen Warren) 23*3045d7f0SStephen Warren 24*3045d7f0SStephen Warrenenv__block_devs = ( 25*3045d7f0SStephen Warren {'type': 'mmc', 'id': '0'}, # eMMC; always present 26*3045d7f0SStephen Warren {'type': 'mmc', 'id': '1'}, # SD card; present since I plugged one in 27*3045d7f0SStephen Warren) 28*3045d7f0SStephen Warren 29*3045d7f0SStephen Warrenb) udev rules to set permissions on devices nodes, so that sudo is not 30*3045d7f0SStephen Warrenrequired. For example: 31*3045d7f0SStephen Warren 32*3045d7f0SStephen WarrenACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", KERNELS=="3-13", MODE:="666" 33*3045d7f0SStephen Warren 34*3045d7f0SStephen Warren(You may wish to change the group ID instead of setting the permissions wide 35*3045d7f0SStephen Warrenopen. All that matters is that the user ID running the test can access the 36*3045d7f0SStephen Warrendevice.) 37*3045d7f0SStephen Warren''' 38*3045d7f0SStephen Warren 39*3045d7f0SStephen Warrendef open_ums_device(host_ums_dev_node): 40*3045d7f0SStephen Warren '''Attempt to open a device node, returning either the opened file handle, 41*3045d7f0SStephen Warren or None on any error.''' 42*3045d7f0SStephen Warren 43*3045d7f0SStephen Warren try: 44*3045d7f0SStephen Warren return open(host_ums_dev_node, 'rb') 45*3045d7f0SStephen Warren except: 46*3045d7f0SStephen Warren return None 47*3045d7f0SStephen Warren 48*3045d7f0SStephen Warrendef wait_for_ums_device(host_ums_dev_node): 49*3045d7f0SStephen Warren '''Continually attempt to open the device node exported by the "ums" 50*3045d7f0SStephen Warren command, and either return the opened file handle, or raise an exception 51*3045d7f0SStephen Warren after a timeout.''' 52*3045d7f0SStephen Warren 53*3045d7f0SStephen Warren for i in xrange(100): 54*3045d7f0SStephen Warren fh = open_ums_device(host_ums_dev_node) 55*3045d7f0SStephen Warren if fh: 56*3045d7f0SStephen Warren return fh 57*3045d7f0SStephen Warren time.sleep(0.1) 58*3045d7f0SStephen Warren raise Exception('UMS device did not appear') 59*3045d7f0SStephen Warren 60*3045d7f0SStephen Warrendef wait_for_ums_device_gone(host_ums_dev_node): 61*3045d7f0SStephen Warren '''Continually attempt to open the device node exported by the "ums" 62*3045d7f0SStephen Warren command, and either return once the device has disappeared, or raise an 63*3045d7f0SStephen Warren exception if it does not before a timeout occurs.''' 64*3045d7f0SStephen Warren 65*3045d7f0SStephen Warren for i in xrange(100): 66*3045d7f0SStephen Warren fh = open_ums_device(host_ums_dev_node) 67*3045d7f0SStephen Warren if not fh: 68*3045d7f0SStephen Warren return 69*3045d7f0SStephen Warren fh.close() 70*3045d7f0SStephen Warren time.sleep(0.1) 71*3045d7f0SStephen Warren raise Exception('UMS device did not disappear') 72*3045d7f0SStephen Warren 73*3045d7f0SStephen Warren@pytest.mark.buildconfigspec('cmd_usb_mass_storage') 74*3045d7f0SStephen Warrendef test_ums(u_boot_console, env__usb_dev_port, env__block_devs): 75*3045d7f0SStephen Warren '''Test the "ums" command; the host system must be able to enumerate a UMS 76*3045d7f0SStephen Warren device when "ums" is running, and this device must disappear when "ums" is 77*3045d7f0SStephen Warren aborted.''' 78*3045d7f0SStephen Warren 79*3045d7f0SStephen Warren tgt_usb_ctlr = env__usb_dev_port['tgt_usb_ctlr'] 80*3045d7f0SStephen Warren host_ums_dev_node = env__usb_dev_port['host_ums_dev_node'] 81*3045d7f0SStephen Warren 82*3045d7f0SStephen Warren # We're interested in testing USB device mode on each port, not the cross- 83*3045d7f0SStephen Warren # product of that with each device. So, just pick the first entry in the 84*3045d7f0SStephen Warren # device list here. We'll test each block device somewhere else. 85*3045d7f0SStephen Warren tgt_dev_type = env__block_devs[0]['type'] 86*3045d7f0SStephen Warren tgt_dev_id = env__block_devs[0]['id'] 87*3045d7f0SStephen Warren 88*3045d7f0SStephen Warren cmd = 'ums %s %s %s' % (tgt_usb_ctlr, tgt_dev_type, tgt_dev_id) 89*3045d7f0SStephen Warren u_boot_console.run_command('ums 0 mmc 0', wait_for_prompt=False) 90*3045d7f0SStephen Warren fh = wait_for_ums_device(host_ums_dev_node) 91*3045d7f0SStephen Warren fh.read(4096) 92*3045d7f0SStephen Warren fh.close() 93*3045d7f0SStephen Warren u_boot_console.ctrlc() 94*3045d7f0SStephen Warren wait_for_ums_device_gone(host_ums_dev_node) 95