Merge lp:~adeuring/launchpad/hwdb-class-udev-device-9 into lp:launchpad
- hwdb-class-udev-device-9
- Merge into devel
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/hwdb-class-udev-device-9 |
Merge into: | lp:launchpad |
Diff against target: |
829 lines 2 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+43/-7) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+391/-52) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/hwdb-class-udev-device-9 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eleanor Berger (community) | code | Approve | |
Review via email: mp+13562@code.launchpad.net |
Commit message
Description of the change
Abel Deuring (adeuring) wrote : | # |
Abel Deuring (adeuring) wrote : | # |
This branch is based on lp:~adeuring/launchpad/hwdb-class-udev-device-9, which is reviewd, but has not yet landed. Here is the diff against that branch:
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -1835,6 +1835,9 @@
Since these components are not the most important ones
for the HWDB, we'll ignore them for now. Bug 237038.
+ - 'disk' is used udev submissions for a node related to the
+ sd or sr driver of (real or fake) SCSI block devices.
+
- info.bus == 'drm' is used by the HAL for the direct
@@ -1847,6 +1850,12 @@
- info.bus == 'net' is used by the HAL version in
+ - 'partition' is used in udev submissions for a node
+ related to disk partition
+
+ - 'scsi_disk' is used in udev submissions for a sub-node of
+ the real device node.
+
@@ -1858,6 +1867,12 @@
"SCSI aspect" of another HAL node which represents the
real device.
+ 'scsi_target' is used in udev data for SCSI target nodes,
+ the parent of a SCSI device (or LUN) node.
+
+ 'spi_transport' (SCSI Parallel Transport) is used in
+ udev data for a sub-node of real SCSI devices.
+
@@ -1873,20 +1888,31 @@
the root node of a USB device has info.bus == 'usb_device'.
+ 'usb_interface' is used in udv submissions for interface
+ nodes of USB devices.
+
of video devices.
"""
+ # The root node is always a real device, but its raw_bus
+ # property can have different values: None or 'Unknown' in
+ # submissions with HAL data, 'acpi' for submissions with udev
+ # data.
+ if self.is_
+ return True
+
bus = self.raw_bus
# This set of buses is only used once; it's easier to have it
# here than to put it elsewhere and have to document its
# location and purpose.
- if bus in (None, 'drm', 'dvb', 'memstick_host', 'net',
- 'scsi_generic', 'scsi_host', 'sound', 'ssb', 'tty',
- 'usb', 'video4linux', ):
+ if bus in (None, 'disk', 'drm', 'dvb', 'memstick_host', 'net',
+ 'partition', 'scsi_disk', 'scsi_generic', 'scsi_host',
+ 'scsi_target', 'sound', 'spi_transport', 'ssb', 'tty',
+ 'usb', 'usb_interface', 'video4linux', ):
#
...
Abel Deuring (adeuring) wrote : | # |
> This branch is based on lp:~adeuring/launchpad/hwdb-class-udev-device-9,
sigh, that should be lp:~adeuring/launchpad/hwdb-class-udev-device-8
Eleanor Berger (intellectronica) : | # |
Preview Diff
1 | === modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py' |
2 | --- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-15 13:59:33 +0000 |
3 | +++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-19 11:30:32 +0000 |
4 | @@ -1835,6 +1835,9 @@ |
5 | Since these components are not the most important ones |
6 | for the HWDB, we'll ignore them for now. Bug 237038. |
7 | |
8 | + - 'disk' is used udev submissions for a node related to the |
9 | + sd or sr driver of (real or fake) SCSI block devices. |
10 | + |
11 | - info.bus == 'drm' is used by the HAL for the direct |
12 | rendering interface of a graphics card. |
13 | |
14 | @@ -1847,6 +1850,12 @@ |
15 | - info.bus == 'net' is used by the HAL version in |
16 | Intrepid for the "output aspects" of network devices. |
17 | |
18 | + - 'partition' is used in udev submissions for a node |
19 | + related to disk partition |
20 | + |
21 | + - 'scsi_disk' is used in udev submissions for a sub-node of |
22 | + the real device node. |
23 | + |
24 | info.bus == 'scsi_generic' is used by the HAL version in |
25 | Intrepid for a HAL node representing the generic |
26 | interface of a SCSI device. |
27 | @@ -1858,6 +1867,12 @@ |
28 | "SCSI aspect" of another HAL node which represents the |
29 | real device. |
30 | |
31 | + 'scsi_target' is used in udev data for SCSI target nodes, |
32 | + the parent of a SCSI device (or LUN) node. |
33 | + |
34 | + 'spi_transport' (SCSI Parallel Transport) is used in |
35 | + udev data for a sub-node of real SCSI devices. |
36 | + |
37 | info.bus == 'sound' is used by the HAL version in |
38 | Intrepid for "aspects" of sound devices. |
39 | |
40 | @@ -1873,20 +1888,31 @@ |
41 | info.bus == 'usb' is used for end points of USB devices; |
42 | the root node of a USB device has info.bus == 'usb_device'. |
43 | |
44 | + 'usb_interface' is used in udv submissions for interface |
45 | + nodes of USB devices. |
46 | + |
47 | info.bus == 'video4linux' is used for the "input aspect" |
48 | of video devices. |
49 | """ |
50 | + # The root node is always a real device, but its raw_bus |
51 | + # property can have different values: None or 'Unknown' in |
52 | + # submissions with HAL data, 'acpi' for submissions with udev |
53 | + # data. |
54 | + if self.is_root_device: |
55 | + return True |
56 | + |
57 | bus = self.raw_bus |
58 | # This set of buses is only used once; it's easier to have it |
59 | # here than to put it elsewhere and have to document its |
60 | # location and purpose. |
61 | - if bus in (None, 'drm', 'dvb', 'memstick_host', 'net', |
62 | - 'scsi_generic', 'scsi_host', 'sound', 'ssb', 'tty', |
63 | - 'usb', 'video4linux', ): |
64 | + if bus in (None, 'disk', 'drm', 'dvb', 'memstick_host', 'net', |
65 | + 'partition', 'scsi_disk', 'scsi_generic', 'scsi_host', |
66 | + 'scsi_target', 'sound', 'spi_transport', 'ssb', 'tty', |
67 | + 'usb', 'usb_interface', 'video4linux', ): |
68 | # |
69 | # The computer itself is the only HAL device without the |
70 | # info.bus property that we treat as a real device. |
71 | - return self.udi == ROOT_UDI |
72 | + return False |
73 | elif bus == 'usb_device': |
74 | vendor_id = self.usb_vendor_id |
75 | product_id = self.usb_product_id |
76 | @@ -1910,7 +1936,7 @@ |
77 | 'host controller: %s' % self.udi) |
78 | return False |
79 | return True |
80 | - elif bus == 'scsi': |
81 | + elif bus in ('scsi', 'scsi_device'): |
82 | # Ensure consistency with HALDevice.real_bus |
83 | return self.real_bus is not None |
84 | else: |
85 | @@ -2564,7 +2590,17 @@ |
86 | devtype = properties.get('DEVTYPE') |
87 | if devtype is not None: |
88 | return devtype |
89 | - return properties.get('SUBSYSTEM') |
90 | + subsystem = properties.get('SUBSYSTEM') |
91 | + # A real mess: The main node of a SCSI device has |
92 | + # SUBSYSTEM = 'scsi' and DEVTYPE = 'scsi_device', while |
93 | + # a sub-node has SUBSYSTEM='scsi_device'. We don't want |
94 | + # the two to be confused. The latter node is not of any |
95 | + # interest for us, so we return None. This ensures that |
96 | + # is_real_device returns False for the sub-node. |
97 | + if subsystem != 'scsi_device': |
98 | + return subsystem |
99 | + else: |
100 | + return None |
101 | |
102 | @property |
103 | def is_root_device(self): |
104 | @@ -2665,7 +2701,7 @@ |
105 | # While SCSI devices from valid submissions should have four |
106 | # ancestors, we can't be sure for bogus or broken submissions. |
107 | try: |
108 | - controller = self.parent.parent.parent.parent |
109 | + controller = self.parent.parent.parent |
110 | except AttributeError: |
111 | controller = None |
112 | if controller is None: |
113 | |
114 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py' |
115 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-15 15:28:38 +0000 |
116 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-19 11:30:32 +0000 |
117 | @@ -2859,18 +2859,6 @@ |
118 | '/sys/class/dmi/id/product_name': 'LIFEBOOK E8210', |
119 | } |
120 | |
121 | - self.pci_device_data = { |
122 | - 'P': '/devices/pci0000:00/0000:00:1f.2', |
123 | - 'E': { |
124 | - 'PCI_CLASS': '10602', |
125 | - 'PCI_ID': '8086:27C5', |
126 | - 'PCI_SUBSYS_ID': '10CF:1387', |
127 | - 'PCI_SLOT_NAME': '0000:00:1f.2', |
128 | - 'SUBSYSTEM': 'pci', |
129 | - 'DRIVER': 'ahci', |
130 | - } |
131 | - } |
132 | - |
133 | self.usb_device_data = { |
134 | 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2', |
135 | 'E': { |
136 | @@ -2882,8 +2870,10 @@ |
137 | }, |
138 | } |
139 | |
140 | + self.pci_pccard_bridge_path = ( |
141 | + '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0') |
142 | self.pci_pccard_bridge = { |
143 | - 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0', |
144 | + 'P': self.pci_pccard_bridge_path, |
145 | 'E': { |
146 | 'DRIVER': 'yenta_cardbus', |
147 | 'PCI_CLASS': '60700', |
148 | @@ -2894,8 +2884,10 @@ |
149 | } |
150 | } |
151 | |
152 | + self.pccard_scsi_controller_path = ( |
153 | + '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0') |
154 | self.pccard_scsi_controller_data = { |
155 | - 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0', |
156 | + 'P': self.pccard_scsi_controller_path, |
157 | 'E': { |
158 | 'DRIVER': 'aic7xxx', |
159 | 'PCI_CLASS': '10000', |
160 | @@ -2937,9 +2929,11 @@ |
161 | }, |
162 | } |
163 | |
164 | + self.scsi_scanner_device_path = ( |
165 | + '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0/' |
166 | + 'host6/target6:0:1/6:0:1:0') |
167 | self.scsi_scanner_device_data = { |
168 | - 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
169 | - '0000:09:00.0/host6/target6:0:1/6:0:1:0'), |
170 | + 'P': self.scsi_scanner_device_path, |
171 | 'E': { |
172 | 'DEVTYPE': 'scsi_device', |
173 | 'SUBSYSTEM': 'scsi', |
174 | @@ -2952,6 +2946,31 @@ |
175 | 'type': '6', |
176 | } |
177 | |
178 | + self.scsi_scanner_device_data_2 = { |
179 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
180 | + '0000:09:00.0/host6/target6:0:1/6:0:1:0/scsi_device/' |
181 | + '6:0:1:0'), |
182 | + 'E': { |
183 | + 'SUBSYSTEM': 'scsi_device', |
184 | + }, |
185 | + } |
186 | + |
187 | + self.scsi_scanner_scsi_generic = { |
188 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
189 | + '0000:09:00.0/host6/target6:0:1/6:0:1:0/scsi_generic/sg2'), |
190 | + 'E': { |
191 | + 'SUBSYSTEM': 'scsi_generic', |
192 | + }, |
193 | + } |
194 | + |
195 | + self.scsi_scanner_spi = { |
196 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
197 | + '0000:09:00.0/host6/target6:0:1/spi_transport/target6:0:1'), |
198 | + 'E': { |
199 | + 'SUBSYSTEM': 'spi_transport', |
200 | + }, |
201 | + } |
202 | + |
203 | self.scsi_device_hierarchy_data = [ |
204 | {'udev_data': self.pccard_scsi_controller_data}, |
205 | {'udev_data': self.pci_scsi_controller_scsi_side_1}, |
206 | @@ -2961,10 +2980,14 @@ |
207 | 'udev_data': self.scsi_scanner_device_data, |
208 | 'sysfs_data': self.scsi_scanner_device_sysfs_data, |
209 | }, |
210 | + {'udev_data': self.scsi_scanner_device_data_2}, |
211 | + {'udev_data': self.scsi_scanner_scsi_generic}, |
212 | + {'udev_data': self.scsi_scanner_spi}, |
213 | ] |
214 | |
215 | + self.pci_ide_controller_path = '/devices/pci0000:00/0000:00:1f.1' |
216 | self.pci_ide_controller = { |
217 | - 'P': '/devices/pci0000:00/0000:00:1f.1', |
218 | + 'P': self.pci_ide_controller_path, |
219 | 'E': { |
220 | 'DRIVER': 'ata_piix', |
221 | 'PCI_CLASS': '1018A', |
222 | @@ -2997,9 +3020,10 @@ |
223 | }, |
224 | } |
225 | |
226 | + self.ide_cdrom_device_path = ( |
227 | + '/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0') |
228 | self.ide_cdrom_device_data = { |
229 | - 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/' |
230 | - '4:0:0:0'), |
231 | + 'P': self.ide_cdrom_device_path, |
232 | 'E': { |
233 | 'SUBSYSTEM': 'scsi', |
234 | 'DEVTYPE': 'scsi_device', |
235 | @@ -3013,6 +3037,31 @@ |
236 | 'type': '5', |
237 | } |
238 | |
239 | + self.ide_cdrom_sr_data = { |
240 | + 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/' |
241 | + '4:0:0:0/block/sr0'), |
242 | + 'E': { |
243 | + 'DEVTYPE': 'disk', |
244 | + 'SUBSYSTEM': 'block', |
245 | + }, |
246 | + } |
247 | + |
248 | + self.ide_cdrom_device_data_2 = { |
249 | + 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/' |
250 | + '4:0:0:0/scsi_device/4:0:0:0'), |
251 | + 'E': { |
252 | + 'SUBSYSTEM': 'scsi_device', |
253 | + }, |
254 | + } |
255 | + |
256 | + self.ide_cdrom_scsi_generic_data = { |
257 | + 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/' |
258 | + '4:0:0:0/scsi_generic/sg1'), |
259 | + 'E': { |
260 | + 'SUBSYSTEM': 'scsi_generic', |
261 | + }, |
262 | + } |
263 | + |
264 | self.ide_device_hierarchy_data = [ |
265 | {'udev_data': self.pci_ide_controller}, |
266 | {'udev_data': self.pci_ide_controller_scsi_side_1}, |
267 | @@ -3022,8 +3071,136 @@ |
268 | 'udev_data': self.ide_cdrom_device_data, |
269 | 'sysfs_data': self.ide_cdrom_device_sysfs_data, |
270 | }, |
271 | + {'udev_data': self.ide_cdrom_sr_data}, |
272 | + {'udev_data': self.ide_cdrom_device_data_2}, |
273 | + {'udev_data': self.ide_cdrom_scsi_generic_data}, |
274 | ] |
275 | |
276 | + self.pci_sata_controller_path = '/devices/pci0000:00/0000:00:1f.2' |
277 | + self.pci_sata_controller = { |
278 | + 'P': self.pci_sata_controller_path, |
279 | + 'E': { |
280 | + 'PCI_CLASS': '10602', |
281 | + 'PCI_ID': '8086:27C5', |
282 | + 'PCI_SUBSYS_ID': '10CF:1387', |
283 | + 'PCI_SLOT_NAME': '0000:00:1f.2', |
284 | + 'SUBSYSTEM': 'pci', |
285 | + 'DRIVER': 'ahci', |
286 | + } |
287 | + } |
288 | + |
289 | + self.pci_sata_controller_scsi_side_1 = { |
290 | + 'P': '/devices/pci0000:00/0000:00:1f.2/host0', |
291 | + 'E': { |
292 | + 'DEVTYPE': 'scsi_host', |
293 | + 'SUBSYSTEM': 'scsi', |
294 | + }, |
295 | + } |
296 | + |
297 | + self.pci_sata_controller_scsi_side_2 = { |
298 | + 'P': '/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0', |
299 | + 'E': { |
300 | + 'SUBSYSTEM': 'scsi_host', |
301 | + }, |
302 | + } |
303 | + |
304 | + self.sata_disk_target_data = { |
305 | + 'P': '/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0', |
306 | + 'E': { |
307 | + 'DEVTYPE': 'scsi_target', |
308 | + 'SUBSYSTEM': 'scsi', |
309 | + }, |
310 | + } |
311 | + |
312 | + self.sata_disk_device_path = ( |
313 | + '/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0') |
314 | + self.sata_disk_device_data = { |
315 | + 'P': self.sata_disk_device_path, |
316 | + 'E': { |
317 | + 'DEVTYPE': 'scsi_device', |
318 | + 'DRIVER': 'sd', |
319 | + 'SUBSYSTEM': 'scsi', |
320 | + }, |
321 | + } |
322 | + |
323 | + self.sata_disk_device_sysfs_data = { |
324 | + 'vendor': 'ATA', |
325 | + 'model': 'Hitachi HTS54251', |
326 | + 'type': '0', |
327 | + } |
328 | + |
329 | + self.sata_disk_device_data_2 = { |
330 | + 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/' |
331 | + '0:0:0:0/scsi_device/0:0:0:0'), |
332 | + 'E': { |
333 | + 'SUBSYSTEM': 'scsi_device', |
334 | + }, |
335 | + } |
336 | + |
337 | + self.sata_disk_device_scsi_disk_data = { |
338 | + 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/' |
339 | + '0:0:0:0/scsi_disk/0:0:0:0'), |
340 | + 'E': { |
341 | + 'SUBSYSTEM': 'scsi_disk', |
342 | + }, |
343 | + } |
344 | + |
345 | + self.sata_disk_device_scsi_generic_data = { |
346 | + 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/' |
347 | + '0:0:0:0/scsi_generic/sg0'), |
348 | + 'E': { |
349 | + 'SUBSYSTEM': 'scsi_generic' |
350 | + }, |
351 | + } |
352 | + |
353 | + self.sata_disk_block_data = { |
354 | + 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/' |
355 | + '0:0:0:0/block/sda'), |
356 | + 'E': { |
357 | + 'DEVTYPE': 'disk', |
358 | + 'SUBSYSTEM': 'block', |
359 | + }, |
360 | + } |
361 | + |
362 | + self.sata_disk_partition_data = { |
363 | + 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/' |
364 | + '0:0:0:0/block/sda/sda1'), |
365 | + 'E': { |
366 | + 'DEVTYPE': 'partition', |
367 | + 'SUBSYSTEM': 'block', |
368 | + }, |
369 | + } |
370 | + |
371 | + self.sata_device_hierarchy_data = [ |
372 | + {'udev_data': self.pci_sata_controller}, |
373 | + {'udev_data': self.pci_sata_controller_scsi_side_1}, |
374 | + {'udev_data': self.pci_sata_controller_scsi_side_2}, |
375 | + {'udev_data': self.sata_disk_target_data}, |
376 | + {'udev_data': self.sata_disk_device_data}, |
377 | + { |
378 | + 'udev_data': self.sata_disk_device_data, |
379 | + 'sysfs_data': self.sata_disk_device_sysfs_data, |
380 | + }, |
381 | + {'udev_data': self.sata_disk_device_data_2}, |
382 | + {'udev_data': self.sata_disk_device_scsi_disk_data}, |
383 | + {'udev_data': self.sata_disk_device_scsi_generic_data}, |
384 | + {'udev_data': self.sata_disk_block_data}, |
385 | + {'udev_data': self.sata_disk_partition_data}, |
386 | + ] |
387 | + |
388 | + self.usb_storage_usb_device_path = ( |
389 | + '/devices/pci0000:00/0000:00:1d.7/usb1/1-1') |
390 | + self.usb_storage_usb_device_data = { |
391 | + 'P': self.usb_storage_usb_device_path, |
392 | + 'E': { |
393 | + 'DEVTYPE': 'usb_device', |
394 | + 'DRIVER': 'usb', |
395 | + 'PRODUCT': '1307/163/100', |
396 | + 'TYPE': '0/0/0', |
397 | + 'SUBSYSTEM': 'usb', |
398 | + }, |
399 | + } |
400 | + |
401 | self.usb_storage_usb_interface = { |
402 | 'P': '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0', |
403 | 'E': { |
404 | @@ -3061,9 +3238,11 @@ |
405 | }, |
406 | } |
407 | |
408 | + self.usb_storage_scsi_device_path = ( |
409 | + '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
410 | + 'target7:0:0/7:0:0:0') |
411 | self.usb_storage_scsi_device = { |
412 | - 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
413 | - 'target7:0:0/7:0:0:0'), |
414 | + 'P': self.usb_storage_scsi_device_path, |
415 | 'E': { |
416 | 'DEVTYPE': 'scsi_device', |
417 | 'DRIVER': 'sd', |
418 | @@ -3077,7 +3256,50 @@ |
419 | 'type': '0', |
420 | } |
421 | |
422 | + self.usb_storage_scsi_device_2 = { |
423 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
424 | + 'target7:0:0/7:0:0:0/scsi_device/7:0:0:0'), |
425 | + 'E': { |
426 | + 'SUBSYSTEM': 'scsi_device', |
427 | + }, |
428 | + } |
429 | + |
430 | + self.usb_storage_scsi_disk = { |
431 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
432 | + 'target7:0:0/7:0:0:0/scsi_disk/7:0:0:0'), |
433 | + 'E': { |
434 | + 'SUBSYSTEM': 'scsi_disk', |
435 | + }, |
436 | + } |
437 | + |
438 | + self.usb_storage_scsi_generic = { |
439 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
440 | + 'target7:0:0/7:0:0:0/scsi_generic/sg3'), |
441 | + 'E': { |
442 | + 'SUBSYSTEM': 'scsi_generic', |
443 | + }, |
444 | + } |
445 | + |
446 | + self.usb_storage_block_device_data = { |
447 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
448 | + 'target7:0:0/7:0:0:0/block/sdb'), |
449 | + 'E': { |
450 | + 'DEVTYPE': 'disk', |
451 | + 'SUBSYSTEM': 'block', |
452 | + }, |
453 | + } |
454 | + |
455 | + self.usb_storage_block_partition_data = { |
456 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
457 | + 'target7:0:0/7:0:0:0/block/sdb/sdb1'), |
458 | + 'E': { |
459 | + 'DEVTYPE': 'partition', |
460 | + 'SUBSYSTEM': 'block', |
461 | + }, |
462 | + } |
463 | + |
464 | self.usb_storage_hierarchy_data = [ |
465 | + {'udev_data': self.usb_storage_usb_device_data}, |
466 | {'udev_data': self.usb_storage_usb_interface}, |
467 | {'udev_data': self.usb_storage_scsi_host_1}, |
468 | {'udev_data': self.usb_storage_scsi_host_2}, |
469 | @@ -3086,6 +3308,11 @@ |
470 | 'udev_data': self.usb_storage_scsi_device, |
471 | 'sysfs_data': self.usb_storage_scsi_device_sysfs, |
472 | }, |
473 | + {'udev_data': self.usb_storage_scsi_device_2}, |
474 | + {'udev_data': self.usb_storage_scsi_disk}, |
475 | + {'udev_data': self.usb_storage_scsi_generic}, |
476 | + {'udev_data': self.usb_storage_block_device_data}, |
477 | + {'udev_data': self.usb_storage_block_partition_data}, |
478 | ] |
479 | |
480 | self.no_subsystem_device_data = { |
481 | @@ -3095,7 +3322,7 @@ |
482 | |
483 | def test_device_id(self): |
484 | """Test of UdevDevice.device_id.""" |
485 | - device = UdevDevice(None, self.pci_device_data) |
486 | + device = UdevDevice(None, self.pci_sata_controller) |
487 | self.assertEqual( |
488 | '/devices/pci0000:00/0000:00:1f.2', device.device_id, |
489 | 'Unexpected value of UdevDevice.device_id.') |
490 | @@ -3121,7 +3348,7 @@ |
491 | |
492 | def test_is_pci(self): |
493 | """Test of UdevDevice.is_pci.""" |
494 | - device = UdevDevice(None, self.pci_device_data) |
495 | + device = UdevDevice(None, self.pci_sata_controller) |
496 | self.assertTrue(device.is_pci) |
497 | |
498 | device = UdevDevice(None, self.root_device) |
499 | @@ -3129,7 +3356,7 @@ |
500 | |
501 | def test_pci_class_info(self): |
502 | """Test of UdevDevice.pci_class_info""" |
503 | - device = UdevDevice(None, self.pci_device_data) |
504 | + device = UdevDevice(None, self.pci_sata_controller) |
505 | self.assertEqual( |
506 | (1, 6, 2), device.pci_class_info, |
507 | 'Invalid value of UdevDevice.pci_class_info for PCI device.') |
508 | @@ -3141,7 +3368,7 @@ |
509 | |
510 | def test_pci_class(self): |
511 | """Test of UdevDevice.pci_class""" |
512 | - device = UdevDevice(None, self.pci_device_data) |
513 | + device = UdevDevice(None, self.pci_sata_controller) |
514 | self.assertEqual( |
515 | 1, device.pci_class, |
516 | 'Invalid value of UdevDevice.pci_class for PCI device.') |
517 | @@ -3153,7 +3380,7 @@ |
518 | |
519 | def test_pci_subclass(self): |
520 | """Test of UdevDevice.pci_subclass""" |
521 | - device = UdevDevice(None, self.pci_device_data) |
522 | + device = UdevDevice(None, self.pci_sata_controller) |
523 | self.assertEqual( |
524 | 6, device.pci_subclass, |
525 | 'Invalid value of UdevDevice.pci_class for PCI device.') |
526 | @@ -3165,7 +3392,7 @@ |
527 | |
528 | def test_pci_ids(self): |
529 | """Test of UdevDevice.pci_ids""" |
530 | - device = UdevDevice(None, self.pci_device_data) |
531 | + device = UdevDevice(None, self.pci_sata_controller) |
532 | self.assertEqual( |
533 | {'vendor': 0x8086, |
534 | 'product': 0x27C5, |
535 | @@ -3186,7 +3413,7 @@ |
536 | device = UdevDevice(None, self.usb_device_data) |
537 | self.assertTrue(device.is_usb) |
538 | |
539 | - device = UdevDevice(None, self.pci_device_data) |
540 | + device = UdevDevice(None, self.pci_sata_controller) |
541 | self.assertFalse(device.is_usb) |
542 | |
543 | def test_usb_ids(self): |
544 | @@ -3269,7 +3496,7 @@ |
545 | device = UdevDevice(None, self.root_device) |
546 | self.assertEqual(None, device.raw_bus) |
547 | |
548 | - device = UdevDevice(None, self.pci_device_data) |
549 | + device = UdevDevice(None, self.pci_sata_controller) |
550 | self.assertEqual('pci', device.raw_bus) |
551 | |
552 | device = UdevDevice(None, self.usb_device_data) |
553 | @@ -3283,7 +3510,7 @@ |
554 | device = UdevDevice(None, self.root_device) |
555 | self.assertTrue(device.is_root_device) |
556 | |
557 | - device = UdevDevice(None, self.pci_device_data) |
558 | + device = UdevDevice(None, self.pci_sata_controller) |
559 | self.assertFalse(device.is_root_device) |
560 | |
561 | def test_getVendorOrProduct(self): |
562 | @@ -3297,7 +3524,7 @@ |
563 | self.assertRaises( |
564 | AssertionError, device.getVendorOrProduct, 'nonsense') |
565 | |
566 | - device = UdevDevice(None, self.pci_device_data) |
567 | + device = UdevDevice(None, self.pci_sata_controller) |
568 | self.assertEqual('Unknown', device.getVendorOrProduct('vendor')) |
569 | self.assertEqual('Unknown', device.getVendorOrProduct('product')) |
570 | |
571 | @@ -3338,7 +3565,7 @@ |
572 | self.assertRaises( |
573 | AssertionError, device.getVendorOrProductID, 'nonsense') |
574 | |
575 | - device = UdevDevice(None, self.pci_device_data) |
576 | + device = UdevDevice(None, self.pci_sata_controller) |
577 | self.assertEqual(0x8086, device.getVendorOrProductID('vendor')) |
578 | self.assertEqual(0x27C5, device.getVendorOrProductID('product')) |
579 | |
580 | @@ -3375,7 +3602,7 @@ |
581 | None, self.root_device, None, self.root_device_dmi_data) |
582 | self.assertEqual('FUJITSU SIEMENS', device.vendor_id_for_db) |
583 | |
584 | - device = UdevDevice(None, self.pci_device_data) |
585 | + device = UdevDevice(None, self.pci_sata_controller) |
586 | self.assertEqual('0x8086', device.vendor_id_for_db) |
587 | |
588 | device = UdevDevice(None, self.usb_device_data) |
589 | @@ -3392,7 +3619,7 @@ |
590 | None, self.root_device, None, self.root_device_dmi_data) |
591 | self.assertEqual('LIFEBOOK E8210', device.product_id_for_db) |
592 | |
593 | - device = UdevDevice(None, self.pci_device_data) |
594 | + device = UdevDevice(None, self.pci_sata_controller) |
595 | self.assertEqual('0x27c5', device.product_id_for_db) |
596 | |
597 | device = UdevDevice(None, self.usb_device_data) |
598 | @@ -3405,7 +3632,7 @@ |
599 | |
600 | def test_driver_name(self): |
601 | """Test of UdevDevice.driver_name.""" |
602 | - device = UdevDevice(None, self.pci_device_data) |
603 | + device = UdevDevice(None, self.pci_sata_controller) |
604 | self.assertEqual('ahci', device.driver_name) |
605 | |
606 | device = UdevDevice( |
607 | @@ -3423,22 +3650,42 @@ |
608 | :param parser: A SubmissionParser instance to be passed to |
609 | the constructor of UdevDevice. |
610 | """ |
611 | - parent = None |
612 | - devices = [] |
613 | + devices = {} |
614 | for kwargs in device_data: |
615 | device = UdevDevice(parser, **kwargs) |
616 | - devices.append(device) |
617 | - if parent is not None: |
618 | - parent.addChild(device) |
619 | + devices[device.device_id] = device |
620 | parent = device |
621 | + |
622 | + # Build the parent-child relations so that the parent device |
623 | + # is that device which has the longest path matching the |
624 | + # start of the child's path. |
625 | + # |
626 | + # There is one exception of this rule: The root device has |
627 | + # the path "/devices/LNXSYSTM:00", but the paths of most of |
628 | + # our test deviies start with "/devices/pci". Well patch the |
629 | + # index temporarily in order to find children of the root |
630 | + # device. |
631 | + if '/devices/LNXSYSTM:00' in devices: |
632 | + devices['/devices'] = devices['/devices/LNXSYSTM:00'] |
633 | + del devices['/devices/LNXSYSTM:00'] |
634 | + |
635 | + device_paths = sorted(devices, key=len, reverse=True) |
636 | + for path_index, path in enumerate(device_paths): |
637 | + for parent_path in device_paths[path_index+1:]: |
638 | + if path.startswith(parent_path): |
639 | + devices[parent_path].addChild(devices[path]) |
640 | + break |
641 | + if '/devices' in devices: |
642 | + devices['/devices/LNXSYSTM:00'] = devices['/devices'] |
643 | + del devices['/devices'] |
644 | return devices |
645 | |
646 | def test_scsi_controller(self): |
647 | """Test of UdevDevice.scsi_controller for a PCI controller.""" |
648 | devices = self.buildUdevDeviceHierarchy( |
649 | self.scsi_device_hierarchy_data) |
650 | - controller = devices[0] |
651 | - scsi_device = devices[-1] |
652 | + controller = devices[self.pccard_scsi_controller_path] |
653 | + scsi_device = devices[self.scsi_scanner_device_path] |
654 | self.assertEqual(controller, scsi_device.scsi_controller) |
655 | |
656 | def test_scsi_controller_insufficient_anchestors(self): |
657 | @@ -3451,7 +3698,7 @@ |
658 | parser.submission_key = 'UdevDevice.scsi_controller ancestor missing' |
659 | devices = self.buildUdevDeviceHierarchy( |
660 | self.scsi_device_hierarchy_data[1:], parser) |
661 | - scsi_device = devices[-1] |
662 | + scsi_device = devices[self.scsi_scanner_device_path] |
663 | self.assertEqual(None, scsi_device.scsi_controller) |
664 | self.assertWarningMessage( |
665 | parser.submission_key, |
666 | @@ -3464,14 +3711,14 @@ |
667 | |
668 | For non-SCSI devices, this property is None. |
669 | """ |
670 | - device = UdevDevice(None, self.pci_device_data) |
671 | + device = UdevDevice(None, self.pci_sata_controller) |
672 | self.assertEqual(None, device.scsi_controller) |
673 | |
674 | def test_translateScsiBus_real_scsi_device(self): |
675 | """Test of UdevDevice.translateScsiBus() with a real SCSI device.""" |
676 | devices = self.buildUdevDeviceHierarchy( |
677 | self.scsi_device_hierarchy_data) |
678 | - scsi_device = devices[-1] |
679 | + scsi_device = devices[self.scsi_scanner_device_path] |
680 | self.assertEqual( |
681 | HWBus.SCSI, scsi_device.translateScsiBus()) |
682 | |
683 | @@ -3479,14 +3726,14 @@ |
684 | """Test of UdevDevice.translateScsiBus() with an IDE device.""" |
685 | devices = self.buildUdevDeviceHierarchy( |
686 | self.ide_device_hierarchy_data) |
687 | - ide_device = devices[-1] |
688 | + ide_device = devices[self.ide_cdrom_device_path] |
689 | self.assertEqual(HWBus.IDE, ide_device.translateScsiBus()) |
690 | |
691 | def test_translateScsiBus_usb_device(self): |
692 | """Test of UdevDevice.translateScsiBus() with a USB device.""" |
693 | devices = self.buildUdevDeviceHierarchy( |
694 | self.usb_storage_hierarchy_data) |
695 | - usb_scsi_device = devices[-1] |
696 | + usb_scsi_device = devices[self.usb_storage_scsi_device_path] |
697 | self.assertEqual(None, usb_scsi_device.translateScsiBus()) |
698 | |
699 | def test_translateScsiBus_non_scsi_device(self): |
700 | @@ -3498,8 +3745,8 @@ |
701 | """Test of UdevDevice.translatePciBus().""" |
702 | devices = self.buildUdevDeviceHierarchy( |
703 | self.pci_bridge_pccard_hierarchy_data) |
704 | - pci_device = devices[1] |
705 | - pccard_device = devices[2] |
706 | + pci_device = devices[self.pci_pccard_bridge_path] |
707 | + pccard_device = devices[self.pccard_scsi_controller_path] |
708 | self.assertEqual(HWBus.PCI, pci_device.translatePciBus()) |
709 | self.assertEqual(HWBus.PCCARD, pccard_device.translatePciBus()) |
710 | |
711 | @@ -3525,8 +3772,8 @@ |
712 | """Test of UdevDevice.real_bus for PCI devices.""" |
713 | devices = self.buildUdevDeviceHierarchy( |
714 | self.pci_bridge_pccard_hierarchy_data) |
715 | - pci_device = devices[1] |
716 | - pccard_device = devices[2] |
717 | + pci_device = devices[self.pci_pccard_bridge_path] |
718 | + pccard_device = devices[self.pccard_scsi_controller_path] |
719 | self.assertEqual(HWBus.PCI, pci_device.real_bus) |
720 | self.assertEqual(HWBus.PCCARD, pccard_device.real_bus) |
721 | |
722 | @@ -3534,7 +3781,7 @@ |
723 | """Test of UdevDevice.real_bus for a SCSI device.""" |
724 | devices = self.buildUdevDeviceHierarchy( |
725 | self.scsi_device_hierarchy_data) |
726 | - scsi_device = devices[-1] |
727 | + scsi_device = devices[self.scsi_scanner_device_path] |
728 | self.assertEqual(HWBus.SCSI, scsi_device.real_bus) |
729 | |
730 | def test_real_bus_system(self): |
731 | @@ -3542,6 +3789,98 @@ |
732 | root_device = UdevDevice(None, self.root_device) |
733 | self.assertEqual(HWBus.SYSTEM, root_device.real_bus) |
734 | |
735 | + def test_is_real_device_root_device(self): |
736 | + """Test of UdevDevice._is_real_device for the root device.""" |
737 | + root_device = UdevDevice(None, self.root_device) |
738 | + self.assertTrue(root_device.is_real_device) |
739 | + |
740 | + def test_is_real_device_pci_device(self): |
741 | + """Test of UdevDevice._is_real_device for a PCI device.""" |
742 | + pci_device = UdevDevice(None, self.pci_sata_controller) |
743 | + self.assertTrue(pci_device.is_real_device) |
744 | + |
745 | + def test_is_real_device_scsi_device_related_nodes(self): |
746 | + """Test of UdevDevice._is_real_device for SCSI related nodes. |
747 | + |
748 | + A SCSI device and its controller are represented by several |
749 | + nodes which describe different aspects. Only the controller |
750 | + itself and the node representing the SCSI device are |
751 | + considered to be real devices. |
752 | + """ |
753 | + devices = self.buildUdevDeviceHierarchy( |
754 | + self.scsi_device_hierarchy_data) |
755 | + real_devices = ( |
756 | + self.pccard_scsi_controller_path, self.scsi_scanner_device_path |
757 | + ) |
758 | + for device in devices.values(): |
759 | + self.assertEqual( |
760 | + device.device_id in real_devices, device.is_real_device, |
761 | + 'Invalid result of UdevDevice.is_real_device for %s ' |
762 | + 'Expected %s, got %s' |
763 | + % (device.device_id, device.device_id in real_devices, |
764 | + device.is_real_device)) |
765 | + |
766 | + def test_is_real_device_ide_device_related_nodes(self): |
767 | + """Test of UdevDevice._is_real_device for IDE related nodes. |
768 | + |
769 | + An IDE device and its controller are represented by several |
770 | + nodes which describe different aspects. Only the controller |
771 | + itself and the node representing the IDE device are |
772 | + considered to be real devices. |
773 | + """ |
774 | + devices = self.buildUdevDeviceHierarchy( |
775 | + self.ide_device_hierarchy_data) |
776 | + real_devices = ( |
777 | + self.pci_ide_controller_path, self.ide_cdrom_device_path, |
778 | + ) |
779 | + for device in devices.values(): |
780 | + self.assertEqual( |
781 | + device.device_id in real_devices, device.is_real_device, |
782 | + 'Invalid result of UdevDevice.is_real_device for %s ' |
783 | + 'Expected %s, got %s' |
784 | + % (device.device_id, device.device_id in real_devices, |
785 | + device.is_real_device)) |
786 | + |
787 | + def test_is_real_device_ata_device_related_nodes(self): |
788 | + """Test of UdevDevice._is_real_device for IDE related nodes. |
789 | + |
790 | + An IDE device and its controller are represented by several |
791 | + nodes which describe different aspects. Only the controller |
792 | + itself and the node representing the IDE device are |
793 | + considered to be real devices. |
794 | + """ |
795 | + devices = self.buildUdevDeviceHierarchy( |
796 | + self.sata_device_hierarchy_data) |
797 | + real_devices = ( |
798 | + self.pci_sata_controller_path, self.sata_disk_device_path, |
799 | + ) |
800 | + for device in devices.values(): |
801 | + self.assertEqual( |
802 | + device.device_id in real_devices, device.is_real_device, |
803 | + 'Invalid result of UdevDevice.is_real_device for %s ' |
804 | + 'Expected %s, got %s' |
805 | + % (device.device_id, device.device_id in real_devices, |
806 | + device.is_real_device)) |
807 | + |
808 | + def test_is_real_device_usb_storage_device_related_nodes(self): |
809 | + """Test of UdevDevice._is_real_device for USB storage related nodes. |
810 | + |
811 | + A USB storage device is represented by several nodes which |
812 | + describe different aspects. Only the main USB device is |
813 | + considered to be real devices. |
814 | + """ |
815 | + devices = self.buildUdevDeviceHierarchy( |
816 | + self.usb_storage_hierarchy_data) |
817 | + for device in devices.values(): |
818 | + self.assertEqual( |
819 | + device.device_id == self.usb_storage_usb_device_path, |
820 | + device.is_real_device, |
821 | + 'Invalid result of UdevDevice.is_real_device for %s ' |
822 | + 'Expected %s, got %s' |
823 | + % (device.device_id, |
824 | + device.device_id == self.usb_storage_usb_device_path, |
825 | + device.is_real_device)) |
826 | + |
827 | |
828 | class TestHWDBSubmissionTablePopulation(TestCaseHWDB): |
829 | """Tests of the HWDB popoluation with submitted data.""" |
This branch "adjusts" BaseDevice. is_real_ device for udev data.
The HWDB submission processing script creates instances of class UdevDevice (derived from class BaseDevice) for each udev node found in the submitted data. (run "udevadm info --export-db" to see how this data looks in real like. But note that the output differs in many small details between the udev versions in Jaunty and Karmic.) In many cases udev has more than one node for a given physical device. SCSI devices, for example, have a "main" node, one sub-node for the the "disk aspect" of the device, another sub-node for the generic SCSI driver (allowing you to control the device with "raw" SCSI commands from a user-space program) etc.
We do not want to store these fine details in the HWDB -- we want to store data about a physical device just once. The decision if a given UdevDevice node represents a physical device is made by the property BaseDevice. is_real_ device.
The code of this property accessed the property HALDevice.udi which is not available for class UdevDevice; this is replaced by is_root_device.
The core idea of is_real_device is to base the decision on the value of the property raw_bus. This does not work very well for the root device, where raw_bus is None or "Unknown" for submissions with HAL data, and "acpi" for udev submissions. So I moved the case for the root device to the top of the method, to keep the remaining code a bit more clean.
There are some differences in the values of raw_bus between HAL and udev submissions: For udev data, we can have raw_bus set to "partition", "scsi_disk", "scsi_target", "spi_transport". Such nodes desribe "aspects" of SCSI devices, but not real devices, so I added these values to "if bus in (None..."
These values do not appear in submissions with HAL data, so there is no bad side effect of this change.
The raw_bus is "scsi_device" for the udev node describing the "physical" device, while it is "scsi" for submissions with HAL data, so I had to adjust "elif bus == 'scsi':" too. Again, "scsi_device" is not used in submissions with HAL data, so no bad side effect.
Finally, I had to adjust UdevDevice.raw_bus (diff @@ -2564,7 +2590,17 @@). The core idea if the property is to access the HAL property "info.bus" or "info.subsystem" (depending on the HAL version), and to access "something correspondent" for udev devices, where we use the udev properties SUBSYSTEM and DEVTYPE. The name is intended to show a "contrast" to another property real_bus, which may differ for PCI devices (where real_bus may be "PC Card") and for SCSI devices, which may in fact be IDE, ATA or USB devices.
The idea to use DEVTYPE, if this udev property is available, or SUBSYSTEM otherwsie, works mostly fine, except for a certain sub-node of a real SCSI device, where SUBSYSTEM is "scsi_device" and DEVTYPE is None. This leads to conflicts with the main node of a SCSI device, where SUBSYSTEM is "scsi", and DEVTYPE is "scsi_device". The former node should not be treated as a real device, while the latter should be... So I introduced the "if subsystem != 'scsi_device':" clause. This makes the property raw_bus, let's say, "less raw", but I could not come up with a ...