Delegate creation and destruction of sysfs files to device
and driver layers in order to eliminate races.

Signed-off-by: Salah Triki <salah.tr...@acm.org>
---
 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
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to