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 <mj@ucw.cz> 7 * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com> 8 */ 9 10 #include <linux/init.h> 11 #include <linux/pci.h> 12 #include <linux/module.h> 13 #include <linux/interrupt.h> 14 #include "pci.h" 15 16 DECLARE_RWSEM(pci_bus_sem); 17 /* 18 * find the upstream PCIe-to-PCI bridge of a PCI device 19 * if the device is PCIE, return NULL 20 * if the device isn't connected to a PCIe bridge (that is its parent is a 21 * legacy PCI bridge and the bridge is directly connected to bus 0), return its 22 * parent 23 */ 24 struct pci_dev * 25 pci_find_upstream_pcie_bridge(struct pci_dev *pdev) 26 { 27 struct pci_dev *tmp = NULL; 28 29 if (pci_is_pcie(pdev)) 30 return NULL; 31 while (1) { 32 if (pci_is_root_bus(pdev->bus)) 33 break; 34 pdev = pdev->bus->self; 35 /* a p2p bridge */ 36 if (!pci_is_pcie(pdev)) { 37 tmp = pdev; 38 continue; 39 } 40 /* PCI device should connect to a PCIe bridge */ 41 if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { 42 /* Busted hardware? */ 43 WARN_ON_ONCE(1); 44 return NULL; 45 } 46 return pdev; 47 } 48 49 return tmp; 50 } 51 52 static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) 53 { 54 struct pci_bus* child; 55 struct list_head *tmp; 56 57 if(bus->number == busnr) 58 return bus; 59 60 list_for_each(tmp, &bus->children) { 61 child = pci_do_find_bus(pci_bus_b(tmp), busnr); 62 if(child) 63 return child; 64 } 65 return NULL; 66 } 67 68 /** 69 * pci_find_bus - locate PCI bus from a given domain and bus number 70 * @domain: number of PCI domain to search 71 * @busnr: number of desired PCI bus 72 * 73 * Given a PCI bus number and domain number, the desired PCI bus is located 74 * in the global list of PCI buses. If the bus is found, a pointer to its 75 * data structure is returned. If no bus is found, %NULL is returned. 76 */ 77 struct pci_bus * pci_find_bus(int domain, int busnr) 78 { 79 struct pci_bus *bus = NULL; 80 struct pci_bus *tmp_bus; 81 82 while ((bus = pci_find_next_bus(bus)) != NULL) { 83 if (pci_domain_nr(bus) != domain) 84 continue; 85 tmp_bus = pci_do_find_bus(bus, busnr); 86 if (tmp_bus) 87 return tmp_bus; 88 } 89 return NULL; 90 } 91 92 /** 93 * pci_find_next_bus - begin or continue searching for a PCI bus 94 * @from: Previous PCI bus found, or %NULL for new search. 95 * 96 * Iterates through the list of known PCI busses. A new search is 97 * initiated by passing %NULL as the @from argument. Otherwise if 98 * @from is not %NULL, searches continue from next device on the 99 * global list. 100 */ 101 struct pci_bus * 102 pci_find_next_bus(const struct pci_bus *from) 103 { 104 struct list_head *n; 105 struct pci_bus *b = NULL; 106 107 WARN_ON(in_interrupt()); 108 down_read(&pci_bus_sem); 109 n = from ? from->node.next : pci_root_buses.next; 110 if (n != &pci_root_buses) 111 b = pci_bus_b(n); 112 up_read(&pci_bus_sem); 113 return b; 114 } 115 116 /** 117 * pci_get_slot - locate PCI device for a given PCI slot 118 * @bus: PCI bus on which desired PCI device resides 119 * @devfn: encodes number of PCI slot in which the desired PCI 120 * device resides and the logical device number within that slot 121 * in case of multi-function devices. 122 * 123 * Given a PCI bus and slot/function number, the desired PCI device 124 * is located in the list of PCI devices. 125 * If the device is found, its reference count is increased and this 126 * function returns a pointer to its data structure. The caller must 127 * decrement the reference count by calling pci_dev_put(). 128 * If no device is found, %NULL is returned. 129 */ 130 struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) 131 { 132 struct list_head *tmp; 133 struct pci_dev *dev; 134 135 WARN_ON(in_interrupt()); 136 down_read(&pci_bus_sem); 137 138 list_for_each(tmp, &bus->devices) { 139 dev = pci_dev_b(tmp); 140 if (dev->devfn == devfn) 141 goto out; 142 } 143 144 dev = NULL; 145 out: 146 pci_dev_get(dev); 147 up_read(&pci_bus_sem); 148 return dev; 149 } 150 151 /** 152 * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot 153 * @domain: PCI domain/segment on which the PCI device resides. 154 * @bus: PCI bus on which desired PCI device resides 155 * @devfn: encodes number of PCI slot in which the desired PCI device 156 * resides and the logical device number within that slot in case of 157 * multi-function devices. 158 * 159 * Given a PCI domain, bus, and slot/function number, the desired PCI 160 * device is located in the list of PCI devices. If the device is 161 * found, its reference count is increased and this function returns a 162 * pointer to its data structure. The caller must decrement the 163 * reference count by calling pci_dev_put(). If no device is found, 164 * %NULL is returned. 165 */ 166 struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, 167 unsigned int devfn) 168 { 169 struct pci_dev *dev = NULL; 170 171 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 172 if (pci_domain_nr(dev->bus) == domain && 173 (dev->bus->number == bus && dev->devfn == devfn)) 174 return dev; 175 } 176 return NULL; 177 } 178 EXPORT_SYMBOL(pci_get_domain_bus_and_slot); 179 180 static int match_pci_dev_by_id(struct device *dev, void *data) 181 { 182 struct pci_dev *pdev = to_pci_dev(dev); 183 struct pci_device_id *id = data; 184 185 if (pci_match_one_device(id, pdev)) 186 return 1; 187 return 0; 188 } 189 190 /* 191 * pci_get_dev_by_id - begin or continue searching for a PCI device by id 192 * @id: pointer to struct pci_device_id to match for the device 193 * @from: Previous PCI device found in search, or %NULL for new search. 194 * 195 * Iterates through the list of known PCI devices. If a PCI device is found 196 * with a matching id a pointer to its device structure is returned, and the 197 * reference count to the device is incremented. Otherwise, %NULL is returned. 198 * A new search is initiated by passing %NULL as the @from argument. Otherwise 199 * if @from is not %NULL, searches continue from next device on the global 200 * list. The reference count for @from is always decremented if it is not 201 * %NULL. 202 * 203 * This is an internal function for use by the other search functions in 204 * this file. 205 */ 206 static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, 207 struct pci_dev *from) 208 { 209 struct device *dev; 210 struct device *dev_start = NULL; 211 struct pci_dev *pdev = NULL; 212 213 WARN_ON(in_interrupt()); 214 if (from) 215 dev_start = &from->dev; 216 dev = bus_find_device(&pci_bus_type, dev_start, (void *)id, 217 match_pci_dev_by_id); 218 if (dev) 219 pdev = to_pci_dev(dev); 220 if (from) 221 pci_dev_put(from); 222 return pdev; 223 } 224 225 /** 226 * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id 227 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 228 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 229 * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids 230 * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids 231 * @from: Previous PCI device found in search, or %NULL for new search. 232 * 233 * Iterates through the list of known PCI devices. If a PCI device is found 234 * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its 235 * device structure is returned, and the reference count to the device is 236 * incremented. Otherwise, %NULL is returned. A new search is initiated by 237 * passing %NULL as the @from argument. Otherwise if @from is not %NULL, 238 * searches continue from next device on the global list. 239 * The reference count for @from is always decremented if it is not %NULL. 240 */ 241 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, 242 unsigned int ss_vendor, unsigned int ss_device, 243 struct pci_dev *from) 244 { 245 struct pci_dev *pdev; 246 struct pci_device_id *id; 247 248 /* 249 * pci_find_subsys() can be called on the ide_setup() path, 250 * super-early in boot. But the down_read() will enable local 251 * interrupts, which can cause some machines to crash. So here we 252 * detect and flag that situation and bail out early. 253 */ 254 if (unlikely(no_pci_devices())) 255 return NULL; 256 257 id = kzalloc(sizeof(*id), GFP_KERNEL); 258 if (!id) 259 return NULL; 260 id->vendor = vendor; 261 id->device = device; 262 id->subvendor = ss_vendor; 263 id->subdevice = ss_device; 264 265 pdev = pci_get_dev_by_id(id, from); 266 kfree(id); 267 268 return pdev; 269 } 270 271 /** 272 * pci_get_device - begin or continue searching for a PCI device by vendor/device id 273 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 274 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 275 * @from: Previous PCI device found in search, or %NULL for new search. 276 * 277 * Iterates through the list of known PCI devices. If a PCI device is 278 * found with a matching @vendor and @device, the reference count to the 279 * device is incremented and a pointer to its device structure is returned. 280 * Otherwise, %NULL is returned. A new search is initiated by passing %NULL 281 * as the @from argument. Otherwise if @from is not %NULL, searches continue 282 * from next device on the global list. The reference count for @from is 283 * always decremented if it is not %NULL. 284 */ 285 struct pci_dev * 286 pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) 287 { 288 return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); 289 } 290 291 /** 292 * pci_get_class - begin or continue searching for a PCI device by class 293 * @class: search for a PCI device with this class designation 294 * @from: Previous PCI device found in search, or %NULL for new search. 295 * 296 * Iterates through the list of known PCI devices. If a PCI device is 297 * found with a matching @class, the reference count to the device is 298 * incremented and a pointer to its device structure is returned. 299 * Otherwise, %NULL is returned. 300 * A new search is initiated by passing %NULL as the @from argument. 301 * Otherwise if @from is not %NULL, searches continue from next device 302 * on the global list. The reference count for @from is always decremented 303 * if it is not %NULL. 304 */ 305 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) 306 { 307 struct pci_dev *dev; 308 struct pci_device_id *id; 309 310 id = kzalloc(sizeof(*id), GFP_KERNEL); 311 if (!id) 312 return NULL; 313 id->vendor = id->device = id->subvendor = id->subdevice = PCI_ANY_ID; 314 id->class_mask = PCI_ANY_ID; 315 id->class = class; 316 317 dev = pci_get_dev_by_id(id, from); 318 kfree(id); 319 return dev; 320 } 321 322 /** 323 * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. 324 * @ids: A pointer to a null terminated list of struct pci_device_id structures 325 * that describe the type of PCI device the caller is trying to find. 326 * 327 * Obvious fact: You do not have a reference to any device that might be found 328 * by this function, so if that device is removed from the system right after 329 * this function is finished, the value will be stale. Use this function to 330 * find devices that are usually built into a system, or for a general hint as 331 * to if another device happens to be present at this specific moment in time. 332 */ 333 int pci_dev_present(const struct pci_device_id *ids) 334 { 335 struct pci_dev *found = NULL; 336 337 WARN_ON(in_interrupt()); 338 while (ids->vendor || ids->subvendor || ids->class_mask) { 339 found = pci_get_dev_by_id(ids, NULL); 340 if (found) 341 goto exit; 342 ids++; 343 } 344 exit: 345 if (found) 346 return 1; 347 return 0; 348 } 349 EXPORT_SYMBOL(pci_dev_present); 350 351 /* For boot time work */ 352 EXPORT_SYMBOL(pci_find_bus); 353 EXPORT_SYMBOL(pci_find_next_bus); 354 /* For everyone */ 355 EXPORT_SYMBOL(pci_get_device); 356 EXPORT_SYMBOL(pci_get_subsys); 357 EXPORT_SYMBOL(pci_get_slot); 358 EXPORT_SYMBOL(pci_get_class); 359