[PATCH] PCI: clean up dynamic pci id logic

The dynamic pci id logic has been bothering me for a while, and now that
I started to look into how to move some of this to the driver core, I
thought it was time to clean it all up.

It ends up making the code smaller, and easier to follow, and fixes a
few bugs at the same time (dynamic ids were not being matched
everywhere, and so could be missed on some call paths for new devices,
semaphore not needed to be grabbed when adding a new id and calling the
driver core, etc.)

I also renamed the function pci_match_device() to pci_match_id() as
that's what it really does.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

+79 -150
+1 -1
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
··· 190 190 191 191 /* detect which companion chip is used */ 192 192 while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { 193 - if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { 193 + if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { 194 194 return gx_pci; 195 195 } 196 196 }
+1 -1
drivers/char/hw_random.c
··· 579 579 580 580 /* Probe for Intel, AMD RNGs */ 581 581 for_each_pci_dev(pdev) { 582 - ent = pci_match_device (rng_pci_tbl, pdev); 582 + ent = pci_match_id(rng_pci_tbl, pdev); 583 583 if (ent) { 584 584 rng_ops = &rng_vendor_ops[ent->driver_data]; 585 585 goto match;
+1 -1
drivers/char/watchdog/i8xx_tco.c
··· 401 401 */ 402 402 403 403 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 404 - if (pci_match_device(i8xx_tco_pci_tbl, dev)) { 404 + if (pci_match_id(i8xx_tco_pci_tbl, dev)) { 405 405 i8xx_tco_pci = dev; 406 406 break; 407 407 }
+1 -1
drivers/ide/setup-pci.c
··· 847 847 d = list_entry(l, struct pci_driver, node); 848 848 if(d->id_table) 849 849 { 850 - const struct pci_device_id *id = pci_match_device(d->id_table, dev); 850 + const struct pci_device_id *id = pci_match_id(d->id_table, dev); 851 851 if(id != NULL) 852 852 { 853 853 if(d->probe(dev, id) >= 0)
+1 -1
drivers/parport/parport_pc.c
··· 3008 3008 int ret = 0; 3009 3009 3010 3010 while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { 3011 - id = pci_match_device (parport_pc_pci_tbl, pdev); 3011 + id = pci_match_id(parport_pc_pci_tbl, pdev); 3012 3012 if (id == NULL || id->driver_data >= last_sio) 3013 3013 continue; 3014 3014
+71 -125
drivers/pci/pci-driver.c
··· 7 7 #include <linux/module.h> 8 8 #include <linux/init.h> 9 9 #include <linux/device.h> 10 - #include <linux/pci-dynids.h> 11 10 #include "pci.h" 12 11 13 12 /* ··· 18 19 */ 19 20 20 21 #ifdef CONFIG_HOTPLUG 21 - /** 22 - * pci_device_probe_dynamic() 23 - * 24 - * Walk the dynamic ID list looking for a match. 25 - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. 26 - */ 27 - static int 28 - pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) 29 - { 30 - int error = -ENODEV; 31 - struct list_head *pos; 32 - struct dynid *dynid; 33 22 34 - spin_lock(&drv->dynids.lock); 35 - list_for_each(pos, &drv->dynids.list) { 36 - dynid = list_entry(pos, struct dynid, node); 37 - if (pci_match_one_device(&dynid->id, pci_dev)) { 38 - spin_unlock(&drv->dynids.lock); 39 - error = drv->probe(pci_dev, &dynid->id); 40 - if (error >= 0) { 41 - pci_dev->driver = drv; 42 - return 0; 43 - } 44 - return error; 45 - } 46 - } 47 - spin_unlock(&drv->dynids.lock); 48 - return error; 49 - } 23 + struct pci_dynid { 24 + struct list_head node; 25 + struct pci_device_id id; 26 + }; 50 27 51 28 /** 52 29 * store_new_id ··· 33 58 static inline ssize_t 34 59 store_new_id(struct device_driver *driver, const char *buf, size_t count) 35 60 { 36 - struct dynid *dynid; 37 - struct bus_type * bus; 61 + struct pci_dynid *dynid; 38 62 struct pci_driver *pdrv = to_pci_driver(driver); 39 63 __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, 40 64 subdevice=PCI_ANY_ID, class=0, class_mask=0; ··· 65 91 list_add_tail(&pdrv->dynids.list, &dynid->node); 66 92 spin_unlock(&pdrv->dynids.lock); 67 93 68 - bus = get_bus(pdrv->driver.bus); 69 - if (bus) { 70 - if (get_driver(&pdrv->driver)) { 71 - down_write(&bus->subsys.rwsem); 72 - driver_attach(&pdrv->driver); 73 - up_write(&bus->subsys.rwsem); 74 - put_driver(&pdrv->driver); 75 - } 76 - put_bus(bus); 94 + if (get_driver(&pdrv->driver)) { 95 + driver_attach(&pdrv->driver); 96 + put_driver(&pdrv->driver); 77 97 } 78 98 79 99 return count; 80 100 } 81 - 82 101 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); 83 - static inline void 84 - pci_init_dynids(struct pci_dynids *dynids) 85 - { 86 - spin_lock_init(&dynids->lock); 87 - INIT_LIST_HEAD(&dynids->list); 88 - } 89 102 90 103 static void 91 104 pci_free_dynids(struct pci_driver *drv) 92 105 { 93 - struct list_head *pos, *n; 94 - struct dynid *dynid; 106 + struct pci_dynid *dynid, *n; 95 107 96 108 spin_lock(&drv->dynids.lock); 97 - list_for_each_safe(pos, n, &drv->dynids.list) { 98 - dynid = list_entry(pos, struct dynid, node); 109 + list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { 99 110 list_del(&dynid->node); 100 111 kfree(dynid); 101 112 } ··· 97 138 return error; 98 139 } 99 140 100 - static int 101 - pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv) 102 - { 103 - struct list_head *pos; 104 - struct dynid *dynid; 105 - 106 - spin_lock(&pci_drv->dynids.lock); 107 - list_for_each(pos, &pci_drv->dynids.list) { 108 - dynid = list_entry(pos, struct dynid, node); 109 - if (pci_match_one_device(&dynid->id, pci_dev)) { 110 - spin_unlock(&pci_drv->dynids.lock); 111 - return 1; 112 - } 113 - } 114 - spin_unlock(&pci_drv->dynids.lock); 115 - return 0; 116 - } 117 - 118 141 #else /* !CONFIG_HOTPLUG */ 119 - static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) 120 - { 121 - return -ENODEV; 122 - } 123 - static inline void pci_init_dynids(struct pci_dynids *dynids) {} 124 142 static inline void pci_free_dynids(struct pci_driver *drv) {} 125 143 static inline int pci_create_newid_file(struct pci_driver *drv) 126 - { 127 - return 0; 128 - } 129 - static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv) 130 144 { 131 145 return 0; 132 146 } 133 147 #endif 134 148 135 149 /** 136 - * pci_match_device - Tell if a PCI device structure has a matching 137 - * PCI device id structure 150 + * pci_match_id - See if a pci device matches a given pci_id table 138 151 * @ids: array of PCI device id structures to search in 139 - * @dev: the PCI device structure to match against 140 - * 152 + * @dev: the PCI device structure to match against. 153 + * 141 154 * Used by a driver to check whether a PCI device present in the 142 - * system is in its list of supported devices.Returns the matching 155 + * system is in its list of supported devices. Returns the matching 143 156 * pci_device_id structure or %NULL if there is no match. 157 + * 158 + * Depreciated, don't use this as it will not catch any dynamic ids 159 + * that a driver might want to check for. 144 160 */ 145 - const struct pci_device_id * 146 - pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) 161 + const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, 162 + struct pci_dev *dev) 147 163 { 148 - while (ids->vendor || ids->subvendor || ids->class_mask) { 149 - if (pci_match_one_device(ids, dev)) 150 - return ids; 151 - ids++; 164 + if (ids) { 165 + while (ids->vendor || ids->subvendor || ids->class_mask) { 166 + if (pci_match_one_device(ids, dev)) 167 + return ids; 168 + ids++; 169 + } 152 170 } 153 171 return NULL; 154 172 } 155 173 156 174 /** 157 - * pci_device_probe_static() 158 - * 159 - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. 175 + * pci_match_device - Tell if a PCI device structure has a matching 176 + * PCI device id structure 177 + * @ids: array of PCI device id structures to search in 178 + * @dev: the PCI device structure to match against 179 + * @drv: the PCI driver to match against 180 + * 181 + * Used by a driver to check whether a PCI device present in the 182 + * system is in its list of supported devices. Returns the matching 183 + * pci_device_id structure or %NULL if there is no match. 160 184 */ 161 - static int 162 - pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev) 163 - { 164 - int error = -ENODEV; 185 + const struct pci_device_id *pci_match_device(struct pci_driver *drv, 186 + struct pci_dev *dev) 187 + { 165 188 const struct pci_device_id *id; 189 + struct pci_dynid *dynid; 166 190 167 - if (!drv->id_table) 168 - return error; 169 - id = pci_match_device(drv->id_table, pci_dev); 191 + id = pci_match_id(drv->id_table, dev); 170 192 if (id) 171 - error = drv->probe(pci_dev, id); 172 - if (error >= 0) { 173 - pci_dev->driver = drv; 174 - error = 0; 193 + return id; 194 + 195 + /* static ids didn't match, lets look at the dynamic ones */ 196 + spin_lock(&drv->dynids.lock); 197 + list_for_each_entry(dynid, &drv->dynids.list, node) { 198 + if (pci_match_one_device(&dynid->id, dev)) { 199 + spin_unlock(&drv->dynids.lock); 200 + return &dynid->id; 201 + } 175 202 } 176 - return error; 203 + spin_unlock(&drv->dynids.lock); 204 + return NULL; 177 205 } 178 206 179 207 /** ··· 171 225 */ 172 226 static int 173 227 __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) 174 - { 228 + { 229 + const struct pci_device_id *id; 175 230 int error = 0; 176 231 177 232 if (!pci_dev->driver && drv->probe) { 178 - error = pci_device_probe_static(drv, pci_dev); 179 - if (error == -ENODEV) 180 - error = pci_device_probe_dynamic(drv, pci_dev); 233 + error = -ENODEV; 234 + 235 + id = pci_match_device(drv, pci_dev); 236 + if (id) 237 + error = drv->probe(pci_dev, id); 238 + if (error >= 0) { 239 + pci_dev->driver = drv; 240 + error = 0; 241 + } 181 242 } 182 243 return error; 183 244 } ··· 324 371 .sysfs_ops = &pci_driver_sysfs_ops, 325 372 }; 326 373 327 - static int 328 - pci_populate_driver_dir(struct pci_driver *drv) 329 - { 330 - return pci_create_newid_file(drv); 331 - } 332 - 333 374 /** 334 375 * pci_register_driver - register a new pci driver 335 376 * @drv: the driver structure to register ··· 348 401 drv->driver.shutdown = pci_device_shutdown; 349 402 drv->driver.owner = drv->owner; 350 403 drv->driver.kobj.ktype = &pci_driver_kobj_type; 351 - pci_init_dynids(&drv->dynids); 404 + 405 + spin_lock_init(&drv->dynids.lock); 406 + INIT_LIST_HEAD(&drv->dynids.list); 352 407 353 408 /* register with core */ 354 409 error = driver_register(&drv->driver); 355 410 356 411 if (!error) 357 - pci_populate_driver_dir(drv); 412 + error = pci_create_newid_file(drv); 358 413 359 414 return error; 360 415 } ··· 412 463 * system is in its list of supported devices.Returns the matching 413 464 * pci_device_id structure or %NULL if there is no match. 414 465 */ 415 - static int pci_bus_match(struct device * dev, struct device_driver * drv) 466 + static int pci_bus_match(struct device *dev, struct device_driver *drv) 416 467 { 417 - const struct pci_dev * pci_dev = to_pci_dev(dev); 418 - struct pci_driver * pci_drv = to_pci_driver(drv); 419 - const struct pci_device_id * ids = pci_drv->id_table; 468 + struct pci_dev *pci_dev = to_pci_dev(dev); 469 + struct pci_driver *pci_drv = to_pci_driver(drv); 420 470 const struct pci_device_id *found_id; 421 471 422 - if (!ids) 423 - return 0; 424 - 425 - found_id = pci_match_device(ids, pci_dev); 472 + found_id = pci_match_device(pci_drv, pci_dev); 426 473 if (found_id) 427 474 return 1; 428 475 429 - return pci_bus_match_dynids(pci_dev, pci_drv); 476 + return 0; 430 477 } 431 478 432 479 /** ··· 481 536 482 537 postcore_initcall(pci_driver_init); 483 538 539 + EXPORT_SYMBOL(pci_match_id); 484 540 EXPORT_SYMBOL(pci_match_device); 485 541 EXPORT_SYMBOL(pci_register_driver); 486 542 EXPORT_SYMBOL(pci_unregister_driver);
-18
include/linux/pci-dynids.h
··· 1 - /* 2 - * PCI defines and function prototypes 3 - * Copyright 2003 Dell Inc. 4 - * by Matt Domsch <Matt_Domsch@dell.com> 5 - */ 6 - 7 - #ifndef LINUX_PCI_DYNIDS_H 8 - #define LINUX_PCI_DYNIDS_H 9 - 10 - #include <linux/list.h> 11 - #include <linux/mod_devicetable.h> 12 - 13 - struct dynid { 14 - struct list_head node; 15 - struct pci_device_id id; 16 - }; 17 - 18 - #endif
+2 -1
include/linux/pci.h
··· 860 860 void pci_unregister_driver(struct pci_driver *); 861 861 void pci_remove_behind_bridge(struct pci_dev *); 862 862 struct pci_driver *pci_dev_driver(const struct pci_dev *); 863 - const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); 863 + const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev); 864 + const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); 864 865 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); 865 866 866 867 /* kmem_cache style wrapper around pci_alloc_consistent() */
+1 -1
sound/pci/bt87x.c
··· 804 804 int i; 805 805 const struct pci_device_id *supported; 806 806 807 - supported = pci_match_device(snd_bt87x_ids, pci); 807 + supported = pci_match_device(driver, pci); 808 808 if (supported) 809 809 return supported->driver_data; 810 810