diff options
author | David Kershner | 2017-03-28 15:34:20 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2017-03-29 09:17:02 +0200 |
commit | fbc1023afbc7602c8b1053c8432286750ecbd5a0 (patch) | |
tree | ae806dc9bd48f26acf28d6aff7ecbc695933afae /drivers/staging/unisys/visorbus/visorchipset.c | |
parent | staging: unisys: visorbus: add error handling to handle_command (diff) | |
download | kernel-qcow2-linux-fbc1023afbc7602c8b1053c8432286750ecbd5a0.tar.gz kernel-qcow2-linux-fbc1023afbc7602c8b1053c8432286750ecbd5a0.tar.xz kernel-qcow2-linux-fbc1023afbc7602c8b1053c8432286750ecbd5a0.zip |
staging: unisys: visorbus: add error handling to controlvm_periodic_work
The function controlvm_periodic_work should handle errors appropriately.
Signed-off-by: David Kershner <david.kershner@unisys.com>
Reviewed-by: Reviewed-by: Tim Sell <timothy.sell@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/unisys/visorbus/visorchipset.c')
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchipset.c | 67 |
1 files changed, 32 insertions, 35 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index d4f4afe1eebd..8185430ecd37 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1727,52 +1727,49 @@ static void controlvm_periodic_work(struct work_struct *work) { struct controlvm_message inmsg; - bool got_command = false; - bool handle_command_failed = false; - - while (!visorchannel_signalremove(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_RESPONSE, - &inmsg)) - ; - if (!got_command) { - if (chipset_dev->controlvm_pending_msg_valid) { - /* - * we throttled processing of a prior - * msg, so try to process it again - * rather than reading a new one - */ - inmsg = chipset_dev->controlvm_pending_msg; - chipset_dev->controlvm_pending_msg_valid = false; - got_command = true; - } else { - got_command = (read_controlvm_event(&inmsg) == 0); - } + int err; + + /* Drain the RESPONSE queue make it empty */ + do { + err = visorchannel_signalremove(chipset_dev->controlvm_channel, + CONTROLVM_QUEUE_RESPONSE, + &inmsg); + } while (!err); + + if (err != -EAGAIN) + goto schedule_out; + + if (chipset_dev->controlvm_pending_msg_valid) { + /* + * we throttled processing of a prior + * msg, so try to process it again + * rather than reading a new one + */ + inmsg = chipset_dev->controlvm_pending_msg; + chipset_dev->controlvm_pending_msg_valid = false; + err = 0; + } else { + err = read_controlvm_event(&inmsg); } - handle_command_failed = false; - while (got_command && (!handle_command_failed)) { + while (!err) { chipset_dev->most_recent_message_jiffies = jiffies; - if (handle_command(inmsg, - visorchannel_get_physaddr - (chipset_dev->controlvm_channel) != -EAGAIN)) - got_command = (read_controlvm_event(&inmsg) == 0); - else { - /* - * this is a scenario where throttling - * is required, but probably NOT an - * error...; we stash the current - * controlvm msg so we will attempt to - * reprocess it on our next loop - */ - handle_command_failed = true; + err = handle_command(inmsg, + visorchannel_get_physaddr + (chipset_dev->controlvm_channel)); + if (err == -EAGAIN) { chipset_dev->controlvm_pending_msg = inmsg; chipset_dev->controlvm_pending_msg_valid = true; + break; } + + err = read_controlvm_event(&inmsg); } /* parahotplug_worker */ parahotplug_process_list(); +schedule_out: if (time_after(jiffies, chipset_dev->most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) { /* |