diff options
Diffstat (limited to 'drivers/uwb/neh.c')
-rw-r--r-- | drivers/uwb/neh.c | 46 |
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 | ||
255 | static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) | 255 | static 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 | */ |
563 | void uwb_rc_neh_error(struct uwb_rc *rc, int error) | 564 | void 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 | } |
576 | EXPORT_SYMBOL_GPL(uwb_rc_neh_error); | 583 | EXPORT_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) | |||
605 | void uwb_rc_neh_destroy(struct uwb_rc *rc) | 616 | void 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 | } |