summaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/visorbus/visorchipset.c
diff options
context:
space:
mode:
authorDavid Kershner2016-11-03 16:44:26 +0100
committerGreg Kroah-Hartman2016-11-07 10:56:39 +0100
commit8e609b5b6f871bf12d785f73d5513f0dd1fc2a6e (patch)
treedf83d4aa2c3b3f3fe1ed44f477dc83ce9daaa10f /drivers/staging/unisys/visorbus/visorchipset.c
parentstaging: unisys: visorbus: my_device_changestate: add error response (diff)
downloadkernel-qcow2-linux-8e609b5b6f871bf12d785f73d5513f0dd1fc2a6e.tar.gz
kernel-qcow2-linux-8e609b5b6f871bf12d785f73d5513f0dd1fc2a6e.tar.xz
kernel-qcow2-linux-8e609b5b6f871bf12d785f73d5513f0dd1fc2a6e.zip
staging: unisys: visorbus: my_device_changestate: no longer call device_epilog
Function my_device_changestate should call chipset_device_changestate directly instead of calling device_epilog. Signed-off-by: David Kershner <david.kershner@unisys.com> 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.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index f8dca04b1219..51ac2bb0d704 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -1035,6 +1035,7 @@ static void
my_device_changestate(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
+ struct controlvm_message_header *pmsg_hdr = NULL;
u32 bus_no = cmd->device_change_state.bus_no;
u32 dev_no = cmd->device_change_state.dev_no;
struct spar_segment_state state = cmd->device_change_state.state;
@@ -1054,14 +1055,41 @@ my_device_changestate(struct controlvm_message *inmsg)
rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
goto err_respond;
}
+ if (dev_info->pending_msg_hdr) {
+ /* only non-NULL if dev is still waiting on a response */
+ rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT;
+ goto err_respond;
+ }
+ if (inmsg->hdr.flags.response_expected == 1) {
+ pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL);
+ if (!pmsg_hdr) {
+ rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
+ goto err_respond;
+ }
+
+ memcpy(pmsg_hdr, &inmsg->hdr,
+ sizeof(struct controlvm_message_header));
+ dev_info->pending_msg_hdr = pmsg_hdr;
+ }
+
+ if (state.alive == segment_state_running.alive &&
+ state.operating == segment_state_running.operating)
+ /* Response will be sent from chipset_device_resume */
+ chipset_device_resume(dev_info);
+ /* ServerNotReady / ServerLost / SegmentStateStandby */
+ else if (state.alive == segment_state_standby.alive &&
+ state.operating == segment_state_standby.operating)
+ /*
+ * technically this is standby case where server is lost.
+ * Response will be sent from chipset_device_pause.
+ */
+ chipset_device_pause(dev_info);
- device_epilog(dev_info, state,
- CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc,
- inmsg->hdr.flags.response_expected == 1, 1);
return;
err_respond:
- device_responder(inmsg->hdr.id, &inmsg->hdr, rc);
+ if (inmsg->hdr.flags.response_expected == 1)
+ device_responder(inmsg->hdr.id, &inmsg->hdr, rc);
}
static void