Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
search.c
Go to the documentation of this file.
1 /*
2  * PCI searching functions.
3  *
4  * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter,
5  * David Mosberger-Tang
6  * Copyright (C) 1997 -- 2000 Martin Mares <[email protected]>
7  * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <[email protected]>
8  */
9 
10 #include <linux/init.h>
11 #include <linux/pci.h>
12 #include <linux/slab.h>
13 #include <linux/module.h>
14 #include <linux/interrupt.h>
15 #include "pci.h"
16 
17 DECLARE_RWSEM(pci_bus_sem);
18 EXPORT_SYMBOL_GPL(pci_bus_sem);
19 
20 /*
21  * find the upstream PCIe-to-PCI bridge of a PCI device
22  * if the device is PCIE, return NULL
23  * if the device isn't connected to a PCIe bridge (that is its parent is a
24  * legacy PCI bridge and the bridge is directly connected to bus 0), return its
25  * parent
26  */
27 struct pci_dev *
29 {
30  struct pci_dev *tmp = NULL;
31 
32  if (pci_is_pcie(pdev))
33  return NULL;
34  while (1) {
35  if (pci_is_root_bus(pdev->bus))
36  break;
37  pdev = pdev->bus->self;
38  /* a p2p bridge */
39  if (!pci_is_pcie(pdev)) {
40  tmp = pdev;
41  continue;
42  }
43  /* PCI device should connect to a PCIe bridge */
44  if (pci_pcie_type(pdev) != PCI_EXP_TYPE_PCI_BRIDGE) {
45  /* Busted hardware? */
46  WARN_ON_ONCE(1);
47  return NULL;
48  }
49  return pdev;
50  }
51 
52  return tmp;
53 }
54 
55 static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
56 {
57  struct pci_bus* child;
58  struct list_head *tmp;
59 
60  if(bus->number == busnr)
61  return bus;
62 
63  list_for_each(tmp, &bus->children) {
64  child = pci_do_find_bus(pci_bus_b(tmp), busnr);
65  if(child)
66  return child;
67  }
68  return NULL;
69 }
70 
80 struct pci_bus * pci_find_bus(int domain, int busnr)
81 {
82  struct pci_bus *bus = NULL;
83  struct pci_bus *tmp_bus;
84 
85  while ((bus = pci_find_next_bus(bus)) != NULL) {
86  if (pci_domain_nr(bus) != domain)
87  continue;
88  tmp_bus = pci_do_find_bus(bus, busnr);
89  if (tmp_bus)
90  return tmp_bus;
91  }
92  return NULL;
93 }
94 
104 struct pci_bus *
106 {
107  struct list_head *n;
108  struct pci_bus *b = NULL;
109 
112  n = from ? from->node.next : pci_root_buses.next;
113  if (n != &pci_root_buses)
114  b = pci_bus_b(n);
116  return b;
117 }
118 
133 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn)
134 {
135  struct pci_dev *dev;
136 
139 
140  list_for_each_entry(dev, &bus->devices, bus_list) {
141  if (dev->devfn == devfn)
142  goto out;
143  }
144 
145  dev = NULL;
146  out:
147  pci_dev_get(dev);
149  return dev;
150 }
151 
167 struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
168  unsigned int devfn)
169 {
170  struct pci_dev *dev = NULL;
171 
172  for_each_pci_dev(dev) {
173  if (pci_domain_nr(dev->bus) == domain &&
174  (dev->bus->number == bus && dev->devfn == devfn))
175  return dev;
176  }
177  return NULL;
178 }
180 
181 static int match_pci_dev_by_id(struct device *dev, void *data)
182 {
183  struct pci_dev *pdev = to_pci_dev(dev);
184  struct pci_device_id *id = data;
185 
186  if (pci_match_one_device(id, pdev))
187  return 1;
188  return 0;
189 }
190 
191 /*
192  * pci_get_dev_by_id - begin or continue searching for a PCI device by id
193  * @id: pointer to struct pci_device_id to match for the device
194  * @from: Previous PCI device found in search, or %NULL for new search.
195  *
196  * Iterates through the list of known PCI devices. If a PCI device is found
197  * with a matching id a pointer to its device structure is returned, and the
198  * reference count to the device is incremented. Otherwise, %NULL is returned.
199  * A new search is initiated by passing %NULL as the @from argument. Otherwise
200  * if @from is not %NULL, searches continue from next device on the global
201  * list. The reference count for @from is always decremented if it is not
202  * %NULL.
203  *
204  * This is an internal function for use by the other search functions in
205  * this file.
206  */
207 static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
208  struct pci_dev *from)
209 {
210  struct device *dev;
211  struct device *dev_start = NULL;
212  struct pci_dev *pdev = NULL;
213 
215  if (from)
216  dev_start = &from->dev;
217  dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
218  match_pci_dev_by_id);
219  if (dev)
220  pdev = to_pci_dev(dev);
221  if (from)
222  pci_dev_put(from);
223  return pdev;
224 }
225 
242 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
243  unsigned int ss_vendor, unsigned int ss_device,
244  struct pci_dev *from)
245 {
246  struct pci_device_id id = {
247  .vendor = vendor,
248  .device = device,
249  .subvendor = ss_vendor,
250  .subdevice = ss_device,
251  };
252 
253  return pci_get_dev_by_id(&id, from);
254 }
255 
270 struct pci_dev *
271 pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
272 {
273  return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
274 }
275 
290 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
291 {
292  struct pci_device_id id = {
293  .vendor = PCI_ANY_ID,
294  .device = PCI_ANY_ID,
295  .subvendor = PCI_ANY_ID,
296  .subdevice = PCI_ANY_ID,
297  .class_mask = PCI_ANY_ID,
298  .class = class,
299  };
300 
301  return pci_get_dev_by_id(&id, from);
302 }
303 
315 int pci_dev_present(const struct pci_device_id *ids)
316 {
317  struct pci_dev *found = NULL;
318 
320  while (ids->vendor || ids->subvendor || ids->class_mask) {
321  found = pci_get_dev_by_id(ids, NULL);
322  if (found)
323  goto exit;
324  ids++;
325  }
326 exit:
327  if (found)
328  return 1;
329  return 0;
330 }
332 
333 /* For boot time work */
336 /* For everyone */