18
19
from lpresults.xunit.parsers.usb import Usb
22
PCI_PATTERN = r"^pci:" \
23
"v(?P<vendor_id>[%(hex)s]{8})" \
24
"d(?P<product_id>[%(hex)s]{8})" \
25
"sv(?P<subvendor_id>[%(hex)s]{8})" \
26
"sd(?P<subproduct_id>[%(hex)s]{8})" \
27
"bc(?P<class>[%(hex)s]{2})" \
28
"sc(?P<subclass>[%(hex)s]{2})" \
29
"i(?P<interface>[%(hex)s]{2})" \
30
% {"hex": string.hexdigits}
31
PCI_RE = re.compile(PCI_PATTERN)
33
PNP_PATTERN = r"^acpi:" \
34
"(?P<vendor_name>[%(upper)s]{3})" \
35
"(?P<product_id>[%(hex)s]{4}):" \
36
% {"upper": string.uppercase, "hex": string.hexdigits}
37
PNP_RE = re.compile(PNP_PATTERN)
39
USB_PATTERN = r"^usb:" \
40
"v(?P<vendor_id>[%(hex)s]{4})" \
41
"p(?P<product_id>[%(hex)s]{4})" \
42
"d(?P<revision>[%(hex)s]{4})" \
43
"dc(?P<class>[%(hex)s]{2})" \
44
"dsc(?P<subclass>[%(hex)s]{2})" \
45
"dp(?P<protocol>[%(hex)s]{2})" \
46
"ic(?P<interface_class>[%(hex)s]{2})" \
47
"isc(?P<interface_subclass>[%(hex)s]{2})" \
48
"ip(?P<interface_protocol>[%(hex)s]{2})" \
49
% {"hex": string.hexdigits}
50
USB_RE = re.compile(USB_PATTERN)
52
SCSI_PATTERN = r"^scsi:" \
53
"t-0x(?P<type>[%(hex)s]{2})" \
54
% {"hex": string.hexdigits}
55
SCSI_RE = re.compile(SCSI_PATTERN)
21
58
class UdevadmDevice:
22
__slots__ = ("_environment",)
59
__slots__ = ("_environment", "_stack",)
24
def __init__(self, environment):
61
def __init__(self, environment, stack=[]):
25
62
super(UdevadmDevice, self).__init__()
26
63
self._environment = environment
68
# Change the bus from 'acpi' to 'pnp' for some devices
69
if PNP_RE.match(self._environment.get("MODALIAS", "")) \
70
and self.path.endswith(":00"):
73
# Change the bus from 'block' to parent
74
if self._environment.get("DEVTYPE") == "disk" and self._stack:
75
return self._stack[-1]._environment.get("SUBSYSTEM")
30
77
return self._environment.get("SUBSYSTEM")
159
206
if "ID_DRIVE_FLOPPY" in self._environment:
209
if devtype == "scsi_device":
210
match = SCSI_RE.match(self._environment.get("MODALIAS", ""))
211
type = int(match.group("type"), 16) if match else -1
213
# Check FLASH drives, see /lib/udev/rules.d/80-udisks.rules
214
if type in (0, 7, 14) \
215
and not any(d.driver == "rts_pstor" for d in self._stack):
162
233
if "DRIVER" in self._environment:
163
234
if self._environment["DRIVER"] == "floppy":
173
244
if "DRIVER" in self._environment:
174
245
return self._environment["DRIVER"]
176
if "ID_USB_DRIVER" in self._environment:
177
return self._environment["ID_USB_DRIVER"]
247
# Check parent device for driver
249
parent = self._stack[-1]
250
if "DRIVER" in parent._environment:
251
return parent._environment["DRIVER"]
186
260
def product_id(self):
188
if "PCI_ID" in self._environment:
189
vendor_id, product_id = self._environment["PCI_ID"].split(":")
190
return int(product_id, 16)
193
if "PRODUCT" in self._environment \
194
and self._environment.get("DEVTYPE") == "usb_interface":
195
product_id = self._environment["PRODUCT"].split("/")[1]
196
return int(product_id, 16)
199
if "ID_MODEL_ID" in self._environment:
200
return int(self._environment["ID_MODEL_ID"], 16)
262
match = PCI_RE.match(self._environment.get("MODALIAS", ""))
264
return int(match.group("product_id"), 16)
267
match = USB_RE.match(self._environment.get("MODALIAS", ""))
269
return int(match.group("product_id"), 16)
272
match = PNP_RE.match(self._environment.get("MODALIAS", ""))
274
product_id = int(match.group("product_id"), 16)
275
# Ignore interrupt controllers
276
if product_id > 0x0100:
205
282
def vendor_id(self):
207
if "PCI_ID" in self._environment:
208
vendor_id, product_id = self._environment["PCI_ID"].split(":")
209
return int(vendor_id, 16)
212
if "PRODUCT" in self._environment \
213
and self._environment.get("DEVTYPE") == "usb_interface":
214
vendor_id, product_id, revision \
215
= self._environment["PRODUCT"].split("/")
216
return int(vendor_id, 16)
219
if "ID_VENDOR_ID" in self._environment:
220
return int(self._environment["ID_VENDOR_ID"], 16)
284
match = PCI_RE.match(self._environment.get("MODALIAS", ""))
286
return int(match.group("vendor_id"), 16)
289
match = USB_RE.match(self._environment.get("MODALIAS", ""))
291
return int(match.group("vendor_id"), 16)
247
318
if element in self._environment:
248
319
return self._environment[element].strip('"')
322
if self._environment.get("DEVTYPE") == "scsi_device":
323
for device in reversed(self._stack):
324
if device._environment.get("ID_BUS") == "usb":
325
model = device._environment["ID_MODEL_ENC"]
326
return model.decode("string-escape").strip()
328
if self._environment.get("DEVTYPE") == "disk" \
329
and self._environment.get("ID_BUS") == "ata":
330
model = self._environment["ID_MODEL_ENC"]
331
return model.decode("string-escape").strip()
251
334
if self.driver == "floppy":
252
return "Platform Device"
335
return u"Platform Device"
261
344
if "POWER_SUPPLY_MANUFACTURER" in self._environment:
262
345
return self._environment["POWER_SUPPLY_MANUFACTURER"]
348
match = PNP_RE.match(self._environment.get("MODALIAS", ""))
350
return match.group("vendor_name")
353
if self._environment.get("DEVTYPE") == "scsi_device":
354
for device in reversed(self._stack):
355
if device._environment.get("ID_BUS") == "usb":
356
vendor = device._environment["ID_VENDOR_ENC"]
357
return vendor.decode("string-escape").strip()
333
426
"Device property not supported: %s" % value)
334
427
environment[match.group("key")] = match.group("value")
431
if stack[-1].path + "/" in path:
336
435
# Set default DEVPATH
337
436
environment.setdefault("DEVPATH", path)
339
device = self.device_factory(environment)
438
device = self.device_factory(environment, list(stack))
340
439
if not self._ignoreDevice(device):
341
440
result.addDevice(device)