Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI/IB: add support for pci driver attribute groups

Some drivers (specifically the nes IB driver), want to create a lot of
sysfs driver attributes. Instead of open-coding the creation and
removal of these files (and getting it wrong btw), it's a better idea to
let the driver core handle all of this logic for us.

So add a new field to the pci driver structure, **groups, that allows
pci drivers to specify an attribute group list it wishes to have created
when it is registered with the driver core.

Big bonus is now the driver doesn't race with userspace when the sysfs
files are created vs. when the kobject is announced, so any script/tool
that actually wanted to use these files will not have to poll waiting
for them to show up.

Cc: Faisal Latif <faisal.latif@intel.com>
Cc: Doug Ledford <dledford@redhat.com>
Cc: Sean Hefty <sean.hefty@intel.com>
Cc: Hal Rosenstock <hal.rosenstock@gmail.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Greg Kroah-Hartman and committed by
Doug Ledford
92d50fc1 24bb4d86

+25 -44
+23 -44
drivers/infiniband/hw/nes/nes.c
··· 808 808 } 809 809 810 810 811 - static struct pci_driver nes_pci_driver = { 812 - .name = DRV_NAME, 813 - .id_table = nes_pci_table, 814 - .probe = nes_probe, 815 - .remove = nes_remove, 816 - }; 817 - 818 811 static ssize_t adapter_show(struct device_driver *ddp, char *buf) 819 812 { 820 813 unsigned int devfn = 0xffffffff; ··· 1149 1156 static DRIVER_ATTR_RW(idx_data); 1150 1157 static DRIVER_ATTR_RW(wqm_quanta); 1151 1158 1152 - static int nes_create_driver_sysfs(struct pci_driver *drv) 1153 - { 1154 - int error; 1155 - error = driver_create_file(&drv->driver, &driver_attr_adapter); 1156 - error |= driver_create_file(&drv->driver, &driver_attr_eeprom_cmd); 1157 - error |= driver_create_file(&drv->driver, &driver_attr_eeprom_data); 1158 - error |= driver_create_file(&drv->driver, &driver_attr_flash_cmd); 1159 - error |= driver_create_file(&drv->driver, &driver_attr_flash_data); 1160 - error |= driver_create_file(&drv->driver, &driver_attr_nonidx_addr); 1161 - error |= driver_create_file(&drv->driver, &driver_attr_nonidx_data); 1162 - error |= driver_create_file(&drv->driver, &driver_attr_idx_addr); 1163 - error |= driver_create_file(&drv->driver, &driver_attr_idx_data); 1164 - error |= driver_create_file(&drv->driver, &driver_attr_wqm_quanta); 1165 - return error; 1166 - } 1159 + static struct attribute *nes_attrs[] = { 1160 + &driver_attr_adapter.attr, 1161 + &driver_attr_eeprom_cmd.attr, 1162 + &driver_attr_eeprom_data.attr, 1163 + &driver_attr_flash_cmd.attr, 1164 + &driver_attr_flash_data.attr, 1165 + &driver_attr_nonidx_addr.attr, 1166 + &driver_attr_nonidx_data.attr, 1167 + &driver_attr_idx_addr.attr, 1168 + &driver_attr_idx_data.attr, 1169 + &driver_attr_wqm_quanta.attr, 1170 + NULL, 1171 + }; 1172 + ATTRIBUTE_GROUPS(nes); 1167 1173 1168 - static void nes_remove_driver_sysfs(struct pci_driver *drv) 1169 - { 1170 - driver_remove_file(&drv->driver, &driver_attr_adapter); 1171 - driver_remove_file(&drv->driver, &driver_attr_eeprom_cmd); 1172 - driver_remove_file(&drv->driver, &driver_attr_eeprom_data); 1173 - driver_remove_file(&drv->driver, &driver_attr_flash_cmd); 1174 - driver_remove_file(&drv->driver, &driver_attr_flash_data); 1175 - driver_remove_file(&drv->driver, &driver_attr_nonidx_addr); 1176 - driver_remove_file(&drv->driver, &driver_attr_nonidx_data); 1177 - driver_remove_file(&drv->driver, &driver_attr_idx_addr); 1178 - driver_remove_file(&drv->driver, &driver_attr_idx_data); 1179 - driver_remove_file(&drv->driver, &driver_attr_wqm_quanta); 1180 - } 1174 + static struct pci_driver nes_pci_driver = { 1175 + .name = DRV_NAME, 1176 + .id_table = nes_pci_table, 1177 + .probe = nes_probe, 1178 + .remove = nes_remove, 1179 + .groups = nes_groups, 1180 + }; 1181 + 1181 1182 1182 1183 /** 1183 1184 * nes_init_module - module initialization entry point ··· 1179 1192 static int __init nes_init_module(void) 1180 1193 { 1181 1194 int retval; 1182 - int retval1; 1183 1195 1184 1196 retval = nes_cm_start(); 1185 1197 if (retval) { 1186 1198 printk(KERN_ERR PFX "Unable to start NetEffect iWARP CM.\n"); 1187 1199 return retval; 1188 1200 } 1189 - retval = pci_register_driver(&nes_pci_driver); 1190 - if (retval >= 0) { 1191 - retval1 = nes_create_driver_sysfs(&nes_pci_driver); 1192 - if (retval1 < 0) 1193 - printk(KERN_ERR PFX "Unable to create NetEffect sys files.\n"); 1194 - } 1195 - return retval; 1201 + return pci_register_driver(&nes_pci_driver); 1196 1202 } 1197 1203 1198 1204 ··· 1195 1215 static void __exit nes_exit_module(void) 1196 1216 { 1197 1217 nes_cm_stop(); 1198 - nes_remove_driver_sysfs(&nes_pci_driver); 1199 1218 1200 1219 pci_unregister_driver(&nes_pci_driver); 1201 1220 }
+1
drivers/pci/pci-driver.c
··· 1307 1307 drv->driver.bus = &pci_bus_type; 1308 1308 drv->driver.owner = owner; 1309 1309 drv->driver.mod_name = mod_name; 1310 + drv->driver.groups = drv->groups; 1310 1311 1311 1312 spin_lock_init(&drv->dynids.lock); 1312 1313 INIT_LIST_HEAD(&drv->dynids.list);
+1
include/linux/pci.h
··· 729 729 void (*shutdown) (struct pci_dev *dev); 730 730 int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */ 731 731 const struct pci_error_handlers *err_handler; 732 + const struct attribute_group **groups; 732 733 struct device_driver driver; 733 734 struct pci_dynids dynids; 734 735 };