diff options
author | Thomas Pugliese <thomas.pugliese@gmail.com> | 2014-04-25 17:30:32 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-27 23:56:54 +0200 |
commit | 90ec00d54e28f4b038e66905ea5b9478bcdc3f37 (patch) | |
tree | 71ed3bc15a264277adcad0b562d8198d8656759f /drivers/uwb/rsv.c | |
parent | usb: host: ohci-exynos: Use devm_ioremap_resource instead of devm_ioremap (diff) | |
download | linux-90ec00d54e28f4b038e66905ea5b9478bcdc3f37.tar.xz linux-90ec00d54e28f4b038e66905ea5b9478bcdc3f37.zip |
uwb: fix channel change failure
Make the transition to the UWB_RSV_STATE_NONE state synchronous so that
there is not a race between uwb_rsv_terminate and uwb_rsv_establish.
uwb_rsv_terminate would set the rsv->state to UWB_RSV_STATE_NONE but did
not release the stream resource until a 320ms timeout had expired. If a
user called uwb_rsv_establish during that time, it could fail to
establish the reservation because no stream resources were available.
This patch removes the timer from the uwb_rsv_terminate process since it
is not needed when transitioning to UWB_RSV_STATE_NONE.
Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/uwb/rsv.c')
-rw-r--r-- | drivers/uwb/rsv.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index 3fe611941046..4026f1adff01 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -249,7 +249,9 @@ static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) * super frame and should not be terminated if no response is * received. */ - if (rsv->is_multicast) { + if (rsv->state == UWB_RSV_STATE_NONE) { + sframes = 0; + } else if (rsv->is_multicast) { if (rsv->state == UWB_RSV_STATE_O_INITIATED || rsv->state == UWB_RSV_STATE_O_MOVE_EXPANDING || rsv->state == UWB_RSV_STATE_O_MOVE_COMBINING @@ -322,6 +324,7 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) switch (new_state) { case UWB_RSV_STATE_NONE: uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE); + uwb_rsv_remove(rsv); uwb_rsv_callback(rsv); break; case UWB_RSV_STATE_O_INITIATED: @@ -442,6 +445,8 @@ static void uwb_rsv_handle_timeout_work(struct work_struct *work) uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); goto unlock; + case UWB_RSV_STATE_NONE: + goto unlock; default: break; } |