summaryrefslogtreecommitdiffstats
path: root/driver/base.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-18 00:58:02 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-18 00:58:02 +0200
commit71c759e3fa6fb725c51e3800947848cd549222bf (patch)
tree3ed1cdbfd3045d21bc74e76d69b759e1bbb9e1fb /driver/base.c
parent1f133e363c89e736a4221a3dda800e90a706056a (diff)
downloadpcitool-71c759e3fa6fb725c51e3800947848cd549222bf.tar.gz
pcitool-71c759e3fa6fb725c51e3800947848cd549222bf.tar.bz2
pcitool-71c759e3fa6fb725c51e3800947848cd549222bf.tar.xz
pcitool-71c759e3fa6fb725c51e3800947848cd549222bf.zip
Prevent driver holding hardware locks from unloading
Diffstat (limited to 'driver/base.c')
-rw-r--r--driver/base.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/driver/base.c b/driver/base.c
index d88dcf2..7f4ccad 100644
--- a/driver/base.c
+++ b/driver/base.c
@@ -495,6 +495,22 @@ static struct file_operations pcidriver_fops = {
.release = pcidriver_release,
};
+void pcidriver_module_get(pcidriver_privdata_t *privdata) {
+ try_module_get(THIS_MODULE);
+ atomic_inc(&(privdata->refs));
+// mod_info("Ref: %i\n", atomic_read(&(privdata->refs)));
+}
+
+void pcidriver_module_put(pcidriver_privdata_t *privdata) {
+ if (atomic_add_negative(-1, &(privdata->refs))) {
+ atomic_inc(&(privdata->refs));
+ mod_info("Reference counting error...");
+ } else {
+ module_put(THIS_MODULE);
+// mod_info("Unref: %i\n", atomic_read(&(privdata->refs)));
+ }
+}
+
/**
*
* Called when an application open()s a /dev/fpga*, attaches the private data
@@ -509,6 +525,8 @@ int pcidriver_open(struct inode *inode, struct file *filp)
privdata = container_of( inode->i_cdev, pcidriver_privdata_t, cdev);
filp->private_data = privdata;
+ pcidriver_module_get(privdata);
+
return 0;
}
@@ -525,6 +543,8 @@ int pcidriver_release(struct inode *inode, struct file *filp)
/* Get the private data area */
privdata = filp->private_data;
+ pcidriver_module_put(privdata);
+
return 0;
}