[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 191 /* detect which companion chip is used */ 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) { 194 return gx_pci; 195 } 196 }
··· 190 191 /* detect which companion chip is used */ 192 while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { 193 + if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { 194 return gx_pci; 195 } 196 }
+1 -1
drivers/char/hw_random.c
··· 579 580 /* Probe for Intel, AMD RNGs */ 581 for_each_pci_dev(pdev) { 582 - ent = pci_match_device (rng_pci_tbl, pdev); 583 if (ent) { 584 rng_ops = &rng_vendor_ops[ent->driver_data]; 585 goto match;
··· 579 580 /* Probe for Intel, AMD RNGs */ 581 for_each_pci_dev(pdev) { 582 + ent = pci_match_id(rng_pci_tbl, pdev); 583 if (ent) { 584 rng_ops = &rng_vendor_ops[ent->driver_data]; 585 goto match;
+1 -1
drivers/char/watchdog/i8xx_tco.c
··· 401 */ 402 403 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 404 - if (pci_match_device(i8xx_tco_pci_tbl, dev)) { 405 i8xx_tco_pci = dev; 406 break; 407 }
··· 401 */ 402 403 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 404 + if (pci_match_id(i8xx_tco_pci_tbl, dev)) { 405 i8xx_tco_pci = dev; 406 break; 407 }
+1 -1
drivers/ide/setup-pci.c
··· 847 d = list_entry(l, struct pci_driver, node); 848 if(d->id_table) 849 { 850 - const struct pci_device_id *id = pci_match_device(d->id_table, dev); 851 if(id != NULL) 852 { 853 if(d->probe(dev, id) >= 0)
··· 847 d = list_entry(l, struct pci_driver, node); 848 if(d->id_table) 849 { 850 + const struct pci_device_id *id = pci_match_id(d->id_table, dev); 851 if(id != NULL) 852 { 853 if(d->probe(dev, id) >= 0)
+1 -1
drivers/parport/parport_pc.c
··· 3008 int ret = 0; 3009 3010 while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { 3011 - id = pci_match_device (parport_pc_pci_tbl, pdev); 3012 if (id == NULL || id->driver_data >= last_sio) 3013 continue; 3014
··· 3008 int ret = 0; 3009 3010 while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { 3011 + id = pci_match_id(parport_pc_pci_tbl, pdev); 3012 if (id == NULL || id->driver_data >= last_sio) 3013 continue; 3014
+71 -125
drivers/pci/pci-driver.c
··· 7 #include <linux/module.h> 8 #include <linux/init.h> 9 #include <linux/device.h> 10 - #include <linux/pci-dynids.h> 11 #include "pci.h" 12 13 /* ··· 18 */ 19 20 #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 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 - } 50 51 /** 52 * store_new_id ··· 33 static inline ssize_t 34 store_new_id(struct device_driver *driver, const char *buf, size_t count) 35 { 36 - struct dynid *dynid; 37 - struct bus_type * bus; 38 struct pci_driver *pdrv = to_pci_driver(driver); 39 __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, 40 subdevice=PCI_ANY_ID, class=0, class_mask=0; ··· 65 list_add_tail(&pdrv->dynids.list, &dynid->node); 66 spin_unlock(&pdrv->dynids.lock); 67 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); 77 } 78 79 return count; 80 } 81 - 82 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 90 static void 91 pci_free_dynids(struct pci_driver *drv) 92 { 93 - struct list_head *pos, *n; 94 - struct dynid *dynid; 95 96 spin_lock(&drv->dynids.lock); 97 - list_for_each_safe(pos, n, &drv->dynids.list) { 98 - dynid = list_entry(pos, struct dynid, node); 99 list_del(&dynid->node); 100 kfree(dynid); 101 } ··· 97 return error; 98 } 99 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 #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 static inline void pci_free_dynids(struct pci_driver *drv) {} 125 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 { 131 return 0; 132 } 133 #endif 134 135 /** 136 - * pci_match_device - Tell if a PCI device structure has a matching 137 - * PCI device id structure 138 * @ids: array of PCI device id structures to search in 139 - * @dev: the PCI device structure to match against 140 - * 141 * 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 143 * pci_device_id structure or %NULL if there is no match. 144 */ 145 - const struct pci_device_id * 146 - pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) 147 { 148 - while (ids->vendor || ids->subvendor || ids->class_mask) { 149 - if (pci_match_one_device(ids, dev)) 150 - return ids; 151 - ids++; 152 } 153 return NULL; 154 } 155 156 /** 157 - * pci_device_probe_static() 158 - * 159 - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. 160 */ 161 - static int 162 - pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev) 163 - { 164 - int error = -ENODEV; 165 const struct pci_device_id *id; 166 167 - if (!drv->id_table) 168 - return error; 169 - id = pci_match_device(drv->id_table, pci_dev); 170 if (id) 171 - error = drv->probe(pci_dev, id); 172 - if (error >= 0) { 173 - pci_dev->driver = drv; 174 - error = 0; 175 } 176 - return error; 177 } 178 179 /** ··· 171 */ 172 static int 173 __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) 174 - { 175 int error = 0; 176 177 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); 181 } 182 return error; 183 } ··· 324 .sysfs_ops = &pci_driver_sysfs_ops, 325 }; 326 327 - static int 328 - pci_populate_driver_dir(struct pci_driver *drv) 329 - { 330 - return pci_create_newid_file(drv); 331 - } 332 - 333 /** 334 * pci_register_driver - register a new pci driver 335 * @drv: the driver structure to register ··· 348 drv->driver.shutdown = pci_device_shutdown; 349 drv->driver.owner = drv->owner; 350 drv->driver.kobj.ktype = &pci_driver_kobj_type; 351 - pci_init_dynids(&drv->dynids); 352 353 /* register with core */ 354 error = driver_register(&drv->driver); 355 356 if (!error) 357 - pci_populate_driver_dir(drv); 358 359 return error; 360 } ··· 412 * system is in its list of supported devices.Returns the matching 413 * pci_device_id structure or %NULL if there is no match. 414 */ 415 - static int pci_bus_match(struct device * dev, struct device_driver * drv) 416 { 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; 420 const struct pci_device_id *found_id; 421 422 - if (!ids) 423 - return 0; 424 - 425 - found_id = pci_match_device(ids, pci_dev); 426 if (found_id) 427 return 1; 428 429 - return pci_bus_match_dynids(pci_dev, pci_drv); 430 } 431 432 /** ··· 481 482 postcore_initcall(pci_driver_init); 483 484 EXPORT_SYMBOL(pci_match_device); 485 EXPORT_SYMBOL(pci_register_driver); 486 EXPORT_SYMBOL(pci_unregister_driver);
··· 7 #include <linux/module.h> 8 #include <linux/init.h> 9 #include <linux/device.h> 10 #include "pci.h" 11 12 /* ··· 19 */ 20 21 #ifdef CONFIG_HOTPLUG 22 23 + struct pci_dynid { 24 + struct list_head node; 25 + struct pci_device_id id; 26 + }; 27 28 /** 29 * store_new_id ··· 58 static inline ssize_t 59 store_new_id(struct device_driver *driver, const char *buf, size_t count) 60 { 61 + struct pci_dynid *dynid; 62 struct pci_driver *pdrv = to_pci_driver(driver); 63 __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, 64 subdevice=PCI_ANY_ID, class=0, class_mask=0; ··· 91 list_add_tail(&pdrv->dynids.list, &dynid->node); 92 spin_unlock(&pdrv->dynids.lock); 93 94 + if (get_driver(&pdrv->driver)) { 95 + driver_attach(&pdrv->driver); 96 + put_driver(&pdrv->driver); 97 } 98 99 return count; 100 } 101 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); 102 103 static void 104 pci_free_dynids(struct pci_driver *drv) 105 { 106 + struct pci_dynid *dynid, *n; 107 108 spin_lock(&drv->dynids.lock); 109 + list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { 110 list_del(&dynid->node); 111 kfree(dynid); 112 } ··· 138 return error; 139 } 140 141 #else /* !CONFIG_HOTPLUG */ 142 static inline void pci_free_dynids(struct pci_driver *drv) {} 143 static inline int pci_create_newid_file(struct pci_driver *drv) 144 { 145 return 0; 146 } 147 #endif 148 149 /** 150 + * pci_match_id - See if a pci device matches a given pci_id table 151 * @ids: array of PCI device id structures to search in 152 + * @dev: the PCI device structure to match against. 153 + * 154 * Used by a driver to check whether a PCI device present in the 155 + * system is in its list of supported devices. Returns the matching 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. 160 */ 161 + const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, 162 + struct pci_dev *dev) 163 { 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 + } 170 } 171 return NULL; 172 } 173 174 /** 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. 184 */ 185 + const struct pci_device_id *pci_match_device(struct pci_driver *drv, 186 + struct pci_dev *dev) 187 + { 188 const struct pci_device_id *id; 189 + struct pci_dynid *dynid; 190 191 + id = pci_match_id(drv->id_table, dev); 192 if (id) 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 + } 202 } 203 + spin_unlock(&drv->dynids.lock); 204 + return NULL; 205 } 206 207 /** ··· 225 */ 226 static int 227 __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) 228 + { 229 + const struct pci_device_id *id; 230 int error = 0; 231 232 if (!pci_dev->driver && drv->probe) { 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 + } 242 } 243 return error; 244 } ··· 371 .sysfs_ops = &pci_driver_sysfs_ops, 372 }; 373 374 /** 375 * pci_register_driver - register a new pci driver 376 * @drv: the driver structure to register ··· 401 drv->driver.shutdown = pci_device_shutdown; 402 drv->driver.owner = drv->owner; 403 drv->driver.kobj.ktype = &pci_driver_kobj_type; 404 + 405 + spin_lock_init(&drv->dynids.lock); 406 + INIT_LIST_HEAD(&drv->dynids.list); 407 408 /* register with core */ 409 error = driver_register(&drv->driver); 410 411 if (!error) 412 + error = pci_create_newid_file(drv); 413 414 return error; 415 } ··· 463 * system is in its list of supported devices.Returns the matching 464 * pci_device_id structure or %NULL if there is no match. 465 */ 466 + static int pci_bus_match(struct device *dev, struct device_driver *drv) 467 { 468 + struct pci_dev *pci_dev = to_pci_dev(dev); 469 + struct pci_driver *pci_drv = to_pci_driver(drv); 470 const struct pci_device_id *found_id; 471 472 + found_id = pci_match_device(pci_drv, pci_dev); 473 if (found_id) 474 return 1; 475 476 + return 0; 477 } 478 479 /** ··· 536 537 postcore_initcall(pci_driver_init); 538 539 + EXPORT_SYMBOL(pci_match_id); 540 EXPORT_SYMBOL(pci_match_device); 541 EXPORT_SYMBOL(pci_register_driver); 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 void pci_unregister_driver(struct pci_driver *); 861 void pci_remove_behind_bridge(struct pci_dev *); 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); 864 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); 865 866 /* kmem_cache style wrapper around pci_alloc_consistent() */
··· 860 void pci_unregister_driver(struct pci_driver *); 861 void pci_remove_behind_bridge(struct pci_dev *); 862 struct pci_driver *pci_dev_driver(const struct pci_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); 865 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); 866 867 /* kmem_cache style wrapper around pci_alloc_consistent() */
+1 -1
sound/pci/bt87x.c
··· 804 int i; 805 const struct pci_device_id *supported; 806 807 - supported = pci_match_device(snd_bt87x_ids, pci); 808 if (supported) 809 return supported->driver_data; 810
··· 804 int i; 805 const struct pci_device_id *supported; 806 807 + supported = pci_match_device(driver, pci); 808 if (supported) 809 return supported->driver_data; 810