Delegate creation and destruction of sysfs files to device and driver layers in order to eliminate races. Signed-off-by: Salah Triki <salah.triki@xxxxxxx> --- drivers/staging/dgnc/dgnc_driver.c | 11 ++-- drivers/staging/dgnc/dgnc_sysfs.c | 118 ++++++++++++++----------------------- drivers/staging/dgnc/dgnc_sysfs.h | 10 +--- drivers/staging/dgnc/dgnc_tty.c | 10 ++-- 4 files changed, 54 insertions(+), 95 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index fc6d298..cbfa412 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -142,14 +142,11 @@ static void dgnc_cleanup_module(void) /* Turn off poller right away. */ del_timer_sync(&dgnc_poll_timer); - dgnc_remove_driver_sysfiles(&dgnc_driver); - device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); class_destroy(dgnc_class); unregister_chrdev(dgnc_Major, "dgnc"); for (i = 0; i < dgnc_NumBoards; ++i) { - dgnc_remove_ports_sysfiles(dgnc_Board[i]); dgnc_tty_uninit(dgnc_Board[i]); dgnc_cleanup_board(dgnc_Board[i]); } @@ -180,6 +177,8 @@ static int __init dgnc_init_module(void) /* * Find and configure all the cards */ + dgnc_driver.driver.groups = dgnc_drv_attr_groups; + rc = pci_register_driver(&dgnc_driver); /* @@ -193,8 +192,6 @@ static int __init dgnc_init_module(void) pr_warn("WARNING: dgnc driver load failed. No Digi Neo or Classic boards found.\n"); dgnc_cleanup_module(); - } else { - dgnc_create_driver_sysfiles(&dgnc_driver); } return rc; @@ -281,6 +278,8 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) int rc; /* wake up and enable device */ + pdev->dev.groups = dgnc_dev_attr_groups; + rc = pci_enable_device(pdev); if (rc < 0) { @@ -554,8 +553,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->state = BOARD_READY; brd->dpastatus = BD_RUNNING; - dgnc_create_ports_sysfiles(brd); - /* init our poll helper tasklet */ tasklet_init(&brd->helper_tasklet, brd->bd_ops->tasklet, diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 74a0725..f4ed459 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -24,6 +24,7 @@ #include "dgnc_driver.h" #include "dgnc_mgmt.h" +#include "dgnc_sysfs.h" static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf) { @@ -68,28 +69,22 @@ static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show, dgnc_driver_pollrate_store); -void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) -{ - int rc = 0; - struct device_driver *driverfs = &dgnc_driver->driver; - - rc |= driver_create_file(driverfs, &driver_attr_version); - rc |= driver_create_file(driverfs, &driver_attr_boards); - rc |= driver_create_file(driverfs, &driver_attr_maxboards); - rc |= driver_create_file(driverfs, &driver_attr_pollrate); - if (rc) - pr_err("DGNC: sysfs driver_create_file failed!\n"); -} +static struct attribute *dgnc_drv_attrs[] = { + &driver_attr_version.attr, + &driver_attr_boards.attr, + &driver_attr_maxboards.attr, + &driver_attr_pollrate.attr, + NULL, +}; -void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) -{ - struct device_driver *driverfs = &dgnc_driver->driver; +static struct attribute_group dgnc_drv_attr_group = { + .attrs = dgnc_drv_attrs, +}; - driver_remove_file(driverfs, &driver_attr_version); - driver_remove_file(driverfs, &driver_attr_boards); - driver_remove_file(driverfs, &driver_attr_maxboards); - driver_remove_file(driverfs, &driver_attr_pollrate); -} +struct attribute_group *dgnc_drv_attr_groups[] = { + &dgnc_drv_attr_group, + NULL, +}; #define DGNC_VERIFY_BOARD(p, bd) \ do { \ @@ -338,43 +333,31 @@ static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL); /* this function creates the sys files that will export each signal status * to sysfs each value will be put in a separate filename */ -void dgnc_create_ports_sysfiles(struct dgnc_board *bd) -{ - int rc = 0; - - dev_set_drvdata(&bd->pdev->dev, bd); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_state); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_baud); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_msignals); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_iflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_cflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_oflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_lflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_digi_flag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_rxcount); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_txcount); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_vpd); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_serial_number); - if (rc) - dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n"); -} -/* removes all the sys files created for that port */ -void dgnc_remove_ports_sysfiles(struct dgnc_board *bd) -{ - device_remove_file(&bd->pdev->dev, &dev_attr_ports_state); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_baud); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_msignals); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_iflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_cflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_oflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_lflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_digi_flag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_rxcount); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_txcount); - device_remove_file(&bd->pdev->dev, &dev_attr_vpd); - device_remove_file(&bd->pdev->dev, &dev_attr_serial_number); -} +static struct attribute *dgnc_dev_attrs[] = { + &dev_attr_ports_state.attr, + &dev_attr_ports_baud.attr, + &dev_attr_ports_msignals.attr, + &dev_attr_ports_iflag.attr, + &dev_attr_ports_cflag.attr, + &dev_attr_ports_oflag.attr, + &dev_attr_ports_lflag.attr, + &dev_attr_ports_digi_flag.attr, + &dev_attr_ports_rxcount.attr, + &dev_attr_ports_txcount.attr, + &dev_attr_vpd.attr, + &dev_attr_serial_number.attr, + NULL, +}; + +static struct attribute_group dgnc_dev_attr_group = { + .attrs = dgnc_dev_attrs, +}; + +struct attribute_group *dgnc_dev_attr_groups[] = { + &dgnc_dev_attr_group, + NULL, +}; static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf) @@ -683,22 +666,7 @@ static struct attribute_group dgnc_tty_attribute_group = { .attrs = dgnc_sysfs_tty_entries, }; -void dgnc_create_tty_sysfs(struct un_t *un, struct device *c) -{ - int ret; - - ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group); - if (ret) { - dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n"); - sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group); - return; - } - - dev_set_drvdata(c, un); -} - -void dgnc_remove_tty_sysfs(struct device *c) -{ - sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group); -} - +struct attribute_group *dgnc_tty_attr_groups[] = { + &dgnc_tty_attribute_group, + NULL, +}; diff --git a/drivers/staging/dgnc/dgnc_sysfs.h b/drivers/staging/dgnc/dgnc_sysfs.h index 7be7d55..8ec7b7c 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.h +++ b/drivers/staging/dgnc/dgnc_sysfs.h @@ -25,16 +25,12 @@ struct un_t; struct pci_driver; struct class_device; -void dgnc_create_ports_sysfiles(struct dgnc_board *bd); -void dgnc_remove_ports_sysfiles(struct dgnc_board *bd); +extern struct attribute_group *dgnc_drv_attr_groups[]; +extern struct attribute_group *dgnc_dev_attr_groups[]; +extern struct attribute_group *dgnc_tty_attr_groups[]; -void dgnc_create_driver_sysfiles(struct pci_driver *); -void dgnc_remove_driver_sysfiles(struct pci_driver *); int dgnc_tty_class_init(void); int dgnc_tty_class_destroy(void); -void dgnc_create_tty_sysfs(struct un_t *un, struct device *c); -void dgnc_remove_tty_sysfs(struct device *c); - #endif diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 48e4b90..9ebee55 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -367,12 +367,14 @@ int dgnc_tty_init(struct dgnc_board *brd) classp = tty_register_device(&brd->SerialDriver, i, &ch->ch_bd->pdev->dev); ch->ch_tun.un_sysfs = classp; - dgnc_create_tty_sysfs(&ch->ch_tun, classp); + classp->groups = dgnc_tty_attr_groups; + dev_set_drvdata(classp, &ch->ch_tun); classp = tty_register_device(&brd->PrintDriver, i, &ch->ch_bd->pdev->dev); ch->ch_pun.un_sysfs = classp; - dgnc_create_tty_sysfs(&ch->ch_pun, classp); + classp->groups = dgnc_tty_attr_groups; + dev_set_drvdata(classp, &ch->ch_pun); } } @@ -412,8 +414,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd) brd->dgnc_Serial_Major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_tun.un_sysfs); tty_unregister_device(&brd->SerialDriver, i); } tty_unregister_driver(&brd->SerialDriver); @@ -425,8 +425,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd) brd->dgnc_TransparentPrint_Major = 0; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_pun.un_sysfs); tty_unregister_device(&brd->PrintDriver, i); } tty_unregister_driver(&brd->PrintDriver); -- 1.9.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel