[PATCH V2] staging: dgnc: Creating and destroying sysfs files properly
Salah Triki
salah.triki at acm.org
Fri Dec 18 10:57:18 UTC 2015
Delegate creation and destruction of sysfs files to device
and driver layers in order to eliminate races.
Signed-off-by: Salah Triki <salah.triki at 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..eef1a43 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);
-}
+const 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,
+};
+
+const 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);
-}
-
+const 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..00e7589 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 const struct attribute_group *dgnc_drv_attr_groups[];
+extern const struct attribute_group *dgnc_dev_attr_groups[];
+extern const 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
More information about the devel
mailing list