From 1ccb7b6249f9bc50678e2a383084ed0a34cc9239 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 14 Mar 2012 14:39:42 +0200 Subject: [PATCH] staging/mei: propagate error codes up in the write flow Change mei_write_message's return type from bool to int to enable propagation of the error code up to caller functions. The function now returns -EIO when low level write fails and 0 on success. A similar change is done in intermediate caller functions: mei_send_flow_control, mei_connect, and mei_disconnect This makes code more alike to typical Linux kernel error handling. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/init.c | 16 ++++---- drivers/staging/mei/interface.c | 39 ++++++++----------- drivers/staging/mei/interrupt.c | 68 ++++++++++++++++----------------- drivers/staging/mei/iorw.c | 10 ++--- drivers/staging/mei/main.c | 2 +- drivers/staging/mei/wd.c | 6 +-- 6 files changed, 61 insertions(+), 80 deletions(-) diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c index e24b6ad3d5fb..eab711fb5fc4 100644 --- a/drivers/staging/mei/init.c +++ b/drivers/staging/mei/init.c @@ -366,7 +366,7 @@ void mei_host_start_message(struct mei_device *dev) host_start_req->host_version.major_version = HBM_MAJOR_VERSION; host_start_req->host_version.minor_version = HBM_MINOR_VERSION; dev->recvd_msg = false; - if (!mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, + if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, mei_hdr->length)) { dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); dev->mei_state = MEI_RESETING; @@ -399,7 +399,7 @@ void mei_host_enum_clients_message(struct mei_device *dev) host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request)); host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; - if (!mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req, + if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req, mei_hdr->length)) { dev->mei_state = MEI_RESETING; dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); @@ -407,7 +407,7 @@ void mei_host_enum_clients_message(struct mei_device *dev) } dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - return ; + return; } @@ -485,7 +485,7 @@ int mei_host_client_properties(struct mei_device *dev) host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; host_cli_req->address = b; - if (!mei_write_message(dev, mei_header, + if (mei_write_message(dev, mei_header, (unsigned char *)host_cli_req, mei_header->length)) { dev->mei_state = MEI_RESETING; @@ -608,7 +608,7 @@ void mei_host_init_iamthif(struct mei_device *dev) dev->iamthif_msg_buf = msg_buf; - if (!mei_connect(dev, &dev->iamthif_cl)) { + if (mei_connect(dev, &dev->iamthif_cl)) { dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; dev->iamthif_cl.host_client_id = 0; @@ -670,14 +670,12 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; if (mei_disconnect(dev, cl)) { - mdelay(10); /* Wait for hardware disconnection ready */ - list_add_tail(&cb->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); - } else { rets = -ENODEV; dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n"); goto free; } + mdelay(10); /* Wait for hardware disconnection ready */ + list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); } else { dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); list_add_tail(&cb->cb_list, diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c index 8a80e80cd7df..9a2cfafc52a6 100644 --- a/drivers/staging/mei/interface.c +++ b/drivers/staging/mei/interface.c @@ -125,7 +125,7 @@ int mei_count_empty_write_slots(struct mei_device *dev) * @write_buffer: message buffer will be written * @write_length: message size will be written * - * returns 1 if success, 0 - otherwise. + * This function returns -EIO if write has failed */ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, @@ -157,7 +157,7 @@ int mei_write_message(struct mei_device *dev, dw_to_write = ((write_length + 3) / 4); if (dw_to_write > empty_slots) - return 0; + return -EIO; mei_reg_write(dev, H_CB_WW, *((u32 *) header)); @@ -177,9 +177,9 @@ int mei_write_message(struct mei_device *dev, mei_hcsr_set(dev); dev->me_hw_state = mei_mecsr_read(dev); if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) - return 0; + return -EIO; - return 1; + return 0; } /** @@ -308,7 +308,7 @@ int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) * @dev: the device structure * @cl: private data of the file object * - * returns 1 if success, 0 - otherwise. + * This function returns -EIO on write failure */ int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) { @@ -330,14 +330,11 @@ int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) memset(mei_flow_control->reserved, 0, sizeof(mei_flow_control->reserved)); dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - if (!mei_write_message(dev, mei_hdr, - (unsigned char *) mei_flow_control, - sizeof(struct hbm_flow_control))) - return 0; - - return 1; + cl->host_client_id, cl->me_client_id); + return mei_write_message(dev, mei_hdr, + (unsigned char *) mei_flow_control, + sizeof(struct hbm_flow_control)); } /** @@ -371,7 +368,7 @@ int mei_other_client_is_connecting(struct mei_device *dev, * @dev: the device structure * @cl: private data of the file object * - * returns 1 if success, 0 - otherwise. + * This function returns -EIO on write failure */ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) { @@ -393,12 +390,9 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) mei_cli_disconnect->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; mei_cli_disconnect->reserved[0] = 0; - if (!mei_write_message(dev, mei_hdr, + return mei_write_message(dev, mei_hdr, (unsigned char *) mei_cli_disconnect, - sizeof(struct hbm_client_disconnect_request))) - return 0; - - return 1; + sizeof(struct hbm_client_disconnect_request)); } /** @@ -407,7 +401,7 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) * @dev: the device structure * @cl: private data of the file object * - * returns 1 if success, 0 - otherwise. + * This function returns -EIO on write failure */ int mei_connect(struct mei_device *dev, struct mei_cl *cl) { @@ -428,10 +422,7 @@ int mei_connect(struct mei_device *dev, struct mei_cl *cl) mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD; mei_cli_connect->reserved = 0; - if (!mei_write_message(dev, mei_hdr, + return mei_write_message(dev, mei_hdr, (unsigned char *) mei_cli_connect, - sizeof(struct hbm_client_connect_request))) - return 0; - - return 1; + sizeof(struct hbm_client_connect_request)); } diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index a34e2f3a0706..2007d2447b1c 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -263,26 +263,25 @@ quit: static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) { - if (((*slots) * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (!mei_send_flow_control(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); - } else { - dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); - dev->iamthif_state = MEI_IAMTHIF_READING; - dev->iamthif_flow_control_pending = false; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = - mei_host_buffer_is_empty(dev); - } - return 0; - } else { return -EMSGSIZE; } + *slots -= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (mei_send_flow_control(dev, &dev->iamthif_cl)) { + dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); + return -EIO; + } + + dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); + dev->iamthif_state = MEI_IAMTHIF_READING; + dev->iamthif_flow_control_pending = false; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_msg_buf_size = 0; + dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; + dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); + return 0; } /** @@ -306,7 +305,7 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, *slots -= (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_client_disconnect_request) + 3) / 4; - if (!mei_disconnect(dev, cl)) { + if (mei_disconnect(dev, cl)) { cl->status = 0; cb_pos->information = 0; list_move_tail(&cb_pos->cb_list, @@ -838,24 +837,21 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, { if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (!mei_send_flow_control(dev, cl)) { - cl->status = -ENODEV; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } else { - list_move_tail(&cb_pos->cb_list, - &dev->read_list.mei_cb.cb_list); - } - } else { /* return the cancel routine */ list_del(&cb_pos->cb_list); return -EBADMSG; } + *slots -= (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (mei_send_flow_control(dev, cl)) { + cl->status = -ENODEV; + cb_pos->information = 0; + list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); + return -ENODEV; + } + list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list); + return 0; } @@ -881,7 +877,7 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, cl->state = MEI_FILE_CONNECTING; *slots -= (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_client_connect_request) + 3) / 4; - if (!mei_connect(dev, cl)) { + if (mei_connect(dev, cl)) { cl->status = -ENODEV; cb_pos->information = 0; list_del(&cb_pos->cb_list); @@ -938,7 +934,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, mei_hdr->length); *slots -= (sizeof(struct mei_msg_hdr) + mei_hdr->length + 3) / 4; - if (!mei_write_message(dev, mei_hdr, + if (mei_write_message(dev, mei_hdr, (unsigned char *) (cb_pos->request_buffer.data + cb_pos->information), @@ -967,7 +963,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, (*slots) -= (sizeof(struct mei_msg_hdr) + mei_hdr->length + 3) / 4; - if (!mei_write_message(dev, mei_hdr, + if (mei_write_message(dev, mei_hdr, (unsigned char *) (cb_pos->request_buffer.data + cb_pos->information), @@ -1028,7 +1024,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, *slots -= (sizeof(struct mei_msg_hdr) + mei_hdr->length + 3) / 4; - if (!mei_write_message(dev, mei_hdr, + if (mei_write_message(dev, mei_hdr, (dev->iamthif_msg_buf + dev->iamthif_msg_buf_index), mei_hdr->length)) { @@ -1063,7 +1059,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, *slots -= (sizeof(struct mei_msg_hdr) + mei_hdr->length + 3) / 4; - if (!mei_write_message(dev, mei_hdr, + if (mei_write_message(dev, mei_hdr, (dev->iamthif_msg_buf + dev->iamthif_msg_buf_index), mei_hdr->length)) { diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c index a6b969471835..121b3770ec04 100644 --- a/drivers/staging/mei/iorw.c +++ b/drivers/staging/mei/iorw.c @@ -162,7 +162,7 @@ int mei_ioctl_connect_client(struct file *file, && !mei_other_client_is_connecting(dev, cl)) { dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); dev->mei_host_buffer_is_empty = false; - if (!mei_connect(dev, cl)) { + if (mei_connect(dev, cl)) { dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n"); rets = -ENODEV; goto end; @@ -434,13 +434,11 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) cl->read_cb = cb; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; - if (!mei_send_flow_control(dev, cl)) { + if (mei_send_flow_control(dev, cl)) { rets = -ENODEV; goto unlock; - } else { - list_add_tail(&cb->cb_list, - &dev->read_list.mei_cb.cb_list); } + list_add_tail(&cb->cb_list, &dev->read_list.mei_cb.cb_list); } else { list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list); } @@ -500,7 +498,7 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) mei_hdr.me_addr = dev->iamthif_cl.me_client_id; mei_hdr.reserved = 0; dev->iamthif_msg_buf_index += mei_hdr.length; - if (!mei_write_message(dev, &mei_hdr, + if (mei_write_message(dev, &mei_hdr, (unsigned char *)(dev->iamthif_msg_buf), mei_hdr.length)) return -ENODEV; diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index 64456cec2e06..55b390823aed 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -740,7 +740,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, mei_hdr.reserved = 0; dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", *((u32 *) &mei_hdr)); - if (!mei_write_message(dev, &mei_hdr, + if (mei_write_message(dev, &mei_hdr, (unsigned char *) (write_cb->request_buffer.data), mei_hdr.length)) { rets = -ENODEV; diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index f397835d7be9..a6910da78a64 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -74,7 +74,7 @@ bool mei_wd_host_init(struct mei_device *dev) dev_dbg(&dev->pdev->dev, "check wd_cl\n"); if (MEI_FILE_CONNECTING == dev->wd_cl.state) { - if (!mei_connect(dev, &dev->wd_cl)) { + if (mei_connect(dev, &dev->wd_cl)) { dev_dbg(&dev->pdev->dev, "Failed to connect to WD client\n"); dev->wd_cl.state = MEI_FILE_DISCONNECTED; dev->wd_cl.host_client_id = 0; @@ -119,9 +119,7 @@ int mei_wd_send(struct mei_device *dev) else return -EINVAL; - if (mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length)) - return 0; - return -EIO; + return mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length); } /** -- 2.20.1