diff options
-rw-r--r-- | drivers/uwb/lc-rc.c | 5 | ||||
-rw-r--r-- | drivers/uwb/neh.c | 46 |
2 files changed, 35 insertions, 16 deletions
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index 38e3d57ec8f7..f00633d334dd 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c | |||
@@ -79,7 +79,6 @@ static void uwb_rc_sys_release(struct device *dev) | |||
79 | struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); | 79 | struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); |
80 | struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); | 80 | struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); |
81 | 81 | ||
82 | uwb_rc_neh_destroy(rc); | ||
83 | uwb_rc_ie_release(rc); | 82 | uwb_rc_ie_release(rc); |
84 | kfree(rc); | 83 | kfree(rc); |
85 | } | 84 | } |
@@ -311,7 +310,7 @@ void uwb_rc_rm(struct uwb_rc *rc) | |||
311 | rc->ready = 0; | 310 | rc->ready = 0; |
312 | 311 | ||
313 | uwb_dbg_del_rc(rc); | 312 | uwb_dbg_del_rc(rc); |
314 | uwb_rsv_cleanup(rc); | 313 | uwb_rsv_remove_all(rc); |
315 | uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE); | 314 | uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE); |
316 | if (rc->beaconing >= 0) | 315 | if (rc->beaconing >= 0) |
317 | uwb_rc_beacon(rc, -1, 0); | 316 | uwb_rc_beacon(rc, -1, 0); |
@@ -322,6 +321,7 @@ void uwb_rc_rm(struct uwb_rc *rc) | |||
322 | rc->stop(rc); | 321 | rc->stop(rc); |
323 | 322 | ||
324 | uwbd_stop(rc); | 323 | uwbd_stop(rc); |
324 | uwb_rc_neh_destroy(rc); | ||
325 | 325 | ||
326 | uwb_dev_lock(&rc->uwb_dev); | 326 | uwb_dev_lock(&rc->uwb_dev); |
327 | rc->priv = NULL; | 327 | rc->priv = NULL; |
@@ -331,6 +331,7 @@ void uwb_rc_rm(struct uwb_rc *rc) | |||
331 | uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); | 331 | uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); |
332 | __uwb_rc_sys_rm(rc); | 332 | __uwb_rc_sys_rm(rc); |
333 | mutex_unlock(&rc->uwb_beca.mutex); | 333 | mutex_unlock(&rc->uwb_beca.mutex); |
334 | uwb_rsv_cleanup(rc); | ||
334 | uwb_beca_release(rc); | 335 | uwb_beca_release(rc); |
335 | uwb_dev_rm(&rc->uwb_dev); | 336 | uwb_dev_rm(&rc->uwb_dev); |
336 | } | 337 | } |
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 | } |