struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev);
struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev);
- uwb_rc_neh_destroy(rc);
uwb_rc_ie_release(rc);
kfree(rc);
}
rc->ready = 0;
uwb_dbg_del_rc(rc);
- uwb_rsv_cleanup(rc);
+ uwb_rsv_remove_all(rc);
uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE);
if (rc->beaconing >= 0)
uwb_rc_beacon(rc, -1, 0);
rc->stop(rc);
uwbd_stop(rc);
+ uwb_rc_neh_destroy(rc);
uwb_dev_lock(&rc->uwb_dev);
rc->priv = NULL;
uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL);
__uwb_rc_sys_rm(rc);
mutex_unlock(&rc->uwb_beca.mutex);
+ uwb_rsv_cleanup(rc);
uwb_beca_release(rc);
uwb_dev_rm(&rc->uwb_dev);
}
static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
{
- del_timer(&neh->timer);
__uwb_rc_ctx_put(rc, neh);
list_del(&neh->list_node);
}
__uwb_rc_neh_rm(rc, neh);
spin_unlock_irqrestore(&rc->neh_lock, flags);
+ del_timer_sync(&neh->timer);
uwb_rc_neh_put(neh);
}
rceb->bEventContext, size);
} else {
neh = uwb_rc_neh_lookup(rc, rceb);
- if (neh)
+ if (neh) {
+ del_timer_sync(&neh->timer);
uwb_rc_neh_cb(neh, rceb, size);
- else
+ } else
dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
rceb->bEventType, le16_to_cpu(rceb->wEvent),
rceb->bEventContext, size);
*/
void uwb_rc_neh_error(struct uwb_rc *rc, int error)
{
- struct uwb_rc_neh *neh, *next;
+ struct uwb_rc_neh *neh;
unsigned long flags;
- BUG_ON(error >= 0);
- spin_lock_irqsave(&rc->neh_lock, flags);
- list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) {
+ for (;;) {
+ spin_lock_irqsave(&rc->neh_lock, flags);
+ if (list_empty(&rc->neh_list)) {
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+ break;
+ }
+ neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
__uwb_rc_neh_rm(rc, neh);
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+
+ del_timer_sync(&neh->timer);
uwb_rc_neh_cb(neh, NULL, error);
}
- spin_unlock_irqrestore(&rc->neh_lock, flags);
}
EXPORT_SYMBOL_GPL(uwb_rc_neh_error);
unsigned long flags;
spin_lock_irqsave(&rc->neh_lock, flags);
- __uwb_rc_neh_rm(rc, neh);
+ if (neh->context)
+ __uwb_rc_neh_rm(rc, neh);
+ else
+ neh = NULL;
spin_unlock_irqrestore(&rc->neh_lock, flags);
- uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
+ if (neh)
+ uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
}
/** Initializes the @rc's neh subsystem
void uwb_rc_neh_destroy(struct uwb_rc *rc)
{
unsigned long flags;
- struct uwb_rc_neh *neh, *next;
+ struct uwb_rc_neh *neh;
- spin_lock_irqsave(&rc->neh_lock, flags);
- list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) {
+ for (;;) {
+ spin_lock_irqsave(&rc->neh_lock, flags);
+ if (list_empty(&rc->neh_list)) {
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+ break;
+ }
+ neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
__uwb_rc_neh_rm(rc, neh);
+ spin_unlock_irqrestore(&rc->neh_lock, flags);
+
+ del_timer_sync(&neh->timer);
uwb_rc_neh_put(neh);
}
- spin_unlock_irqrestore(&rc->neh_lock, flags);
}