summaryrefslogtreecommitdiff
path: root/drivers/uwb
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2009-01-06 17:55:32 (GMT)
committerDavid Vrabel <david.vrabel@csr.com>2009-01-06 17:55:32 (GMT)
commit2226b1c219a18804bc40e32a5d53c287a6c925d9 (patch)
tree1456249aa02e80623e043433b6c93cf5f45fcfac /drivers/uwb
parent238c6d54830c624f34ac9cf123ac04aebfca5013 (diff)
downloadlinux-2226b1c219a18804bc40e32a5d53c287a6c925d9.tar.xz
uwb: safely remove all reservations
When removing all reservations during shutdown, terminate them first and then wait for any pending timeout work to complete. This prevents the timeout work from running after the reservation has been freed. Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/uwb')
-rw-r--r--drivers/uwb/rsv.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index ec6eecb..886f977 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -114,7 +114,8 @@ void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
devaddr = rsv->target.devaddr;
uwb_dev_addr_print(target, sizeof(target), &devaddr);
- dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
+ dev_dbg(dev, "rsv %s %s -> %s: %s\n",
+ text, owner, target, uwb_rsv_state_str(rsv->state));
}
static void uwb_rsv_release(struct kref *kref)
@@ -511,8 +512,7 @@ void uwb_rsv_remove(struct uwb_rsv *rsv)
if (uwb_rsv_is_owner(rsv))
uwb_rsv_put_stream(rsv);
-
- del_timer_sync(&rsv->timer);
+
uwb_dev_put(rsv->owner);
if (rsv->target.type == UWB_RSV_TARGET_DEV)
uwb_dev_put(rsv->target.dev);
@@ -943,13 +943,22 @@ void uwb_rsv_remove_all(struct uwb_rc *rc)
mutex_lock(&rc->rsvs_mutex);
list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
- uwb_rsv_remove(rsv);
+ if (rsv->state != UWB_RSV_STATE_NONE)
+ uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+ del_timer_sync(&rsv->timer);
}
/* Cancel any postponed update. */
rc->set_drp_ie_pending = 0;
mutex_unlock(&rc->rsvs_mutex);
cancel_delayed_work_sync(&rc->rsv_update_work);
+ flush_workqueue(rc->rsv_workq);
+
+ mutex_lock(&rc->rsvs_mutex);
+ list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
+ uwb_rsv_remove(rsv);
+ }
+ mutex_unlock(&rc->rsvs_mutex);
}
void uwb_rsv_init(struct uwb_rc *rc)