Commit 765b2f82 authored by Sameer Wadgaonkar's avatar Sameer Wadgaonkar Committed by Greg Kroah-Hartman

staging: unisys: visorbus: added struct visorchipset_device

Added the structure visorchipset_device and moved the globals to
the struct. The visorchipset_init() function saves acpi_device
within this structure.
Reported-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSameer Wadgaonkar <sameer.wadgaonkar@unisys.com>
Signed-off-by: default avatarDavid Kershner <david.kershner@unisys.com>
Reviewed-by: default avatarTim Sell <timothy.sell@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c0487e7e
...@@ -72,9 +72,6 @@ visorchipset_release(struct inode *inode, struct file *file) ...@@ -72,9 +72,6 @@ visorchipset_release(struct inode *inode, struct file *file)
* message, we switch back to fast polling mode. * message, we switch back to fast polling mode.
*/ */
#define MIN_IDLE_SECONDS 10 #define MIN_IDLE_SECONDS 10
static unsigned long poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
/* when we got our last controlvm message */
static unsigned long most_recent_message_jiffies;
struct parser_context { struct parser_context {
unsigned long allocbytes; unsigned long allocbytes;
...@@ -85,22 +82,28 @@ struct parser_context { ...@@ -85,22 +82,28 @@ struct parser_context {
char data[0]; char data[0];
}; };
static struct delayed_work periodic_controlvm_work; struct visorchipset_device {
struct acpi_device *acpi_device;
static struct cdev file_cdev; unsigned long poll_jiffies;
static struct visorchannel **file_controlvm_channel; /* when we got our last controlvm message */
unsigned long most_recent_message_jiffies;
static struct visorchannel *controlvm_channel; struct delayed_work periodic_controlvm_work;
static unsigned long controlvm_payload_bytes_buffered; struct cdev file_cdev;
struct visorchannel **file_controlvm_channel;
/* struct visorchannel *controlvm_channel;
* The following globals are used to handle the scenario where we are unable to unsigned long controlvm_payload_bytes_buffered;
* offload the payload from a controlvm message due to memory requirements. In /*
* this scenario, we simply stash the controlvm message, then attempt to * The following variables are used to handle the scenario where we are
* process it again the next time controlvm_periodic_work() runs. * unable to offload the payload from a controlvm message due to memory
* requirements. In this scenario, we simply stash the controlvm
* message, then attempt to process it again the next time
* controlvm_periodic_work() runs.
*/ */
static struct controlvm_message controlvm_pending_msg; struct controlvm_message controlvm_pending_msg;
static bool controlvm_pending_msg_valid; bool controlvm_pending_msg_valid;
};
static struct visorchipset_device *chipset_dev;
struct parahotplug_request { struct parahotplug_request {
struct list_head list; struct list_head list;
...@@ -119,7 +122,7 @@ static ssize_t toolaction_show(struct device *dev, ...@@ -119,7 +122,7 @@ static ssize_t toolaction_show(struct device *dev,
{ {
u8 tool_action = 0; u8 tool_action = 0;
visorchannel_read(controlvm_channel, visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
tool_action), &tool_action, sizeof(u8)); tool_action), &tool_action, sizeof(u8));
return sprintf(buf, "%u\n", tool_action); return sprintf(buf, "%u\n", tool_action);
...@@ -136,7 +139,7 @@ static ssize_t toolaction_store(struct device *dev, ...@@ -136,7 +139,7 @@ static ssize_t toolaction_store(struct device *dev,
return -EINVAL; return -EINVAL;
ret = visorchannel_write ret = visorchannel_write
(controlvm_channel, (chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
tool_action), tool_action),
&tool_action, sizeof(u8)); &tool_action, sizeof(u8));
...@@ -153,7 +156,7 @@ static ssize_t boottotool_show(struct device *dev, ...@@ -153,7 +156,7 @@ static ssize_t boottotool_show(struct device *dev,
{ {
struct efi_spar_indication efi_spar_indication; struct efi_spar_indication efi_spar_indication;
visorchannel_read(controlvm_channel, visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
efi_spar_ind), &efi_spar_indication, efi_spar_ind), &efi_spar_indication,
sizeof(struct efi_spar_indication)); sizeof(struct efi_spar_indication));
...@@ -172,7 +175,7 @@ static ssize_t boottotool_store(struct device *dev, ...@@ -172,7 +175,7 @@ static ssize_t boottotool_store(struct device *dev,
efi_spar_indication.boot_to_tool = val; efi_spar_indication.boot_to_tool = val;
ret = visorchannel_write ret = visorchannel_write
(controlvm_channel, (chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
efi_spar_ind), &(efi_spar_indication), efi_spar_ind), &(efi_spar_indication),
sizeof(struct efi_spar_indication)); sizeof(struct efi_spar_indication));
...@@ -188,7 +191,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, ...@@ -188,7 +191,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr,
{ {
u32 error = 0; u32 error = 0;
visorchannel_read(controlvm_channel, visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
installation_error), installation_error),
&error, sizeof(u32)); &error, sizeof(u32));
...@@ -205,7 +208,7 @@ static ssize_t error_store(struct device *dev, struct device_attribute *attr, ...@@ -205,7 +208,7 @@ static ssize_t error_store(struct device *dev, struct device_attribute *attr,
return -EINVAL; return -EINVAL;
ret = visorchannel_write ret = visorchannel_write
(controlvm_channel, (chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
installation_error), installation_error),
&error, sizeof(u32)); &error, sizeof(u32));
...@@ -221,7 +224,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, ...@@ -221,7 +224,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
u32 text_id = 0; u32 text_id = 0;
visorchannel_read visorchannel_read
(controlvm_channel, (chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
installation_text_id), installation_text_id),
&text_id, sizeof(u32)); &text_id, sizeof(u32));
...@@ -238,7 +241,7 @@ static ssize_t textid_store(struct device *dev, struct device_attribute *attr, ...@@ -238,7 +241,7 @@ static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
return -EINVAL; return -EINVAL;
ret = visorchannel_write ret = visorchannel_write
(controlvm_channel, (chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
installation_text_id), installation_text_id),
&text_id, sizeof(u32)); &text_id, sizeof(u32));
...@@ -253,7 +256,7 @@ static ssize_t remaining_steps_show(struct device *dev, ...@@ -253,7 +256,7 @@ static ssize_t remaining_steps_show(struct device *dev,
{ {
u16 remaining_steps = 0; u16 remaining_steps = 0;
visorchannel_read(controlvm_channel, visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
installation_remaining_steps), installation_remaining_steps),
&remaining_steps, sizeof(u16)); &remaining_steps, sizeof(u16));
...@@ -271,7 +274,7 @@ static ssize_t remaining_steps_store(struct device *dev, ...@@ -271,7 +274,7 @@ static ssize_t remaining_steps_store(struct device *dev,
return -EINVAL; return -EINVAL;
ret = visorchannel_write ret = visorchannel_write
(controlvm_channel, (chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
installation_remaining_steps), installation_remaining_steps),
&remaining_steps, sizeof(u16)); &remaining_steps, sizeof(u16));
...@@ -292,7 +295,7 @@ parser_id_get(struct parser_context *ctx) ...@@ -292,7 +295,7 @@ parser_id_get(struct parser_context *ctx)
static void parser_done(struct parser_context *ctx) static void parser_done(struct parser_context *ctx)
{ {
controlvm_payload_bytes_buffered -= ctx->param_bytes; chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes;
kfree(ctx); kfree(ctx);
} }
...@@ -405,7 +408,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, ...@@ -405,7 +408,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr,
controlvm_init_response(&outmsg, msg_hdr, response); controlvm_init_response(&outmsg, msg_hdr, response);
outmsg.cmd.init_chipset.features = features; outmsg.cmd.init_chipset.features = features;
return visorchannel_signalinsert(controlvm_channel, return visorchannel_signalinsert(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_REQUEST, &outmsg); CONTROLVM_QUEUE_REQUEST, &outmsg);
} }
...@@ -455,7 +458,7 @@ controlvm_respond(struct controlvm_message_header *msg_hdr, int response) ...@@ -455,7 +458,7 @@ controlvm_respond(struct controlvm_message_header *msg_hdr, int response)
if (outmsg.hdr.flags.test_message == 1) if (outmsg.hdr.flags.test_message == 1)
return -EINVAL; return -EINVAL;
return visorchannel_signalinsert(controlvm_channel, return visorchannel_signalinsert(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_REQUEST, &outmsg); CONTROLVM_QUEUE_REQUEST, &outmsg);
} }
...@@ -468,7 +471,7 @@ static int controlvm_respond_physdev_changestate( ...@@ -468,7 +471,7 @@ static int controlvm_respond_physdev_changestate(
controlvm_init_response(&outmsg, msg_hdr, response); controlvm_init_response(&outmsg, msg_hdr, response);
outmsg.cmd.device_change_state.state = state; outmsg.cmd.device_change_state.state = state;
outmsg.cmd.device_change_state.flags.phys_device = 1; outmsg.cmd.device_change_state.flags.phys_device = 1;
return visorchannel_signalinsert(controlvm_channel, return visorchannel_signalinsert(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_REQUEST, &outmsg); CONTROLVM_QUEUE_REQUEST, &outmsg);
} }
...@@ -484,7 +487,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) ...@@ -484,7 +487,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ)
u16 local_crash_msg_count; u16 local_crash_msg_count;
int err; int err;
err = visorchannel_read(controlvm_channel, err = visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
saved_crash_message_count), saved_crash_message_count),
&local_crash_msg_count, sizeof(u16)); &local_crash_msg_count, sizeof(u16));
...@@ -501,7 +504,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) ...@@ -501,7 +504,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ)
return -EIO; return -EIO;
} }
err = visorchannel_read(controlvm_channel, err = visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
saved_crash_message_offset), saved_crash_message_offset),
&local_crash_msg_offset, sizeof(u32)); &local_crash_msg_offset, sizeof(u32));
...@@ -514,7 +517,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) ...@@ -514,7 +517,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ)
switch (typ) { switch (typ) {
case CRASH_DEV: case CRASH_DEV:
local_crash_msg_offset += sizeof(struct controlvm_message); local_crash_msg_offset += sizeof(struct controlvm_message);
err = visorchannel_write(controlvm_channel, err = visorchannel_write(chipset_dev->controlvm_channel,
local_crash_msg_offset, local_crash_msg_offset,
msg, msg,
sizeof(struct controlvm_message)); sizeof(struct controlvm_message));
...@@ -525,7 +528,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) ...@@ -525,7 +528,7 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ)
} }
break; break;
case CRASH_BUS: case CRASH_BUS:
err = visorchannel_write(controlvm_channel, err = visorchannel_write(chipset_dev->controlvm_channel,
local_crash_msg_offset, local_crash_msg_offset,
msg, msg,
sizeof(struct controlvm_message)); sizeof(struct controlvm_message));
...@@ -576,7 +579,7 @@ device_changestate_responder(enum controlvm_id cmd_id, ...@@ -576,7 +579,7 @@ device_changestate_responder(enum controlvm_id cmd_id,
outmsg.cmd.device_change_state.dev_no = dev_no; outmsg.cmd.device_change_state.dev_no = dev_no;
outmsg.cmd.device_change_state.state = response_state; outmsg.cmd.device_change_state.state = response_state;
return visorchannel_signalinsert(controlvm_channel, return visorchannel_signalinsert(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_REQUEST, &outmsg); CONTROLVM_QUEUE_REQUEST, &outmsg);
} }
...@@ -1398,7 +1401,7 @@ setup_crash_devices_work_queue(struct work_struct *work) ...@@ -1398,7 +1401,7 @@ setup_crash_devices_work_queue(struct work_struct *work)
chipset_init(&msg); chipset_init(&msg);
/* get saved message count */ /* get saved message count */
if (visorchannel_read(controlvm_channel, if (visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
saved_crash_message_count), saved_crash_message_count),
&local_crash_msg_count, sizeof(u16)) < 0) { &local_crash_msg_count, sizeof(u16)) < 0) {
...@@ -1415,7 +1418,7 @@ setup_crash_devices_work_queue(struct work_struct *work) ...@@ -1415,7 +1418,7 @@ setup_crash_devices_work_queue(struct work_struct *work)
} }
/* get saved crash message offset */ /* get saved crash message offset */
if (visorchannel_read(controlvm_channel, if (visorchannel_read(chipset_dev->controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
saved_crash_message_offset), saved_crash_message_offset),
&local_crash_msg_offset, sizeof(u32)) < 0) { &local_crash_msg_offset, sizeof(u32)) < 0) {
...@@ -1425,7 +1428,7 @@ setup_crash_devices_work_queue(struct work_struct *work) ...@@ -1425,7 +1428,7 @@ setup_crash_devices_work_queue(struct work_struct *work)
} }
/* read create device message for storage bus offset */ /* read create device message for storage bus offset */
if (visorchannel_read(controlvm_channel, if (visorchannel_read(chipset_dev->controlvm_channel,
local_crash_msg_offset, local_crash_msg_offset,
&local_crash_bus_msg, &local_crash_bus_msg,
sizeof(struct controlvm_message)) < 0) { sizeof(struct controlvm_message)) < 0) {
...@@ -1435,7 +1438,7 @@ setup_crash_devices_work_queue(struct work_struct *work) ...@@ -1435,7 +1438,7 @@ setup_crash_devices_work_queue(struct work_struct *work)
} }
/* read create device message for storage device */ /* read create device message for storage device */
if (visorchannel_read(controlvm_channel, if (visorchannel_read(chipset_dev->controlvm_channel,
local_crash_msg_offset + local_crash_msg_offset +
sizeof(struct controlvm_message), sizeof(struct controlvm_message),
&local_crash_dev_msg, &local_crash_dev_msg,
...@@ -1548,11 +1551,11 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1548,11 +1551,11 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
switch (offset) { switch (offset) {
case VISORCHIPSET_MMAP_CONTROLCHANOFFSET: case VISORCHIPSET_MMAP_CONTROLCHANOFFSET:
vma->vm_flags |= VM_IO; vma->vm_flags |= VM_IO;
if (!*file_controlvm_channel) if (!*chipset_dev->file_controlvm_channel)
return -ENXIO; return -ENXIO;
visorchannel_read visorchannel_read
(*file_controlvm_channel, (*chipset_dev->file_controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol, offsetof(struct spar_controlvm_channel_protocol,
gp_control_channel), gp_control_channel),
&addr, sizeof(addr)); &addr, sizeof(addr));
...@@ -1633,9 +1636,9 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) ...@@ -1633,9 +1636,9 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
{ {
int rc = 0; int rc = 0;
file_controlvm_channel = controlvm_channel; chipset_dev->file_controlvm_channel = controlvm_channel;
cdev_init(&file_cdev, &visorchipset_fops); cdev_init(&chipset_dev->file_cdev, &visorchipset_fops);
file_cdev.owner = THIS_MODULE; chipset_dev->file_cdev.owner = THIS_MODULE;
if (MAJOR(major_dev) == 0) { if (MAJOR(major_dev) == 0) {
rc = alloc_chrdev_region(&major_dev, 0, 1, "visorchipset"); rc = alloc_chrdev_region(&major_dev, 0, 1, "visorchipset");
/* dynamic major device number registration required */ /* dynamic major device number registration required */
...@@ -1647,7 +1650,8 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) ...@@ -1647,7 +1650,8 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
if (rc < 0) if (rc < 0)
return rc; return rc;
} }
rc = cdev_add(&file_cdev, MKDEV(MAJOR(major_dev), 0), 1); rc = cdev_add(&chipset_dev->file_cdev,
MKDEV(MAJOR(major_dev), 0), 1);
if (rc < 0) { if (rc < 0) {
unregister_chrdev_region(major_dev, 1); unregister_chrdev_region(major_dev, 1);
return rc; return rc;
...@@ -1658,9 +1662,9 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel) ...@@ -1658,9 +1662,9 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
static void static void
visorchipset_file_cleanup(dev_t major_dev) visorchipset_file_cleanup(dev_t major_dev)
{ {
if (file_cdev.ops) if (chipset_dev->file_cdev.ops)
cdev_del(&file_cdev); cdev_del(&chipset_dev->file_cdev);
file_cdev.ops = NULL; chipset_dev->file_cdev.ops = NULL;
unregister_chrdev_region(major_dev, 1); unregister_chrdev_region(major_dev, 1);
} }
...@@ -1677,7 +1681,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) ...@@ -1677,7 +1681,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
* '\0'-terminated * '\0'-terminated
*/ */
allocbytes++; allocbytes++;
if ((controlvm_payload_bytes_buffered + bytes) if ((chipset_dev->controlvm_payload_bytes_buffered + bytes)
> MAX_CONTROLVM_PAYLOAD_BYTES) { > MAX_CONTROLVM_PAYLOAD_BYTES) {
*retry = true; *retry = true;
return NULL; return NULL;
...@@ -1710,7 +1714,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) ...@@ -1710,7 +1714,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
} }
ctx->byte_stream = true; ctx->byte_stream = true;
controlvm_payload_bytes_buffered += ctx->param_bytes; chipset_dev->controlvm_payload_bytes_buffered += ctx->param_bytes;
return ctx; return ctx;
...@@ -1769,10 +1773,10 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) ...@@ -1769,10 +1773,10 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr)
if (!local_addr) { if (!local_addr) {
controlvm_init_response(&ackmsg, &inmsg.hdr, controlvm_init_response(&ackmsg, &inmsg.hdr,
CONTROLVM_RESP_SUCCESS); CONTROLVM_RESP_SUCCESS);
if (controlvm_channel) if (chipset_dev->controlvm_channel)
visorchannel_signalinsert(controlvm_channel, visorchannel_signalinsert(
CONTROLVM_QUEUE_ACK, chipset_dev->controlvm_channel,
&ackmsg); CONTROLVM_QUEUE_ACK, &ackmsg);
} }
switch (inmsg.hdr.id) { switch (inmsg.hdr.id) {
case CONTROLVM_CHIPSET_INIT: case CONTROLVM_CHIPSET_INIT:
...@@ -1844,7 +1848,7 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) ...@@ -1844,7 +1848,7 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr)
static bool static bool
read_controlvm_event(struct controlvm_message *msg) read_controlvm_event(struct controlvm_message *msg)
{ {
if (!visorchannel_signalremove(controlvm_channel, if (!visorchannel_signalremove(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_EVENT, msg)) { CONTROLVM_QUEUE_EVENT, msg)) {
/* got a message */ /* got a message */
if (msg->hdr.flags.test_message == 1) if (msg->hdr.flags.test_message == 1)
...@@ -1892,19 +1896,19 @@ controlvm_periodic_work(struct work_struct *work) ...@@ -1892,19 +1896,19 @@ controlvm_periodic_work(struct work_struct *work)
bool got_command = false; bool got_command = false;
bool handle_command_failed = false; bool handle_command_failed = false;
while (!visorchannel_signalremove(controlvm_channel, while (!visorchannel_signalremove(chipset_dev->controlvm_channel,
CONTROLVM_QUEUE_RESPONSE, CONTROLVM_QUEUE_RESPONSE,
&inmsg)) &inmsg))
; ;
if (!got_command) { if (!got_command) {
if (controlvm_pending_msg_valid) { if (chipset_dev->controlvm_pending_msg_valid) {
/* /*
* we throttled processing of a prior * we throttled processing of a prior
* msg, so try to process it again * msg, so try to process it again
* rather than reading a new one * rather than reading a new one
*/ */
inmsg = controlvm_pending_msg; inmsg = chipset_dev->controlvm_pending_msg;
controlvm_pending_msg_valid = false; chipset_dev->controlvm_pending_msg_valid = false;
got_command = true; got_command = true;
} else { } else {
got_command = read_controlvm_event(&inmsg); got_command = read_controlvm_event(&inmsg);
...@@ -1913,10 +1917,10 @@ controlvm_periodic_work(struct work_struct *work) ...@@ -1913,10 +1917,10 @@ controlvm_periodic_work(struct work_struct *work)
handle_command_failed = false; handle_command_failed = false;
while (got_command && (!handle_command_failed)) { while (got_command && (!handle_command_failed)) {
most_recent_message_jiffies = jiffies; chipset_dev->most_recent_message_jiffies = jiffies;
if (handle_command(inmsg, if (handle_command(inmsg,
visorchannel_get_physaddr visorchannel_get_physaddr
(controlvm_channel))) (chipset_dev->controlvm_channel)))
got_command = read_controlvm_event(&inmsg); got_command = read_controlvm_event(&inmsg);
else { else {
/* /*
...@@ -1927,29 +1931,34 @@ controlvm_periodic_work(struct work_struct *work) ...@@ -1927,29 +1931,34 @@ controlvm_periodic_work(struct work_struct *work)
* reprocess it on our next loop * reprocess it on our next loop
*/ */
handle_command_failed = true; handle_command_failed = true;
controlvm_pending_msg = inmsg; chipset_dev->controlvm_pending_msg = inmsg;
controlvm_pending_msg_valid = true; chipset_dev->controlvm_pending_msg_valid = true;
} }
} }
/* parahotplug_worker */ /* parahotplug_worker */
parahotplug_process_list(); parahotplug_process_list();
if (time_after(jiffies, if (time_after(jiffies, chipset_dev->most_recent_message_jiffies +
most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) { (HZ * MIN_IDLE_SECONDS))) {
/* /*
* it's been longer than MIN_IDLE_SECONDS since we * it's been longer than MIN_IDLE_SECONDS since we
* processed our last controlvm message; slow down the * processed our last controlvm message; slow down the
* polling * polling
*/ */
if (poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW) if (chipset_dev->poll_jiffies !=
poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW; POLLJIFFIES_CONTROLVMCHANNEL_SLOW)
chipset_dev->poll_jiffies =
POLLJIFFIES_CONTROLVMCHANNEL_SLOW;
} else { } else {
if (poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_FAST) if (chipset_dev->poll_jiffies !=
poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; POLLJIFFIES_CONTROLVMCHANNEL_FAST)
chipset_dev->poll_jiffies =
POLLJIFFIES_CONTROLVMCHANNEL_FAST;
} }
schedule_delayed_work(&periodic_controlvm_work, poll_jiffies); schedule_delayed_work(&chipset_dev->periodic_controlvm_work,
chipset_dev->poll_jiffies);
} }
static int static int
...@@ -1958,36 +1967,49 @@ visorchipset_init(struct acpi_device *acpi_device) ...@@ -1958,36 +1967,49 @@ visorchipset_init(struct acpi_device *acpi_device)
int err = -ENODEV; int err = -ENODEV;
u64 addr; u64 addr;
uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID;
struct visorchannel *controlvm_channel;
addr = controlvm_get_channel_address(); addr = controlvm_get_channel_address();
if (!addr) if (!addr)
goto error; goto error;
controlvm_channel = visorchannel_create_with_lock(addr, 0, chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL);
GFP_KERNEL, uuid); if (!chipset_dev)
if (!controlvm_channel)
goto error; goto error;
acpi_device->driver_data = chipset_dev;
chipset_dev->acpi_device = acpi_device;
chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
controlvm_channel = visorchannel_create_with_lock(addr,
0, GFP_KERNEL, uuid);
if (!controlvm_channel)
goto error_free_chipset_dev;
chipset_dev->controlvm_channel = controlvm_channel;
if (!SPAR_CONTROLVM_CHANNEL_OK_CLIENT( if (!SPAR_CONTROLVM_CHANNEL_OK_CLIENT(
visorchannel_get_header(controlvm_channel))) visorchannel_get_header(controlvm_channel)))
goto error_destroy_channel; goto error_destroy_channel;
major_dev = MKDEV(visorchipset_major, 0); major_dev = MKDEV(visorchipset_major, 0);
err = visorchipset_file_init(major_dev, &controlvm_channel); err = visorchipset_file_init(major_dev,
&chipset_dev->controlvm_channel);
if (err < 0) if (err < 0)
goto error_destroy_channel; goto error_destroy_channel;
/* if booting in a crash kernel */ /* if booting in a crash kernel */
if (is_kdump_kernel()) if (is_kdump_kernel())
INIT_DELAYED_WORK(&periodic_controlvm_work, INIT_DELAYED_WORK(&chipset_dev->periodic_controlvm_work,
setup_crash_devices_work_queue); setup_crash_devices_work_queue);
else else
INIT_DELAYED_WORK(&periodic_controlvm_work, INIT_DELAYED_WORK(&chipset_dev->periodic_controlvm_work,
controlvm_periodic_work); controlvm_periodic_work);
most_recent_message_jiffies = jiffies; chipset_dev->most_recent_message_jiffies = jiffies;
poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
schedule_delayed_work(&periodic_controlvm_work, poll_jiffies); schedule_delayed_work(&chipset_dev->periodic_controlvm_work,
chipset_dev->poll_jiffies);
visorchipset_platform_device.dev.devt = major_dev; visorchipset_platform_device.dev.devt = major_dev;
if (platform_device_register(&visorchipset_platform_device) < 0) { if (platform_device_register(&visorchipset_platform_device) < 0) {
...@@ -2008,11 +2030,14 @@ visorchipset_init(struct acpi_device *acpi_device) ...@@ -2008,11 +2030,14 @@ visorchipset_init(struct acpi_device *acpi_device)
platform_device_unregister(&visorchipset_platform_device); platform_device_unregister(&visorchipset_platform_device);
error_cancel_work: error_cancel_work:
cancel_delayed_work_sync(&periodic_controlvm_work); cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work);
visorchipset_file_cleanup(major_dev); visorchipset_file_cleanup(major_dev);
error_destroy_channel: error_destroy_channel:
visorchannel_destroy(controlvm_channel); visorchannel_destroy(chipset_dev->controlvm_channel);
error_free_chipset_dev:
kfree(chipset_dev);
error: error:
POSTCODE_LINUX(CHIPSET_INIT_FAILURE_PC, 0, err, DIAG_SEVERITY_ERR); POSTCODE_LINUX(CHIPSET_INIT_FAILURE_PC, 0, err, DIAG_SEVERITY_ERR);
...@@ -2026,12 +2051,14 @@ visorchipset_exit(struct acpi_device *acpi_device) ...@@ -2026,12 +2051,14 @@ visorchipset_exit(struct acpi_device *acpi_device)
visorbus_exit(); visorbus_exit();
cancel_delayed_work_sync(&periodic_controlvm_work); cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work);
visorchannel_destroy(controlvm_channel); visorchannel_destroy(chipset_dev->controlvm_channel);
visorchipset_file_cleanup(visorchipset_platform_device.dev.devt); visorchipset_file_cleanup(visorchipset_platform_device.dev.devt);
platform_device_unregister(&visorchipset_platform_device); platform_device_unregister(&visorchipset_platform_device);
kfree(chipset_dev);
POSTCODE_LINUX(DRIVER_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); POSTCODE_LINUX(DRIVER_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment