diff options
Diffstat (limited to 'drivers/staging/unisys/visorbus/visorchipset.c')
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchipset.c | 465 |
1 files changed, 139 insertions, 326 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index d7148c351d3f..97778d733e1e 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -91,18 +91,6 @@ static struct cdev file_cdev; static struct visorchannel **file_controlvm_channel; static struct visorchannel *controlvm_channel; - -/* Manages the request payload in the controlvm channel */ -struct visor_controlvm_payload_info { - u8 *ptr; /* pointer to base address of payload pool */ - u64 offset; /* - * offset from beginning of controlvm - * channel to beginning of payload * pool - */ - u32 bytes; /* number of bytes in payload pool */ -}; - -static struct visor_controlvm_payload_info controlvm_payload_info; static unsigned long controlvm_payload_bytes_buffered; /* @@ -114,60 +102,6 @@ static unsigned long controlvm_payload_bytes_buffered; static struct controlvm_message controlvm_pending_msg; static bool controlvm_pending_msg_valid; -/* - * This describes a buffer and its current state of transfer (e.g., how many - * bytes have already been supplied as putfile data, and how many bytes are - * remaining) for a putfile_request. - */ -struct putfile_active_buffer { - /* a payload from a controlvm message, containing a file data buffer */ - struct parser_context *parser_ctx; - /* points within data area of parser_ctx to next byte of data */ - size_t bytes_remaining; -}; - -#define PUTFILE_REQUEST_SIG 0x0906101302281211 -/* - * This identifies a single remote --> local CONTROLVM_TRANSMIT_FILE - * conversation. Structs of this type are dynamically linked into - * <Putfile_request_list>. - */ -struct putfile_request { - u64 sig; /* PUTFILE_REQUEST_SIG */ - - /* header from original TransmitFile request */ - struct controlvm_message_header controlvm_header; - - /* link to next struct putfile_request */ - struct list_head next_putfile_request; - - /* - * head of putfile_buffer_entry list, which describes the data to be - * supplied as putfile data; - * - this list is added to when controlvm messages come in that supply - * file data - * - this list is removed from via the hotplug program that is actually - * consuming these buffers to write as file data - */ - struct list_head input_buffer_list; - spinlock_t req_list_lock; /* lock for input_buffer_list */ - - /* waiters for input_buffer_list to go non-empty */ - wait_queue_head_t input_buffer_wq; - - /* data not yet read within current putfile_buffer_entry */ - struct putfile_active_buffer active_buf; - - /* - * <0 = failed, 0 = in-progress, >0 = successful; - * note that this must be set with req_list_lock, and if you set <0, - * it is your responsibility to also free up all of the other objects - * in this struct (like input_buffer_list, active_buf.parser_ctx) - * before releasing the lock - */ - int completion_status; -}; - struct parahotplug_request { struct list_head list; int id; @@ -188,7 +122,7 @@ static ssize_t toolaction_show(struct device *dev, visorchannel_read(controlvm_channel, offsetof(struct spar_controlvm_channel_protocol, tool_action), &tool_action, sizeof(u8)); - return scnprintf(buf, PAGE_SIZE, "%u\n", tool_action); + return sprintf(buf, "%u\n", tool_action); } static ssize_t toolaction_store(struct device *dev, @@ -223,8 +157,7 @@ static ssize_t boottotool_show(struct device *dev, offsetof(struct spar_controlvm_channel_protocol, efi_spar_ind), &efi_spar_indication, sizeof(struct efi_spar_indication)); - return scnprintf(buf, PAGE_SIZE, "%u\n", - efi_spar_indication.boot_to_tool); + return sprintf(buf, "%u\n", efi_spar_indication.boot_to_tool); } static ssize_t boottotool_store(struct device *dev, @@ -259,7 +192,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, offsetof(struct spar_controlvm_channel_protocol, installation_error), &error, sizeof(u32)); - return scnprintf(buf, PAGE_SIZE, "%i\n", error); + return sprintf(buf, "%i\n", error); } static ssize_t error_store(struct device *dev, struct device_attribute *attr, @@ -292,7 +225,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, offsetof(struct spar_controlvm_channel_protocol, installation_text_id), &text_id, sizeof(u32)); - return scnprintf(buf, PAGE_SIZE, "%i\n", text_id); + return sprintf(buf, "%i\n", text_id); } static ssize_t textid_store(struct device *dev, struct device_attribute *attr, @@ -324,7 +257,7 @@ static ssize_t remaining_steps_show(struct device *dev, offsetof(struct spar_controlvm_channel_protocol, installation_remaining_steps), &remaining_steps, sizeof(u16)); - return scnprintf(buf, PAGE_SIZE, "%hu\n", remaining_steps); + return sprintf(buf, "%hu\n", remaining_steps); } static ssize_t remaining_steps_store(struct device *dev, @@ -353,60 +286,12 @@ parser_id_get(struct parser_context *ctx) { struct spar_controlvm_parameters_header *phdr = NULL; - if (!ctx) - return NULL_UUID_LE; phdr = (struct spar_controlvm_parameters_header *)(ctx->data); return phdr->id; } -/* - * Describes the state from the perspective of which controlvm messages have - * been received for a bus or device. - */ - -enum PARSER_WHICH_STRING { - PARSERSTRING_INITIATOR, - PARSERSTRING_TARGET, - PARSERSTRING_CONNECTION, - PARSERSTRING_NAME, /* TODO: only PARSERSTRING_NAME is used ? */ -}; - -static void -parser_param_start(struct parser_context *ctx, - enum PARSER_WHICH_STRING which_string) -{ - struct spar_controlvm_parameters_header *phdr = NULL; - - if (!ctx) - return; - - phdr = (struct spar_controlvm_parameters_header *)(ctx->data); - switch (which_string) { - case PARSERSTRING_INITIATOR: - ctx->curr = ctx->data + phdr->initiator_offset; - ctx->bytes_remaining = phdr->initiator_length; - break; - case PARSERSTRING_TARGET: - ctx->curr = ctx->data + phdr->target_offset; - ctx->bytes_remaining = phdr->target_length; - break; - case PARSERSTRING_CONNECTION: - ctx->curr = ctx->data + phdr->connection_offset; - ctx->bytes_remaining = phdr->connection_length; - break; - case PARSERSTRING_NAME: - ctx->curr = ctx->data + phdr->name_offset; - ctx->bytes_remaining = phdr->name_length; - break; - default: - break; - } -} - static void parser_done(struct parser_context *ctx) { - if (!ctx) - return; controlvm_payload_bytes_buffered -= ctx->param_bytes; kfree(ctx); } @@ -420,8 +305,6 @@ parser_string_get(struct parser_context *ctx) void *value = NULL; int i; - if (!ctx) - return NULL; pscan = ctx->curr; nscan = ctx->bytes_remaining; if (nscan == 0) @@ -444,6 +327,21 @@ parser_string_get(struct parser_context *ctx) return value; } +static void * +parser_name_get(struct parser_context *ctx) +{ + struct spar_controlvm_parameters_header *phdr = NULL; + + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); + + if (phdr->name_offset + phdr->name_length > ctx->param_bytes) + return NULL; + + ctx->curr = ctx->data + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; + return parser_string_get(ctx); +} + struct visor_busdev { u32 bus_no; u32 dev_no; @@ -521,7 +419,7 @@ chipset_init(struct controlvm_message *inmsg) POSTCODE_LINUX(CHIPSET_INIT_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); if (chipset_inited) { - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + rc = -CONTROLVM_RESP_ALREADY_DONE; res = -EIO; goto out_respond; } @@ -613,27 +511,33 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) return err; } - if (typ == CRASH_BUS) { + switch (typ) { + case CRASH_DEV: + local_crash_msg_offset += sizeof(struct controlvm_message); err = visorchannel_write(controlvm_channel, local_crash_msg_offset, msg, - sizeof(struct controlvm_message)); + sizeof(struct controlvm_message)); if (err) { - POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0, + POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0, DIAG_SEVERITY_ERR); return err; } - } else { - local_crash_msg_offset += sizeof(struct controlvm_message); + break; + case CRASH_BUS: 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, + POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0, DIAG_SEVERITY_ERR); return err; } + break; + default: + pr_info("Invalid crash_obj_type\n"); + break; } return 0; } @@ -722,8 +626,11 @@ bus_create(struct controlvm_message *inmsg) 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 (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) { + err = save_crash_message(inmsg, CRASH_BUS); + if (err) + goto err_free_bus_info; + } if (inmsg->hdr.flags.response_expected == 1) { pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), @@ -857,9 +764,10 @@ bus_configure(struct controlvm_message *inmsg, 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); + if (parser_ctx) { + bus_info->partition_uuid = parser_id_get(parser_ctx); + bus_info->name = parser_name_get(parser_ctx); + } POSTCODE_LINUX(BUS_CONFIGURE_EXIT_PC, 0, bus_no, DIAG_SEVERITY_PRINT); @@ -874,7 +782,7 @@ err_respond: return err; } -static void +static int my_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; @@ -884,37 +792,37 @@ my_device_create(struct controlvm_message *inmsg) struct visor_device *dev_info = NULL; struct visor_device *bus_info; struct visorchannel *visorchannel; - int rc = CONTROLVM_RESP_SUCCESS; + int err; bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - goto out_respond; + err = -ENODEV; + goto err_respond; } if (bus_info->state.created == 0) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - goto out_respond; + err = -EINVAL; + goto err_respond; } dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (dev_info && (dev_info->state.created == 1)) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto out_respond; + err = -EEXIST; + goto err_respond; } dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); if (!dev_info) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_respond; + err = -ENOMEM; + goto err_respond; } dev_info->chipset_bus_no = bus_no; @@ -936,20 +844,23 @@ my_device_create(struct controlvm_message *inmsg) if (!visorchannel) { POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_free_dev_info; + err = -ENOMEM; + goto err_free_dev_info; } dev_info->visorchannel = visorchannel; dev_info->channel_type_guid = cmd->create_device.data_type_uuid; if (uuid_le_cmp(cmd->create_device.data_type_uuid, - spar_vhba_channel_protocol_uuid) == 0) - save_crash_message(inmsg, CRASH_DEV); + spar_vhba_channel_protocol_uuid) == 0) { + err = save_crash_message(inmsg, CRASH_DEV); + if (err) + goto err_free_dev_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; + err = -ENOMEM; + goto err_free_dev_info; } memcpy(pmsg_hdr, &inmsg->hdr, @@ -960,17 +871,18 @@ my_device_create(struct controlvm_message *inmsg) chipset_device_create(dev_info); POSTCODE_LINUX(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, DIAG_SEVERITY_PRINT); - return; + return 0; -out_free_dev_info: +err_free_dev_info: kfree(dev_info); -out_respond: +err_respond: if (inmsg->hdr.flags.response_expected == 1) - device_responder(inmsg->hdr.id, &inmsg->hdr, rc); + device_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int my_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; @@ -979,30 +891,30 @@ my_device_changestate(struct controlvm_message *inmsg) u32 dev_no = cmd->device_change_state.dev_no; struct spar_segment_state state = cmd->device_change_state.state; struct visor_device *dev_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err; dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, DIAG_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; + err = -ENODEV; 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; + err = -EINVAL; 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; + err = -EIO; 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; + err = -ENOMEM; goto err_respond; } @@ -1023,15 +935,15 @@ my_device_changestate(struct controlvm_message *inmsg) * Response will be sent from chipset_device_pause. */ chipset_device_pause(dev_info); - - return; + return 0; err_respond: if (inmsg->hdr.flags.response_expected == 1) - device_responder(inmsg->hdr.id, &inmsg->hdr, rc); + device_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int my_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; @@ -1039,27 +951,27 @@ my_device_destroy(struct controlvm_message *inmsg) 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; + int err; dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { - rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; + err = -ENODEV; goto err_respond; } if (dev_info->state.created == 0) { - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + err = -EINVAL; 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; + err = -EIO; 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; + err = -ENOMEM; goto err_respond; } @@ -1069,107 +981,33 @@ my_device_destroy(struct controlvm_message *inmsg) } chipset_device_destroy(dev_info); - return; + return 0; err_respond: if (inmsg->hdr.flags.response_expected == 1) - device_responder(inmsg->hdr.id, &inmsg->hdr, rc); -} - -/** - * initialize_controlvm_payload_info() - init controlvm_payload_info struct - * @phys_addr: the physical address of controlvm channel - * @offset: the offset to payload - * @bytes: the size of the payload in bytes - * @info: the returning valid struct - * - * When provided with the physical address of the controlvm channel - * (phys_addr), the offset to the payload area we need to manage - * (offset), and the size of this payload area (bytes), fills in the - * controlvm_payload_info struct. - * - * Return: CONTROLVM_RESP_SUCCESS for success or a negative for failure - */ -static int -initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, - struct visor_controlvm_payload_info *info) -{ - u8 *payload = NULL; - - if (!info) - return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - - if ((offset == 0) || (bytes == 0)) - return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - - payload = memremap(phys_addr + offset, bytes, MEMREMAP_WB); - 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; - - return CONTROLVM_RESP_SUCCESS; -} - -static void -destroy_controlvm_payload_info(struct visor_controlvm_payload_info *info) -{ - if (info->ptr) { - memunmap(info->ptr); - info->ptr = NULL; - } - memset(info, 0, sizeof(struct visor_controlvm_payload_info)); -} - -static void -initialize_controlvm_payload(void) -{ - u64 phys_addr = visorchannel_get_physaddr(controlvm_channel); - u64 payload_offset = 0; - u32 payload_bytes = 0; - - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - request_payload_offset), - &payload_offset, sizeof(payload_offset)) < 0) { - 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(CONTROLVM_INIT_FAILURE_PC, 0, 0, - DIAG_SEVERITY_ERR); - return; - } - initialize_controlvm_payload_info(phys_addr, - payload_offset, payload_bytes, - &controlvm_payload_info); + device_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } /* - * The general parahotplug flow works as follows. The visorchipset - * driver receives a DEVICE_CHANGESTATE message from Command - * specifying a physical device to enable or disable. The CONTROLVM - * message handler calls parahotplug_process_message, which then adds - * the message to a global list and kicks off a udev event which - * causes a user level script to enable or disable the specified - * device. The udev script then writes to - * /proc/visorchipset/parahotplug, which causes parahotplug_proc_write - * to get called, at which point the appropriate CONTROLVM message is - * retrieved from the list and responded to. + * The general parahotplug flow works as follows. The visorchipset receives + * a DEVICE_CHANGESTATE message from Command specifying a physical device + * to enable or disable. The CONTROLVM message handler calls + * parahotplug_process_message, which then adds the message to a global list + * and kicks off a udev event which causes a user level script to enable or + * disable the specified device. The udev script then writes to + * /sys/devices/platform/visorchipset/parahotplug, which causes the + * parahotplug store functions to get called, at which point the + * appropriate CONTROLVM message is retrieved from the list and responded + * to. */ #define PARAHOTPLUG_TIMEOUT_MS 2000 /** - * parahotplug_next_id() - generate unique int to match an outstanding CONTROLVM - * message with a udev script /proc response + * parahotplug_next_id() - generate unique int to match an outstanding + * CONTROLVM message with a udev script /sys + * response * * Return: a unique integer value */ @@ -1236,7 +1074,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ * @id: the id of the request * @active: indicates whether the request is assigned to active partition * - * Called from the /proc handler, which means the user script has + * Called from the /sys handler, which means the user script has * finished the enable/disable. Find the matching identifier, and * respond to the CONTROLVM message with success. * @@ -1433,7 +1271,7 @@ parahotplug_process_message(struct controlvm_message *inmsg) * * devices are automatically enabled at * initialization. - */ + */ parahotplug_request_kickoff(req); controlvm_respond_physdev_changestate (&inmsg->hdr, @@ -1455,22 +1293,33 @@ parahotplug_process_message(struct controlvm_message *inmsg) } } -/** - * visorchipset_chipset_ready() - sends chipset_ready action +/* + * chipset_ready_uevent() - sends chipset_ready action * * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. * - * Return: CONTROLVM_RESP_SUCCESS + * Return: 0 on success, negative on failure */ static int -visorchipset_chipset_ready(void) +chipset_ready_uevent(struct controlvm_message_header *msg_hdr) { kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_ONLINE); - return CONTROLVM_RESP_SUCCESS; + + if (msg_hdr->flags.response_expected) + return controlvm_respond(msg_hdr, CONTROLVM_RESP_SUCCESS); + + return 0; } +/* + * chipset_selftest_uevent() - sends chipset_selftest action + * + * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. + * + * Return: 0 on success, negative on failure + */ static int -visorchipset_chipset_selftest(void) +chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) { char env_selftest[20]; char *envp[] = { env_selftest, NULL }; @@ -1478,54 +1327,29 @@ visorchipset_chipset_selftest(void) sprintf(env_selftest, "SPARSP_SELFTEST=%d", 1); kobject_uevent_env(&visorchipset_platform_device.dev.kobj, KOBJ_CHANGE, envp); - return CONTROLVM_RESP_SUCCESS; + + if (msg_hdr->flags.response_expected) + return controlvm_respond(msg_hdr, CONTROLVM_RESP_SUCCESS); + + return 0; } -/** - * visorchipset_chipset_notready() - sends chipset_notready action +/* + * chipset_notready_uevent() - sends chipset_notready action * * Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset. * - * Return: CONTROLVM_RESP_SUCCESS + * Return: 0 on success, negative on failure */ static int -visorchipset_chipset_notready(void) +chipset_notready_uevent(struct controlvm_message_header *msg_hdr) { kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_OFFLINE); - return CONTROLVM_RESP_SUCCESS; -} - -static void -chipset_ready(struct controlvm_message_header *msg_hdr) -{ - int rc = visorchipset_chipset_ready(); - if (rc != CONTROLVM_RESP_SUCCESS) - rc = -rc; if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, rc); -} - -static void -chipset_selftest(struct controlvm_message_header *msg_hdr) -{ - int rc = visorchipset_chipset_selftest(); + return controlvm_respond(msg_hdr, CONTROLVM_RESP_SUCCESS); - if (rc != CONTROLVM_RESP_SUCCESS) - rc = -rc; - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, rc); -} - -static void -chipset_notready(struct controlvm_message_header *msg_hdr) -{ - int rc = visorchipset_chipset_notready(); - - if (rc != CONTROLVM_RESP_SUCCESS) - rc = -rc; - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, rc); + return 0; } static inline unsigned int @@ -1846,8 +1670,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) int allocbytes = sizeof(struct parser_context) + bytes; struct parser_context *ctx; - if (retry) - *retry = false; + *retry = false; /* * alloc an 0 extra byte to ensure payload is @@ -1856,14 +1679,12 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) allocbytes++; if ((controlvm_payload_bytes_buffered + bytes) > MAX_CONTROLVM_PAYLOAD_BYTES) { - if (retry) - *retry = true; + *retry = true; return NULL; } ctx = kzalloc(allocbytes, GFP_KERNEL | __GFP_NORETRY); if (!ctx) { - if (retry) - *retry = true; + *retry = true; return NULL; } @@ -1990,19 +1811,18 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); break; case CONTROLVM_CHIPSET_READY: - chipset_ready(&inmsg.hdr); + chipset_ready_uevent(&inmsg.hdr); break; case CONTROLVM_CHIPSET_SELFTEST: - chipset_selftest(&inmsg.hdr); + chipset_selftest_uevent(&inmsg.hdr); break; case CONTROLVM_CHIPSET_STOP: - chipset_notready(&inmsg.hdr); + chipset_notready_uevent(&inmsg.hdr); break; default: if (inmsg.hdr.flags.response_expected) controlvm_respond - (&inmsg.hdr, - -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN); + (&inmsg.hdr, -CONTROLVM_RESP_ID_UNKNOWN); break; } @@ -2057,7 +1877,7 @@ parahotplug_process_list(void) if (req->msg.hdr.flags.response_expected) controlvm_respond_physdev_changestate( &req->msg.hdr, - CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT, + CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT, req->msg.cmd.device_change_state.state); parahotplug_request_destroy(req); } @@ -2148,17 +1968,14 @@ visorchipset_init(struct acpi_device *acpi_device) if (!controlvm_channel) goto error; - if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( - visorchannel_get_header(controlvm_channel))) { - initialize_controlvm_payload(); - } else { + if (!SPAR_CONTROLVM_CHANNEL_OK_CLIENT( + visorchannel_get_header(controlvm_channel))) goto error_destroy_channel; - } major_dev = MKDEV(visorchipset_major, 0); err = visorchipset_file_init(major_dev, &controlvm_channel); if (err < 0) - goto error_destroy_payload; + goto error_destroy_channel; /* if booting in a crash kernel */ if (is_kdump_kernel()) @@ -2194,9 +2011,6 @@ error_cancel_work: cancel_delayed_work_sync(&periodic_controlvm_work); visorchipset_file_cleanup(major_dev); -error_destroy_payload: - destroy_controlvm_payload_info(&controlvm_payload_info); - error_destroy_channel: visorchannel_destroy(controlvm_channel); @@ -2213,7 +2027,6 @@ visorchipset_exit(struct acpi_device *acpi_device) visorbus_exit(); cancel_delayed_work_sync(&periodic_controlvm_work); - destroy_controlvm_payload_info(&controlvm_payload_info); visorchannel_destroy(controlvm_channel); @@ -2277,7 +2090,7 @@ static void exit_unisys(void) acpi_bus_unregister_driver(&unisys_acpi_driver); } -module_param_named(major, visorchipset_major, int, S_IRUGO); +module_param_named(major, visorchipset_major, int, 0444); MODULE_PARM_DESC(visorchipset_major, "major device number to use for the device node"); |