• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The Chromium 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
5PLUGABLE_7PORT_LAYOUT = {1:7,
6                         2:6,
7                         3:5,
8                         4:{1:4, 2:3, 3:2, 4:1}}
9
10PLUGABLE_7PORT_USB3_LAYOUT = {1:{1:1, 2:2, 3:3, 4:4},
11                              2:5,
12                              3:6,
13                              4:7}
14
15KEEDOX_LAYOUT = {1:1,
16                 2:2,
17                 3:3,
18                 4:{1:4, 2:5, 3:6, 4:7}}
19
20VIA_LAYOUT = {1:1,
21              2:2,
22              3:3,
23              4:{1:4, 2:5, 3:6, 4:7}}
24
25class HubType(object):
26  def __init__(self, id_func, port_mapping):
27    """Defines a type of hub.
28
29    Args:
30      id_func: [USBNode -> bool] is a function that can be run on a node
31        to determine if the node represents this type of hub.
32      port_mapping: [dict(int:(int|dict))] maps virtual to physical port
33        numbers. For instance, {3:1, 1:2, 2:3} means that virtual port 3
34        corresponds to physical port 1, virtual port 1 corresponds to physical
35        port 2, and virtual port 2 corresponds to physical port 3. In the
36        case of hubs with "internal" topology, this is represented by nested
37        maps. For instance, {1:{1:1,2:2},2:{1:3,2:4}} means, e.g. that the
38        device plugged into physical port 3 will show up as being connected
39        to port 1, on a device which is connected to port 2 on the hub.
40    """
41    self._id_func = id_func
42    # v2p = "virtual to physical" ports
43    self._v2p_port = port_mapping
44
45  def IsType(self, node):
46    """Determines if the given Node is a hub of this type.
47
48    Args:
49      node: [USBNode] Node to check.
50    """
51    return self._id_func(node)
52
53  def GetPhysicalPortToNodeTuples(self, node):
54    """Gets devices connected to the physical ports on a hub of this type.
55
56    Args:
57      node: [USBNode] Node representing a hub of this type.
58
59    Yields:
60      A series of (int, USBNode) tuples giving a physical port
61      and the USBNode connected to it.
62
63    Raises:
64      ValueError: If the given node isn't a hub of this type.
65    """
66    if self.IsType(node):
67      for res in self._GppHelper(node, self._v2p_port):
68        yield res
69    else:
70      raise ValueError('Node must be a hub of this type')
71
72  def _GppHelper(self, node, mapping):
73    """Helper function for GetPhysicalPortToNodeMap.
74
75    Gets devices connected to physical ports, based on device tree
76    rooted at the given node and the mapping between virtual and physical
77    ports.
78
79    Args:
80      node: [USBNode] Root of tree to search for devices.
81      mapping: [dict] Mapping between virtual and physical ports.
82
83    Yields:
84      A series of (int, USBNode) tuples giving a physical port
85      and the Node connected to it.
86    """
87    for (virtual, physical) in mapping.iteritems():
88      if node.HasPort(virtual):
89        if isinstance(physical, dict):
90          for res in self._GppHelper(node.PortToDevice(virtual), physical):
91            yield res
92        else:
93          yield (physical, node.PortToDevice(virtual))
94
95def _is_plugable_7port_hub(node):
96  """Check if a node is a Plugable 7-Port Hub
97  (Model USB2-HUB7BC)
98  The topology of this device is a 4-port hub,
99  with another 4-port hub connected on port 4.
100  """
101  if '1a40:0101' not in node.desc:
102    return False
103  if not node.HasPort(4):
104    return False
105  return '1a40:0101' in node.PortToDevice(4).desc
106
107# Plugable 7-Port USB-3 Hubs show up twice in the USB devices list; they have
108# two different "branches", one which has USB2 devices and one which has
109# USB3 devices. The "part2" is the "USB-2" branch of the hub, the
110# "part3" is the "USB-3" branch of the hub.
111
112def _is_plugable_7port_usb3_part2_hub(node):
113  """Check if a node is the "USB2 branch" of
114  a Plugable 7-Port USB-3 Hub (Model USB3-HUB7BC)
115  The topology of this device is a 4-port hub,
116  with another 4-port hub connected on port 1.
117  """
118  if '2109:2811' not in node.desc:
119    return False
120  if not node.HasPort(1):
121    return False
122  return '2109:2811' in node.PortToDevice(1).desc
123
124def _is_plugable_7port_usb3_part3_hub(node):
125  """Check if a node is the "USB3 branch" of
126  a Plugable 7-Port USB-3 Hub (Model USB3-HUB7BC)
127  The topology of this device is a 4-port hub,
128  with another 4-port hub connected on port 1.
129  """
130  if '2109:8110' not in node.desc:
131    return False
132  if not node.HasPort(1):
133    return False
134  return '2109:8110' in node.PortToDevice(1).desc
135
136def _is_keedox_hub(node):
137  """Check if a node is a Keedox hub.
138  The topology of this device is a 4-port hub,
139  with another 4-port hub connected on port 4.
140  """
141  if '0bda:5411' not in node.desc:
142    return False
143  if not node.HasPort(4):
144    return False
145  return '0bda:5411' in node.PortToDevice(4).desc
146
147def _is_via_hub(node):
148  """Check if a node is a Via Labs hub.
149  The topology of this device is a 4-port hub,
150  with another 4-port hub connected on port 4.
151  """
152  if '2109:2812' not in node.desc and '2109:0812' not in node.desc:
153    return False
154  if not node.HasPort(4):
155    return False
156  return ('2109:2812' in node.PortToDevice(4).desc or
157          '2109:0812' in node.PortToDevice(4).desc)
158
159
160PLUGABLE_7PORT = HubType(_is_plugable_7port_hub, PLUGABLE_7PORT_LAYOUT)
161PLUGABLE_7PORT_USB3_PART2 = HubType(_is_plugable_7port_usb3_part2_hub,
162                                    PLUGABLE_7PORT_USB3_LAYOUT)
163PLUGABLE_7PORT_USB3_PART3 = HubType(_is_plugable_7port_usb3_part3_hub,
164                                    PLUGABLE_7PORT_USB3_LAYOUT)
165KEEDOX = HubType(_is_keedox_hub, KEEDOX_LAYOUT)
166VIA = HubType(_is_via_hub, VIA_LAYOUT)
167
168ALL_HUBS = [PLUGABLE_7PORT,
169            PLUGABLE_7PORT_USB3_PART2,
170            PLUGABLE_7PORT_USB3_PART3,
171            KEEDOX,
172            VIA]
173
174def GetHubType(type_name):
175  if type_name == 'plugable_7port':
176    return PLUGABLE_7PORT
177  elif type_name == 'plugable_7port_usb3_part2':
178    return PLUGABLE_7PORT_USB3_PART2
179  elif type_name == 'plugable_7port_usb3_part3':
180    return PLUGABLE_7PORT_USB3_PART3
181  elif type_name == 'keedox':
182    return KEEDOX
183  elif type_name == 'via':
184    return VIA
185  raise ValueError('Invalid hub type')
186