aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/uwb/lc-rc.c5
-rw-r--r--drivers/uwb/neh.c46
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
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}