lkml.org 
[lkml]   [2004]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] Fix pci_bus_find_capability()

Hi Greg. pci_bus_find_capability() is currently broken. It checks the
wrong device's hdr_type for being a cardbus bridge or not. This patch
pulls the guts of pci_bus_find_capability() and pci_find_capability()
into a new function __pci_bus_find_cap() and changes these two functions
to call it.

Index: drivers/pci/pci.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/pci/pci.c,v
retrieving revision 1.4
diff -u -p -r1.4 pci.c
--- a/drivers/pci/pci.c 8 Oct 2003 20:52:35 -0000 1.4
+++ b/drivers/pci/pci.c 10 Feb 2004 18:01:13 -0000
@@ -67,6 +67,39 @@ pci_max_busnr(void)
return max;
}

+static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
+{
+ u16 status;
+ u8 pos, id;
+ int ttl = 48;
+
+ pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
+ if (!(status & PCI_STATUS_CAP_LIST))
+ return 0;
+
+ switch (hdr_type) {
+ case PCI_HEADER_TYPE_NORMAL:
+ case PCI_HEADER_TYPE_BRIDGE:
+ pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos);
+ break;
+ case PCI_HEADER_TYPE_CARDBUS:
+ pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos);
+ break;
+ default:
+ return 0;
+ }
+ while (ttl-- && pos >= 0x40) {
+ pos &= ~3;
+ pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
+ if (id == 0xff)
+ break;
+ if (id == cap)
+ return pos;
+ pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
+ }
+ return 0;
+}
+
/**
* pci_find_capability - query for devices' capabilities
* @dev: PCI device to query
@@ -94,34 +127,7 @@ pci_max_busnr(void)
int
pci_find_capability(struct pci_dev *dev, int cap)
{
- u16 status;
- u8 pos, id;
- int ttl = 48;
-
- pci_read_config_word(dev, PCI_STATUS, &status);
- if (!(status & PCI_STATUS_CAP_LIST))
- return 0;
- switch (dev->hdr_type) {
- case PCI_HEADER_TYPE_NORMAL:
- case PCI_HEADER_TYPE_BRIDGE:
- pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos);
- break;
- case PCI_HEADER_TYPE_CARDBUS:
- pci_read_config_byte(dev, PCI_CB_CAPABILITY_LIST, &pos);
- break;
- default:
- return 0;
- }
- while (ttl-- && pos >= 0x40) {
- pos &= ~3;
- pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
- }
- return 0;
+ return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap);
}

/**
@@ -139,35 +145,11 @@ pci_find_capability(struct pci_dev *dev,
*/
int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
{
- u16 status;
- u8 pos, id;
- int ttl = 48;
- struct pci_dev *dev = bus->self;
+ u8 hdr_type;

- pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
- if (!(status & PCI_STATUS_CAP_LIST))
- return 0;
- switch (dev->hdr_type) {
- case PCI_HEADER_TYPE_NORMAL:
- case PCI_HEADER_TYPE_BRIDGE:
- pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos);
- break;
- case PCI_HEADER_TYPE_CARDBUS:
- pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos);
- break;
- default:
- return 0;
- }
- while (ttl-- && pos >= 0x40) {
- pos &= ~3;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
- }
- return 0;
+ pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+
+ return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
}

/**
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:00    [W:0.052 / U:0.552 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site