G Pooja Shamili [Fri, 11 Mar 2016 23:52:02 +0000 (05:22 +0530)]
staging: netlogic: Replacing pr_err with dev_err after the call to devm_kzalloc
The function devm_kzalloc has a first argument of type struct device *.
This is the type of argument required by printing functions such as
dev_info, dev_err, etc. Thus, functions like pr_info should not
normally be used after a call to devm_kzalloc. Thus, all pr_err occurances are
replaced with dev_err function calls
Signed-off-by: G Pooja Shamili <poojashamili@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
G Pooja Shamili [Fri, 11 Mar 2016 23:58:54 +0000 (05:28 +0530)]
staging: mt29f_spinand: Replacing pr_info with dev_info after the call to devm_kzalloc
The function devm_kzalloc has a first argument of type struct device *.
This is the type of argument required by printing functions such as
dev_info, dev_err, etc. Thus, functions like pr_info should not normally
be used after a call to devm_kzalloc. Thus, all pr_info occurances are
replaced with dev_info function calls.
This was done using Coccinelle, the patch being:
@@
expression E1,E2;
expression list args;
@@
Derek Yerger [Fri, 11 Mar 2016 22:31:18 +0000 (17:31 -0500)]
staging: ion: debugfs invalid gfp mask
The current code attempts assignment of -1 to an unsigned type. Note that
in a downstream function ion_page_pool_shrink this mask is only ever
evaluated against __GFP_HIGHMEM
(drivers/staging/android/ion/ion_page_pool.c, line 125).
staging: rts5208: Replace pci_enable_device with pcim_enable_device
Devm_ functions allocate memory that is automatically freed when
a driver detaches.
Replace pci_enable_device with pcim_enable_device. Remove unnecessary
pci_disable_device and pci_release_regions from probe and remove
functions in rts5208 driver since pcim_enable_device contains a call
to pcim_release which contains calls to both pci_disable_device and
pci_release_regions.
staging: speakup: Replace del_timer with del_timer_sync
Use del_timer_sync to ensure timer is stopped on all CPUs before
the driver exists and the timer should not run when the module is
being removed. Since the timer is not called from an interrupt
context, this change is safe and will not cause deadlock.
The Coccinelle semantic patch used to make this change is as
follows:
// <smpl>
@r@
declarer name module_exit;
identifier ex;
@@
Sandeep Jain [Mon, 29 Feb 2016 13:18:30 +0000 (18:48 +0530)]
staging: lowmemorykiller: fix 2 checks that checkpatch complained
Specifically:
lowmemorykiller.c:53: CHECK: use a blank line after enum declarations
lowmemorykiller.c:60: CHECK: use a blank line after enum declarations
staging: rdma: hfi1: file_ops: Replace ALIGN with PAGE_ALIGN
mm.h contains a helper function PAGE_ALIGN which aligns the pointer
to the page boundary instead of using ALIGN(expression, PAGE_SIZE)
This change was made with the help of the following Coccinelle
semantic patch:
//<smpl>
@@
expression e;
symbol PAGE_SIZE;
@@
(
- ALIGN(e, PAGE_SIZE)
+ PAGE_ALIGN(e)
|
- IS_ALIGNED(e, PAGE_SIZE)
+ PAGE_ALIGNED(e)
)
//</smpl>
staging: rdma: hfi1: driver: Replace IS_ALIGNED with PAGE_ALIGNED
mm.h contains a helper function PAGE_ALIGNED which tests whether
an address is aligned to PAGE_SIZE instead of using
IS_ALIGNED(expression, PAGE_SIZE)
This change was made with the help of the following Coccinelle
semantic patch:
//<smpl>
@@
expression e;
symbol PAGE_SIZE;
@@
(
- ALIGN(e, PAGE_SIZE)
+ PAGE_ALIGN(e)
|
- IS_ALIGNED(e, PAGE_SIZE)
+ PAGE_ALIGNED(e)
)
//</smpl>
staging: rdma: hfi1: Replace ALIGN with PAGE_ALIGN
mm.h contains a helper function PAGE_ALIGN which aligns the pointer
to the page boundary instead of using ALIGN(expression, PAGE_SIZE)
This change was made with the help of the following Coccinelle
semantic patch:
//<smpl>
@@
expression e;
symbol PAGE_SIZE;
@@
(
- ALIGN(e, PAGE_SIZE)
+ PAGE_ALIGN(e)
|
- IS_ALIGNED(e, PAGE_SIZE)
+ PAGE_ALIGNED(e)
)
//</smpl>
Bhumika Goyal [Fri, 26 Feb 2016 10:04:31 +0000 (15:34 +0530)]
Staging: rdma: Use min macro instead of ternary operator
This patch replaces ternary operator with macro min as it shorter and
thus increases code readability. Macro min return the minimum of the
two compared values.
Made a semantic patch for changes:
@@
type T;
T x;
T y;
@@
(
- x < y ? x : y
+ min(x,y)
|
- x > y ? x : y
+ max(x,y)
)
Unnecessary pci_set_drvdata() has been removed since the driver
core clears the driver data to NULL after device release or on
probe failure. There is no need to manually clear the device
driver data to NULL.
The Coccinelle semantic patch used to make this change is as follows:
//<smpl>
@@
struct pci_dev *pci;
@@
- pci_set_drvdata(pci, NULL);
//</smpl>
staging: rdma: hfi1: Do not use | with a variable with value 0
mr->lkey has a value equal to 0. There is no need to combine it with
other things with | as for any value x, 0|x is always x.
Semantic patch used:
@@
expression x, e, e1;
statement S;
@@
if (x == 0) {
... when != x = e1
when != while(...) S
when != for(...;...;...) S
(
* x |= e
|
* x | e
)
... when any
}
Remove an unnecessary kfree since rcd->opstats's value must be NULL
for the code to execute `bail` label.
This fixes the following smatch warning:
drivers/staging/rdma/hfi1/init.c:335 hfi1_create_ctxtdata() warn:
calling kfree() when 'rcd->opstats' is always NULL.
staging: lustre: lnet: o2iblnd: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: socklnd: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: socklnd_proto: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: libcfs: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: osc_cache: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: osc: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: api-ni: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: peer: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: config: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: router: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: conrpc: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: lnet: lib-move: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: lustre: obdclass: Use list_for_each_entry_safe
Doubly linked lists which are iterated using list_empty
and list_entry macros have been replaced with list_for_each_entry_safe
macro.
This makes the iteration simpler and more readable.
This patch replaces the while loop containing list_empty and list_entry
with list_for_each_entry_safe.
This was done with Coccinelle.
@@
expression E1;
identifier I1, I2;
type T;
iterator name list_for_each_entry_safe;
@@
T *I1;
+ T *tmp;
...
- while (list_empty(&E1) == 0)
+ list_for_each_entry_safe (I1, tmp, &E1, I2)
{
...when != T *I1;
- I1 = list_entry(E1.next, T, I2);
...
}
staging: iio: adc: Replace of_iomap() with devm_ioremap_resource()
The adc driver uses of_iomap() which doesn't request the resource and
isn't device managed so error handling is needed. of_iomap() is mainly
used in cases where there is no driver or struct device so a switch to
devm_ functions is required.
This patch switches to use devm_ioremap_resource() instead which
automatically requests the resource and is freed when the driver
detaches.
Removed the error handling to unmap I/O registers i.e.
iounmap() in probe and remove functions of this driver and
consequently removed an unnecessary label.
Alison Schofield [Sun, 28 Feb 2016 08:22:50 +0000 (00:22 -0800)]
staging: iio: ade7854: use devm_iio_device_register
Replace iio_device_register with the device managed version.
This change is safe because it does not change the order of
any device removal actions. Unregistering the device was the
only removal action. The newly emptied .remove functions are
deleted.
Bhumika Goyal [Fri, 11 Mar 2016 06:58:50 +0000 (12:28 +0530)]
Staging: rtl8723au: Remove unused functions and prototype
The functions rtw_ap_inform_ch_switch23a, rtw_acl_remove_sta23a and
rtw_acl_add_sta23a are not used anywhere in the kernel. So remove their
definition and prototype.
staging: rtl8723au: hal: Remove unnecessary function and its call
The function odm_DynamicBBPowerSaving23a on being called, simply returns
back. The function hasn't been mentioned in the TODO and doesn't have FIXME
code around. Hence, odm_DynamicBBPowerSaving23a and its calls have been
removed.
Bhumika Goyal [Sun, 28 Feb 2016 17:25:29 +0000 (22:55 +0530)]
Staging: rtl8723au: Remove print statements and debug messages
The memory allocation functions generates a call stack containing
all the context information on failure, so print statements and debug
messages can be removed on failure of these functions. Also remove
unwanted {} around if block after removal of these messages.
Done using coccinelle:
@@
expression e;
@@
e=\(kmalloc\|kmalloc\|kmalloc_array\|alloc_netdev\|kzalloc\|
devm_kzalloc\|devm_ioremap\)(...);
...
if(!e){
- \(DBG_8723A\|printk\|pr_err\|CERROR\|DBG_88E\)(...);
...when any
}
Bhumika Goyal [Fri, 26 Feb 2016 10:04:30 +0000 (15:34 +0530)]
Staging: rtl8723au: Use min macro instead of ternary operator
This patch replaces ternary operator with macro min as it shorter and
thus increases code readability. Macro min return the minimum of the
two compared values.
Made a semantic patch for changes:
@@
type T;
T x;
T y;
@@
(
- x < y ? x : y
+ min(x,y)
|
- x > y ? x : y
+ max(x,y)
)
Bhumika Goyal [Fri, 4 Mar 2016 13:45:55 +0000 (19:15 +0530)]
Staging: fsl-mc: Replace pr_err with dev_err
This patch replaces pr_err calls with dev_err when the device structure
is available as dev_* prints identifying information about the struct device.
Done using coccinelle:
@r exists@
identifier f, s;
identifier x;
position p;
@@
f(...,struct s *x,...) {
<+...
when != x == NULL
\(pr_err@p\|pr_debug@p\|pr_info\)(...);
...+>
}
Bhumika Goyal [Fri, 4 Mar 2016 13:44:52 +0000 (19:14 +0530)]
Staging: fsl-mc: Replace pr_debug with dev_dbg
This patch replaces pr_debug calls with dev_dbg when the device structure
is available as dev_* prints identifying information about the struct
device.
Done using coccinelle:
@r exists@
identifier f, s;
identifier x;
position p;
@@
f(...,struct s *x,...) {
<+...
when != x == NULL
\(pr_err@p\|pr_debug@p\|pr_info\)(...);
...+>
}
staging: fsl-mc: bus: Eliminate double function call
A call to irq_find_matching_host was already made and the result
has been stored in mc_msi_domain. mc_msi_domain is again reassigned
using the same function call which is redundant.
irq_find_matching_host returns/locates a domain for a given fwnode.
The domain is identified using device node and bus_token(if several
domains have same device node but different purposes they can be
distinguished using bus-specific token).
http://www.bricktou.com/include/linux/irqdomain_irq_find_matching_host_en.html
Also, of_property_read_bool finds and reads a boolean from a property
device node from which the property value is to be read. It doesn't
alter the device node.
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/083698.html
Since, both the function calls have the same device node and bus_token,
the return values shall be the same. Hence, the second call has been
removed.
This was done using Coccinelle:
@r@
idexpression *x;
identifier f;
position p1,p2;
@@
x@p1 = f(...)
... when != x
(
x@p2 = f(...)
)
@script:python@
p1 << r.p1;
p2 << r.p2;
@@
if (p1[0].line == p2[0].line):
cocci.include_match(False)
@@
idexpression *x;
identifier f;
position r.p1,r.p2;
@@
Bhumika Goyal [Fri, 11 Mar 2016 14:03:05 +0000 (19:33 +0530)]
Staging: android: ashmem.c: Convert macros page_range_{subsumes/subsumed_by/in}_range to static inline function
Convert macros page_range_{subsumes/subsumed_by/in}_range to static
inline function as static inline functions are preferred over macros.
The change can be done as the arguments at all call sites have the same
type. Also, all three macro have same type of arguments and return
values so they can converted using a common semantic patch.
@r@
identifier f;
expression e;
@@
#define f(...) e
Bhumika Goyal [Fri, 11 Mar 2016 14:03:04 +0000 (19:33 +0530)]
Staging: android: ashmem.c: Redefine macros as static inline functions
Convert macros page_in_range and range_before_page into static inline
functions as static inline functions are preferred over macros. The
change can be done as the arguments at all call sites have the same type.
Also, both the macros have same type of arguments and return
values.
Done using coccinelle:
@r@
identifier f;
expression e;
@@
#define f(...) e
staging: android: Use devm_kcalloc instead of devm_kzalloc
Replace devm_kzalloc with devm_kcalloc to ensure there are no integer
overflows from the multiplication of a number * sizeof.
The following Coccinelle semantic patch was used to make this change:
//<smpl>
@@
expression dev,E1,E2,E3;
@@
- devm_kzalloc(dev,E1*sizeof(E2),E3)
+ devm_kcalloc(dev,E1,sizeof(E2),E3)
//</smpl>
staging: android: Replace min_t/max_t with min/max
Replace min_t/max_t with min/max when both variables are of the same
type.
The Coccinelle semantic patch used to make this change is as follows:
@@
type T;
T a,b;
@@
- min_t(T, a, b)
+ min(a, b)
@@
type T;
T a,b;
@@
- max_t(T, a, b)
+ max(a, b)
staging: android: ion: tegra: Replace IS_ERR_OR_NULL with IS_ERR
Replace IS_ERR_OR_NULL test with an IS_ERR test since
ion_device_create() function returns a valid device or a -PTR_ERR
only as evidenced by the comment on the function prototype.
staging: android: ion: tegra: Use devm_kcalloc instead of devm_kzalloc
Replace devm_kzalloc with devm_kcalloc to ensure there are no integer
overflows from the multiplication of a number * sizeof.
The following Coccinelle semantic patch was used to make this change:
//<smpl>
@@
expression dev,E1,E3;
type T;
@@
- devm_kzalloc(dev,E1*sizeof(T),E3)
+ devm_kcalloc(dev,E1,sizeof(T),E3)
//</smpl>
This patch removes unnecessary return variables and compresses the
return logic.
The coccinelle script that finds and fixes this issue is:
@@ type T; identifier i,f; constant C; @@
- T i;
...when != i
when strict
( return -C;
|
- i =
+ return
f(...);
- return i;
)
EunTaik Lee [Wed, 24 Feb 2016 04:38:06 +0000 (04:38 +0000)]
staging/android/ion : fix a race condition in the ion driver
There is a use-after-free problem in the ion driver.
This is caused by a race condition in the ion_ioctl()
function.
A handle has ref count of 1 and two tasks on different
cpus calls ION_IOC_FREE simultaneously.
cpu 0 cpu 1
-------------------------------------------------------
ion_handle_get_by_id()
(ref == 2)
ion_handle_get_by_id()
(ref == 3)
ion_free()
(ref == 2)
ion_handle_put()
(ref == 1)
ion_free()
(ref == 0 so ion_handle_destroy() is
called
and the handle is freed.)
ion_handle_put() is called and it
decreases the slub's next free pointer
The problem is detected as an unaligned access in the
spin lock functions since it uses load exclusive
instruction. In some cases it corrupts the slub's
free pointer which causes a mis-aligned access to the
next free pointer.(kmalloc returns a pointer like ffffc0745b4580aa). And it causes lots of other
hard-to-debug problems.
This symptom is caused since the first member in the
ion_handle structure is the reference count and the
ion driver decrements the reference after it has been
freed.
To fix this problem client->lock mutex is extended
to protect all the codes that uses the handle.
Signed-off-by: Eun Taik Lee <eun.taik.lee@samsung.com> Reviewed-by: Laura Abbott <labbott@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- res = platform_get_resource(pdev, IORESOURCE_MEM, n);
... when != res
- if (res == NULL) { ... \(goto l;\|return ret;\) }
... when != res
+ res = platform_get_resource(pdev, IORESOURCE_MEM, n);
e = devm_ioremap_resource(e1, res);
// </smpl>
Shraddha Barke [Sat, 5 Mar 2016 19:25:31 +0000 (00:55 +0530)]
Staging: gdm72xx: Remove gdm72xx driver
Remove support for gdm72xx driver from the kernel since Wimax is dead.
[1] http://www.networkworld.com/article/2220370/4g/wimax-is-dead.html
[2] http://www.androidcentral.com/sprint-confirms-wimax-shutdown-november-6-2015
Chrome OS can distribute this driver alongside their library.
staging: gs_fpgaboot: drop wrapper function 'finish_driver'
Remove the function 'finish_driver' since a direct call to
platform_device_unregister() is intuitive enough to signify the original
intention of the function being removed. Coccinelle semantic patch used to
detect this:
Sudip Mukherjee [Sat, 27 Feb 2016 12:03:35 +0000 (17:33 +0530)]
staging: dgnc: cleanup properly
dgnc_cleanup_module() was called when the module unloaded to do a total
cleanup and it was also called if pci_register_driver() fails. But
dgnc_cleanup_module() will try dgnc_remove_driver_sysfiles() but the
sysfiles will be created only if pci_register_driver() succeeds.
So if pci_register_driver() fails and we try dgnc_cleanup_module() then we
were getting:
[ 942.001479] BUG: unable to handle kernel NULL pointer dereference at 00000018
[ 942.001482] IP: [<c122c7a8>] sysfs_remove_file_ns+0x8/0x20
Sudip Mukherjee [Sat, 27 Feb 2016 12:03:34 +0000 (17:33 +0530)]
staging: dgnc: unregister pci driver
We may choose to load the module without the hardware present. That will
register the pci driver but since probe will not succeed so
dgnc_NumBoards will be 0. Now if we unload the module then the pci
driver stays registered as dgnc_NumBoards is 0. And if we try to load
the module again it fails with the error:
"Driver 'dgnc' is already registered."
Sudip Mukherjee [Sat, 27 Feb 2016 12:03:33 +0000 (17:33 +0530)]
staging: dgnc: remove pci_unregister_driver
If pci_register_driver() fails then dgnc_NumBoards can never be more
than zero. dgnc_NumBoards is incremented only at the end of a successful
probe. And moreover if the pci driver has failed to register then we
never need to unregister it. Lets just print the warning, perform the
cleanup and exit with the error code.