1# SPDX-License-Identifier: GPL-2.0 2# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 4""" Test for bind command """ 5 6import re 7import pytest 8 9def in_tree(response, name, uclass, drv, depth, last_child): 10 lines = [x.strip() for x in response.splitlines()] 11 leaf = '' 12 if depth != 0: 13 leaf = ' ' + ' ' * (depth - 1) 14 if not last_child: 15 leaf = leaf + r'\|' 16 else: 17 leaf = leaf + '`' 18 19 leaf = leaf + '-- ' + name 20 line = (r' *{:10.10} *[0-9]* \[ [ +] \] {:20.20} [` |]{}$' 21 .format(uclass, drv, leaf)) 22 prog = re.compile(line) 23 for l in lines: 24 if prog.match(l): 25 return True 26 return False 27 28@pytest.mark.boardspec('sandbox') 29@pytest.mark.buildconfigspec('cmd_bind') 30def test_bind_unbind_with_node(u_boot_console): 31 32 tree = u_boot_console.run_command('dm tree') 33 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 34 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 35 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 36 37 #bind usb_ether driver (which has no compatible) to usb@1 node. 38 ##New entry usb_ether should appear in the dm tree 39 response = u_boot_console.run_command('bind /usb@1 usb_ether') 40 assert response == '' 41 tree = u_boot_console.run_command('dm tree') 42 assert in_tree(tree, 'usb@1', 'ethernet', 'usb_ether', 1, True) 43 44 #Unbind child #1. No error expected and all devices should be there except for bind-test-child1 45 response = u_boot_console.run_command('unbind /bind-test/bind-test-child1') 46 assert response == '' 47 tree = u_boot_console.run_command('dm tree') 48 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 49 assert 'bind-test-child1' not in tree 50 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 51 52 #bind child #1. No error expected and all devices should be there 53 response = u_boot_console.run_command('bind /bind-test/bind-test-child1 phy_sandbox') 54 assert response == '' 55 tree = u_boot_console.run_command('dm tree') 56 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 57 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True) 58 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, False) 59 60 #Unbind child #2. No error expected and all devices should be there except for bind-test-child2 61 response = u_boot_console.run_command('unbind /bind-test/bind-test-child2') 62 assert response == '' 63 tree = u_boot_console.run_command('dm tree') 64 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 65 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True) 66 assert 'bind-test-child2' not in tree 67 68 69 #Bind child #2. No error expected and all devices should be there 70 response = u_boot_console.run_command('bind /bind-test/bind-test-child2 simple_bus') 71 assert response == '' 72 tree = u_boot_console.run_command('dm tree') 73 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 74 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 75 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 76 77 #Unbind parent. No error expected. All devices should be removed and unbound 78 response = u_boot_console.run_command('unbind /bind-test') 79 assert response == '' 80 tree = u_boot_console.run_command('dm tree') 81 assert 'bind-test' not in tree 82 assert 'bind-test-child1' not in tree 83 assert 'bind-test-child2' not in tree 84 85 #try binding invalid node with valid driver 86 response = u_boot_console.run_command('bind /not-a-valid-node simple_bus') 87 assert response != '' 88 tree = u_boot_console.run_command('dm tree') 89 assert 'not-a-valid-node' not in tree 90 91 #try binding valid node with invalid driver 92 response = u_boot_console.run_command('bind /bind-test not_a_driver') 93 assert response != '' 94 tree = u_boot_console.run_command('dm tree') 95 assert 'bind-test' not in tree 96 97 #bind /bind-test. Device should come up as well as its children 98 response = u_boot_console.run_command('bind /bind-test simple_bus') 99 assert response == '' 100 tree = u_boot_console.run_command('dm tree') 101 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 102 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 103 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 104 105 response = u_boot_console.run_command('unbind /bind-test') 106 assert response == '' 107 108def get_next_line(tree, name): 109 treelines = [x.strip() for x in tree.splitlines() if x.strip()] 110 child_line = '' 111 for idx, line in enumerate(treelines): 112 if '-- ' + name in line: 113 try: 114 child_line = treelines[idx+1] 115 except: 116 pass 117 break 118 return child_line 119 120@pytest.mark.boardspec('sandbox') 121@pytest.mark.buildconfigspec('cmd_bind') 122@pytest.mark.singlethread 123def test_bind_unbind_with_uclass(u_boot_console): 124 #bind /bind-test 125 response = u_boot_console.run_command('bind /bind-test simple_bus') 126 assert response == '' 127 128 #make sure bind-test-child2 is there and get its uclass/index pair 129 tree = u_boot_console.run_command('dm tree') 130 child2_line = [x.strip() for x in tree.splitlines() if '-- bind-test-child2' in x] 131 assert len(child2_line) == 1 132 133 child2_uclass = child2_line[0].split()[0] 134 child2_index = int(child2_line[0].split()[1]) 135 136 #bind simple_bus as a child of bind-test-child2 137 response = u_boot_console.run_command( 138 'bind {} {} simple_bus'.format(child2_uclass, child2_index)) 139 140 #check that the child is there and its uclass/index pair is right 141 tree = u_boot_console.run_command('dm tree') 142 143 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 144 assert child_of_child2_line 145 child_of_child2_index = int(child_of_child2_line.split()[1]) 146 assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True) 147 assert child_of_child2_index == child2_index + 1 148 149 #unbind the child and check it has been removed 150 response = u_boot_console.run_command('unbind simple_bus {}'.format(child_of_child2_index)) 151 assert response == '' 152 tree = u_boot_console.run_command('dm tree') 153 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 154 assert not in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True) 155 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 156 assert child_of_child2_line == '' 157 158 #bind simple_bus as a child of bind-test-child2 159 response = u_boot_console.run_command( 160 'bind {} {} simple_bus'.format(child2_uclass, child2_index)) 161 162 #check that the child is there and its uclass/index pair is right 163 tree = u_boot_console.run_command('dm tree') 164 treelines = [x.strip() for x in tree.splitlines() if x.strip()] 165 166 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 167 assert child_of_child2_line 168 child_of_child2_index = int(child_of_child2_line.split()[1]) 169 assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True) 170 assert child_of_child2_index == child2_index + 1 171 172 #unbind the child and check it has been removed 173 response = u_boot_console.run_command( 174 'unbind {} {} simple_bus'.format(child2_uclass, child2_index)) 175 assert response == '' 176 177 tree = u_boot_console.run_command('dm tree') 178 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 179 180 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 181 assert child_of_child2_line == '' 182 183 #unbind the child again and check it doesn't change the tree 184 tree_old = u_boot_console.run_command('dm tree') 185 response = u_boot_console.run_command( 186 'unbind {} {} simple_bus'.format(child2_uclass, child2_index)) 187 tree_new = u_boot_console.run_command('dm tree') 188 189 assert response == '' 190 assert tree_old == tree_new 191 192 response = u_boot_console.run_command('unbind /bind-test') 193 assert response == '' 194