1cef7893435aa41160dd1255c43cb8498279738ccChris Craik#!/usr/bin/env python 2cef7893435aa41160dd1255c43cb8498279738ccChris Craik# Copyright 2015 The Chromium Authors. All rights reserved. 3cef7893435aa41160dd1255c43cb8498279738ccChris Craik# Use of this source code is governed by a BSD-style license that can be 4cef7893435aa41160dd1255c43cb8498279738ccChris Craik# found in the LICENSE file. 5cef7893435aa41160dd1255c43cb8498279738ccChris Craik 6cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport argparse 7cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport fcntl 8cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport logging 933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport os 10cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport re 11cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport sys 12cef7893435aa41160dd1255c43cb8498279738ccChris Craik 1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckif __name__ == '__main__': 1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck sys.path.append( 1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck os.path.abspath(os.path.join(os.path.dirname(__file__), 1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck '..', '..'))) 1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 18cef7893435aa41160dd1255c43cb8498279738ccChris Craikfrom devil.android import device_errors 19cef7893435aa41160dd1255c43cb8498279738ccChris Craikfrom devil.utils import lsusb 20cef7893435aa41160dd1255c43cb8498279738ccChris Craikfrom devil.utils import run_tests_helper 21cef7893435aa41160dd1255c43cb8498279738ccChris Craik 22ee838d1c4002134ff5af32da272140586c4d31deJohn Recklogger = logging.getLogger(__name__) 23ee838d1c4002134ff5af32da272140586c4d31deJohn Reck 24cef7893435aa41160dd1255c43cb8498279738ccChris Craik_INDENTATION_RE = re.compile(r'^( *)') 25cef7893435aa41160dd1255c43cb8498279738ccChris Craik_LSUSB_BUS_DEVICE_RE = re.compile(r'^Bus (\d{3}) Device (\d{3}):') 26cef7893435aa41160dd1255c43cb8498279738ccChris Craik_LSUSB_ENTRY_RE = re.compile(r'^ *([^ ]+) +([^ ]+) *([^ ].*)?$') 27cef7893435aa41160dd1255c43cb8498279738ccChris Craik_LSUSB_GROUP_RE = re.compile(r'^ *([^ ]+.*):$') 28cef7893435aa41160dd1255c43cb8498279738ccChris Craik 29cef7893435aa41160dd1255c43cb8498279738ccChris Craik_USBDEVFS_RESET = ord('U') << 8 | 20 30cef7893435aa41160dd1255c43cb8498279738ccChris Craik 31cef7893435aa41160dd1255c43cb8498279738ccChris Craik 32cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef reset_usb(bus, device): 33cef7893435aa41160dd1255c43cb8498279738ccChris Craik """Reset the USB device with the given bus and device.""" 34cef7893435aa41160dd1255c43cb8498279738ccChris Craik usb_file_path = '/dev/bus/usb/%03d/%03d' % (bus, device) 35cef7893435aa41160dd1255c43cb8498279738ccChris Craik with open(usb_file_path, 'w') as usb_file: 36ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.debug('fcntl.ioctl(%s, %d)', usb_file_path, _USBDEVFS_RESET) 37cef7893435aa41160dd1255c43cb8498279738ccChris Craik fcntl.ioctl(usb_file, _USBDEVFS_RESET) 38cef7893435aa41160dd1255c43cb8498279738ccChris Craik 39cef7893435aa41160dd1255c43cb8498279738ccChris Craik 40cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef reset_android_usb(serial): 41cef7893435aa41160dd1255c43cb8498279738ccChris Craik """Reset the USB device for the given Android device.""" 42cef7893435aa41160dd1255c43cb8498279738ccChris Craik lsusb_info = lsusb.lsusb() 43cef7893435aa41160dd1255c43cb8498279738ccChris Craik 44cef7893435aa41160dd1255c43cb8498279738ccChris Craik bus = None 45cef7893435aa41160dd1255c43cb8498279738ccChris Craik device = None 46cef7893435aa41160dd1255c43cb8498279738ccChris Craik for device_info in lsusb_info: 47cef7893435aa41160dd1255c43cb8498279738ccChris Craik device_serial = lsusb.get_lsusb_serial(device_info) 48cef7893435aa41160dd1255c43cb8498279738ccChris Craik if device_serial == serial: 49cef7893435aa41160dd1255c43cb8498279738ccChris Craik bus = int(device_info.get('bus')) 50cef7893435aa41160dd1255c43cb8498279738ccChris Craik device = int(device_info.get('device')) 51cef7893435aa41160dd1255c43cb8498279738ccChris Craik 52cef7893435aa41160dd1255c43cb8498279738ccChris Craik if bus and device: 53cef7893435aa41160dd1255c43cb8498279738ccChris Craik reset_usb(bus, device) 54cef7893435aa41160dd1255c43cb8498279738ccChris Craik else: 55cef7893435aa41160dd1255c43cb8498279738ccChris Craik raise device_errors.DeviceUnreachableError( 5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'Unable to determine bus(%s) or device(%s) for device %s' 5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck % (bus, device, serial)) 58cef7893435aa41160dd1255c43cb8498279738ccChris Craik 59cef7893435aa41160dd1255c43cb8498279738ccChris Craik 60cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef reset_all_android_devices(): 61cef7893435aa41160dd1255c43cb8498279738ccChris Craik """Reset all USB devices that look like an Android device.""" 62cef7893435aa41160dd1255c43cb8498279738ccChris Craik _reset_all_matching(lambda i: bool(lsusb.get_lsusb_serial(i))) 63cef7893435aa41160dd1255c43cb8498279738ccChris Craik 64cef7893435aa41160dd1255c43cb8498279738ccChris Craik 65cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef _reset_all_matching(condition): 66cef7893435aa41160dd1255c43cb8498279738ccChris Craik lsusb_info = lsusb.lsusb() 67cef7893435aa41160dd1255c43cb8498279738ccChris Craik for device_info in lsusb_info: 68cef7893435aa41160dd1255c43cb8498279738ccChris Craik if int(device_info.get('device')) != 1 and condition(device_info): 69cef7893435aa41160dd1255c43cb8498279738ccChris Craik bus = int(device_info.get('bus')) 70cef7893435aa41160dd1255c43cb8498279738ccChris Craik device = int(device_info.get('device')) 71cef7893435aa41160dd1255c43cb8498279738ccChris Craik try: 72cef7893435aa41160dd1255c43cb8498279738ccChris Craik reset_usb(bus, device) 73cef7893435aa41160dd1255c43cb8498279738ccChris Craik serial = lsusb.get_lsusb_serial(device_info) 74cef7893435aa41160dd1255c43cb8498279738ccChris Craik if serial: 75ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.info( 76ee838d1c4002134ff5af32da272140586c4d31deJohn Reck 'Reset USB device (bus: %03d, device: %03d, serial: %s)', 77cef7893435aa41160dd1255c43cb8498279738ccChris Craik bus, device, serial) 78cef7893435aa41160dd1255c43cb8498279738ccChris Craik else: 79ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.info( 80ee838d1c4002134ff5af32da272140586c4d31deJohn Reck 'Reset USB device (bus: %03d, device: %03d)', 81cef7893435aa41160dd1255c43cb8498279738ccChris Craik bus, device) 82cef7893435aa41160dd1255c43cb8498279738ccChris Craik except IOError: 83ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.error( 84cef7893435aa41160dd1255c43cb8498279738ccChris Craik 'Failed to reset USB device (bus: %03d, device: %03d)', 85cef7893435aa41160dd1255c43cb8498279738ccChris Craik bus, device) 86cef7893435aa41160dd1255c43cb8498279738ccChris Craik 87cef7893435aa41160dd1255c43cb8498279738ccChris Craik 88cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef main(): 89cef7893435aa41160dd1255c43cb8498279738ccChris Craik parser = argparse.ArgumentParser() 90cef7893435aa41160dd1255c43cb8498279738ccChris Craik parser.add_argument('-v', '--verbose', action='count') 91cef7893435aa41160dd1255c43cb8498279738ccChris Craik parser.add_argument('-s', '--serial') 92cef7893435aa41160dd1255c43cb8498279738ccChris Craik parser.add_argument('--bus', type=int) 93cef7893435aa41160dd1255c43cb8498279738ccChris Craik parser.add_argument('--device', type=int) 94cef7893435aa41160dd1255c43cb8498279738ccChris Craik args = parser.parse_args() 95cef7893435aa41160dd1255c43cb8498279738ccChris Craik 96cef7893435aa41160dd1255c43cb8498279738ccChris Craik run_tests_helper.SetLogLevel(args.verbose) 97cef7893435aa41160dd1255c43cb8498279738ccChris Craik 98cef7893435aa41160dd1255c43cb8498279738ccChris Craik if args.serial: 99cef7893435aa41160dd1255c43cb8498279738ccChris Craik reset_android_usb(args.serial) 100cef7893435aa41160dd1255c43cb8498279738ccChris Craik elif args.bus and args.device: 101cef7893435aa41160dd1255c43cb8498279738ccChris Craik reset_usb(args.bus, args.device) 102cef7893435aa41160dd1255c43cb8498279738ccChris Craik else: 103cef7893435aa41160dd1255c43cb8498279738ccChris Craik parser.error('Unable to determine target. ' 104cef7893435aa41160dd1255c43cb8498279738ccChris Craik 'Specify --serial or BOTH --bus and --device.') 105cef7893435aa41160dd1255c43cb8498279738ccChris Craik 106cef7893435aa41160dd1255c43cb8498279738ccChris Craik return 0 107cef7893435aa41160dd1255c43cb8498279738ccChris Craik 108cef7893435aa41160dd1255c43cb8498279738ccChris Craik 109cef7893435aa41160dd1255c43cb8498279738ccChris Craikif __name__ == '__main__': 110cef7893435aa41160dd1255c43cb8498279738ccChris Craik sys.exit(main()) 111cef7893435aa41160dd1255c43cb8498279738ccChris Craik 112