xend: fix finding pci capability
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 4 Aug 2008 10:10:27 +0000 (11:10 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 4 Aug 2008 10:10:27 +0000 (11:10 +0100)
Xend doesn't start up on my laptop which has a PCI-CardBus bridge.
PCI-CardBus bridge device doesn't have a capability chain.
Also sanity checking of a capability chain.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
tools/python/xen/util/pci.py

index 2fce04a8c5e47851dac3dbe8fc8dfe1aafd43170..36fd4ebe9e772c62d5e87aaccd830e2a9bfe10e2 100644 (file)
@@ -44,6 +44,12 @@ PCI_STATUS = 0x6
 PCI_CLASS_DEVICE = 0x0a
 PCI_CLASS_BRIDGE_PCI = 0x0604
 
+PCI_HEADER_TYPE = 0x0e
+PCI_HEADER_TYPE_MASK = 0x7f
+PCI_HEADER_TYPE_NORMAL  = 0
+PCI_HEADER_TYPE_BRIDGE  = 1
+PCI_HEADER_TYPE_CARDBUS = 2
+
 PCI_CAPABILITY_LIST = 0x34
 PCI_CB_BRIDGE_CONTROL = 0x3e
 PCI_BRIDGE_CTL_BUS_RESET= 0x40
@@ -710,12 +716,24 @@ class PciDevice:
                self.name+SYSFS_PCI_DEV_CONFIG_PATH
         try:
             conf_file = open(path, 'rb')
+            conf_file.seek(PCI_HEADER_TYPE)
+            header_type = ord(conf_file.read(1)) & PCI_HEADER_TYPE_MASK
+            if header_type == PCI_HEADER_TYPE_CARDBUS:
+                return
             conf_file.seek(PCI_STATUS_OFFSET)
             status = ord(conf_file.read(1))
             if status&PCI_STATUS_CAP_MASK:
                 conf_file.seek(PCI_CAP_OFFSET)
                 capa_pointer = ord(conf_file.read(1))
+                capa_count = 0
                 while capa_pointer:
+                    if capa_pointer < 0x40:
+                        raise PciDeviceParseError(
+                            ('Broken capability chain: %s' % self.name))
+                    capa_count += 1
+                    if capa_count > 96:
+                        raise PciDeviceParseError(
+                            ('Looped capability chain: %s' % self.name))
                     conf_file.seek(capa_pointer)
                     capa_id = ord(conf_file.read(1))
                     capa_pointer = ord(conf_file.read(1))