aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/uwb/neh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/uwb/neh.c')
-rw-r--r--drivers/uwb/neh.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index 9b4eb64327ac..48b4ece1a627 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -254,7 +254,6 @@ error_kzalloc:
254 254
255static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) 255static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
256{ 256{
257 del_timer(&neh->timer);
258 __uwb_rc_ctx_put(rc, neh); 257 __uwb_rc_ctx_put(rc, neh);
259 list_del(&neh->list_node); 258 list_del(&neh->list_node);
260} 259}
@@ -275,6 +274,7 @@ void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
275 __uwb_rc_neh_rm(rc, neh); 274 __uwb_rc_neh_rm(rc, neh);
276 spin_unlock_irqrestore(&rc->neh_lock, flags); 275 spin_unlock_irqrestore(&rc->neh_lock, flags);
277 276
277 del_timer_sync(&neh->timer);
278 uwb_rc_neh_put(neh); 278 uwb_rc_neh_put(neh);
279} 279}
280 280
@@ -438,9 +438,10 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
438 rceb->bEventContext, size); 438 rceb->bEventContext, size);
439 } else { 439 } else {
440 neh = uwb_rc_neh_lookup(rc, rceb); 440 neh = uwb_rc_neh_lookup(rc, rceb);
441 if (neh) 441 if (neh) {
442 del_timer_sync(&neh->timer);
442 uwb_rc_neh_cb(neh, rceb, size); 443 uwb_rc_neh_cb(neh, rceb, size);
443 else 444 } else
444 dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", 445 dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
445 rceb->bEventType, le16_to_cpu(rceb->wEvent), 446 rceb->bEventType, le16_to_cpu(rceb->wEvent),
446 rceb->bEventContext, size); 447 rceb->bEventContext, size);
@@ -562,16 +563,22 @@ EXPORT_SYMBOL_GPL(uwb_rc_neh_grok);
562 */ 563 */
563void uwb_rc_neh_error(struct uwb_rc *rc, int error) 564void uwb_rc_neh_error(struct uwb_rc *rc, int error)
564{ 565{
565 struct uwb_rc_neh *neh, *next; 566 struct uwb_rc_neh *neh;
566 unsigned long flags; 567 unsigned long flags;
567 568
568 BUG_ON(error >= 0); 569 for (;;) {
569 spin_lock_irqsave(&rc->neh_lock, flags); 570 spin_lock_irqsave(&rc->neh_lock, flags);
570 list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { 571 if (list_empty(&rc->neh_list)) {
572 spin_unlock_irqrestore(&rc->neh_lock, flags);
573 break;
574 }
575 neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
571 __uwb_rc_neh_rm(rc, neh); 576 __uwb_rc_neh_rm(rc, neh);
577 spin_unlock_irqrestore(&rc->neh_lock, flags);
578
579 del_timer_sync(&neh->timer);
572 uwb_rc_neh_cb(neh, NULL, error); 580 uwb_rc_neh_cb(neh, NULL, error);
573 } 581 }
574 spin_unlock_irqrestore(&rc->neh_lock, flags);
575} 582}
576EXPORT_SYMBOL_GPL(uwb_rc_neh_error); 583EXPORT_SYMBOL_GPL(uwb_rc_neh_error);
577 584
@@ -583,10 +590,14 @@ static void uwb_rc_neh_timer(unsigned long arg)
583 unsigned long flags; 590 unsigned long flags;
584 591
585 spin_lock_irqsave(&rc->neh_lock, flags); 592 spin_lock_irqsave(&rc->neh_lock, flags);
586 __uwb_rc_neh_rm(rc, neh); 593 if (neh->context)
594 __uwb_rc_neh_rm(rc, neh);
595 else
596 neh = NULL;
587 spin_unlock_irqrestore(&rc->neh_lock, flags); 597 spin_unlock_irqrestore(&rc->neh_lock, flags);
588 598
589 uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT); 599 if (neh)
600 uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
590} 601}
591 602
592/** Initializes the @rc's neh subsystem 603/** Initializes the @rc's neh subsystem
@@ -605,12 +616,19 @@ void uwb_rc_neh_create(struct uwb_rc *rc)
605void uwb_rc_neh_destroy(struct uwb_rc *rc) 616void uwb_rc_neh_destroy(struct uwb_rc *rc)
606{ 617{
607 unsigned long flags; 618 unsigned long flags;
608 struct uwb_rc_neh *neh, *next; 619 struct uwb_rc_neh *neh;
609 620
610 spin_lock_irqsave(&rc->neh_lock, flags); 621 for (;;) {
611 list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { 622 spin_lock_irqsave(&rc->neh_lock, flags);
623 if (list_empty(&rc->neh_list)) {
624 spin_unlock_irqrestore(&rc->neh_lock, flags);
625 break;
626 }
627 neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
612 __uwb_rc_neh_rm(rc, neh); 628 __uwb_rc_neh_rm(rc, neh);
629 spin_unlock_irqrestore(&rc->neh_lock, flags);
630
631 del_timer_sync(&neh->timer);
613 uwb_rc_neh_put(neh); 632 uwb_rc_neh_put(neh);
614 } 633 }
615 spin_unlock_irqrestore(&rc->neh_lock, flags);
616} 634}