diff options
Diffstat (limited to 'drivers/uwb/neh.c')
| -rw-r--r-- | drivers/uwb/neh.c | 13 | 
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index 697e56a5bcd..8cb71bb333c 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -85,6 +85,7 @@  #include <linux/timer.h>  #include <linux/slab.h>  #include <linux/err.h> +#include <linux/export.h>  #include "uwb-internal.h" @@ -106,6 +107,7 @@ struct uwb_rc_neh {  	u8 evt_type;  	__le16 evt;  	u8 context; +	u8 completed;  	uwb_rc_cmd_cb_f cb;  	void *arg; @@ -408,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size  	struct device *dev = &rc->uwb_dev.dev;  	struct uwb_rc_neh *neh;  	struct uwb_rceb *notif; +	unsigned long flags;  	if (rceb->bEventContext == 0) {  		notif = kmalloc(size, GFP_ATOMIC); @@ -421,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size  	} else {  		neh = uwb_rc_neh_lookup(rc, rceb);  		if (neh) { -			del_timer_sync(&neh->timer); +			spin_lock_irqsave(&rc->neh_lock, flags); +			/* to guard against a timeout */ +			neh->completed = 1; +			del_timer(&neh->timer); +			spin_unlock_irqrestore(&rc->neh_lock, flags);  			uwb_rc_neh_cb(neh, rceb, size);  		} else  			dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -567,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg)  	unsigned long flags;  	spin_lock_irqsave(&rc->neh_lock, flags); +	if (neh->completed) { +		spin_unlock_irqrestore(&rc->neh_lock, flags); +		return; +	}  	if (neh->context)  		__uwb_rc_neh_rm(rc, neh);  	else  | 
