staging: unisys: detect controlvm channel on module load

The controlvm channel is not removable from a guest after the guest starts,
so it makes no sense to constantly check for it. Move the channel address
discovery to visorchipset_init(), and remove all of the checks for the channel
address from the rest of the module, as the module will not load if the
channel pointer is not valid.

Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Benjamin Romer 2014-07-17 12:39:58 -04:00 committed by Greg Kroah-Hartman
parent 524b0b63a1
commit 8a1182eb34
1 changed files with 65 additions and 121 deletions

View File

@ -576,8 +576,6 @@ static void
controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response)
{
CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
controlvm_init_response(&outmsg, msgHdr, response);
/* For DiagPool channel DEVICE_CHANGESTATE, we need to send
* back the deviceChangeState structure in the packet. */
@ -604,8 +602,6 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
ULTRA_CHIPSET_FEATURE features)
{
CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
controlvm_init_response(&outmsg, msgHdr, response);
outmsg.cmd.initChipset.features = features;
if (!visorchannel_signalinsert(ControlVm_channel,
@ -620,8 +616,6 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr,
int response, ULTRA_SEGMENT_STATE state)
{
CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
controlvm_init_response(&outmsg, msgHdr, response);
outmsg.cmd.deviceChangeState.state = state;
outmsg.cmd.deviceChangeState.flags.physicalDevice = 1;
@ -739,9 +733,6 @@ device_changestate_responder(CONTROLVM_ID cmdId,
VISORCHIPSET_DEVICE_INFO *p = NULL;
CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
p = finddevice(&DevInfoList, busNo, devNo);
if (!p) {
LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo);
@ -1855,7 +1846,6 @@ controlvm_periodic_work(struct work_struct *work)
{
VISORCHIPSET_CHANNEL_INFO chanInfo;
CONTROLVM_MESSAGE inmsg;
char s[99];
BOOL gotACommand = FALSE;
BOOL handle_command_failed = FALSE;
static U64 Poll_Count;
@ -1870,32 +1860,9 @@ controlvm_periodic_work(struct work_struct *work)
goto Away;
memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO));
if (!ControlVm_channel) {
HOSTADDRESS addr = controlvm_get_channel_address();
if (addr != 0) {
ControlVm_channel =
visorchannel_create_with_lock
(addr,
sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
UltraControlvmChannelProtocolGuid);
if (ControlVm_channel == NULL)
LOGERR("failed to create controlvm channel");
else if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
(visorchannel_get_header(ControlVm_channel),
NULL)) {
LOGINF("Channel %s (ControlVm) discovered",
visorchannel_id(ControlVm_channel, s));
initialize_controlvm_payload();
} else {
LOGERR("controlvm channel is invalid");
visorchannel_destroy(ControlVm_channel);
ControlVm_channel = NULL;
}
}
}
Poll_Count++;
if ((ControlVm_channel != NULL) || (Poll_Count >= 250))
if (Poll_Count >= 250)
; /* keep going */
else
goto Away;
@ -1914,54 +1881,46 @@ controlvm_periodic_work(struct work_struct *work)
}
}
if (ControlVm_channel) {
while (visorchannel_signalremove(ControlVm_channel,
CONTROLVM_QUEUE_RESPONSE,
&inmsg)) {
if (inmsg.hdr.PayloadMaxBytes != 0) {
LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
(ulong) inmsg.hdr.PayloadMaxBytes,
(ulong) inmsg.hdr.PayloadVmOffset,
inmsg.hdr.Id);
}
}
if (!gotACommand) {
if (ControlVm_Pending_Msg_Valid) {
/* we throttled processing of a prior
* msg, so try to process it again
* rather than reading a new one
*/
inmsg = ControlVm_Pending_Msg;
ControlVm_Pending_Msg_Valid = FALSE;
gotACommand = TRUE;
} else
gotACommand = read_controlvm_event(&inmsg);
while (visorchannel_signalremove(ControlVm_channel,
CONTROLVM_QUEUE_RESPONSE,
&inmsg)) {
if (inmsg.hdr.PayloadMaxBytes != 0) {
LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
(ulong) inmsg.hdr.PayloadMaxBytes,
(ulong) inmsg.hdr.PayloadVmOffset,
inmsg.hdr.Id);
}
}
if (!gotACommand) {
if (ControlVm_Pending_Msg_Valid) {
/* we throttled processing of a prior
* msg, so try to process it again
* rather than reading a new one
*/
inmsg = ControlVm_Pending_Msg;
ControlVm_Pending_Msg_Valid = FALSE;
gotACommand = TRUE;
} else
gotACommand = read_controlvm_event(&inmsg);
}
handle_command_failed = FALSE;
while (gotACommand && (!handle_command_failed)) {
Most_recent_message_jiffies = jiffies;
if (ControlVm_channel) {
if (handle_command(inmsg,
visorchannel_get_physaddr
(ControlVm_channel)))
gotACommand = read_controlvm_event(&inmsg);
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;
ControlVm_Pending_Msg = inmsg;
ControlVm_Pending_Msg_Valid = TRUE;
}
} else {
handle_command(inmsg, 0);
gotACommand = FALSE;
if (handle_command(inmsg,
visorchannel_get_physaddr
(ControlVm_channel)))
gotACommand = read_controlvm_event(&inmsg);
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;
ControlVm_Pending_Msg = inmsg;
ControlVm_Pending_Msg_Valid = TRUE;
}
}
@ -1998,7 +1957,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
CONTROLVM_MESSAGE localCrashCreateBusMsg;
CONTROLVM_MESSAGE localCrashCreateDevMsg;
CONTROLVM_MESSAGE msg;
HOSTADDRESS host_addr;
U32 localSavedCrashMsgOffset;
U16 localSavedCrashMsgCount;
@ -2021,26 +1979,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
chipset_init(&msg);
host_addr = controlvm_get_channel_address();
if (!host_addr) {
LOGERR("Huh? Host address is NULL");
POSTCODE_LINUX_2(CRASH_DEV_HADDR_NULL, POSTCODE_SEVERITY_ERR);
return;
}
ControlVm_channel =
visorchannel_create_with_lock
(host_addr,
sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
UltraControlvmChannelProtocolGuid);
if (ControlVm_channel == NULL) {
LOGERR("failed to create controlvm channel");
POSTCODE_LINUX_2(CRASH_DEV_CONTROLVM_NULL,
POSTCODE_SEVERITY_ERR);
return;
}
/* get saved message count */
if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
@ -2331,9 +2269,6 @@ proc_read_installer(struct file *file, char __user *buf,
char *vbuf;
loff_t pos = *offset;
if (!ControlVm_channel)
return -ENODEV;
if (pos < 0)
return -EINVAL;
@ -2383,9 +2318,6 @@ proc_write_installer(struct file *file,
U16 remainingSteps;
U32 error, textId;
if (!ControlVm_channel)
return -ENODEV;
/* Check to make sure there is no buffer overflow */
if (count > (sizeof(buf) - 1))
return -EINVAL;
@ -2447,9 +2379,6 @@ proc_read_toolaction(struct file *file, char __user *buf,
char *vbuf;
loff_t pos = *offset;
if (!ControlVm_channel)
return -ENODEV;
if (pos < 0)
return -EINVAL;
@ -2488,9 +2417,6 @@ proc_write_toolaction(struct file *file,
char buf[3];
U8 toolAction;
if (!ControlVm_channel)
return -ENODEV;
/* Check to make sure there is no buffer overflow */
if (count > (sizeof(buf) - 1))
return -EINVAL;
@ -2530,9 +2456,6 @@ proc_read_bootToTool(struct file *file, char __user *buf,
char *vbuf;
loff_t pos = *offset;
if (!ControlVm_channel)
return -ENODEV;
if (pos < 0)
return -EINVAL;
@ -2571,9 +2494,6 @@ proc_write_bootToTool(struct file *file,
int inputVal;
ULTRA_EFI_SPAR_INDICATION efiSparIndication;
if (!ControlVm_channel)
return -ENODEV;
/* Check to make sure there is no buffer overflow */
if (count > (sizeof(buf) - 1))
return -EINVAL;
@ -2612,9 +2532,11 @@ static int __init
visorchipset_init(void)
{
int rc = 0, x = 0;
char s[64];
struct proc_dir_entry *installer_file;
struct proc_dir_entry *toolaction_file;
struct proc_dir_entry *bootToTool_file;
HOSTADDRESS addr;
if (!unisys_spar_platform)
return -ENODEV;
@ -2646,6 +2568,30 @@ visorchipset_init(void)
goto Away;
}
addr = controlvm_get_channel_address();
if (addr != 0) {
ControlVm_channel =
visorchannel_create_with_lock
(addr,
sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
UltraControlvmChannelProtocolGuid);
if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
(visorchannel_get_header(ControlVm_channel),
NULL)) {
LOGINF("Channel %s (ControlVm) discovered",
visorchannel_id(ControlVm_channel, s));
initialize_controlvm_payload();
} else {
LOGERR("controlvm channel is invalid");
visorchannel_destroy(ControlVm_channel);
ControlVm_channel = NULL;
return -ENODEV;
}
} else {
LOGERR("no controlvm channel discovered");
return -ENODEV;
}
MajorDev = MKDEV(visorchipset_major, 0);
rc = visorchipset_file_init(MajorDev, &ControlVm_channel);
if (rc < 0) {
@ -2795,12 +2741,10 @@ visorchipset_exit(void)
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
proc_DeInit();
if (ControlVm_channel != NULL) {
LOGINF("Channel %s (ControlVm) disconnected",
visorchannel_id(ControlVm_channel, s));
visorchannel_destroy(ControlVm_channel);
ControlVm_channel = NULL;
}
LOGINF("Channel %s (ControlVm) disconnected",
visorchannel_id(ControlVm_channel, s));
visorchannel_destroy(ControlVm_channel);
visorchipset_file_cleanup();
POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO);
LOGINF("chipset driver unloaded");