diff options
Diffstat (limited to 'drivers/staging/unisys/visorbus/visorchipset.c')
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchipset.c | 653 |
1 files changed, 338 insertions, 315 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 59871495ea85..d7148c351d3f 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -29,7 +29,7 @@ #include "visorbus_private.h" #include "vmcallinterface.h" -#define CURRENT_FILE_PC VISOR_CHIPSET_PC_visorchipset_main_c +#define CURRENT_FILE_PC VISOR_BUS_PC_visorchipset_c #define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1 #define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100 @@ -57,7 +57,6 @@ visorchipset_open(struct inode *inode, struct file *file) if (minor_number) return -ENODEV; - file->private_data = NULL; return 0; } @@ -499,7 +498,7 @@ controlvm_init_response(struct controlvm_message *msg, } } -static void +static int controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, int response, enum ultra_chipset_feature features) @@ -508,34 +507,33 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, controlvm_init_response(&outmsg, msg_hdr, response); outmsg.cmd.init_chipset.features = features; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - return; - } + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } -static void +static int chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; enum ultra_chipset_feature features = 0; int rc = CONTROLVM_RESP_SUCCESS; + int res = 0; - POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); if (chipset_inited) { rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + res = -EIO; goto out_respond; } chipset_inited = 1; - POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); /* * Set features to indicate we support parahotplug (if Command * also supports it). */ - features = - inmsg->cmd.init_chipset. - features & ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG; + features = inmsg->cmd.init_chipset.features & + ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG; /* * Set the "reply" bit so Command knows this is a @@ -545,25 +543,25 @@ chipset_init(struct controlvm_message *inmsg) out_respond: if (inmsg->hdr.flags.response_expected) - controlvm_respond_chipset_init(&inmsg->hdr, rc, features); + res = controlvm_respond_chipset_init(&inmsg->hdr, rc, features); + + return res; } -static void +static int controlvm_respond(struct controlvm_message_header *msg_hdr, int response) { struct controlvm_message outmsg; controlvm_init_response(&outmsg, msg_hdr, response); if (outmsg.hdr.flags.test_message == 1) - return; + return -EINVAL; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - return; - } + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } -static void controlvm_respond_physdev_changestate( +static int controlvm_respond_physdev_changestate( struct controlvm_message_header *msg_hdr, int response, struct spar_segment_state state) { @@ -572,10 +570,8 @@ static void controlvm_respond_physdev_changestate( controlvm_init_response(&outmsg, msg_hdr, response); outmsg.cmd.device_change_state.state = state; outmsg.cmd.device_change_state.flags.phys_device = 1; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - return; - } + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } enum crash_obj_type { @@ -583,74 +579,80 @@ enum crash_obj_type { CRASH_BUS, }; -static void +static int save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) { u32 local_crash_msg_offset; u16 local_crash_msg_count; + int err; - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - saved_crash_message_count), - &local_crash_msg_count, sizeof(u16)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_read(controlvm_channel, + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_count), + &local_crash_msg_count, sizeof(u16)); + if (err) { + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } if (local_crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, - local_crash_msg_count, - POSTCODE_SEVERITY_ERR); - return; + POSTCODE_LINUX(CRASH_DEV_COUNT_FAILURE_PC, 0, + local_crash_msg_count, + DIAG_SEVERITY_ERR); + return -EIO; } - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - saved_crash_message_offset), - &local_crash_msg_offset, sizeof(u32)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_read(controlvm_channel, + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_offset), + &local_crash_msg_offset, sizeof(u32)); + if (err) { + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } if (typ == CRASH_BUS) { - if (visorchannel_write(controlvm_channel, - local_crash_msg_offset, - msg, - sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_write(controlvm_channel, + local_crash_msg_offset, + msg, + sizeof(struct controlvm_message)); + if (err) { + POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } } else { local_crash_msg_offset += sizeof(struct controlvm_message); - if (visorchannel_write(controlvm_channel, - local_crash_msg_offset, - msg, - sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_write(controlvm_channel, + local_crash_msg_offset, + msg, + sizeof(struct controlvm_message)); + if (err) { + POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } } + return 0; } -static void +static int bus_responder(enum controlvm_id cmd_id, struct controlvm_message_header *pending_msg_hdr, int response) { if (!pending_msg_hdr) - return; /* no controlvm response needed */ + return -EIO; if (pending_msg_hdr->id != (u32)cmd_id) - return; + return -EINVAL; - controlvm_respond(pending_msg_hdr, response); + return controlvm_respond(pending_msg_hdr, response); } -static void +static int device_changestate_responder(enum controlvm_id cmd_id, struct visor_device *p, int response, struct spar_segment_state response_state) @@ -660,9 +662,9 @@ device_changestate_responder(enum controlvm_id cmd_id, u32 dev_no = p->chipset_dev_no; if (!p->pending_msg_hdr) - return; /* no controlvm response needed */ + return -EIO; if (p->pending_msg_hdr->id != cmd_id) - return; + return -EINVAL; controlvm_init_response(&outmsg, p->pending_msg_hdr, response); @@ -670,175 +672,74 @@ device_changestate_responder(enum controlvm_id cmd_id, outmsg.cmd.device_change_state.dev_no = dev_no; outmsg.cmd.device_change_state.state = response_state; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) - return; + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } -static void +static int device_responder(enum controlvm_id cmd_id, struct controlvm_message_header *pending_msg_hdr, int response) { if (!pending_msg_hdr) - return; /* no controlvm response needed */ + return -EIO; if (pending_msg_hdr->id != (u32)cmd_id) - return; - - controlvm_respond(pending_msg_hdr, response); -} - -static void -bus_epilog(struct visor_device *bus_info, - u32 cmd, struct controlvm_message_header *msg_hdr, - int response, bool need_response) -{ - struct controlvm_message_header *pmsg_hdr = NULL; - - if (!bus_info) { - /* - * relying on a valid passed in response code - * be lazy and re-use msg_hdr for this failure, is this ok?? - */ - pmsg_hdr = msg_hdr; - goto out_respond; - } - - if (bus_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; - pmsg_hdr = bus_info->pending_msg_hdr; - goto out_respond; - } - - if (need_response) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - POSTCODE_LINUX_4(MALLOC_FAILURE_PC, cmd, - bus_info->chipset_bus_no, - POSTCODE_SEVERITY_ERR); - return; - } - - memcpy(pmsg_hdr, msg_hdr, - sizeof(struct controlvm_message_header)); - bus_info->pending_msg_hdr = pmsg_hdr; - } - - if (response == CONTROLVM_RESP_SUCCESS) { - switch (cmd) { - case CONTROLVM_BUS_CREATE: - chipset_bus_create(bus_info); - break; - case CONTROLVM_BUS_DESTROY: - chipset_bus_destroy(bus_info); - break; - } - } - -out_respond: - bus_responder(cmd, pmsg_hdr, response); -} - -static void -device_epilog(struct visor_device *dev_info, - struct spar_segment_state state, u32 cmd, - struct controlvm_message_header *msg_hdr, int response, - bool need_response, bool for_visorbus) -{ - struct controlvm_message_header *pmsg_hdr = NULL; - - if (!dev_info) { - /* - * relying on a valid passed in response code - * be lazy and re-use msg_hdr for this failure, is this ok?? - */ - pmsg_hdr = msg_hdr; - goto out_respond; - } - - if (dev_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; - pmsg_hdr = dev_info->pending_msg_hdr; - goto out_respond; - } - - if (need_response) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - response = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_respond; - } - - memcpy(pmsg_hdr, msg_hdr, - sizeof(struct controlvm_message_header)); - dev_info->pending_msg_hdr = pmsg_hdr; - } - - if (response >= 0) { - switch (cmd) { - case CONTROLVM_DEVICE_CREATE: - chipset_device_create(dev_info); - break; - case CONTROLVM_DEVICE_CHANGESTATE: - /* ServerReady / ServerRunning / SegmentStateRunning */ - if (state.alive == segment_state_running.alive && - state.operating == - segment_state_running.operating) { - 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 - */ - chipset_device_pause(dev_info); - } - break; - case CONTROLVM_DEVICE_DESTROY: - chipset_device_destroy(dev_info); - break; - } - } + return -EINVAL; -out_respond: - device_responder(cmd, pmsg_hdr, response); + return controlvm_respond(pending_msg_hdr, response); } -static void +static int bus_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->create_bus.bus_no; - int rc = CONTROLVM_RESP_SUCCESS; struct visor_device *bus_info; struct visorchannel *visorchannel; + int err; bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (bus_info && (bus_info->state.created == 1)) { - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto out_bus_epilog; + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EEXIST; + goto err_respond; } + bus_info = kzalloc(sizeof(*bus_info), GFP_KERNEL); if (!bus_info) { - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_bus_epilog; + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_respond; } INIT_LIST_HEAD(&bus_info->list_all); bus_info->chipset_bus_no = bus_no; bus_info->chipset_dev_no = BUS_ROOT_DEVICE; - POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, bus_no, DIAG_SEVERITY_PRINT); + + if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) + save_crash_message(inmsg, CRASH_BUS); + + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), + GFP_KERNEL); + if (!pmsg_hdr) { + POSTCODE_LINUX(MALLOC_FAILURE_PC, cmd, + bus_info->chipset_bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_free_bus_info; + } + + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + bus_info->pending_msg_hdr = pmsg_hdr; + } visorchannel = visorchannel_create(cmd->create_bus.channel_addr, cmd->create_bus.channel_bytes, @@ -846,89 +747,138 @@ bus_create(struct controlvm_message *inmsg) cmd->create_bus.bus_data_type_uuid); if (!visorchannel) { - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - kfree(bus_info); - bus_info = NULL; - goto out_bus_epilog; + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_free_pending_msg; } bus_info->visorchannel = visorchannel; - if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) - save_crash_message(inmsg, CRASH_BUS); - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); + /* Response will be handled by chipset_bus_create */ + chipset_bus_create(bus_info); + + POSTCODE_LINUX(BUS_CREATE_EXIT_PC, 0, bus_no, DIAG_SEVERITY_PRINT); + return 0; + +err_free_pending_msg: + kfree(bus_info->pending_msg_hdr); + +err_free_bus_info: + kfree(bus_info); -out_bus_epilog: - bus_epilog(bus_info, CONTROLVM_BUS_CREATE, &inmsg->hdr, - rc, inmsg->hdr.flags.response_expected == 1); +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int bus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->destroy_bus.bus_no; struct visor_device *bus_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err; bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (!bus_info) - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - else if (bus_info->state.created == 0) - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + if (!bus_info) { + err = -ENODEV; + goto err_respond; + } + if (bus_info->state.created == 0) { + err = -ENOENT; + goto err_respond; + } + if (bus_info->pending_msg_hdr) { + /* only non-NULL if dev is still waiting on a response */ + err = -EEXIST; + goto err_respond; + } + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + POSTCODE_LINUX(MALLOC_FAILURE_PC, cmd, + bus_info->chipset_bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_respond; + } - bus_epilog(bus_info, CONTROLVM_BUS_DESTROY, &inmsg->hdr, - rc, inmsg->hdr.flags.response_expected == 1); + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + bus_info->pending_msg_hdr = pmsg_hdr; + } - /* bus_info is freed as part of the busdevice_release function */ + /* Response will be handled by chipset_bus_destroy */ + chipset_bus_destroy(bus_info); + return 0; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int bus_configure(struct controlvm_message *inmsg, struct parser_context *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no; struct visor_device *bus_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err = 0; bus_no = cmd->configure_bus.bus_no; - POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CONFIGURE_ENTRY_PC, 0, bus_no, + DIAG_SEVERITY_PRINT); bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { - POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; + POSTCODE_LINUX(BUS_CONFIGURE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EINVAL; + goto err_respond; } else if (bus_info->state.created == 0) { - POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; + POSTCODE_LINUX(BUS_CONFIGURE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EINVAL; + goto err_respond; } else if (bus_info->pending_msg_hdr) { - POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; - } else { - visorchannel_set_clientpartition - (bus_info->visorchannel, - cmd->configure_bus.guest_handle); - bus_info->partition_uuid = parser_id_get(parser_ctx); - parser_param_start(parser_ctx, PARSERSTRING_NAME); - bus_info->name = parser_string_get(parser_ctx); - - POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CONFIGURE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EIO; + goto err_respond; } - bus_epilog(bus_info, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, - rc, inmsg->hdr.flags.response_expected == 1); + + err = visorchannel_set_clientpartition + (bus_info->visorchannel, + cmd->configure_bus.guest_handle); + if (err) + goto err_respond; + + bus_info->partition_uuid = parser_id_get(parser_ctx); + parser_param_start(parser_ctx, PARSERSTRING_NAME); + bus_info->name = parser_string_get(parser_ctx); + + POSTCODE_LINUX(BUS_CONFIGURE_EXIT_PC, 0, bus_no, + DIAG_SEVERITY_PRINT); + + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return 0; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } static void my_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->create_device.bus_no; u32 dev_no = cmd->create_device.dev_no; struct visor_device *dev_info = NULL; @@ -938,31 +888,31 @@ my_device_create(struct controlvm_message *inmsg) bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto out_respond; } if (bus_info->state.created == 0) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto out_respond; } dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (dev_info && (dev_info->state.created == 1)) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto out_respond; } dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); if (!dev_info) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; goto out_respond; } @@ -974,8 +924,8 @@ my_device_create(struct controlvm_message *inmsg) /* not sure where the best place to set the 'parent' */ dev_info->device.parent = &bus_info->device; - POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, + DIAG_SEVERITY_PRINT); visorchannel = visorchannel_create_with_lock(cmd->create_device.channel_addr, @@ -984,12 +934,10 @@ my_device_create(struct controlvm_message *inmsg) cmd->create_device.data_type_uuid); if (!visorchannel) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - kfree(dev_info); - dev_info = NULL; - goto out_respond; + goto out_free_dev_info; } dev_info->visorchannel = visorchannel; dev_info->channel_type_guid = cmd->create_device.data_type_uuid; @@ -997,18 +945,36 @@ my_device_create(struct controlvm_message *inmsg) spar_vhba_channel_protocol_uuid) == 0) save_crash_message(inmsg, CRASH_DEV); - POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); + 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 out_free_dev_info; + } + + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + dev_info->pending_msg_hdr = pmsg_hdr; + } + /* Chipset_device_create will send response */ + chipset_device_create(dev_info); + POSTCODE_LINUX(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, + DIAG_SEVERITY_PRINT); + return; + +out_free_dev_info: + kfree(dev_info); + out_respond: - device_epilog(dev_info, segment_state_running, - CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, - inmsg->hdr.flags.response_expected == 1, 1); + if (inmsg->hdr.flags.response_expected == 1) + device_responder(inmsg->hdr.id, &inmsg->hdr, rc); } 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; @@ -1017,39 +983,97 @@ my_device_changestate(struct controlvm_message *inmsg) dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { - POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; - } else if (dev_info->state.created == 0) { - POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + goto err_respond; + } + if (dev_info->state.created == 0) { + POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); 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 ((rc >= CONTROLVM_RESP_SUCCESS) && dev_info) - device_epilog(dev_info, state, - CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc, - inmsg->hdr.flags.response_expected == 1, 1); + 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); + + return; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + device_responder(inmsg->hdr.id, &inmsg->hdr, rc); } static void my_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->destroy_device.bus_no; u32 dev_no = cmd->destroy_device.dev_no; struct visor_device *dev_info; int rc = CONTROLVM_RESP_SUCCESS; dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); - if (!dev_info) + if (!dev_info) { rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; - else if (dev_info->state.created == 0) + goto err_respond; + } + if (dev_info->state.created == 0) { rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + goto err_respond; + } - if ((rc >= CONTROLVM_RESP_SUCCESS) && dev_info) - device_epilog(dev_info, segment_state_running, - CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, - inmsg->hdr.flags.response_expected == 1, 1); + 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; + } + + chipset_device_destroy(dev_info); + return; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + device_responder(inmsg->hdr.id, &inmsg->hdr, rc); } /** @@ -1075,7 +1099,6 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, if (!info) return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - memset(info, 0, sizeof(struct visor_controlvm_payload_info)); if ((offset == 0) || (bytes == 0)) return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; @@ -1083,6 +1106,7 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, if (!payload) return -CONTROLVM_RESP_ERROR_IOREMAP_FAILED; + memset(info, 0, sizeof(struct visor_controlvm_payload_info)); info->offset = offset; info->bytes = bytes; info->ptr = payload; @@ -1111,16 +1135,16 @@ initialize_controlvm_payload(void) offsetof(struct spar_controlvm_channel_protocol, request_payload_offset), &payload_offset, sizeof(payload_offset)) < 0) { - POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CONTROLVM_INIT_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } if (visorchannel_read(controlvm_channel, offsetof(struct spar_controlvm_channel_protocol, request_payload_bytes), &payload_bytes, sizeof(payload_bytes)) < 0) { - POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CONTROLVM_INIT_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } initialize_controlvm_payload_info(phys_addr, @@ -1317,7 +1341,7 @@ static struct attribute *visorchipset_install_attrs[] = { NULL }; -static struct attribute_group visorchipset_install_group = { +static const struct attribute_group visorchipset_install_group = { .name = "install", .attrs = visorchipset_install_attrs }; @@ -1540,7 +1564,7 @@ setup_crash_devices_work_queue(struct work_struct *work) u32 local_crash_msg_offset; u16 local_crash_msg_count; - POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CRASH_DEV_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); /* send init chipset msg */ msg.hdr.id = CONTROLVM_CHIPSET_INIT; @@ -1554,15 +1578,15 @@ setup_crash_devices_work_queue(struct work_struct *work) offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_count), &local_crash_msg_count, sizeof(u16)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } if (local_crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, - local_crash_msg_count, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_COUNT_FAILURE_PC, 0, + local_crash_msg_count, + DIAG_SEVERITY_ERR); return; } @@ -1571,8 +1595,8 @@ setup_crash_devices_work_queue(struct work_struct *work) offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_offset), &local_crash_msg_offset, sizeof(u32)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1581,8 +1605,8 @@ setup_crash_devices_work_queue(struct work_struct *work) local_crash_msg_offset, &local_crash_bus_msg, sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_RD_BUS_FAIULRE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_RD_BUS_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1592,8 +1616,8 @@ setup_crash_devices_work_queue(struct work_struct *work) sizeof(struct controlvm_message), &local_crash_dev_msg, sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_RD_DEV_FAIULRE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_RD_DEV_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1601,8 +1625,8 @@ setup_crash_devices_work_queue(struct work_struct *work) if (local_crash_bus_msg.cmd.create_bus.channel_addr) { bus_create(&local_crash_bus_msg); } else { - POSTCODE_LINUX_2(CRASH_DEV_BUS_NULL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_BUS_NULL_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1610,11 +1634,11 @@ setup_crash_devices_work_queue(struct work_struct *work) if (local_crash_dev_msg.cmd.create_device.channel_addr) { my_device_create(&local_crash_dev_msg); } else { - POSTCODE_LINUX_2(CRASH_DEV_DEV_NULL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_DEV_NULL_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } - POSTCODE_LINUX_2(CRASH_DEV_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CRASH_DEV_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); } void @@ -2119,8 +2143,6 @@ visorchipset_init(struct acpi_device *acpi_device) if (!addr) goto error; - memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info)); - controlvm_channel = visorchannel_create_with_lock(addr, 0, GFP_KERNEL, uuid); if (!controlvm_channel) @@ -2152,11 +2174,12 @@ visorchipset_init(struct acpi_device *acpi_device) visorchipset_platform_device.dev.devt = major_dev; if (platform_device_register(&visorchipset_platform_device) < 0) { - POSTCODE_LINUX_2(DEVICE_REGISTER_FAILURE_PC, DIAG_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_REGISTER_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); err = -ENODEV; goto error_cancel_work; } - POSTCODE_LINUX_2(CHIPSET_INIT_SUCCESS_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_SUCCESS_PC, 0, 0, DIAG_SEVERITY_PRINT); err = visorbus_init(); if (err < 0) @@ -2178,14 +2201,14 @@ error_destroy_channel: visorchannel_destroy(controlvm_channel); error: - POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, err, POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CHIPSET_INIT_FAILURE_PC, 0, err, DIAG_SEVERITY_ERR); return err; } static int visorchipset_exit(struct acpi_device *acpi_device) { - POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DRIVER_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); visorbus_exit(); @@ -2196,7 +2219,7 @@ visorchipset_exit(struct acpi_device *acpi_device) visorchipset_file_cleanup(visorchipset_platform_device.dev.devt); platform_device_unregister(&visorchipset_platform_device); - POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DRIVER_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); return 0; } |